使用ncurses开发双陆棋:循环导致棋盘内容异常的问题排查
问题分析与修复方案
核心问题:下半部分棋子循环逻辑完全错误
你后两个循环的边界计算逻辑错误,导致循环根本没有执行,甚至可能因坐标越界覆盖棋盘内容:
错误代码(后两个循环)
// 第三个循环(下半部分右侧) for(int k=BOARD_HEIGHT+START_Y-2; k>BOARD_HEIGHT+START_Y-2+board->pawn_count[i-1]; k--){ mvprintw(k,j,"%c",board->pawn_color[i-1]); } // 第四个循环(下半部分左侧)同理
假设pawn_count[i-1]为2,右侧计算值为BOARD_HEIGHT+START_Y-2+2 = BOARD_HEIGHT+START_Y,而k初始值是BOARD_HEIGHT+START_Y-2,此时k > BOARD_HEIGHT+START_Y不成立,循环直接跳过,自然不会渲染棋子。若pawn_count出现异常值,还可能导致k变成负数,覆盖屏幕顶部内容。
修复方案:重构下半部分绘制逻辑
将从下往上绘制的循环改为从0开始计数,逐次向上偏移,逻辑更直观,避免边界计算失误:
void print_pawns(Board *board){ // 上半部分左侧(13-18位) for(int i=13, j=START_X+2; i<=3*FIELDS/4; i++, j+=4){ for(int k=0; k<board->pawn_count[i-1]; k++){ mvprintw(START_Y+1 + k, j,"%c",board->pawn_color[i-1]); } } // 上半部分右侧(19-24位) for(int i=19, j=CENTER+4; i<=FIELDS; i++, j+=4){ for(int k=0; k<board->pawn_count[i-1]; k++){ mvprintw(START_Y+1 + k, j,"%c",board->pawn_color[i-1]); } } // 下半部分右侧(1-6位) for(int i=1, j=BOARD_WIDTH+START_X-3; i<=FIELDS/4; i++, j-=4){ for(int k=0; k<board->pawn_count[i-1]; k++){ // 从底部向上数第k个位置 mvprintw( (BOARD_HEIGHT+START_Y-2) - k, j,"%c",board->pawn_color[i-1]); } } // 下半部分左侧(7-12位) for(int i=7, j=CENTER-4; i<=FIELDS/2; i++, j-=4){ for(int k=0; k<board->pawn_count[i-1]; k++){ mvprintw( (BOARD_HEIGHT+START_Y-2) - k, j,"%c",board->pawn_color[i-1]); } } }
额外问题:棋盘边框被覆盖的解决
你提到移动输出位置时边框的-变成空白,是因为j的坐标可能误落在边框位置。需确保所有棋子绘制的坐标范围:
- 水平方向:
START_X+1到BOARD_WIDTH+START_X-2(左右边框之间) - 垂直方向:
START_Y+1到BOARD_HEIGHT+START_Y-2(上下边框之间)
调试小技巧
- 在循环内添加
printw("i=%d, j=%d, k=%d\n", i, j, k); refresh();,直接在终端打印坐标值,确认循环是否执行、坐标是否正确。 - 插入
getch();暂停程序,观察每一步的渲染结果。
内容的提问来源于stack exchange,提问作者oskarw7
相关产品推荐
相关产品推荐

