Snake in C-整数被更改而没有被更改-这是什么问题?

时间:2018-11-21 14:52:55

标签: c arrays

(程序语言为c-进行更正时,请仅使用菜鸟可以做的事情,我从1周开始便开始学习此内容)

问题是:请参见“ int snakelen = 1;”在主开始时?

我从不更改该整数。但是当我结束游戏时,它是0。为什么?

如果我在游戏中途尝试更改蛇形,则游戏将完全中断,并且我会收到Windows错误声音。 怎么了?

(尽管我使用随机发生器,食物也不会随机产生。并且它只产生底部或仅产生顶部-大约每5分钟发生一次变化。另一个小故障。)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <time.h>
#include <math.h>

#define SIZE 2048 //32(*2 because every 2nd one is a space) * 32
#define HSIZE 1024 //32 * 32
#define UP_ 1
#define DOWN_ 3
#define LEFT_ 4
#define RIGHT_ 2
#define YSIZE 64 //length of a row (including spaces)

//TO PLAY: Start the game once, right-click the command-promt at the top, click Settings -> Layout . Then change the window size to 64 (hor) * 33 (vert)

int counter = 0;
int gamespeed = 400;//Intervall in which a game-frame gets rendered

int spawnfood(int* freetable, int snakelen)
{
    srand ( time(NULL) ); //randomize
    int randomIndex = rand()%(HSIZE - 1); //take random non-x-filled position from array
    int randomValue = freetable[randomIndex]; //output the random position
    return randomValue;
}

int main()
{
    int nofood = 1; //is there food in the game? 1 = no
    //int tmp = 0; //temporary memory for later
    int tmp2 = 0; //temporary memory2
    int snakelen = 1; //length of snake
    int snakedir = RIGHT_; //Position the snake is looking
    int snakeheadxpos = 0; //x-position of snake
    int snakeheadypos = 0; //y-position of snake
    char q;//The button that was pressed last


    char gametable[SIZE]; //the game-screen //fill it with spaces
    for(int i = 0; i < SIZE; i++)
    {
        gametable[i]=' ';
    }
    gametable[SIZE] = '\0';


    int freetable[(HSIZE)]; // 32*32 list of all pixels, which shows whether a pixel is an x or not
    for(int i = 0; i < (HSIZE); i++)
    {
        freetable[i]= i*2; //fill the array with its numbers
    }


    //START OF GAME
    printf("Press any Button to start the game!\n");
    getch();
    for(int i = 0; i < 31; i++){
        printf("\n");
    }

    while(q != 27)
    {
        counter++;
        if(kbhit()) //if button is pressed
        {
            q = getch(); //q = that button
            switch(q) //change the way the snake looks via WASD
            {
            case 'w':
                if(snakedir != DOWN_)
                    snakedir = UP_;
                break;
            case 'a':
                if(snakedir != RIGHT_)
                    snakedir = LEFT_;
                break;
            case 's':
                if(snakedir != UP_)
                    snakedir = DOWN_;
                break;
            case 'd':
                if(snakedir != LEFT_)
                    snakedir = RIGHT_;
                break;
            default:
                break;
            }

        }
        if(counter%gamespeed == 0) //Renders a game-frame at the intervall of gamespeed
        {
            switch(snakedir)
            {

            case UP_:
                if(snakeheadypos==0)
                {
                    goto exit_loop; //ran into a wall
                }
                snakeheadypos--;
                break;

            case DOWN_:
                if(snakeheadypos==31)
                {
                    goto exit_loop; //ran into a wall
                }
                snakeheadypos++;
                break;

            case RIGHT_:
                if(snakeheadxpos==31)
                {
                    goto exit_loop; //ran into a wall
                }
                snakeheadxpos++;
                break;

            case LEFT_:
                if(snakeheadxpos==0)
                {
                    goto exit_loop; //ran into a wall
                }
                snakeheadxpos--;
                break;
            default:
                break;
            }

            if((gametable[snakeheadypos*YSIZE + 2*snakeheadxpos] == 'o'))
            {
                //snakelen++; //<-- WHEN YOU REMOVE THE FIRST //, THE GAME STARTS TO BUG AND I GET WINDOWS ERROR SOUNDS!
                nofood = 1; //no more food is in the game
            }
            gametable[snakeheadypos*YSIZE + 2*snakeheadxpos] = 'x'; //set the pixel ur at the the moment to 'x'

            gametable[tmp2] =' ';
            tmp2 = snakeheadypos*64+snakeheadxpos*2;
            //spawn food if there is none
            if(nofood)
            {
                gametable[spawnfood(freetable, snakelen)] = 'o';
                nofood = 0; //food is already placed
            }
            printf("%s", gametable); // print the gametable
        }
    }
exit_loop: ; //if you ran into a wall
    printf("Game Over - Score: %d", snakelen);
}

2 个答案:

答案 0 :(得分:4)

 char gametable[SIZE]; //the game-screen //fill it with spaces
 ...
 gametable[SIZE] = '\0';

这是错误的。您可以使用索引0到N-1索引大小为N的数组。 gametable[SIZE]在数组之外,对其进行分配会调用未定义的行为。

答案 1 :(得分:0)

注意:这不是“给男人一条鱼”的答案。这是一个“教人钓鱼的答案”。

在读取或写入数组的每条语句中,都应检查数组索引的有效性。

例如,代替

gametable[snakeheadypos*YSIZE + 2*snakeheadxpos] = 'x';

gametable[tmp2] =' ';

...写...

int index;

index=snakeheadypos*YSIZE + 2*snakeheadxpos;
if(index<0 || index >=SIZE){printf("Index error A: value is %d", index);exit(1);}
gametable[index] = 'x';

index=tmp2;
if(index<0 || index >=SIZE){printf("Index error B: value is %d", index);exit(1);}
gametable[index] =' ';

这种技术可以帮助您检测数组索引问题,这可能是非常常见的错误来源,并且可以产生各种奇怪的症状。