【问题标题】:Assistance with a loop循环辅助
【发布时间】:2016-05-30 03:08:33
【问题描述】:

我的代码被困在一些事情上,所以我可以完成它。我正在为一项任务制作井字游戏,但我被卡住了。教授要求我们进行输入验证,我把大部分都记下来了。

playGame 中我有“输入无效”的最后几行,我希望它循环并询问你是否要重新开始游戏,我可以输入一个不是 1 或 0 的数字,但如果我输入一个字母相反,它会不断循环,直到抛出异常。

我在 playerMove 中有一个输入验证,它做同样的事情。如果我放一封信,它会一遍又一遍地循环。如果我输入了一个不可接受的数字,它会说它无效,但它会抛出异常。与您输入 2 之类的数字相比,它会询问您是否想玩的第一个问题。它会说它不是正确的输入并再次提出问题,但我似乎无法在其他方法中复制它。

另外,我似乎无法以平局结束比赛,我不知道为什么。如果有人可以帮忙,那就太好了,我根本想不通。

import java.util.Scanner; //Used for player's input in game



public class TicTacToe 
{

//instance variables
private char[][] board; //Tic Tac Toe Board, 2d array
private boolean xTurn; // true when X's turn, false if O's turn
private Scanner input; // Scanner for reading input from keyboard

//Constants for creation of gameboard
public final int ROWS = 3; //total rows
public final int COLS = 3; //total columns
public final int WIN = 3; //amount needed to win

public TicTacToe()

{
    //creates the board
    board = new char[ROWS][COLS];

    for(int r = 0; r < ROWS; r++)
    {
        for(int c = 0; c < COLS; c++)
        {   
            board[r][c] = ' ';
        }
    }

    //X's turn when game starts
    xTurn = true; 

    //creates our input object for the turn player
    input = new Scanner(System.in);
}
    //shows game board
    public void displayBoard()

    {   
    int colNum = 0; //number of columns
    int rowNum = 0; //number of rows

    //creates column labels
    System.out.println(" \n");
    System.out.println("     Columns ");
    for (int num = 0; num < COLS; num++)
    {
        System.out.print("   " + colNum);
        colNum++;
    }

    //creates vertical columns and spaces between each spot 
    System.out.println(" \n");
    for (int row = 0; row < ROWS; row++) 
    {
        //numbers rows
        System.out.print(" " + rowNum + "  ");
        rowNum++;

        for (int col = 0; col < COLS; ++col) 
        {

            System.out.print(board[row][col]); // print each of the cells

            if (col != COLS - 1) 
            {
                System.out.print(" | ");   // print vertical partition
            }   
     }

     System.out.println();

     //creates seperation of rows
     if (row != ROWS - 1) 
     {
        System.out.println("   ------------"); // print horizontal partition
     }

    }
    //labels row
    System.out.println("Rows \n");
    }

    //displays turn player
    public void displayTurn()
    {
        if (xTurn)
        {
            System.out.println("X's Turn");

        }
        else
        {
            System.out.println("O's Turn");
        }


    }

    //allows you to make move
    public boolean playerMove()
    {
        boolean invalid = true;
        int row = 0;
        int column = 0;

        while(invalid)
        {
            System.out.println("Which row (first) then column (second) would you like to \n"
                    + "play this turn? Enter 2 numbers between 0-2 as \n"
                    + "displayed on the board, seperated by a space to \n"
                    + "choose your position.");
            if (input.hasNextInt())
            {
            row = input.nextInt();

            if (row >= ROWS|| row < 0 || column >= COLS || column < 0)
                {
                    System.out.println("Invalid position");
                }

            if (row >= 0 && row <= ROWS - 1 && column >= 0 && column <= COLS - 1)
            {
                if (board[row][column] != ' ')
                {
                    System.out.println("Spot is taken \n");
                }

                else
                {
                    invalid = false;
                }

            }



            }
            else
            {
                System.out.println("Invalid position");
            }

            if(input.hasNextInt())
            {
            column = input.nextInt();

             if (row >= ROWS|| row < 0 || column >= COLS || column < 0)
                {
                    System.out.println("Invalid position");
                }

            //checks if spot is filled
            if (row >= 0 && row <= ROWS - 1 && column >= 0 && column <= COLS - 1)
            {
                if (board[row][column] != ' ')
                {
                    System.out.println("Spot is taken \n");
                }
                else
                {
                    invalid = false;
                }

            }



            }
            else
                {
                    System.out.println("Invalid position");
                }
//fills spot if not taken
            if (xTurn)
            {
                board[row][column] = 'X';
            }
            else
            {
                board[row][column] = 'O';
            }
        }
        return displayWinner(row,column);       
    }


    public boolean displayWinner(int lastR, int lastC)
    {
        boolean winner = false;
        int letter = board[lastR][lastC];

        //checks row for win
        int spotsFilled = 0;
        for (int c = 0; c < COLS; c++)
        {
            if(board[lastR][c] == letter)
            {
                spotsFilled++;
            }
        }

        if (spotsFilled == WIN)
        {
            winner = true;


        }

        //checks columns for win
        spotsFilled = 0;
        for (int r = 0; r < ROWS; r++)
        {
            if(board[r][lastC] == letter)
            {
                spotsFilled++;
            }
        }

        if (spotsFilled == WIN)
        {
            winner = true;

        }

        //checks diagonals for win
        spotsFilled = 0;
        for (int i = 0; i < WIN; i++)
        {
            if(board[i][i] == letter)
            {
                spotsFilled++;
            }
        }

        if(spotsFilled == WIN)
        {
            winner = true;

        }

        //checks other diagonal
        spotsFilled = 0;
        for(int i = 0; i < COLS; i++)
        {
            if(board[i][(COLS-1)- i] == letter)
            {
                spotsFilled++;
            }
        }
        if(spotsFilled == WIN)
        {
            winner = true;

        }


        return winner;
    }

//checks if board is full
public boolean fullBoard()
{
    int filledSpots = 0;

    for(int r = 0; r < ROWS; r++)
    {
        for (int c = 0; c < COLS; c++)
        {
            if (board[r][c] == 'X' || board[r][c] == 'O')
            {
                filledSpots++;
            }
        }
    }
    return filledSpots == ROWS*COLS;
}

//plays game
public void playGame()
{
    boolean finish = true;
    System.out.println("Are your ready to start?");
    System.out.println("1 for Yes or 0 for No? : ");

    if (input.hasNextInt())
    {
        int choice = input.nextInt();

        if(choice > 1 || choice < 0)
    {
        System.out.println("Invalid choice");
        playGame();
    }

    else if (choice == 1)
    {
    while (finish)
    {
        displayBoard();
        displayTurn();

        if (playerMove())
        {
            displayBoard();
            if (xTurn)
            {
                System.out.println("X won");
                displayBoard();
            }
            else
            {
                System.out.println("O won");
                displayBoard();
            }

        }
        else if (fullBoard())
        {
            displayBoard(); 
            System.out.println("Draw");


        }
        else
        {
            xTurn=!xTurn;
        }

        }

    }
}
    else 
    {
        System.out.println("Input not valid");
        playGame();
    }
}

}

和测试人员

public class TicTacToeTester {

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {

    TicTacToe tictactoe = new TicTacToe();

    tictactoe.playGame();
}

}

【问题讨论】:

    标签: java validation loops tic-tac-toe


    【解决方案1】:

    要获得不引发异常的数字输入验证,您需要执行以下操作

    int num;
        while(true){
            try{
                Scanner input = new Scanner(System.in);
                num = Integer.parseInt(input.nextLine());
                break;
            }catch(NumberFormatException e){}
        }
    

    这将一直循环,直到您输入一个可以转换为 int 的字符串,因此是一个数字。

    【讨论】:

    • 教授说我们无法捕获或抛出异常。我能够在不抛出异常的情况下完成它,但他们只是一遍又一遍地循环问题
    【解决方案2】:

    您可以简单地获取下一个字符并将其与“0”或“1”进行比较。

    试试这个:

    String userInput = input.nextLine();
    if(userInput.charAt(0) == '0' || userInput.charAt(0) == '1'){
        //do what you have to do if it is a 0 or 1
    }
    else {
       //do what you have to do if it is an invalid input
    }
    

    【讨论】:

      【解决方案3】:

      所以你的程序发生了很多事情。关于playerMove()playGame() 方法中循环的主要问题,我能够在this 帖子的帮助下修复它。现在playGame() 方法将:

      1)检查输入是否可以解释为int

      2)检查输入是否在有效行范围内

      3)检查输入是否在有效的列范围内

      4)检查输入是否不尝试覆盖占用的单元格

      如果用户的输入无效,playGame() 方法现在将为用户提供另一个输入新值的机会。

      您的代码中有很多冗余,例如:

      if (row &gt;= ROWS|| row &lt; 0 || column &gt;= COLS || column &lt; 0) 您在输入列之前测试列的值。 之后直接检查位置是否被占用if (row &gt;= 0 &amp;&amp; row &lt;= ROWS - 1 &amp;&amp; column &gt;= 0 &amp;&amp; column &lt;= COLS - 1)。在这里,您基本上执行了相同的if 语句,但使用了不同的语法,实际上您根本不需要重新检查。另一个问题是,在用户输入列之前,您还要检查一个位置是否已被占用。这在游戏的早期阶段是多余的,并且在棋盘填满时没有意义,因为它可能会发出警告,指出点 [row][0] 已满(当然,0 是您设置的默认值)在用户输入之前初始化列变量,并且行是行的值输入)。当然,您在下一节中重复相同的操作,当前面的if 语句已经证明行值有效时再次检查行值,但我不会深入讨论,因为它几乎相同。所以事不宜迟,下面是新的playerMove() 方法:

      public boolean playerMove()
          {
              int row = 0;
              int column = 0;
      
              System.out.println("Which row (first) then column (second) would you like to \n"
                      + "play this turn? Enter 2 numbers between 0-2 as \n"
                      + "displayed on the board, seperated by a space to \n"
                      + "choose your position.");
              while(true){
                  System.out.println("Enter row number:");
                  while (true)
                  {
                      if(!input.hasNextInt()){ //Checking row number validity
                          System.out.println("Input not valid, try again!");
                          input.next();
                          continue;
                      }   
                      row=input.nextInt();
                      if(row >= ROWS|| row < 0 ){ //Checking row range
                          System.out.println("Invalid position, rows out of range! Try again:");
                          //input.next();
                          continue;
                      }
                      break;
                  }
      
                  System.out.println("Enter column number:");
                  while(true){
                      if(!input.hasNextInt()){    //Checking column number validity
                          System.out.println("Input not valid, try again:");
                          input.next();
                          continue;
                      }   
                      column = input.nextInt();
                      if (column >= COLS || column < 0)   //Checking column range
                      {
                          System.out.println("Invalid position, columns out of range! Try again:");
                          input.next();
                          continue;
                      }
                      break;
                  }
                  //checks if spot is filled
                  if (board[row][column] != ' ')
                  {
                      System.out.println("Spot is taken, pick a new position:");
                      continue;
                  }
                  break;
              }
      
              //fills spot if not taken
              if (xTurn)
                  board[row][column] = 'X';
              else
                  board[row][column] = 'O';
              return displayWinner(row,column);
          }
      

      至于你的游戏不承认draws的另一个问题(实际上不仅draws未被承认,而且wins strong> 被忽略),解决方案非常简单。在您的 playGame() 方法中,您只需要在 playerMove() 返回 true 的部分以及在没有赢家的情况下董事会已满的部分添加一个 break 语句。这将结束游戏并退出无休止的while 循环(终止进程中的程序)。这是新的playGame() 确认游戏结束(获胜/平局)和错误循环免费:

      public void playGame()
          {
              //boolean finish = true;
              System.out.println("Are your ready to start?");
              System.out.println("1 for Yes or 0 for No? : ");
              //int choice=input.nextInt();
              while(!input.hasNextInt()){
                  System.out.println("Input not valid, try again!");
                  input.next();
                  //int choice=input.next();
              }
              int choice=input.nextInt();
              System.out.print("choice is "+choice);
              if(choice > 1 || choice < 0)
              {
                  System.out.println("Invalid choice");
                  playGame();
              }
      
              else if (choice == 1)
              {
                  while (true)
                  {
                      displayBoard();
                      displayTurn();
      
                      if (playerMove())
                      {
                          displayBoard();
                          if (xTurn)
                          {
                              System.out.println("X won");
                              displayBoard();
                              break;
                          }
                          else
                          {
                              System.out.println("O won");
                              displayBoard();
                              break;
                          }
      
                      }
                      else if (fullBoard())
                      {
                          displayBoard(); 
                          System.out.println("Draw");
                          break;
                      }
                      else
                      {
                          xTurn=!xTurn;
                      }
                  }
              }
          }
      

      我想添加的另一件事是您的displayWinner(..) 方法。我加了

      if (spotsFilled == WIN)
              {
                  return winner = true;
      
              }
      

      部分,以便当连续有 3 个相同类型时该方法返回一个值。同样,我们在这里看到了冗余,您继续检查不需要这样做的地方,因为您已经有了所需的答案(在这种情况下,获胜者是 true)。所以这里是变化:

      public boolean displayWinner(int lastR, int lastC)
          {
              boolean winner = false;
              int letter = board[lastR][lastC];
      
              //checks row for win
              int spotsFilled = 0;
              for (int c = 0; c < COLS; c++)
              {
                  if(board[lastR][c] == letter)
                  {
                      spotsFilled++;
                  }
              }
      
              if (spotsFilled == WIN)
              {
                  return winner = true;
      
              }
      
              //checks columns for win
              spotsFilled = 0;
              for (int r = 0; r < ROWS; r++)
              {
                  if(board[r][lastC] == letter)
                  {
                      spotsFilled++;
                  }
              }
      
              if (spotsFilled == WIN)
              {
                  return winner = true;
      
              }
      
              //checks diagonals for win
              spotsFilled = 0;
              for (int i = 0; i < WIN; i++)
              {
                  if(board[i][i] == letter)
                  {
                      spotsFilled++;
                  }
              }
      
              if(spotsFilled == WIN)
              {
                  return winner = true;
      
              }
      
              //checks other diagonal
              spotsFilled = 0;
              for(int i = 0; i < COLS; i++)
              {
                  if(board[i][(COLS-1)- i] == letter)
                  {
                      spotsFilled++;
                  }
              }
              if(spotsFilled == WIN)
              {
                  return winner = true;
      
              }
              return winner;
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-12-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多