为什么循环停止迭代?

时间:2014-03-25 21:13:35

标签: java loops do-while tic-tac-toe

我是一名初学者,正在为我的班级编写一个gui tic-tac-toe程序。 (没有玩家,只是计算机生成)。

我的程序中的所有内容都按预期工作,除了一件事;似乎我的checkWinner方法调用的放置位置不正确,因为X&O和O的分配总是完成。一旦有胜利者,为什么要赢得循环结束?

它将根据方法调用返回正确的获胜者,但for循环将继续迭代并填写其余的(所以有时它看起来像x和o win或者一个赢得两次)。我一直在疯狂,认为可能是我的checkWinner方法调用和if语句的位置。当我设置取消循环的winner = true;不应该?我试过把它放在每个for循环之间,内部和外部,没有运气:(

我已经标记了我认为问题的区域 //这里有什么问题?// 在该部分的右侧代码。谢谢你的任何输入!! :)

  public void actionPerformed(ActionEvent e)
  {
    int total = 0, i = 0;
    boolean winner = false;


    //stop current game if a winner is found
    do{

      // Generate random # 0-1 for the labels and assign 
      // X for a 0 value and O for a 1 value

      for (int row = 0; row < gameboard.length; row++) //rows
      {
        for (int col = 0; col < gameboard[row].length; col++) //columns
        { 

          //Generate random number
          gameboard[row][col] = (int)(Math.random() * 2);  

          //Assign proper values
          if(gameboard[row][col] == 0)
          {
            labels[i].setText("X");
            gameboard[row][col] = 10; //this will help check for the winner
          }

          else if(gameboard[row][col] == 1)
          {
            labels[i].setText("O");   
            gameboard[row][col] = 100; //this will help check for winner
          }             


          /**Send the array a the method to find a winner
            The x's are counted as 10s
            The 0s are counted as 100s
            if any row, column or diag = 30, X wins
            if any row, column or diag = 300, Y wins
            else it will be a tie
            */

          total = checkWinner(gameboard);      **//Is this okay here??//**
          if(total == 30 || total == 300)        //
            winner = true;                //Shouldn't this cancel the do-while?


          i++; //next label

        }
      }//end for
    }while(!winner);//end while



    //DISPLAY WINNER
    if(total == 30)
      JOptionPane.showMessageDialog(null, "X is the Winner!");
    else if(total == 300)
      JOptionPane.showMessageDialog(null, "0 is the Winner!");
    else
      JOptionPane.showMessageDialog(null, "It was a tie!");
  }

5 个答案:

答案 0 :(得分:2)

最简单的方法是立即中断所有循环。 (即使有些人不喜欢这样)

outerwhile: while(true){

  // Generate random # 0-1 for the labels and assign 
  // X for a 0 value and O for a 1 value

  for (int row = 0; row < gameboard.length; row++) //rows
  {
    for (int col = 0; col < gameboard[row].length; col++) //columns
    { 

      total = checkWinner(gameboard);     
      if(total == 30 || total == 300)        
        break outerwhile;  //leave outer while, implicit canceling all inner fors.


      i++; //next label
    }
  }//end for
}//end while

这不会允许“平局”选项,因为如果没有找到胜利者,则基本上将重启游戏。为了获得平局,你根本不需要外线,并且当找到胜利者时可以立即离开两个人:

  Boolean winner = false;
  outerfor: for (int row = 0; row < gameboard.length; row++) //rows
  {
    for (int col = 0; col < gameboard[row].length; col++) //columns
    { 

      total = checkWinner(gameboard);     
      if(total == 30 || total == 300){        
        winner = true;     
        break outerfor;  //leave outer for, implicit canceling inner for.

      }

      i++; //next label
    }
  }//end for

  if (winner){
    //winner
  }else{
     //tie.
  }

答案 1 :(得分:0)

在两个winner循环完成之前,您不会检查for的值。设置break后立即添加winner = true,然后添加

if (winner)
{
    break;
}

到外部for循环的开头或结尾。

答案 2 :(得分:0)

您的问题是您的do / while语句包含在for语句中。因此for语句在到达while语句之前最终会运行整个循环。解决这个问题的一个解决方案是在for语句中检查获胜者并打破:

//stop current game if a winner is found
do {

    for (int row = 0; row < gameboard.length; row++) //rows
    {
        for (int col = 0; col < gameboard[row].length; col++) //columns
        { 

            // ... your other code ...

            total = checkWinner(gameboard);
            if(total == 30 || total == 300) {
                winner = true;
                break; // end current for-loop
            }

            i++; //next label
        }

        if (winner) break; // we have a winner so we want to kill the for-loop
    } //end for

} while(!winner); //end while

所以你应该能够循环完成两个for-statement并打破胜利者。你的代码似乎也没有处理绑定案例,但我猜你已经知道了。

答案 3 :(得分:0)

我认为你应该改变你的循环条件并添加一个bool。

你有一个&#34;领带&#34;条件,但目前你只检查胜利者。没有checkWinner代码的唯一解释是你每次都遇到平局。

因此...

boolean tie;
boolean winner;

do {
//your stuff
}
while(!(tie || winner))

编辑:我没有意识到你将while循环放在for循环之外,你需要打破for循环才能检查while条件。

//stop current game if a winner is found
    do{

      for (int row = 0; row < gameboard.length; row++) //rows
      {
        for (int col = 0; col < gameboard[row].length; col++) //columns
        { 
            if(winner || tie)
                break;
        }//end for

        if(winner || tie)
            break;
      }//end for
    }while(!(winner || tie));//end while
//the rest of your stuff here

答案 4 :(得分:0)

首先,你的代码在板上迭代并生成X和O的随机标记。这导致一些非常奇怪的板状态,总是逐行填充,并且可能具有不平衡的X和O标记数量

恕我直言,你应该以相反的方式组织你的代码,以填补类似真实游戏的董事会。我的意思是一系列9个标记'XOXOXOXOX'在板上传播。

Labels labels为九个字符的数组,初始化为9个空格。

public int doGame( Labels labels)
{
    labels = "         ";
    int itisXmove = true;              // player X or O turn
    for( int movesLeft = 9; movesLeft > 0; movesLeft --)
    {
        int position =          // 0 .. movesLeft-1
                (int) Math.floor(Math.random() * movesLeft);

        for( int pos = 0; pos < 9; pos ++)        // find position
            if( labels[ pos] == " ")              // unused pos?
                if( position-- == 0)              // countdown
                {
                    if( itisXmove)                // use the pos
                        labels[ pos] = "X";       // for current player
                    else
                        labels[ pos] = "O";
                    break;
                }

        int result = checkWinner( labels);        // who wins (non-zero)?
        if( result != 0)
            return result;

        itisXmove = ! itisXmove;                  // next turn
    }
    return 0;                                     // a tie
}

然后

public void actionPerformed(ActionEvent e)
{
    Labels labels;

    int result = doGame( labels);

    if( result == valueForX)
        JOptionPane.showMessageDialog(null, "X is the Winner!");
    else if( result == valueForO)
        JOptionPane.showMessageDialog(null, "O is the Winner!");
    else
        JOptionPane.showMessageDialog(null, "It's a tie!");

    for( int rowpos = 0; rowpos < 9; rowpos += 3)
    {
        for( int colpos = 0; colpos < 3; colpos ++)
            /* output (char)label[ rowpos + colpos] */;

        /* output (char)newline */;
    }
}