关于蛇游戏中的随机数

时间:2016-12-27 05:19:58

标签: c++ random

#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;
    }

但是我仍然发现食物有时会出现在同一个地方,因为我吃的代码是没用的。我该如何解决这个问题?

2 个答案:

答案 0 :(得分:3)

问题在于您的move_logicrunning功能。你不是偶然连续两次在相同的位置产生食物,实际发生的是当玩家改变方向时,蛇实际上移动了两次,导致它跳过一个位置。如果你经过食物并改变方向来获取食物,你实际上会跳过食物。

E.g。从snakeheadX = 2snakeheadY = 5moving = 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_foodyfoodx当时没有改变检查foodyprev_foodxprev_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能够弄清楚问题是什么,但我希望这可以帮助你解决问题。