Я хочу, чтобы игра в крестики-нолики сбросилась и показывала Draw, если она связана

Но, похоже, это не работает.

package com.codewithmischief.tictactoe;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import org.w3c.dom.Text;

public class MainActivity extends AppCompatActivity {
boolean gameActive = true;
int activePlayer = 0;
int[] gameState = {2,2,2,2,2,2,2,2,2};
int[][] winPosition={
                 {0,1,2},{3,4,5},{6,7,8},
                 {0,3,6},{1,4,7},{6,7,8},
                 {0,4,8},{6,4,2}
                     };

public void tapBtn(View view) {
    ImageView img = (ImageView) view;

    int tappedImg = Integer.parseInt(img.getTag().toString());
    if(!gameActive){
        gameReset(view);
    }
    if(gameState[tappedImg] == 2) {
        gameState[tappedImg] = activePlayer;
        if (activePlayer == 0) {
            img.setImageResource(R.drawable.x);
            activePlayer = 1;
            TextView status = findViewById(R.id.status);
            status.setText("O's Turn");
        } else {
            img.setImageResource(R.drawable.o);
            activePlayer = 0;
            TextView status = findViewById(R.id.status);
            status.setText("X's Turn");
        }
    }
        //check if someone has won
       for(int[] winPos : winPosition){

           if(gameState[winPos[0]]==gameState[winPos[1]]
                   && gameState[winPos[1]]==gameState[winPos[2]]
                   && gameState[winPos[0]]!=2)
           {
               String winner;
               gameActive=false;
               if(gameState[winPos[0]]==0){
                  winner = "X won";
               }
               else if(gameState[winPos[0]]==1){
                   winner = "O won";
               }
               else{
                   winner="draw"; //this one is not working also i want it to reset the game when draw.
               }
               TextView status=findViewById(R.id.status);
               status.setText(winner);

           }

       }
}


public void gameReset(View view) {
    gameActive = true;
    activePlayer = 0;
    for(int i=0; i<gameState.length;i++){
        gameState[i]=2;
    }
    ((ImageView)findViewById(R.id.imageView0)).setImageResource(0);
    ((ImageView)findViewById(R.id.imageView1)).setImageResource(0);
    ((ImageView)findViewById(R.id.imageView2)).setImageResource(0);
    ((ImageView)findViewById(R.id.imageView3)).setImageResource(0);
    ((ImageView)findViewById(R.id.imageView4)).setImageResource(0);
    ((ImageView)findViewById(R.id.imageView5)).setImageResource(0);
    ((ImageView)findViewById(R.id.imageView6)).setImageResource(0);
    ((ImageView)findViewById(R.id.imageView7)).setImageResource(0);
    ((ImageView)findViewById(R.id.imageView8)).setImageResource(0);
    TextView status = findViewById(R.id.status);
    status.setText("X's Turn");
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}
}
-1
Mayuresh Raval 21 Авг 2020 в 10:34

2 ответа

Лучший ответ

Просто внутри цикла for вы проверяете

if (gameState[winPos[0]] == gameState[winPos[1]]
 && gameState[winPos[1]] == gameState[winPos[2]]
 && gameState[winPos[0]] != 2)

Это означает, что кто-то должен выиграть: в строке есть три одинаковых значения, и это значение не является пустой плиткой.

Когда у вас появится внутреннее утверждение if:

if (gameState[winPos[0]] == 0) {
    winner = "X won";
} else if (gameState[winPos[0]] == 1) {
    winner = "O won";
} els e{
    winner="draw"; //this one is not working also i want it to reset the game when draw.
}

Либо X выиграл, либо O выиграл, но это не может быть ничья , потому что внешний оператор if уже определил, что кто-то выиграл.

Чтобы проверить наличие ничьей, вам просто нужно, чтобы код вышел из цикла for без определения победителя, а затем проверьте, что ни одна из плиток не пуста.

ИЗМЕНИТЬ : по запросу, добавив мое предложение в виде двух фрагментов кода.

Сначала замените цикл for следующим кодом. Обратите внимание, что я вытащил строку winner из цикла и добавил break, чтобы выйти из цикла, как только будет найден победитель. Точно так же я вытащил из цикла часть, которая выбирает и устанавливает текстовое значение метки, так что оно не вызывается для каждой итерации.

String winner = null;
for (int[] winPos : winPosition) {
  // Did somebody win?
  if (gameState[winPos[0]] == gameState[winPos[1]]
      && gameState[winPos[1]] == gameState[winPos[2]]
      && gameState[winPos[0]] != 2) {
    gameActive = false;
    if (gameState[winPos[0]] == 0) {
      winner = "X won";
    } else if (gameState[winPos[0]] == 1) {
      winner = "O won";
    }
    // We found the winner, so exit the loop
    break;
  }
}
// If there is no winner yet, it might be a draw
if (winner == null && boardIsFull(gameState)) {
  winner = "draw";
}
// Only set the label text if there is a value to set
if (winner != null) {
  TextView status = findViewById(R.id.status);
  status.setText(winner);
}

Затем вам понадобится реализация метода boardIsFull, который относительно прост:

private boolean boardIsFull(int[] gameState) {
  for (int i = 0; i < gameState.length; ++i) {
    if (gameState[i] == 2) {
      return false;
    }
  }
  return true;
}
0
Billy Brown 21 Авг 2020 в 08:07

В вашем коде:

   for(int[] winPos : winPosition){

       if(gameState[winPos[0]]==gameState[winPos[1]]
               && gameState[winPos[1]]==gameState[winPos[2]]
/* A */        && gameState[winPos[0]]!=2)
       {
           String winner;
           gameActive=false;
           if(gameState[winPos[0]]==0){
              winner = "X won";
           }
           else if(gameState[winPos[0]]==1){
               winner = "O won";
           }
/* B */    else{
               winner="draw"; //this one is not working also i want it to reset the game when draw.
           }
           TextView status=findViewById(R.id.status);
           status.setText(winner);

       }

Строка A означает, что следующий код выполняется, только если gameState[winPos[0]] не равно 2.

Однако линия B может быть достигнута только в том случае, если gameState[winPos[0]] равно 2, что не может быть связано с условием в строке A.

0
Thomas Kläger 21 Авг 2020 в 07:43