#include <iostream>
#include <string>
#include <windows.h>
#include <conio.h>
#include <time.h>
using namespace std;
int map_height=22;
int map_width=22;
string border="ùþ";
int snakeheadX=map_width/2-1;
int snakeheadY=map_height/2;
string head_symbol="¡·";
int snakesize;
bool gameover=false;
enum action{up, down, right1, left1, stop};
action moving=stop;
int foodx;
int foody;
void food();
void draw(){
system("cls");
food();
for(int i=0;i<map_width;i++){ // Game frame
cout<<border;
}
cout<<endl;
for(int i=0;i<map_height;i++){
cout<<border;
for(int j=0;j<map_width-2;j++){
if(i==snakeheadY && j==snakeheadX){
cout<<head_symbol;
}
else if(i==foody && j==foodx){
cout<<"¡¯";
}
else
cout<<" ";
}
cout<<border;
cout<<endl;
}
for(int i=0;i<map_width;i++){
cout<<border;
}
}
void running(int moving){
if(moving==up){ //Up
snakeheadY--;
}
if(moving==down){ //Down
snakeheadY++;
}
if(moving==left1){ //Left
snakeheadX--;
}
if(moving==right1){ //Right
snakeheadX++;
}
if(moving==stop){
snakeheadX=snakeheadX;
snakeheadY=snakeheadY;
}
}
void food(){
int prev_foodx=foodx;
int prev_foody=foody;
int a=rand()%(map_width-3)+1;
int b=rand()%(map_height-1)+1;
if(foodx==snakeheadX && foody==snakeheadY){
if(prev_foodx==a && prev_foody==b){
foodx=rand()%(map_width-3)+1;
foody=rand()%(map_height-1)+1;
}
else{
foodx=a;
foody=b;
}
}
}
void move_logic(int getkeyboarddown){
if(getkeyboarddown=='w'){ //Up
snakeheadY--;
moving=up;
}
if(getkeyboarddown=='s'){ //Down
snakeheadY++;
moving=down;
}
if(getkeyboarddown=='a'){ //Left
snakeheadX--;
moving=left1;
}
if(getkeyboarddown=='d'){ //Right
snakeheadX++;
moving=right1;
}
}
void game_logic(){
if (snakeheadX>=map_width || snakeheadX<=0 || snakeheadY<=0 || snakeheadY>=map_height){
cout<<endl<<"Game over!";
gameover=true;
}
}
int main()
{
srand(time(0));
foodx=rand()%(map_width-3)+1;
foody=rand()%(map_height-1)+1;
while(!gameover){
Sleep(50);
cout<<foodx<<" "<<foody;
running(moving);
draw();
game_logic();
if(kbhit()){
move_logic(getch());
}
}
return 0;
}
上面的代码是我在C ++中的蛇游戏代码。虽然游戏没有完成,但我发现食物有时可能会在蛇吃完后出现在同一个地方。因此,在函数food()中,我在下面添加了一个代码脚本来防止这种状态。
if(foodx==snakeheadX && foody==snakeheadY){
if(prev_foodx==a && prev_foody==b){
foodx=rand()%(map_width-3)+1;
foody=rand()%(map_height-1)+1;
cout<<"ok";
}
else{
foodx=a;
foody=b;
}
但是我仍然发现食物有时会出现在同一个地方,因为我吃的代码是没用的。我该如何解决这个问题?
答案 0 :(得分:3)
问题在于您的move_logic
和running
功能。你不是偶然连续两次在相同的位置产生食物,实际发生的是当玩家改变方向时,蛇实际上移动了两次,导致它跳过一个位置。如果你经过食物并改变方向来获取食物,你实际上会跳过食物。
E.g。从snakeheadX = 2
,snakeheadY = 5
和moving = left1
开始,请播放器按s
更改方向。 move_logic()
将snakeheadY
增加到6
,然后将running()
增加snakeheadY
增加到7
,之后只有draw()
和{{} 1}}叫,所以如果食物处于位置(2,6),那么就会错过,看起来蛇正好穿过它,或者就像在同一个位置产生新食物一样。
要解决此问题,功能food()
不应修改move_logic()
或snakeheadX
。只有snakeheadY
函数才能修改它们。
除此之外,它看起来应该可行,但有很多可以清理的东西。例如。您应该在函数running()
和else if
中使用链式running()
语句。在功能move_logic()
中,food()
和prev_foodx
实际上并没有做任何有用的事情,因为prev_foody
和foodx
当时没有改变检查foody
和prev_foodx
时prev_foody
每次调用时都会生成随机位置,而不是仅在必要时生成随机位置,并且允许食物在相同位置生成两次,尽管只有1/22 ^ 4的机会。因此,使用循环可以更好地实现随机性,如下所示:
food()
答案 1 :(得分:0)
我看不出是什么导致了你的问题,但你可以做一个改变,以防止代码连续两次随机生成相同的x和y坐标是替换代码
if(prev_foodx==a && prev_foody==b){
foodx=rand()%(map_width-3)+1;
foody=rand()%(map_height-1)+1;
}
与
if(prev_foodx==a && prev_foody==b){
food();
}
然后食物功能会自动调用,直到它为食物提供新的x和y坐标。您还可以优化函数,以便在每次绘制屏幕时不会生成随机数,方法是将if语句移动到您声明的变量上方。
void food(){
if(foodx==snakeheadX && foody==snakeheadY){
int prev_foodx=foodx;
int prev_foody=foody;
int a=rand()%(map_width-3)+1;
int b=rand()%(map_height-1)+1;
if(prev_foodx==a && prev_foody==b){
food();
} else{
foodx=a;
foody=b;
}
}
}
此外,食物的名称并没有告诉我发生了什么。也许在绘图功能中你可以说
if(foodx==snakeheadX && foody==snakeheadY){
changeFoodPos();
}`
然后代替您的食物功能,您有一个changeFoodPos
功能。拥有一个特定用途的功能(比如改变食物的位置,而不是具有可以用食物做任何事情的功能)总是更好。此外,您不需要prev_foodx和prev_foody变量。你可以做到
void changeFoodPos(){
if(foodx==snakeheadX && foody==snakeheadY){
int newX = rand()%(map_width-3)+1;
int newY = rand()%(map_height-1)+1;
if(foodx==newX && foody==newY){
changeFoodPos();
} else{
foodx = newX;
foody = newY;
}
}
}
无论如何,我知道这并没有直接回答你的问题。看起来David Scarlett能够弄清楚问题是什么,但我希望这可以帮助你解决问题。