使用NCurses在C语言中持久化Worldle游戏每行字符颜色的方法
解决NCurses版Worldle中历史行颜色被覆盖的问题
问题根源
你的代码存在几个关键问题导致历史行颜色被覆盖:
- 重复初始化颜色对:每次调用
verificare_cuvant都执行start_color()和init_pair(1),且始终用同一个颜色对ID(1),新的颜色设置会覆盖旧的,导致之前的行颜色错误。 - 未定位光标到新行:每次输出新单词时没有移动光标到下一行,导致新内容直接覆盖旧内容的位置。
- 频繁局部刷新:每个字符输出后就调用
wrefresh,容易引发屏幕绘制冲突。
修复步骤
- 全局初始化颜色:在程序启动时仅调用一次
start_color(),提前定义所有需要的颜色对(比如绿色用ID1,黄色用ID2),避免重复覆盖。 - 跟踪当前输入行:添加变量记录已猜行数,每次处理新单词前用
wmove()将光标定位到新行的起始位置。 - 整行绘制后统一刷新:处理完整行的字符和颜色后,再调用一次
wrefresh,减少不必要的屏幕更新。 - 优化字母匹配逻辑:匹配到正确位置的字母后,及时减少对应字母的计数,避免后续错误匹配黄色。
修改后的代码示例
首先在程序初始化阶段完成颜色配置(只执行一次):
// 程序启动时的初始化代码 initscr(); cbreak(); noecho(); start_color(); // 预定义颜色对:ID1=白字绿底,ID2=白字黄底 init_pair(1, COLOR_WHITE, COLOR_GREEN); init_pair(2, COLOR_WHITE, COLOR_YELLOW);
然后修改verificare_cuvant函数,添加行号参数定位光标:
void verificare_cuvant(char cuvant_verificare[10], WINDOW * chenar_verificare, char cuvant_de_ghicit[6], int *castig, int current_row) { int alfabet[127], gasit; memset(alfabet, 0, sizeof(alfabet)); int word_len = strlen(cuvant_de_ghicit); // 统计目标单词的字母数量 for(int i = 0; i < word_len; i++) { alfabet[(unsigned char)cuvant_de_ghicit[i]]++; } // 定位光标到当前行的起始位置(假设每行从第0列开始) wmove(chenar_verificare, current_row, 0); if(strcmp(cuvant_verificare, cuvant_de_ghicit) == 0) { wattron(chenar_verificare, COLOR_PAIR(1)); wprintw(chenar_verificare, "%s", cuvant_verificare); wattroff(chenar_verificare, COLOR_PAIR(1)); (*castig) = 1; } else { for (int i = 0; i < word_len; i++) { if (cuvant_verificare[i] == cuvant_de_ghicit[i]) { wattron(chenar_verificare, COLOR_PAIR(1)); wprintw(chenar_verificare, "%c", cuvant_verificare[i]); wattroff(chenar_verificare, COLOR_PAIR(1)); // 匹配正确位置后,减少对应字母的剩余计数 alfabet[(unsigned char)cuvant_verificare[i]]--; } else { gasit = 0; // 检查当前字母是否存在于目标单词的剩余数量中 if (alfabet[(unsigned char)cuvant_verificare[i]] > 0) { wattron(chenar_verificare, COLOR_PAIR(2)); wprintw(chenar_verificare, "%c", cuvant_verificare[i]); wattroff(chenar_verificare, COLOR_PAIR(2)); alfabet[(unsigned char)cuvant_verificare[i]]--; gasit = 1; } if (gasit == 0) { // 默认黑底白字直接输出 wprintw(chenar_verificare, "%c", cuvant_verificare[i]); } } } } // 整行处理完成后统一刷新窗口 wrefresh(chenar_verificare); }
使用说明
调用函数时需维护一个current_row变量,初始值为0,每完成一次猜词就将其加1,确保新内容输出到下一行:
int current_row = 0; int win_flag = 0; // 第一次猜词 verificare_cuvant(guess_word, game_win, target_word, &win_flag, current_row); current_row++; // 第二次猜词 verificare_cuvant(guess_word2, game_win, target_word, &win_flag, current_row); current_row++;
内容的提问来源于stack exchange,提问作者vasile ion
相关产品推荐
相关产品推荐

