【问题标题】:Simple console labirinth game: Need help to figure out a bug简单的控制台迷宫游戏:需要帮助找出错误
【发布时间】:2023-03-30 22:02:01
【问题描述】:

我无聊地做了一个非常简单的迷宫游戏,但是有一个奇怪的错误我无法弄清楚为什么会发生。

当我尝试进入障碍物时,输出的第一行会发生变化。此外,根据我尝试移动的位置,它可以向右移动 1 个或多个字符。考虑到我的showFrame() 函数每次输出前都会清除屏幕,这对我来说很奇怪。

当您尝试进入障碍物时,第 90 条线会起作用。如果新位置无效,它会先恢复位置,然后调用showFrame()showFrame()在输出前清除控制台。那么是什么导致第一行移位?为什么它会根据按下的键而有所不同?

代码如下。如果我理解正确,你需要在 linux 上编译和运行,而不是 windows,因为 ncurses 和 getchar 函数?但我不确定。 (不是真正的 C 程序员)

编译时添加-lncurses 参数。如果你没有安装 ncurses 库,可以在这里下载: http://ftp.gnu.org/pub/gnu/ncurses/ncurses-5.7.tar.gz

#include <stdio.h>
#include <ncurses.h>
#include <stdlib.h>

int positionX = 1,
    positionY = 19,
    oldPositionX, 
    oldPositionY,
    sizeX, 
    sizeY;
char matrix[20][20] = 
   {'|', ' ', '|', ' ', ' ', ' ', ' ', ' ', '-', '-', '-', '-', '-', ' ', ' ', ' ', ' ', '|', ' ', '|',
    '|', ' ', '|', ' ', ' ', ' ', '|', '-', '-', ' ', ' ', ' ', '-', '-', '|', ' ', ' ', ' ', ' ', '|',
    '|', ' ', '-', '-', '-', '-', '-', ' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', '-', '-', ' ', '|',
    '|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '-', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', '|', ' ', '|',
    '-', '-', '-', '|', ' ', '|', ' ', ' ', '|', ' ', '|', ' ', ' ', ' ', '-', '-', ' ', '|', ' ', '|',
    ' ', ' ', ' ', '|', ' ', '|', ' ', ' ', '|', ' ', '-', '-', '|', ' ', ' ', '|', ' ', '|', ' ', '|',
    ' ', '|', ' ', '|', ' ', '|', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', '|', '|', ' ', '|', ' ', '|',
    ' ', '|', ' ', ' ', ' ', '-', '-', '|', '|', ' ', ' ', ' ', '|', ' ', '|', ' ', ' ', '|', ' ', '|',
    ' ', '-', '-', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ', ' ', '|', ' ', '|', ' ', '-', '-', '-', '|',
    ' ', ' ', ' ', '|', ' ', '|', ' ', '|', ' ', '|', '-', '-', '-', ' ', '|', ' ', '|', ' ', ' ', '|',
    '-', '-', '-', '|', ' ', '|', ' ', '|', ' ', '|', ' ', ' ', ' ', ' ', '|', ' ', '-', '|', ' ', '|',
    '|', ' ', ' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ', ' ', '|', ' ', ' ', '|', ' ', '|',
    '|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '|', ' ', '-', '-', '-', '|', ' ', ' ', '|', ' ', '|',
    '|', ' ', '|', '-', '-', '-', '-', '-', '-', '-', ' ', ' ', ' ', ' ', '|', ' ', '-', '-', ' ', '|',
    '|', ' ', '|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '-', '-', '-', ' ', ' ', '|',
    '|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '-', '-', '-', '-', ' ', ' ', ' ', ' ', ' ', ' ', '|',
    '|', '-', '-', '-', '-', '-', ' ', '|', '-', '-', ' ', ' ', '|', ' ', ' ', ' ', '-', '-', '-', '|',
    '|', ' ', ' ', ' ', ' ', ' ', ' ', '|', ' ', ' ', '|', ' ', '-', '|', ' ', ' ', ' ', ' ', ' ', '|',
    '|', ' ', '|', '-', '-', '-', '-', '-', ' ', ' ', '|', ' ', ' ', ' ', ' ', '-', '-', '-', '-', '|',
    '|', ' ', '|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '|', '-', '-', '|', ' ', '|', ' ', ' ', ' ', ' '};

void main() {
   char key;
   int stty;

   // Get the size of the matrix   
   sizeX = sizeof(matrix) / sizeof(matrix[0]);
   sizeY = sizeof(matrix[0]);

   while(1) {
      // Output level
      showFrame();

      // Wait for user input to move player position
      stty = system("stty raw");
      key = getchar();
      system("stty cooked");

      // Store previou position and move player position accordingly
      oldPositionX = positionX;
      oldPositionY = positionY;
      switch(key) {
         case 'w':   positionY--;
                     break;
         case 'a':   positionX--;
                     break;
         case 's':   positionY++;
                     break;
         case 'd':   positionX++;
                     break;
         default:    printf("\bThat's an invalid key, stupid!\nYou're supposed to play with WASD keys.\n");
                     exit(0);
      }

      // Check to see if new position is okay
      if(positionY >= sizeY || positionY < 0 || positionX >= sizeX || positionX < 0) {
         revertPosition();
      }

      // Check to see if level cleared!
      if(positionX == 1 && positionY == 0) {
         showFrame();
         printf("You cleared the level, Sherlock.\nYou must be really proud of yourself\n");
         return;
      }
   }
}

int showFrame() {
   int i, j;

   // Output the matrix
   system("clear");
   for(i=0; i<sizeX; i++) {
      for(j=0; j<sizeY; j++) {
         // Check if player's position is at the current block
         if(i == positionY && j == positionX) {
            // If the players position is in an invalid block, revert his position
            if(matrix[i][j] != ' ') {
               revertPosition();
               showFrame();
               printf("You can't go there, stupid!\n");
               return 1;
            } else {
               printf("* ");
            }
         } else {
            printf("%c ", matrix[i][j]);
         }
      }
      printf("\n");
   }
   return 0;
}

void revertPosition() {
   positionX = oldPositionX;
   positionY = oldPositionY;
}

【问题讨论】:

  • 最好在code review上提问
  • @hacks 我做了,但他们把我推荐回来了,因为一些我不完全理解的模棱两可的原因
  • 我不知道为什么。他们总是试图在 SO 上提出这样的问题。事实上我在Win7上。我不能再帮你了。 (在虚拟机上我安装了kali 但有一些问题)。希望有人回复。

标签: c debugging console-application


【解决方案1】:

好像clear有问题。

要确定问题所在,您应该开始查找那些移动第一行的字符来自何处。添加:

   system("clear");
   printf('\n');
   for(i=0; i<sizeX; i++) {
      for(j=0; j<sizeY; j++) {

带来一点光。好像我要上去,那里的字和上面那一行一样,一直到我的位置。

现在,您需要找出为什么 system("clear"); 没有按照预期删除这些字符。经过一些试验和错误,我设法发现如果你在清除之前打印一个'\n',它就可以正常工作。

由于我以前从未使用过 ncurses,我无法解释为什么会发生这种情况。我的假设是 clear 命令逐行清除终端。一行以换行符结束。因此,您需要做的就是在这些尾随字符之后附加换行符(我建议您在 showFrame 函数的开头打印它,以避免类似情况):

int showFrame() {
   int i, j;

   // Output the matrix
   printf('\n');
   system("clear");
   for(i=0; i<sizeX; i++) {
      for(j=0; j<sizeY; j++) {
         // Check if player's position is at the current block
         if(i == positionY && j == positionX) {
            // If the players position is in an invalid block, revert his position
            if(matrix[i][j] != ' ') {
               revertPosition();
               showFrame();
               printf("You can't go there, stupid!\n");
               return 1;
            } else {
               printf("* ");
            }
         } else {
            printf("%c ", matrix[i][j]);
         }
      }
      printf("\n");
   }
   return 0;
}

我希望这对你有用。另外,让我对您的代码发表一些评论:

使用全局变量是strongly discouraged。 关于 main 的返回值,我建议你阅读this。 另外,你的 ethier 在 main 之前声明你的函数:

int showFrame();
void revertPosition();

要么将它们的整个定义移到 main 之前。事实上,您的代码没有在我的机器上编译(gcc 4.8.1)。

【讨论】:

  • 确实如此,非常感谢您的解决方案和代码注释,干杯!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-20
  • 1970-01-01
  • 1970-01-01
  • 2013-09-30
  • 1970-01-01
  • 2012-06-11
  • 2016-05-25
相关资源
最近更新 更多