首先,我希望允许我在这里寻求一些调试帮助。话虽如此,我已经创建了这个简单的小井字游戏,基本上已经完成了,但是这个语义错误一直在杀死我。
显然,我花了一些时间试图自己找出问题所在,但你可以说我已经放弃了,所以我现在就在这里 :)
对于一些简要概述,该板由 char ttt[3][3] 类型的数组表示。玩家也是 char 类型的变量,因此它们不是“X”就是“O”,棋盘坐标以字母形式输入:
示例运行将如下所示:
********************************
---a------b------c---
| | | |
---d------e------f---
| | | |
---g------h------i---
| | | |
---------------------
player1: O, it is your turn.
Select a cell [a, b, c, ... i]
a
********************************
---a------b------c---
| O | | |
---d------e------f---
| | | |
---g------h------i---
| | | |
---------------------
player2: X, it is your turn.
Select a cell [a, b, c, ... i]
数组 ttt[3][3] 被初始化,使得每个元素都只是 ' '。
在大多数情况下,程序运行良好。为了为你们节省一些时间,我相信以下方法运行良好
- 布尔获胜者(字符播放器)
- 布尔游戏IsDraw()
- 无效的显示板()
- 字符串播放器ID(字符播放器)
- 和主要方法
我确实看到问题很可能包含在我的 getPlayerInput(char player) 方法中:
void getPlayerInput(char player)
{
int row = 0;
int col = 0;
System.out.println(playerID(player) + ", it is your turn.");
System.out.println("Select a cell [a, b, c, ... i]");
char answer;
answer = scan.next().charAt(0);
switch(answer)
{
case 'a':
row = 0;
col = 0;
break;
case 'b':
row = 0;
col = 1;
break;
case 'c':
row = 0;
col = 2;
break;
case 'd':
row = 1;
col = 0;
break;
case 'e':
row = 1;
col = 1;
break;
case 'f':
row = 1;
col = 2;
break;
case 'g':
row = 2;
col = 0;
break;
case 'h':
row = 2;
col = 1;
break;
case 'i':
row = 2;
col = 2;
break;
default:
System.out.println("Invalid location, try again.");
getPlayerInput(player);
}
if(ttt[row][col] != ' ')
{
System.out.println("This square is taken. Try again.");
getPlayerInput(player);
}
else
{
ttt[row][col] = player;
}
}
对我来说,它看起来不错,但我的输出表明并非如此。该方法包括两个故障保险,
如果用户输入了超出棋盘范围的内容('a' 到 'i' 之外的字符),
或者如果用户在板上选择了已经被另一个“X”或“O”占据的字母/位置。
在这两种情况下,该方法都会打印出输入了一些错误的输入,然后再次调用 getPlayerInput()。
我通过调试注意到的是,如果只输入有效的输入,程序似乎运行良好。但是,如果输入了错误的输入(任一类型),然后输入了有效的输入,有时该方法会打印仍然输入了错误的输入。
例如,
********************************
---a------b------c---
| | | |
---d------e------f---
| | | |
---g------h------i---
| | | |
---------------------
player1: O, it is your turn.
Select a cell [a, b, c, ... i]
a
********************************
---a------b------c---
| O | | |
---d------e------f---
| | | |
---g------h------i---
| | | |
---------------------
player2: X, it is your turn.
Select a cell [a, b, c, ... i]
z
Invalid location, try again.
player2: X, it is your turn.
Select a cell [a, b, c, ... i]
e
This square is taken. Try again.
player2: X, it is your turn.
Select a cell [a, b, c, ... i]
f
********************************
---a------b------c---
| O | | |
---d------e------f---
| | X | X |
---g------h------i---
| | | |
---------------------
player1: O, it is your turn.
Select a cell [a, b, c, ... i]
请注意,我输入了 char 的 azef。'z' 显然是一个无效字符,因此该方法按预期工作(到目前为止),打印出它是无效输入,然后该方法再次运行,要求输入。然后输入了“e”,显然是一个有效的位置,但是该方法打印出“正方形已经被占用”,而显然不是。但是,输入不同的字符“f”允许我退出它。
最终结果是玩家“X”有两个回合并填满了“e”和“f”两个方格。
应该注意的是,如果用户不断输入错误的输入,他应该一直停留在该方法中,直到输入有效的输入,但这显然是一个好的输入被误解为错误输入的情况,并且循环可以'除非输入了不同的良好输入实例,否则将退出。
所以,说了这么多,帮助meee?无论如何,我非常感谢任何有耐心读到这里的人......
如果您想自己运行代码,以下是源代码:
import java.util.*;
class TicTacToe
{
char ttt[][] = new char[3][3];
static final char player1 = 'O';
static final char player2 = 'X';
Scanner scan =new Scanner(System.in);
String playerID(char player)
{
if (player == player1)
return "player1: "+player;
else
return "player2: "+ player;
}
void getPlayerInput(char player)
{
int row = 0;
int col = 0;
System.out.println(playerID(player) + ", it is your turn.");
System.out.println("Select a cell [a, b, c, ... i]");
char answer;
answer = scan.next().charAt(0);
switch(answer)
{
case 'a':
row = 0;
col = 0;
break;
case 'b':
row = 0;
col = 1;
break;
case 'c':
row = 0;
col = 2;
break;
case 'd':
row = 1;
col = 0;
break;
case 'e':
row = 1;
col = 1;
break;
case 'f':
row = 1;
col = 2;
break;
case 'g':
row = 2;
col = 0;
break;
case 'h':
row = 2;
col = 1;
break;
case 'i':
row = 2;
col = 2;
break;
default:
System.out.println("Invalid location, try again.");
getPlayerInput(player);
}
if(ttt[row][col] != ' ')
{
System.out.println("This square is taken. Try again.");
getPlayerInput(player);
}
else
{
ttt[row][col] = player;
}
}
boolean gameIsDraw()
{
boolean isDraw = true;
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 3; j++)
{
if(ttt[i][j] == ' ')
{
isDraw = false;
}
}
}
return isDraw;
}
boolean winner(char player)
{
boolean hasWon = false;
// possible horizontal wins
for(int i = 0; i < 3; i++)
{
if(ttt[i][0] == player && ttt[i][1] == player && ttt[i][2] == player)
{
hasWon = true;
}
}
// possible vertical wins
for(int i = 0; i < 3; i++)
{
if(ttt[0][i] == player && ttt[1][i] == player && ttt[2][i] == player)
{
hasWon = true;
}
}
// one diagonal win
if(ttt[0][0] == player && ttt[1][1] == player && ttt[2][2] == player)
{
hasWon = true;
}
// other diagonal win
if(ttt[0][2] == player && ttt[1][1] == player && ttt[2][0] == player)
{
hasWon = true;
}
return hasWon;
}
void displayBoard()
{
System.out.println("********************************");
System.out.println(" ---a------b------c---");
for (int i=0; i<3; i++)
{
for (int j=0; j< 3; j++)
{
if (j == 0) System.out.print(" | ");
System.out.print(ttt[i][j]);
if (j < 2) System.out.print( " | ");
if (j==2) System.out.print(" |");
}
System.out.println();
switch (i)
{
case 0:
System.out.println(" ---d------e------f---");
break;
case 1:
System.out.println(" ---g------h------i---");
break;
case 2:
System.out.println(" ---------------------");
break;
}
}
}
void newgame()
{
char currPlayer = player1;
for(int i=0; i<3; i++)
for(int j=0; j<3; j++)
ttt[i][j] =' ';
boolean continueFlag = true;
while (continueFlag)
{
displayBoard();
if (gameIsDraw())
{
System.out.println("Game Ends in Draw");
continueFlag = false;
}
else
{
getPlayerInput(currPlayer);
if (winner(currPlayer))
{
System.out.println("We have a winner: " + playerID(currPlayer));
displayBoard();
continueFlag = false;
}
else
{
if (currPlayer == player1) currPlayer = player2;
else currPlayer = player1;
}
}
}
}
public static void main(String[] args)
{
TicTacToe game = new TicTacToe();
String str;
do
{
game.newgame();
System.out.println("Do you want to play Tic-Tac-Toe (y/n)?");
str= game.scan.next();
} while ("y".equals(str));
System.out.println("Bye");
}
}