C语言国家接龙游戏:代码重构、UI优化与淘汰逻辑完善
C语言实现Atlas国家接龙游戏优化方案
现存问题对应优化思路
1. 消除重复样板代码
不要把所有逻辑堆在main函数里,按功能拆分独立模块:
- 用
Player结构体统一存储玩家编号、淘汰状态,避免零散定义多组平行变量 - 通用逻辑抽为独立函数:包括国家名校验、输入字符串标准化(大小写统一)、存活玩家统计、下一位玩家索引计算、跨平台清屏,相同逻辑不要在代码里重复写多次
- 国家词库、最大玩家数、字符串最大长度这类固定值用宏定义,后续调整规则不用翻遍代码改硬编码的魔数
- 用整型数组统一标记国家是否被使用,避免每次校验都写重复的遍历逻辑
2. 游戏化命令行交互改造
- 程序启动、回合切换时打印分割线和醒目标题,不同类型输出加明确前缀区分:系统提示、回合提示、错误提示、胜利提示用不同标识,和普通程序日志区分开
- 每回合开始前刷新屏幕,展示当前对局核心信息:剩余存活玩家数、上一个有效国家名、当前需要匹配的首字母,不用玩家自己翻之前的输出记规则
- 淘汰、胜利节点给明确反馈,直接说明判定原因,不要只输出模糊的"输入错误"
- 自动把玩家输入的大写字母转成小写,避免因为大小写问题判定输入无效,降低无意义的挫败感
3. 多玩家续局逻辑重构
- 给每个玩家增加淘汰状态标记,玩家答错后只把对应标记设为已淘汰,不要直接退出整个程序
- 回合轮转时自动跳过已淘汰的玩家,按顺序轮到下一位存活玩家
- 每轮判定结束后统计存活玩家数量,当存活数仅剩1人时立刻终止对局,判定该玩家为最终胜者
- 用索引取模的方式实现玩家轮次循环,不用硬编码固定轮次,适配2人及以上的任意玩家数量对局
参考实现代码
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #include <time.h> // 固定配置宏定义 #define MAX_COUNTRY_LEN 32 #define MAX_PLAYERS 6 #define COUNTRY_LIB_SIZE 19 // 国家词库,可自行扩充 const char* country_lib[COUNTRY_LIB_SIZE] = { "china", "america", "canada", "japan", "korea", "australia", "brazil", "france", "germany", "india", "italy", "mexico", "russia", "spain", "thailand", "turkey", "vietnam", "egypt", "peru" }; // 玩家结构体 typedef struct { int id; int is_eliminated; // 0=未淘汰 1=已淘汰 } Player; // 跨平台清屏 void clear_screen() { #ifdef _WIN32 system("cls"); #else system("clear"); #endif } // 字符串统一转小写 void str_to_lower(char* str) { for(int i=0; str[i]; i++) { str[i] = tolower(str[i]); } } // 查找国家是否在词库中,返回索引,不存在返回-1 int find_country(const char* input) { for(int i=0; i<COUNTRY_LIB_SIZE; i++) { if(strcmp(input, country_lib[i]) == 0) { return i; } } return -1; } // 统计存活玩家数量 int count_alive(Player* players, int total_p) { int cnt = 0; for(int i=0; i<total_p; i++) { if(!players[i].is_eliminated) cnt++; } return cnt; } // 获取下一个存活玩家的索引 int get_next_player(int cur_idx, Player* players, int total_p) { int next = (cur_idx + 1) % total_p; while(players[next].is_eliminated) { next = (next + 1) % total_p; } return next; } int main() { srand(time(NULL)); int player_num; Player players[MAX_PLAYERS]; int used[COUNTRY_LIB_SIZE] = {0}; // 标记国家是否被使用 char last_country[MAX_COUNTRY_LEN]; char input[MAX_COUNTRY_LEN]; // 初始化界面 clear_screen(); puts("================================="); puts(" ATLAS 国家接龙游戏 "); puts(" 规则:接上一个国家的尾字母说国家 "); puts(" 不能重复,说错直接淘汰,最后存活获胜"); puts("================================="); printf("请输入参与玩家数量(2-%d):", MAX_PLAYERS); scanf("%d", &player_num); // 清洗输入缓冲区 while(getchar() != '\n'); if(player_num <2 || player_num > MAX_PLAYERS) { puts("[错误] 玩家数量不符合要求"); return 1; } // 初始化玩家 for(int i=0; i<player_num; i++) { players[i].id = i+1; players[i].is_eliminated = 0; } // 随机选第一个国家作为开局 int start_idx = rand() % COUNTRY_LIB_SIZE; strcpy(last_country, country_lib[start_idx]); used[start_idx] = 1; char need_start = last_country[strlen(last_country)-1]; int cur_player = 0; // 主游戏循环 while(count_alive(players, player_num) > 1) { clear_screen(); puts("-------------------"); printf("[对局状态] 剩余存活玩家:%d人\n", count_alive(players, player_num)); printf("[上一个有效国家] %s\n", last_country); printf("[当前要求] 请输入以字母 %c 开头的国家名:\n", need_start); printf("[玩家%d的回合] 请输入:", players[cur_player].id); scanf("%s", input); str_to_lower(input); // 校验输入 int c_idx = find_country(input); int valid = 1; if(c_idx == -1) { printf("[判定] 玩家%d淘汰!%s 不在有效国家词库中\n", players[cur_player].id, input); valid = 0; } else if(used[c_idx]) { printf("[判定] 玩家%d淘汰!%s 已经被使用过\n", players[cur_player].id, input); valid = 0; } else if(input[0] != need_start) { printf("[判定] 玩家%d淘汰!%s 首字母不是%c\n", players[cur_player].id, input, need_start); valid = 0; } if(!valid) { players[cur_player].is_eliminated = 1; // 淘汰后暂停一下让玩家看提示 puts("按回车键继续对局..."); while(getchar() != '\n'); getchar(); } else { // 输入有效,更新状态 used[c_idx] = 1; strcpy(last_country, input); need_start = last_country[strlen(last_country)-1]; } // 轮到下一个玩家 cur_player = get_next_player(cur_player, players, player_num); } // 游戏结束,公布胜者 clear_screen(); puts("================================="); printf("🎉 游戏结束!玩家%d 获得最终胜利!\n", players[cur_player].id); puts("================================="); return 0; }
代码说明
- 代码做了跨平台兼容,Windows和Linux/macOS下都可以正常编译运行
- 输入自动转小写,不会因为玩家输入大写字母判定错误
- 每轮淘汰后会暂停等待玩家确认,不会直接清屏跳过淘汰提示
- 词库存放在全局数组中,想要扩充国家列表直接往
country_lib里加字符串、同步修改COUNTRY_LIB_SIZE宏的值即可 - 所有配置项都放在代码开头的宏定义里,调整最大玩家数、国家名长度不需要改核心逻辑
内容的提问来源于stack exchange,提问作者vedbanerjee
相关产品推荐
相关产品推荐

