我的代码卡住了一些东西,所以我可以完成它。我为一项作业制作了一个tic tac toe游戏,但我被卡住了。教授要求我们进行输入验证,然后我将其中的大部分都删除了。
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();
}
}
答案 0 :(得分:0)
要获得不会引发异常的数字输入验证,您需要执行类似的操作
int num;
while(true){
try{
Scanner input = new Scanner(System.in);
num = Integer.parseInt(input.nextLine());
break;
}catch(NumberFormatException e){}
}
这将继续循环,直到你输入一个可以转换为int的字符串,因此是一个数字。
答案 1 :(得分:0)
您可以简单地获取下一个字符并将其与“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
}
答案 2 :(得分:0)
所以你的计划还有很多。关于playerMove()
和playGame()
方法中循环的主要问题,我可以在this帖子的帮助下修复它。现在playGame()
方法将:
1)检查输入是否可以解释为int
2)检查输入是否在有效行范围内
3)检查输入是否在有效列范围内
4)检查输入是否未尝试覆盖占用的单元格
如果输入无效,playGame()
方法将为用户提供另一个输入新值的机会。
您的代码中存在大量冗余,例如:
if (row >= ROWS|| row < 0 || column >= COLS || column < 0)
在您输入之前测试列的值。
然后直接检查现场是否被占用if (row >= 0 && row <= ROWS - 1 && column >= 0 && column <= COLS - 1)
。在这里,您基本上执行相同的if
语句,但语法不同,实际上您根本不需要重新检查。另一个问题是你还在用户输入列之前检查一个点是否被占用。这在游戏的早期阶段是多余的,并且在董事会填满时没有意义,因为它可能已经发出警告,即[[]行[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);
}
关于游戏的其他问题,不承认抽奖(实际上不仅抽奖未被承认,而且胜利被忽略了),解决方案非常简单。在playGame()
方法中,您只需在break
返回 true 的部分添加playerMove()
语句,并在电路板变满的部分中添加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;
}
方法。我添加了
true
部分,以便当一行中有3个相同类型时,该方法返回一个值。同样,我们在这里看到冗余,您继续检查无需执行此操作的位置,因为您已经获得了所需的答案(在这种情况下,获胜者为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;
}
)。所以这里是变化:
date -d 20160219 +%s%6N