C++ 蛇形游戏——尾巴运动

C++ 蛇形游戏——尾巴运动,c++,C++,我在玩蛇游戏,尾巴移动有问题。我理解这一部分的逻辑,即尾部的每一段都遵循前一段,从尾部的末端开始。我正在查看其他人的代码,它看起来像这样 #include <iostream> #include <conio.h> #include <windows.h> using namespace std; bool gameOver; const int width = 20; const int height = 20; int x, y, fruitX, fr

我在玩蛇游戏,尾巴移动有问题。我理解这一部分的逻辑,即尾部的每一段都遵循前一段,从尾部的末端开始。我正在查看其他人的代码,它看起来像这样


 #include <iostream>
#include <conio.h>
#include <windows.h>
using namespace std;
bool gameOver;
const int width = 20;
const int height = 20;
int x, y, fruitX, fruitY, score;
int tailx[100], taily[100];
int nTail;
enum eDirecton { Stop, Left, Right, Up, Down } dir;

void Setup()
{
 gameOver = false;
 dir = Stop;
 x = width / 2;
 y = height / 2;
 fruitX = rand() % width;
 fruitY = rand() % height;
 score = 0;
}
void Draw()
{
 system("cls"); 
 for (int i = 0; i < width + 2; i++)
     cout << "#";
 cout << endl;

 for (int i = 0; i < height; i++)
 {
     for (int j = 0; j < width; j++)
     {
         if (j == 0)
             cout << "#";
         if (i == y && j == x)
             cout << "O";
         else if (i == fruitY && j == fruitX)
             cout << "F";
         else
         {
             bool print = false;
             for (int k = 0; k < nTail; k++)
             {
                 if (tailx[k] == j && taily[k] == i)
                 {
                     cout << "o";
                     print = true;
                 }
             }
             if (!print)
                 cout << " ";
         }


         if (j == width - 1)
             cout << "#";
     }
     cout << endl;
 }

 for (int i = 0; i < width + 2; i++)
     cout << "#";
 cout << endl;
 cout << "Score:" << score << endl;
}
void Input()
{
 if (_kbhit())
 {
     switch (_getch())
     {
     case 'a':
         dir = Left;
         break;
     case 'd':
         dir = Right;
         break;
     case 'w':
         dir = Up;
         break;
     case 's':
         dir = Down;
         break;
     case 'x':
         gameOver = true;
         break;
     }
 }
}
void Logic()
{
 for (int i = nTail - 1; i > 0; i--)
 {
     tailx[i] = tailx[i - 1];
     taily[i] = taily[i - 1];
 }
 tailx[0] = x;
 taily[0] = y;

 switch (dir)
 {
 case Left:
     x--;
     break;
 case Right:
     x++;
     break;
 case Up:
     y--;
     break;
 case Down:
     y++;
     break;
 default:
     break;
 }

 if (x >= width) x = 0; else if (x < 0) x = width - 1;
 if (y >= height) y = 0; else if (y < 0) y = height - 1;

 for (int i = 0; i < nTail; i++)
     if (tailx[i] == x && taily[i] == y)
         gameOver = true;

 if (x == fruitX && y == fruitY)
 {
     score += 10;
     fruitX = rand() % width;
     fruitY = rand() % height;
     nTail++;
 }
}
int main()
{
 Setup();
 while (!gameOver)
 {
     Draw();
     Input();
     Logic();
     Sleep(50); 
 }
 return 0;
}
为每个元素指定了什么值? 显示snake时,它有一个for循环来遍历屏幕的每个坐标,在它内部有另一个for循环来比较tailx[i]和taily[i]与每个坐标,以找到打印每个尾部片段的正确位置。既然tailx和tialy没有存储尾部分段的坐标,那么这段代码是怎么工作的呢


非常感谢你

你是对的;此代码无法工作,并且具有未定义的行为

nTail
甚至没有初始化任何内容


你确定这是一个完整的程序,而不仅仅是粘在一起的片段吗?还是一种“伪代码”来显示逻辑而不是实际有效的C++?您需要
nTail
和所有数组元素的值。

可能在末尾缺少一行,看起来像:

if(nTail < 100) { nTail++; }
让我们一步一步来完成这个

在我们进入循环之前,您的尾部数组将如下所示:(我在这里使用
NA
来表示“垃圾”)

我们进入循环,将
i
初始化为
nTail-1
,即
-1
。这没有通过
i>0
的检查,因此我们甚至没有进入循环

现在,我们将获取新的
x
y
VAL,并将它们分配到尾部,同时递增
nTail
。因此,进入下一个循环,我们的变量将如下所示:

nTail = 1

+-------------------------+
|Name | 0 | 1 | 2 | 3 | 4 |
|-------------------------|
|  X  | 1 | NA| NA| NA| NA|
+-------------------------+
|  Y  | 1 | NA| NA| NA| NA|
+-------------------------+
nTail = 3

+-------------------------+
|Name | 0 | 1 | 2 | 3 | 4 |
|-------------------------|
|  X  | 3 | 2 | NA| NA| NA|
+-------------------------+
|  Y  | 3 | 2 | NA| NA| NA|
+-------------------------+
nTail = 4

+-------------------------+
|Name | 0 | 1 | 2 | 3 | 4 |
|-------------------------|
|  X  | 4 | 3 | 2 | NA| NA|
+-------------------------+
|  Y  | 4 | 3 | 2 | NA| NA|
+-------------------------+
我们将进入,初始化
i
nTail-1=>0
。这没有通过
i>0
的检查,因此我们也没有进入循环(这听起来不对……也许您正在将
nTail
初始化为1而不是0?)

我们朝下,抓取新的x/y VAL和增量
nTail
,然后用以下命令重新启动循环:

nTail = 2

+-------------------------+
|Name | 0 | 1 | 2 | 3 | 4 |
|-------------------------|
|  X  | 2 | NA| NA| NA| NA|
+-------------------------+
|  Y  | 2 | NA| NA| NA| NA|
+-------------------------+
初始化
i
nTail-1=>1
意味着由于
i>0
我们将最终进入内部循环

使用
i=1
,我们更新尾部阵列:

tailx[1] = tailx[0];
taily[1] = taily[0];
然后头朝下,抓取新值并递增
nTail
。我们的变量现在看起来像:

nTail = 1

+-------------------------+
|Name | 0 | 1 | 2 | 3 | 4 |
|-------------------------|
|  X  | 1 | NA| NA| NA| NA|
+-------------------------+
|  Y  | 1 | NA| NA| NA| NA|
+-------------------------+
nTail = 3

+-------------------------+
|Name | 0 | 1 | 2 | 3 | 4 |
|-------------------------|
|  X  | 3 | 2 | NA| NA| NA|
+-------------------------+
|  Y  | 3 | 2 | NA| NA| NA|
+-------------------------+
nTail = 4

+-------------------------+
|Name | 0 | 1 | 2 | 3 | 4 |
|-------------------------|
|  X  | 4 | 3 | 2 | NA| NA|
+-------------------------+
|  Y  | 4 | 3 | 2 | NA| NA|
+-------------------------+
在下一个循环之后,情况将如下所示:

nTail = 1

+-------------------------+
|Name | 0 | 1 | 2 | 3 | 4 |
|-------------------------|
|  X  | 1 | NA| NA| NA| NA|
+-------------------------+
|  Y  | 1 | NA| NA| NA| NA|
+-------------------------+
nTail = 3

+-------------------------+
|Name | 0 | 1 | 2 | 3 | 4 |
|-------------------------|
|  X  | 3 | 2 | NA| NA| NA|
+-------------------------+
|  Y  | 3 | 2 | NA| NA| NA|
+-------------------------+
nTail = 4

+-------------------------+
|Name | 0 | 1 | 2 | 3 | 4 |
|-------------------------|
|  X  | 4 | 3 | 2 | NA| NA|
+-------------------------+
|  Y  | 4 | 3 | 2 | NA| NA|
+-------------------------+

如果您愿意,我将留给您继续跟踪。

您对它是否有效有多大把握?大概在绘制蛇时,会使用
nTail
的当前值,并且该值会在代码的其他地方初始化或更新(当蛇被喂食时)。您粘贴的片段声明了三个变量,不初始化其中任何一个,并立即使用所有三个。您确定代码段中没有代码丢失吗?我很抱歉造成混淆!我已经更新了帖子,并添加了整个程序。我建议与你从中获得代码的人进行对话。代码只是为了显示逻辑。在最初的程序中,它确实初始化了nTail,并且每次蛇的长度增加时,nTail都会得到更新。请不要问我们关于代码的问题,然后向我们展示一些完全不同的代码。那浪费了我们所有的时间。非常感谢你的帮助!