You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 08:39:20