C语言井字棋项目:main函数中switch语句未执行直接跳至棋盘
C语言井字棋菜单不显示问题修复
问题根源
- 未初始化的switch条件:全局变量
choices没有初始值,程序启动时是随机垃圾值,几乎不可能匹配case 1,导致菜单代码直接被跳过,程序直接进入后续游戏循环。 - 逻辑顺序颠倒:菜单流程完全搞反——应该先打印菜单、获取用户选择,再用switch处理用户的选择(
def变量),而非用未初始化的choices作为switch判断条件。 - 语法与调用错误:
case 1里的void displayBoard();是函数声明,不是调用,正确写法为displayBoard();case 3的struct Player;、case 4的fclose;都是无效语法,无实际功能- 选择说明后直接进入游戏循环,不符合菜单交互逻辑
修复后的完整代码
#include <stdio.h> #include <conio.h> // 若使用gcc编译,可替换为getchar()或调整输入处理 char square[] = { 'o', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; int checkWin(); struct Player { char init[3]; // 玩家缩写 char xo; // X或O int wins; // 胜场 int losses; // 负场 int ties; // 平局 int turn; // 回合 }; int checkWin() { if (square[1] == square[2] && square[2] == square[3]) return 1; else if (square[4] == square[5] && square[5] == square[6]) return 1; else if (square[7] == square[8] && square[8] == square[9]) return 1; else if (square[1] == square[4] && square[4] == square[7]) return 1; else if (square[2] == square[5] && square[5] == square[8]) return 1; else if (square[3] == square[6] && square[6] == square[9]) return 1; else if (square[1] == square[5] && square[5] == square[9]) { return 1; } else if (square[3] == square[5] && square[5] == square[7]) return 1; else if (square[1] != '1' && square[2] != '2' && square[3] != '3' && square[4] != '4' && square[5] != '5' && square[6] != '6' && square[7] != '7' && square[8] != '8' && square[9] != '9') return 0; else { return -1; } } void displayBoard() { printf("\n\n\tTic Tac Toe\n\n"); printf("Player 1 (X) - Player 2 (O)\n\n\n"); // 棋盘显示 printf(" | | \n"); printf(" %c | %c | %c \n", square[1], square[2], square[3]); printf("_____|_____|_____\n"); printf(" | | \n"); printf(" %c | %c | %c \n", square[4], square[5], square[6]); printf("_____|_____|_____\n"); printf(" | | \n"); printf(" %c | %c | %c \n", square[7], square[8], square[9]); printf(" | | \n\n"); } // 重置棋盘,用于新游戏 void resetBoard() { for(int i=1; i<=9; i++) { square[i] = '0' + i; } } void showInstructions() { printf("----INSTRUCTIONS----\n\n"); printf("To begin the game, select play in the menu.\n"); printf("This is your board:\n\n"); printf("----------\n"); printf("1 | 2 | 3\n"); printf("----------\n"); printf("4 | 5 | 6\n"); printf("----------\n"); printf("7 | 8 | 9\n"); printf("----------\n\n"); printf("Players will take turns inputting their X or O by entering the number on the board.\n"); printf("The first player to get three of their letter in a row wins.\n\n"); printf("Press any key to return to menu..."); getch(); printf("\n\n"); } void showStatistics(struct Player p1, struct Player p2) { printf("----STATISTICS----\n\n"); printf("Player 1 (%c):\n", p1.xo); printf("Wins: %d Losses: %d Ties: %d\n\n", p1.wins, p1.losses, p1.ties); printf("Player 2 (%c):\n", p2.xo); printf("Wins: %d Losses: %d Ties: %d\n\n", p2.wins, p2.losses, p2.ties); printf("Press any key to return to menu..."); getch(); printf("\n\n"); } int main() { int player = 1, i, choice; char mark; int def; struct Player p1 = {"P1", 'X', 0, 0, 0, 1}; struct Player p2 = {"P2", 'O', 0, 0, 0, 2}; while(1) { // 菜单循环 // 打印菜单 printf("\t\t\t1. PLAY\n"); printf("\t\t\t2. INSTRUCTIONS\n"); printf("\t\t\t3. STATISTICS\n"); printf("\t\t\t4. EXIT\n\n"); printf("\t\t\tENTER A NUMBER (1-4): "); scanf("%d", &def); switch(def) { case 1: resetBoard(); // 重置棋盘 do { displayBoard(); player = (player % 2) ? 1 : 2; printf("Player %d, enter a number: ", player); scanf("%d", &choice); mark = (player == 1) ? 'X' : 'O'; if (choice >=1 && choice <=9 && square[choice] == '0' + choice) { square[choice] = mark; } else { printf("Invalid move! "); player--; getch(); } i = checkWin(); player++; } while (i == -1); displayBoard(); if (i == 1) { printf("==>\aPlayer %d wins!\n", --player); if(player ==1) { p1.wins++; p2.losses++; } else { p2.wins++; p1.losses++; } } else { printf("==>\aGame draw!\n"); p1.ties++; p2.ties++; } printf("Press any key to return to menu..."); getch(); printf("\n\n"); player =1; // 重置玩家回合 break; case 2: showInstructions(); break; case 3: showStatistics(p1, p2); break; case 4: printf("Exiting game..."); return 0; default: printf("Invalid choice! Please enter 1-4.\n"); getch(); printf("\n\n"); } } return 0; }
修复说明
- 重构菜单逻辑:用
while(1)循环包裹菜单,支持用户多次选择操作 - 初始化玩家结构体,实现基础胜负统计功能
- 添加棋盘重置函数,避免多局游戏时棋盘状态混乱
- 修正函数调用错误,调整为"先打印菜单获取选择,再用switch处理"的正确流程
- 修复无效语法,完善输入校验逻辑
- 添加返回菜单的交互提示,提升用户体验
内容的提问来源于stack exchange,提问作者newah
相关产品推荐
相关产品推荐

