简单的控制台迷宫游戏:需要帮助找出错误

时间:2013-11-23 06:51:57

标签: c debugging console-application

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

当我试图进入障碍物时,我的输出的第一行发生了变化。此外,根据我尝试移动的位置,它可以向右移动1个或多个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;
}

1 个答案:

答案 0 :(得分:1)

似乎有一个明确的问题。

要确定问题,您应该开始查找转移第一行的字符来自哪些内容。添加:

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

带来一点点光明。似乎如果我想上去,那里的人物与上线,我的位置相同。

现在,您需要找到system("clear");未删除这些字符的原因。经过一些反复试验后,我设法发现如果您打印了一个&#39; \ n&#39;在清理之前,它按照预期工作。

由于我之前从未使用过ncurses,我无法解释你为什么会这样。我的结果是清除命令逐行清除终端。一行以换行符结束。所以,你需要做的就是在那些尾随字符之后添加换行符(我建议你在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。 关于主要的返回值,我建议您阅读this。 此外,您的ethier在main之前声明您的功能:

int showFrame();
void revertPosition();

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