井字棋(Tic Tac Toe)首步标记不显示问题求助
井字棋首步标记无法显示的问题
我是编程新手,刚接触C语言,目前和伙伴开发井字棋(Tic Tac Toe)项目时遇到问题:首位玩家的第一步标记无法在控制台显示,但后续步骤的标记显示正常,且程序能正确识别该位置已被占用。
问题控制台输出
Welcome to Tic Tac Toe! To make a selection, enter the row and column of the square you want to play. Ex. 0,2 for first row, third column. | | ----------- | | ----------- | | Player 1, choose between X or O to play: X Do you want to start first? (Y/N): Y Player , Where would you like to go? Enter the row and then columns seperated by a comma here (e.g. 0,2): 1,1 | | ----------- | | ----------- | | Player X, Where would you like to go? Enter the row and then columns seperated by a comma here (e.g. 0,2):
项目代码
// Tic Tac Toe game #include <stdio.h> #include <stdbool.h> #include <ctype.h> #define PLAYER_X 'X' #define PLAYER_O 'O' #define OPEN ' ' // use globals for now char player1, player2; // player is limited to X or O char winner = '\0'; char board[3][3] = // board is 3 rows by 3 columns { {OPEN, OPEN, OPEN}, {OPEN, OPEN, OPEN}, {OPEN, OPEN, OPEN} }; // declare functions here void show_directions(); void show_cat(); void show_winner(); void display_board(); char choose_player1_mark (); bool select_first_player(); void play(char player); bool is_winner(char player); bool is_board_full(); char get_next_player(char current_player); int main() { char player; show_directions(); // welcome text hey this is tic tac toe display_board(); player1 = choose_player1_mark(); player2 = (player1 == PLAYER_X) ? PLAYER_O : PLAYER_X; player = select_first_player(); while(!is_board_full()) { play(player); display_board(); if (is_winner(player)) break; else player = get_next_player(player); } if (winner) show_winner(); else show_cat(); return 0; } // define functions here void show_directions() { printf("Welcome to Tic Tac Toe!\n"); printf("To make a selection, enter the row and column of the square you want to play.\n"); printf("Ex. 0,2 for first row, third column.\n"); } void display_board() { printf("\n\n"); printf(" %c | %c | %c \n", board[0][0], board[0][1], board[0][2]); printf("-----------\n"); printf(" %c | %c | %c \n", board[1][0], board[1][1], board[1][2]); printf("-----------\n"); printf(" %c | %c | %c \n", board[2][0], board[2][1], board[2][2]); printf("\n\n\n"); } char choose_player1_mark() { char choice; printf("Player 1, choose between X or O to play: "); while (1) { scanf(" %c", &choice); choice = toupper(choice); if (choice == PLAYER_X || choice == PLAYER_O) return choice; else printf("Invalid choice. Please enter 'X' or 'O': "); } } bool select_first_player() { char choice; printf("Do you want to start first? (Y/N): "); while (1) { scanf(" %c", &choice); choice = toupper(choice); if (choice == 'Y') return true; // player 1 starts first else if(choice == 'N') return false; // player 2 starts first else printf("Invalid choice. Please enter 'Y' or 'N': "); } } void play(char player) { int row, column; printf("Player %c, Where would you like to go?\n", player); printf("Enter the row and then columns seperated by a comma here (e.g. 0,2): "); scanf("%d,%d", &row, &column); while (row < 0 || row > 2 || column < 0 || column > 2 || board[row][column] != OPEN) { printf("Invalid input. Try again.\n"); printf("Enter the row and then columns seperated by a comma here (e.g. 0,2): "); scanf("%d,%d", &row, &column); } board[row][column] = player; } bool is_board_full() { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (board[i][j] == OPEN) return false; } } return true; } bool is_winner(char player) { // Check rows for (int i = 0; i < 3; i++) { if (board[i][0] == player && board[i][1] == player && board [i][2] == player) { winner = player; return true; } } // Check columns for (int j = 0; j < 3; j++) { if (board[0][j] == player && board[1][j] == player && board[2][j] == player) { winner = player; return true; } } // Check diagonals if (board[0][0] == player && board [1][1] == player && board[2][0] == player) { winner = player; return true; } return false; } char get_next_player(char current_player) { return (current_player == PLAYER_X) ? PLAYER_O : PLAYER_X; } void show_winner() { if (winner == PLAYER_X || winner == PLAYER_O) { printf("Player %c wins!\n:", winner); } else { printf("It's a tie! Cat game. \n"); } } void show_cat() { printf("It's a tie! Cat game.\n"); }
问题分析与修复
核心问题1:返回值类型不匹配
select_first_player返回bool类型,但main里用char player接收。true对应ASCII码1,false对应0,都是不可见字符,导致:
- 第一步
play函数里的提示打印出Player , ... - 落子后棋盘存入的是1/0,
display_board打印时无法显示可见标记。
核心问题2:对角线胜利条件错误
is_winner里的对角线判断写错,应该是board[0][0] == player && board[1][1] == player && board[2][2] == player,且遗漏了另一条对角线board[0][2] == player && board[1][1] == player && board[2][0] == player。
修复步骤
1. 修正select_first_player函数
将返回类型改为char,直接返回对应玩家的标记:
// 修改函数声明 char select_first_player(); // 修改函数实现 char select_first_player() { char choice; printf("Do you want to start first? (Y/N): "); while (1) { scanf(" %c", &choice); choice = toupper(choice); if (choice == 'Y') return player1; // 返回玩家1的标记 else if(choice == 'N') return player2; // 返回玩家2的标记 else printf("Invalid choice. Please enter 'Y' or 'N': "); } }
2. 修正对角线判断逻辑
在is_winner函数中替换对角线判断代码:
// Check diagonals if (board[0][0] == player && board[1][1] == player && board[2][2] == player) { winner = player; return true; } // 补充另一条对角线判断 if (board[0][2] == player && board[1][1] == player && board[2][0] == player) { winner = player; return true; }
3. 修正show_winner的输出错误
去掉多余的冒号:
printf("Player %c wins!\n", winner);
修复后,第一步的玩家标记会正常显示,落子后棋盘能正确打印标记,对角线胜利条件也能正常触发。
内容的提问来源于stack exchange,提问作者birdawesome
相关产品推荐
相关产品推荐

