c++ - 我达到 18 分后,蛇游戏停止。为什么?
问题描述
好的,这是我编写的经典蛇游戏的一些非常基本的代码。我需要它作为我正在处理的一个更大项目的一部分,但是在测试时我遇到了这个非常烦人的错误。如果有人可以执行它并告诉我我缺少什么,那就太好了。也欢迎任何额外的建议。我附上了下面的代码并写了一些非常基本的注释,希望它们足以理解它。
错误:我的代码在玩家获得 18 分后停止。具体来说,在 score = 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..h] 但h
超出了界限。右边也有一堵墙。所以把所有这些放在一起,我想你想要的是
void setFruit()
{
fx = 1 + (rand() % (h-2));
fy = 1 + (rand() % (w-2));
arena[fx][fy] = fruitrep;
}
此外,您应该更改 Arena 构造函数以使用此函数。最好不要重复这样的代码。
推荐阅读
- java - 以下算法将显示多少颗星?
- sql - 基于查询处理并发生成唯一的列序列值
- c# - 如何在应用程序的初始启动时获取意图
- amazon-web-services - AWS EKS kubectl - 在默认命名空间中找不到资源
- sql - 从列名和数据类型表创建表
- authentication - 如何以静默方式登录多个 Web 应用程序而不会中断用户以保持会话处于活动状态
- machine-learning - 将单个大型 Google Drive 存档导入共享的 Google Colab 项目
- sql-server - 哪种处理事务死锁的方法更可取?
- numpy - Pytorch复制numpy浮点数的不精确值
- javascript - Javascript:将数组添加到二维数组时出现问题