Я делаю простую игру в крестики-нолики, но есть довольно большая проблема. По сути, всякий раз, когда есть любые 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("");
}
}
}
Я не совсем уверен, но я думаю, что это могут быть значения, которые вы установили в своем игровом состоянии. Насколько я вижу, вы всегда устанавливаете его на 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