Моя игра «Крестики-нолики» считает победителя всякий раз, когда подряд выпадают любые 3 символа. Как я могу это исправить?

Я делаю простую игру в крестики-нолики, но есть довольно большая проблема. По сути, всякий раз, когда есть любые 3 символа в ряду (не обязательно 3 O или 3 X, просто любые три, игра считает, что кто-то выиграл). Я знаю, что это проблема с моим методом checkWin, но я не совсем уверен, в чем именно.

Следует отметить, что я назвал свои кнопки 1-10 вместо 0-9, что было плохой идеей в ретроспективе, поскольку массивы начинаются с 0. Я думаю, что это может быть причиной моей проблемы.

Вот что у меня есть со скриншотом приложения.

Большое спасибо,

Люк

package com.example.tictactoe;

import androidx.appcompat.app.AppCompatActivity;

import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

private TextView PlayerOneScore, PlayerTwoScore, winStatus;
private Button [] mButtons = new Button[10];
private Button reset;

private int PlayerOneScoreCount, PlayerTwoScoreCount, roundCount;
boolean PlayerTurn;

int [] gameState = {2,2,2,2,2,2,2,2,2,2};

int [][] winStates = {
        {1,2,3},{4,5,6},{7,8,9},
        {1,4,7},{2,5,8},{3,6,9},
        {1,5,9},{3,5,7}};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    PlayerOneScore = (TextView)findViewById(R.id.P1Score);
    PlayerTwoScore = (TextView)findViewById(R.id.P2Score);
    winStatus = (TextView)findViewById(R.id.winStatus);

    reset = (Button) findViewById(R.id.reset);

    for (int i=1; i < mButtons.length; i++){
        String buttonID = "btn" + i;
        int resourceID = getResources().getIdentifier(buttonID, "id", getPackageName());
        mButtons[i] = (Button) findViewById(resourceID);
        mButtons[i].setOnClickListener(this);
    }

    roundCount = 0;
    PlayerOneScoreCount = 0;
    PlayerTwoScoreCount = 0;
    PlayerTurn = true;
}

@Override
public void onClick(View v) {
    if (!((Button)v).getText().toString().equals("")){
        return;
    }
    String buttonID = v.getResources().getResourceEntryName(v.getId());
    int gameStatePointer = Integer.parseInt(buttonID.substring
            (buttonID.length()-1, buttonID.length()));

    if (PlayerTurn){
        ((Button)v).setText("X");
        ((Button)v).setTextColor(Color.parseColor("#545454"));
        gameState[gameStatePointer] = 0;
    }else {
        ((Button)v).setText("O");
        ((Button)v).setTextColor(Color.parseColor("#F2EBD3"));
        gameState[gameStatePointer] = 0;
    }
    roundCount++;

    if (checkWin()){
        if (PlayerTurn){
            PlayerOneScoreCount++;
            updatePlayerScore();
            Toast.makeText(this, "Player One Won!", Toast.LENGTH_SHORT).show();
            playAgain();
        }else {
            PlayerTwoScoreCount++;
            updatePlayerScore();
            Toast.makeText(this, "Player Two Won!", Toast.LENGTH_SHORT).show();
            playAgain();
        }

    }else if (roundCount == 9){
        playAgain();
        Toast.makeText(this, "It's a Draw!", Toast.LENGTH_SHORT).show();
    }else {
        PlayerTurn = !PlayerTurn;
    }

    if (PlayerOneScoreCount > PlayerTwoScoreCount){
        winStatus.setText("Player One is Winning!");
    }else if (PlayerTwoScoreCount > PlayerOneScoreCount){
        winStatus.setText("Player Two is Winning!");
    }else {
        winStatus.setText("");
    }

    reset.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            playAgain();
            PlayerOneScoreCount = 0;
            PlayerTwoScoreCount = 0;
            winStatus.setText("");
            updatePlayerScore();
        }
    });
}

public boolean checkWin(){
    boolean Winner = false;

    for (int [] winningState : winStates){
        if (gameState[winningState[0]] == gameState[winningState[1]] &&
                gameState[winningState[1]] == gameState[winningState[2]] &&
                    gameState[winningState[0]]!=2){
            Winner = true;
        }
    }
    return Winner;
}

public void updatePlayerScore(){
    PlayerOneScore.setText(Integer.toString(PlayerOneScoreCount));
    PlayerTwoScore.setText(Integer.toString(PlayerTwoScoreCount));
}

public void playAgain(){
    roundCount = 0;
    PlayerTurn = true;

    for (int i = 1; i < mButtons.length; i++){
        gameState[i] = 2;
        mButtons[i].setText("");
    }
}
}

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
98
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я не совсем уверен, но я думаю, что это могут быть значения, которые вы установили в своем игровом состоянии. Насколько я вижу, вы всегда устанавливаете его на 0 в своем методе onClick.

if (PlayerTurn){
        ((Button)v).setText("X");
        ((Button)v).setTextColor(Color.parseColor("#545454"));
        gameState[gameStatePointer] = 0;
    }else {
        ((Button)v).setText("O");
        ((Button)v).setTextColor(Color.parseColor("#F2EBD3"));
        gameState[gameStatePointer] = 0;
    }

Затем, когда вы проверяете, равны ли значения в игровом состоянии, каждое поле, которое было нажато, имеет 0, поэтому они равны. Вы, вероятно, хотели установить из них другое целое число

Ответ принят как подходящий

В checkWin() вы перебираете различные выигрышные состояния, чтобы увидеть, выиграл ли кто-либо из игроков, сравнивая все Button, которые «принадлежат» данному выигрышному состоянию.

Поскольку вы всегда устанавливаете значение состояния игры равным нулю, если был нажат Button, независимо от того, чей сейчас ход, у вас будет «победитель», как только будут нажаты все Button, принадлежащие одному выигрышному состоянию.

TL;DR Вы можете решить эту проблему, установив разные значения в onClick() в зависимости от того, чья сейчас очередь:

    if (PlayerTurn){
        ((Button)v).setText("X");
        ((Button)v).setTextColor(Color.parseColor("#545454"));
        gameState[gameStatePointer] = 1;
    }else {
        ((Button)v).setText("O");
        ((Button)v).setTextColor(Color.parseColor("#F2EBD3"));
        gameState[gameStatePointer] = 0;
    }

Спасибо вам обоим! Я знал, что это было что-то очень маленькое, как это! Теперь все работает отлично, большое спасибо за помощь! <3

Super 22.12.2020 01:59

Другие вопросы по теме