我已经为自己的井字游戏编写了以下代码:
#include <stdio.h>
#include <math.h>
void instructions();
void printboard(char board[3][3]);
int wincheck(char board[3][3]);
int main(){
char tictac[3][3] = {{'-', '-', '-'}, {'-', '-', '-'}, {'-', '-', '-'}};
int player = 0;
int win = 0;
int player_choice = 0;
int row = 0;
int col = 0;
instructions();
for(int i=0; i<9 && win==0; i++){
printboard(tictac);
player = i%2 + 1;
do{
printf("\nPlayer #%d, enter your spot choice:\n", player);
scanf("%d", &player_choice);
if(player_choice == 1){
row = 0;
col = 0;
}
else if(player_choice == 2){
row = 0;
col = 1;
}
else if(player_choice == 3){
row = 0;
col = 2;
}
else if(player_choice == 4){
row = 1;
col = 0;
}
else if(player_choice == 5){
row = 1;
col = 1;
}
else if(player_choice == 6){
row = 1;
col = 2;
}
else if(player_choice == 7){
row = 2;
col = 0;
}
else if(player_choice == 8){
row = 2;
col = 1;
}
else if(player_choice == 9){
row = 2;
col = 2;
}
else{
printf("Not a valid choice, please choose again.");
}
}while(player_choice<0 || player_choice>9 || tictac[row][col]!='-');
if(player == 1){
tictac[row][col] = 'X';
}
else if(player == 2){
tictac[row][col] = 'O';
}
if(wincheck(tictac)!=0){
win = player;
}
}
printboard(tictac);
if(!win){
printf("\n\nTHE GAME IS A DRAW!\n");
}
else{
printf("\n\nCONGRATULAIONS PLAYER #%d, YOU WON!\n", win);
}
}
void instructions(){
printf("\n\t\t\t WELCOME TO TIC TAC TOE!\n");
printf("\nGame Rules:\n");
printf("\nThe program will ask the player to enter which spot they would like to place their X or O.\nPlease use spot numbers as shown below:\n\n");
printf("\t\t\t\t 1 | 2 | 3 \n");
printf("\t\t\t\t---+---+---\n");
printf("\t\t\t\t 4 | 5 | 6 \n");
printf("\t\t\t\t---+---+---\n");
printf("\t\t\t\t 7 | 8 | 9 \n");
printf("\n\t------------------------LET'S BEGIN!------------------------\n\n\n");
}
void printboard(char board[3][3]){
printf("\t\t\t\t %c | %c | %c \n", board[0][0], board[0][1], board[0][2]);
printf("\t\t\t\t---+---+---\n");
printf("\t\t\t\t %c | %c | %c \n", board[1][0], board[1][1], board[1][2]);
printf("\t\t\t\t---+---+---\n");
printf("\t\t\t\t %c | %c | %c \n", board[2][0], board[2][1], board[2][2]);
}
int wincheck(char board[3][3]){
if((board[0][0]==board[0][1] && board[0][0]==board[0][2]) || (board[1][0]==board[1][1] && board[1][0]==board[1][2]) || (board[2][0]==board[2][1] && board[2][0]==board[2][2])){
return 1;/*Checks to see if player has won across any of the rows.*/
}
else if((board[0][0]==board[1][0] && board[0][0]==board[2][0]) || (board[0][1]==board[1][1] && board[0][1]==board[2][1]) || (board[0][2]==board[1][2] && board[0][2]==board[2][2])){
return 1;/*Checks to see if player has won down any columns.*/
}
else if((board[0][0]==board[1][1] && board[0][0]==board[2][2]) || (board[0][2]==board[1][1] && board[0][2]==board[2][0])){
return 1;/*Checks to see if player has won in a diagonal.*/
}
else{
return 0;
}
}
我尝试玩游戏时遇到了问题。在第一个玩家选择&#34;游戏点后#34;它认为他们已经赢了。因此我认为这个问题很可能是由于wincheck函数出错,但我无法弄清楚究竟是什么导致了这个问题。我是一名初学程序员,所以如果这是一个愚蠢的问题我会道歉。非常感谢您提供的任何帮助!
答案 0 :(得分:0)
问题是确实与您的wincheck
函数有关。它正确地检查了三个候选单元是否相等,但是不检查了那些单元是否已被填充。这意味着即使在采取任何行动之前,该游戏也将被检测为获胜(由于 all 所有单元格都设置为-
,因此将通过简单的相等性检查)。
因此,仅进行 相等性检查还不够,还必须确保至少有 个这样的单元已被设置为真实玩家。
您还可以通过一些重构使代码更具可读性,例如:
// Returns the actual winner, or '-' if none. Needs x/y start cell
// and x/y deltas (direction, basically).
int checkOneWinPossibility(char board[3][3], int x, int y, int xd, int yd) {
// Check all no-winner scenarios, return winner only if they all fail.
if (board[x][y] == '-') return '-';
if (board[x][y] != board[x+xd][y+yd]) return '-';
if (board[x][y] != board[x+xd*2][y+yd*2]) return '-';
return board[x][y];
}
int checkAllWinPossibilities(char board[3][3]){
int winner;
// Horizontals.
if ((winner = checkOneWinner(board, 0, 0, 0, 1)) != '-') return winner;
if ((winner = checkOneWinner(board, 1, 0, 0, 1)) != '-') return winner;
if ((winner = checkOneWinner(board, 2, 0, 0, 1)) != '-') return winner;
// Verticals.
if ((winner = checkOneWinner(board, 0, 0, 1, 0)) != '-') return winner;
if ((winner = checkOneWinner(board, 0, 1, 1, 0)) != '-') return winner;
if ((winner = checkOneWinner(board, 0, 2, 1, 0)) != '-') return winner;
// Diagonals.
if ((winner = checkOneWinner(board, 0, 0, 1, 1)) != '-') return winner;
if ((winner = checkOneWinner(board, 2, 0, -1, 1)) != '-') return winner;
return '-';
}
只需执行以下操作即可将最后一个对角线检查 与return
语句组合在一起:
return checkOneWinner(board, 2, 0, -1, 1);
但是我更喜欢(稍微强迫症)将其保持不变:-)
他们都返回了 actual 赢家,而不仅仅是表明有赢家。您可能不需要该信息,因为它显然是最后移动的玩家,但是返回额外信息可能并没有实质性危害。