为什么代码中的 else 部分没有触发游戏的重置功能?

huangapple go评论71阅读模式
英文:

Why is the else part of my code not triggering the reset function of the game?

问题

我希望井字游戏重置并在平局时显示"平局"

但是这似乎不起作用

    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");
            } else {
                img.setImageResource(R.drawable.o);
                activePlayer = 0;
                TextView status = findViewById(R.id.status);
                status.setText("轮到X");
            }
        }
            //检查是否有人赢了
           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赢了";
                   }
                   else if(gameState[winPos[0]]==1){
                       winner = "O赢了";
                   }
                   else{
                       winner="平局"; //这个部分也不起作用,我希望在平局时重置游戏。
                   }
                   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");
    }

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

I want the tic tac toe game to reset and show Draw if it's tied

But this doesn't seem to work.

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(&quot;O&#39;s Turn&quot;);
} else {
img.setImageResource(R.drawable.o);
activePlayer = 0;
TextView status = findViewById(R.id.status);
status.setText(&quot;X&#39;s Turn&quot;);
}
}
//check if someone has won
for(int[] winPos : winPosition){
if(gameState[winPos[0]]==gameState[winPos[1]]
&amp;&amp; gameState[winPos[1]]==gameState[winPos[2]]
&amp;&amp; gameState[winPos[0]]!=2)
{
String winner;
gameActive=false;
if(gameState[winPos[0]]==0){
winner = &quot;X won&quot;;
}
else if(gameState[winPos[0]]==1){
winner = &quot;O won&quot;;
}
else{
winner=&quot;draw&quot;; //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&lt;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(&quot;X&#39;s Turn&quot;);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}

答案1

得分: 0

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 赢了";
} else if (gameState[winPos[0]] == 1) {
    winner = "O 赢了";
} else {
    winner = "平局"; //这部分也无法正常工作,我希望在平局时重置游戏。
}

要么是 X 赢了,要么是 O 赢了,但是不可能是平局,因为外部的if语句已经确定了有人赢了。

要检查是否平局,你只需要在没有设置赢家的情况下退出for循环,然后检查所有的格子是否都不为空。

编辑: 根据请求,将我的建议分成两段代码。

首先,用以下代码替换for循环部分。注意我将winner字符串从循环中拿出来,并且在找到赢家后添加了break来退出循环。类似地,我将获取和设置标签文本值的部分从循环中提取出来,以便它不会在每次迭代时都被调用。

String winner = null;
for (int[] winPos : winPosition) {
  // 是否有人赢了?
  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 赢了";
    } else if (gameState[winPos[0]] == 1) {
      winner = "O 赢了";
    }
    // 找到赢家,退出循环
    break;
  }
}
// 如果还没有赢家,可能是平局
if (winner == null && boardIsFull(gameState)) {
  winner = "平局";
}
// 只有在有值要设置时才设置标签文本
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;
}
英文:

Just inside the for loop, you check

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

This means that somebody must have won: there are three of the same value in a row, and the value is not an empty tile.

When you then have your inner if statement:

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

Either X has won, or O has won, but it cannot be a draw, because the outer if statement has already determined that somebody has won.

To check for a draw, you just need to have the code exit the for loop without having set a winner, and then check that none of the tiles are empty.

EDIT: as requested, adding my suggestion as two code fragments.

First, replace the for loop with the following code. Notice that I pulled the winner string out of the loop and I added a break to exit the loop as soon as a winner is found. Similarly, I pulled the part that fetches and sets the label's text value out of the loop, so that it is not called for every iteration.

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

You will then need an implementation of the boardIsFull method, which is relatively straightforward:

private boolean boardIsFull(int[] gameState) {
  for (int i = 0; i &lt; gameState.length; ++i) {
    if (gameState[i] == 2) {
      return false;
    }
  }
  return true;
}

答案2

得分: 0

在您的代码中:

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 赢了";
        } else if (gameState[winPos[0]] == 1) {
            winner = "O 赢了";
        } else {
            winner = "平局"; // 这部分目前还没有生效,同时我希望在平局时重置游戏。
        }
        TextView status = findViewById(R.id.status);
        status.setText(winner);
    }
}
英文:

In your code:

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

Line A means that the following code is only executed when gameState[winPos[0]] is not 2.

Line B however can only be reached if gameState[winPos[0]] is equal to 2, which cannot be due to the condition on line A.

huangapple
  • 本文由 发表于 2020年8月21日 15:34:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/63518498.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定