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

C语言终端游戏角色与L型障碍物均无法移动问题排查

C语言游戏故障排查

故障描述

  • 预期功能:
    • 自带标题界面,支持退出或开始游戏
    • 开始游戏后渲染游戏字符数组,玩家可通过a/d/s按键控制角色O左移、右移、下移
    • 每向下移动一行获得积分,踩到P点位获得额外积分
    • 玩家到达y坐标202且积分为正则获胜,渲染恭喜界面;积分变为负值(踩到#点位或碰到每0.5秒下移的L型墙)则失败,渲染失败界面并支持退出或重开
  • 故障现象:玩家控制的角色O和L型障碍物完全无法移动

问题代码

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <fcntl.h>
#include <unistd.h>

char quickchar(float delay);
void render();
void titleRender();
void renderLoss();
void renderWin();
int score();

char titlescreen[20][59] = { };
char diffdiff[20][46] = {
    (Grid removed due to char limit)                       
};
char gameover[20][50] = {
    (Grid removed due to char limit)                       
};
char gameboard[203][26] = {
    (Grid removed due to char limit)
};

int playerx;
int playery;
int pts;

void entryRender();
void gameRender();

int main() {
    int input;
    char replay;
    int lx;
    int ly;
    char walkin;
    int gaming;
    char titlechoice;
    int diff;
    int running;

    lx = 0;
    ly = 0;
    running = 1;
    playerx = 13;
    playery = 5;
    pts = 25;
    gaming = 0;

    while (gaming == 0) {
        titleRender();
        printf("\033[1;32m");
        printf("\nPress 'p' to play or 'x' to exit!");
        printf("\033[0m");
        scanf(" %c", &titlechoice);
               
        if (titlechoice == 'p') {
            gaming += 4;
        }

        if (titlechoice == 'x') {
            return 0;
        }
    }

    while (gaming == 4) {
        system("stty -echo raw");
        render();
        printf("\033[1;35m");
        printf("Choose a direction: s/Down, a/Left, d/Right.\n\r");
        printf("\033[0m");
        walkin = quickchar(0.5);
        scanf("%c", &walkin);
        //obj behaviour

        if (walkin == 's' && 
            gameboard[playery +1][playerx] != '#' && 
            gameboard[playery + 1][playerx] != '+' && 
            gameboard[playery + 1][playerx] != '|' &&                                                                             
            gameboard[playery + 1][playerx] != '-') { 
            playery++;
            pts += 5;

            if (gameboard[playery + 1][playerx] == '#') {
                pts -= 25;
            }

            if (gameboard[playery + 1][playerx] == 'P') {
                printf("Points increased!\n\r");
                pts += 50;
                gameboard[playery + 1][playerx] = '_';
            }
        }
        else if (walkin == 'a' && 
                 gameboard[playery][playerx - 1] != '#' && 
                 gameboard[playery][playerx - 1] != '+' && 
                 gameboard[playery][playerx - 1] != '|' && 
                 gameboard[playery][playerx - 1] != '-') {
            playerx--;
           
            if (gameboard[playery][playerx - 1] == '#') {
                pts -= 25;
            }

            if (gameboard[playery][playerx - 1] == 'P') {
                printf("Points increased!\n\r");
                pts += 50;
                gameboard[playery][playerx - 1] = '_';
            }
        } 
        else if (walkin == 'd' && 
                 gameboard[playery][playerx + 1] != '#' && 
                 gameboard[playery][playerx + 1] != '+' &&
                 gameboard[playery][playerx + 1] != '|' &&
                 gameboard[playery][playerx + 1] != '-') {
             playerx++;
            
             if (gameboard[playery][playerx + 1] == '#') {
                 pts -= 25;
             }

             if (gameboard[playery + 1][playerx] == 'P') {
                 printf("Points increased!\n\r");
                 pts += 50;
                 gameboard[playery][playerx + 1] = '_';
             }
         }
            
         if (walkin == 'a' || walkin == 's' || walkin == 'd' || 
             walkin != 'a' || walkin != ' ' || walkin != 'd' ) {
             for (ly = 0; ly = 202; ly++) {
                 for (lx = 1; lx = 25; lx++) {
                     gameboard[ly][lx] = 'L';
                 }
             }
         }
        
         if (pts <= 0) {
             system("clear");
             renderLoss();
             scanf("%c", &replay);

             if (replay == 'Y') {
                 gaming = 3;
             }

             if (replay == 'N') {
                 gaming = 5;
             }
         }
        
         if (playery == 202) {
             renderWin();
             printf("");
             printf("Congrats! You got a score of %d !", pts);
             printf("");
             scanf("%c", &replay);
                               
             if (replay == 'Y') {
                 gaming = 4;
             }

             if (replay == 'N') {
                 gaming = 5;
             }
         }
               
         //player postion == 203y, then congrta screen
         //ask player to set gaming to 4(replay) or none (exit program)
     }

     system("stty echo -raw");

     return 0;
 }

 void render() {
     int y,x,k;

     system("clear");
     printf("\033[01;33m");
     printf("||POINTS: %d||\r\n", pts);
     printf("\033[0m");

     for (y = 0; y < 203; y++) {
         for (x = 0; x < 26; x++) {
             if (y == playery && x == playerx) {
                 printf("\033[0;32m");
                 printf("O");
                 printf("\033[0m");
             } 
             else {
                 printf("\033[1;36m");
                 printf("%c", gameboard[y][x]);
                 printf("\033[0m");
             }
         }
               
         printf("\r\n");
     }
}

void titleRender() {
    int y, x;
    system("clear");

    for (y = 0; y < 20; y++) {
        for (x = 0; x < 59; x++) {
            printf("\033[0;32m");
            printf(" %c", titlescreen[y][x]);
            printf("\033[0m");
        }
           
        printf("\r\n");
    }
}

void renderLoss() {
    int y, x;
    system("clear");
   
    for (y = 0; y < 20; y++) {
        for (x = 0; x < 50; x++) {
            printf("\033[0;31m");
            printf(" %c", gameover[y][x]);
            printf("\033[0m");
        }
       
        printf("\r\n");
    }
}

void renderWin() {
    int y, x;
    system("clear");
   
    for (y = 0; y < 20; y++) {
        for (x = 0; x < 46; x++) {
            printf("\033[0;33m");
            printf(" %c", diffdiff[y][x]);
            printf("\033[0m");
        }
       
        printf("\r\n");
    }
}

char quickchar(float delay) {
    int flags;
    char c;

    usleep((int)(delay*1000000));

    flags = fcntl(0, F_GETFL, 0);
    fcntl(0, F_SETFL, flags | O_NONBLOCK);
    c = getchar();
    fcntl(0, F_SETFL, flags ^ O_NONBLOCK);

    return c;
}

错误排查结果

1. 角色无法移动的核心原因

调用quickchar(0.5)已经读取了一次按键输入,后续又用scanf("%c", &walkin)覆盖了读取结果,导致实际按键输入被丢弃,删掉多余的scanf行即可恢复角色控制。

此外移动判定逻辑存在顺序问题:在判断移动的条件里已经排除了目标点位是#的情况,后续检测踩#扣积分的分支永远不会执行,d键对应的P点位检测还存在坐标写错、引号缺失的语法错误,导致加分逻辑失效。

2. L型障碍物无法移动的核心原因

  • 障碍物生成的循环条件写的是赋值操作ly = 202、lx = 25,而非比较判断ly < 202、lx < 25,直接触发死循环卡住程序
  • 外层触发生成L墙的if判断逻辑恒为真,不管输入是什么都会直接把游戏板所有位置覆盖为L,且完全没有写L墙逐行下移的逻辑,自然看不到障碍物正常移动

3. 其他潜在崩溃风险

  • 失败界面的scanf("%c", replay)缺少取地址符&,会触发段错误
  • renderWin函数原本直接打印数组名而非数组元素diffdiff[y][x],胜利界面会乱码
  • renderLoss函数原本循环y到26,但gameover数组只有20行,会越界访问崩溃

内容的提问来源于stack exchange,提问作者David G.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 19:15:00