Snake游戏在我达到18分后停止.为什么?

  • 本文关键字:18分 游戏 Snake c++
  • 更新时间 :
  • 英文 :


这是我为一款经典的蛇类游戏编写的一些非常基本的代码。我需要它作为一个更大的项目的一部分,我正在工作,但在测试我遇到了这个非常恼人的错误。如果有人能执行它并告诉我我错过了什么,那就太好了。任何额外的建议也欢迎。我附上了下面的代码,并写了一些非常基本的注释,希望他们足以理解它。

错误:我的代码在玩家达到18点后停止。更具体地说,当分数= 18时,控制台没有更多的水果出现。

#include<iostream>
#include<conio.h>
#include<vector>
#include<queue>
#include<utility>
#include<windows.h>
using namespace std;
bool play = true;
int score = 0;
class Arena
{
private: 
int length, w, h, size, fx, fy;
char snakerep, fruitrep, dir;
queue<pair<int,int>> snakey, marker;
vector<vector<char>> arena;
public:
Arena()
{
//snake stuff
length = 1;
snakerep = 'O';
for(int i = 0 ; i < length ; i++)
snakey.push({1, i+1});
dir = 'R';

//arena stuff
size = 25;
h = size, w = 2*size;
arena.resize(h, vector<char>(w, ' '));

//fruit stuff
fruitrep = 'F';
fx = 1 + (rand() % h);
fy = 1 + (rand() % w);
arena[fx][fy] = fruitrep;
}
void setFruit()
{
fx = 1 + (rand() % h);
fy = 1 + (rand() % w);

arena[fx][fy] = fruitrep;
}

void setArena()
{

for(int i = 0 ; i < w ; i++)
{
arena[0][i] = '*';
arena[h-1][i] = '*';
}
for(int i = 1 ; i < h-1 ; i++)
{
arena[i][0] = '*';
arena[i][w-1] = '*';
}
for(int i = 1 ; i < h-1; i++)
{
for(int j = 1; j < w-1 ; j++)
{
arena[i][j] = ' ';
}
}
arena[fx][fy] = fruitrep;
}
void setSnake()
{
queue<pair<int,int>> temp_snakey = snakey;

while(!temp_snakey.empty())
{
pair<int, int> xy = temp_snakey.front();
temp_snakey.pop();
int x = xy.first, y = xy.second;
//condition for hitting any of the boundaries
if (x <= 0 || y <= 0 || x >= size-1 || y >= 2*size-1)
play = false;
//condition for hitting itself
if (arena[x][y] == snakerep)
play = false;
//condition for if a fruit is eaten
if (arena[x][y] == fruitrep)
{
setFruit();
//increase length of the snake 
length++, score++;
marker.push({x,y});
}
arena[x][y] = snakerep;
}
}
void moveSnake(char dir)
{
//calculate the new location of the head or whatever according to the direction given within the brackets
pair<int,int> prevHead = snakey.back(), newHead;
if (dir == 'R')
newHead = {prevHead.first, prevHead.second+1};
else if (dir == 'L')
newHead = {prevHead.first, prevHead.second-1};
else if (dir == 'U')
newHead = {prevHead.first-1, prevHead.second}; 
else if (dir == 'D')
newHead = {prevHead.first+1, prevHead.second};
//pop the tail from the queue and add the new head
pair<int, int> tail = snakey.front();
if (!marker.empty() && tail == marker.front())
marker.pop();
else
snakey.pop();

snakey.push(newHead);
}
void printAll()
{
//prints the matrix
for(int i = 0 ; i < h ; i++)
{
for(int j = 0 ; j < w ; j++)
{
cout<<arena[i][j];
}
cout<<endl;
}
}
void getDirection()
{
if(_kbhit())
{
char ch = _getch();
if (dir == 'R' || dir == 'L')
{
if (ch == 'w')
dir = 'U'; 
else if (ch == 's')
dir = 'D';
else if (ch == 'x')
play = false;
}   
else if (dir == 'U' || dir == 'D')
{
if (ch == 'd')
dir = 'R'; 
else if (ch == 'a')
dir = 'L';
else if (ch == 'x')
play = false;
}
}
}
void playGame()
{
getDirection();
setArena();
moveSnake(dir);
setSnake();
printAll();
}
};
int main()
{
Arena A;
while(play)
{
A.playGame();
cout<<" SCORE = "<<score<<endl;
//better than using system("cls"), because it moves cursor to beginning of console, flickering stops
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), {0, 0});
}
return 0;
}

第18个水果越界生成。您的随机定位功能不正确。你有

void setFruit()
{
fx = 1 + (rand() % h);
fy = 1 + (rand() % w);

arena[fx][fy] = fruitrep;
}

好的,考虑fx,rand() % h会给你一个[0 ..]包括H-1,但你要加1,因为第0个位置是一个墙。所以现在你有[1..h],但是h是越界的。右边也有一堵墙。综上所述,我认为你需要的是

void setFruit()
{
fx = 1 + (rand() % (h-2));
fy = 1 + (rand() % (w-2));

arena[fx][fy] = fruitrep;
}

你也应该改变Arena构造函数来使用这个函数。这样的代码最好不要重复。

最新更新