GetRandomValue function in Raylib giving 0 every time

109 Views Asked by At

I'm trying to make a snake game in Raylib. I've gotten to the stage of writing a cell (food) to the screen, this is my code:

#include "raylib.h"

#define CELLSIZE 30
#define CELLCOUNT 25

Color green = {173, 204, 96, 255};
Color darkGreen = {43, 51, 24, 255};


int main(void){

        Vector2 foodPos = {GetRandomValue(0, CELLCOUNT - 1),GetRandomValue(0, CELLCOUNT - 1)};


        InitWindow(CELLSIZE * CELLCOUNT, CELLSIZE * CELLCOUNT, "retro snake");
        SetTargetFPS(60);
        BeginDrawing();


        while (!WindowShouldClose())
        {
                BeginDrawing();
                ClearBackground(green);

                DrawRectangle(foodPos.x, foodPos.y, CELLSIZE, CELLSIZE, darkGreen);

                EndDrawing();
        }

        CloseWindow();

        return 0;
}

When I run this code the food is always in the top left corner - it just spawns the food at 0,0 every time.

This is what it looks like.

1

There are 1 best solutions below

0
Oka On

In your code, you are calling GetRandomValue without first calling SetRandomSeed.

void SetRandomSeed(unsigned int seed); // Set the seed for the random number generator

As of Raylib 5, there are two possible pRNGs: C's standard rand (srand), and rprand - an implementation of xoshiro128**.

If the standard C pRNG is in use, calling rand() without first calling srand(seed) behaves as though srand(1) was called during program startup. In this situation, it is extremely likely you would see non-zero values - but since the seed is always the same (1), they would be the same values on every execution of the program.

If rprand is in use, calling the internal rprand_xoshiro without first calling rprand_set_seed results in a pRNG with a zero-state: all numbers generated will be zero. I would hazard a guess that this is what is occurring on your system (in effect: when you call GetRandomValue before SetRandomSeed).


InitWindow calls

SetRandomSeed((unsigned int)time(NULL));

as the last thing it does, and is often the first Raylib library function called in an application, so you can simply reorder the code:

InitWindow(CELLSIZE * CELLCOUNT, CELLSIZE * CELLCOUNT, "retro snake");
SetTargetFPS(60);

Vector2 foodPos = {
    GetRandomValue(0, CELLCOUNT - 1),
    GetRandomValue(0, CELLCOUNT - 1)
};

As pointed out by @pmacfarlane, your coordinates, which are in the range [0, CELLSIZE) must be multiplied by CELLSIZE for the rectangle to be drawn at the correct offset.

Additionally note that the first BeginDrawing(); (outside the loop) is erroneous.

A working example (press SPACE to move the rectangle to a random position):

#include <raylib.h>

#define CELLSIZE 30
#define CELLCOUNT 25
#define RANDOM_CELL() (GetRandomValue(0, CELLCOUNT - 1))

Color green = { 173, 204, 96, 255 };
Color darkGreen = { 43, 51, 24, 255 };

int main(void)
{
    const int dim = CELLCOUNT * CELLSIZE;
    InitWindow(dim, dim, "retro snake");
    SetTargetFPS(60);

    Vector2 foodPos = { RANDOM_CELL(), RANDOM_CELL() };

    while (!WindowShouldClose()) {
        if (IsKeyPressed(KEY_SPACE)) {
            foodPos.x = RANDOM_CELL();
            foodPos.y = RANDOM_CELL();
        }

        BeginDrawing();
        ClearBackground(green);
        DrawRectangle(foodPos.x * CELLSIZE, foodPos.y * CELLSIZE, CELLSIZE, CELLSIZE, darkGreen);
        EndDrawing();
    }

    CloseWindow();
}

proto-snake-gif