snake

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | Submodules | LICENSE

commit 0beeb87f3e8d1ce87f2ce3e1e271625224bd9723
parent 396acc0a104ce5ad3e8c44bd7c8bd6b3cd8f9b00
Author: Samdal <samdal@protonmail.com>
Date:   Wed, 14 Jul 2021 18:30:00 +0200

change to use array instead of linked list

Diffstat:
Msource/main.c | 142+++++++++++++++++++++++++------------------------------------------------------
1 file changed, 45 insertions(+), 97 deletions(-)

diff --git a/source/main.c b/source/main.c @@ -25,82 +25,38 @@ gs_handle(gs_graphics_uniform_t) u_map = {0}; char map_names[32][32] = {0}; uint32_t map_buffer[32] = {0}; +typedef union { + int32_t xy[2]; + struct { + int32_t x, y; + }; +} ivec; -// snake linked list -typedef struct snake { - gs_vec2 pos; - void* next; -} snake_t; -snake_t* tail = &(snake_t){0}; +ivec snake[32 * 32] = {0}; +uint32_t head = 3; gs_vec2 food = {16.0f, 16.0f}; -gs_vec2 prev_move = {0}; -gs_vec2 move = {0}; +ivec prev_move = {0}; +ivec move = {0}; uint32_t prev_move_time = 0; -snake_t* eat_food(snake_t* head) -{ - // move food - map_buffer[(int)food.y] |= (1 << (int)food.x); - do { - food = (gs_vec2){rand() % 32, rand() % 32}; - } while (map_buffer[(int)food.y] & (1 << (int)food.x)); - - // Grow snake - head->next = (snake_t*)gs_malloc(sizeof(snake_t)); - gs_assert(head->next); - gs_vec2 pos = head->pos; - head = head->next; - head->pos = pos; - head->next = NULL; - return head; -} - -void free_snake() -{ - while (tail->next) { - snake_t* head = tail; - for (;;) { - snake_t* next = head->next; - if (!next->next) - break; - head = next; - } - gs_free(head->next); - head->next = NULL; - } -} - void new_game() { // reinitialise buffers for (uint32_t i = 0; i < 32; i++) map_buffer[i] = 0; + for (uint32_t i = 0; i < 32 * 32; i++) + snake[i] = (ivec){0}; prev_move_time = gs_platform_elapsed_time() * 0.01f; - move = (gs_vec2){1.0f, 0.0f}; + move = (ivec){1, 0}; prev_move = move; - free_snake(); - - // init tail piece - snake_t* body = tail; - body->pos = (gs_vec2){16.0f, 16.0f}; - - // place tail piece in map_buffer - map_buffer[(int)body->pos.y] |= (1 << (int)body->pos.x); + head = 3; - for (uint32_t i = 1; i <= 3; i++) { - // create snake piece - body->next = (snake_t*)gs_malloc(sizeof(snake_t)); - gs_assert(body->next); - body = body->next; - - // init snake piece - body->pos = (gs_vec2){16.0f + (float)i, 16.0f}; - body->next = NULL; - - // place snake piece in map_buffer - map_buffer[(int)body->pos.y] |= (1 << (int)body->pos.x); + // place snake in map_buffer + for (uint32_t i = 0; i <= 3; i++) { + snake[i] = (ivec){16+i,16}; + map_buffer[snake[i].y] |= (1 << snake[i].x); } // place food at random position @@ -113,49 +69,42 @@ void move_snake() { gs_printf("FPS: %f\n", gs_engine_subsystem(platform)->time.frame); prev_move = move; - snake_t* body = tail; - - // get new head pos - while (body->next) - body = body->next; - gs_vec2 new_pos = body->pos; - new_pos.x += move.x; - new_pos.y += move.y; + ivec new_pos = {snake[head].x + move.x, snake[head].y + move.y}; + // wrap snake - if (new_pos.x > 31.0f) - new_pos.x = 0.0f; - else if (new_pos.x < 0.0f) - new_pos.x = 31.0f; - else if (new_pos.y > 31.0f) - new_pos.y = 0.0f; - else if (new_pos.y < 0.0f) - new_pos.y = 31.0f; + if (new_pos.x > 31) new_pos.x = 0; + else if (new_pos.x < 0) new_pos.x = 31; + else if (new_pos.y > 31) new_pos.y = 0; + else if (new_pos.y < 0) new_pos.y = 31; // if new pos is food - if (new_pos.x == food.x && new_pos.y == food.y) { - body = eat_food(body); - body->pos = new_pos; + if (new_pos.x == (int)food.x && new_pos.y == (int)food.y) { + // add head to buffer + head++; + snake[head] = new_pos; + map_buffer[new_pos.y] |= (1 << new_pos.x); + + // place food in a random place + do { + food = (gs_vec2){rand() % 32, rand() % 32}; + } while (map_buffer[(int)food.y] & (1 << (int)food.x)); + } else { // remove tail from buffer - body = tail; - map_buffer[(int)body->pos.y] &= ~(1 << (int)body->pos.x); + map_buffer[snake[0].y] &= ~(1 << snake[0].x); // move each snake piece to the next ones position - while (body->next) { - snake_t* next = body->next; - body->pos = next->pos; - body = next; - } - - body->pos = new_pos; + for (uint32_t i = 0; i < head; i++) + snake[i] = snake[i+1]; // check for collision - if (map_buffer[(int)body->pos.y] & (1 << (int)body->pos.x)) { + if (map_buffer[new_pos.y] & (1 << new_pos.x)) { new_game(); return; } // add head to buffer - map_buffer[(int)body->pos.y] |= (1 << (int)body->pos.x); + snake[head] = new_pos; + map_buffer[snake[head].y] |= (1 << snake[head].x); } } @@ -253,10 +202,10 @@ void update() { // inputs if (gs_platform_key_pressed(GS_KEYCODE_ESC)) gs_engine_quit(); - if (gs_platform_key_pressed(GS_KEYCODE_RIGHT) && prev_move.y != 0.0f) move = (gs_vec2){1.0f,0.0f}; - else if (gs_platform_key_pressed(GS_KEYCODE_LEFT) && prev_move.y != 0.0f) move = (gs_vec2){-1.0f,0.0f}; - else if (gs_platform_key_pressed(GS_KEYCODE_UP) && prev_move.x != 0.0f) move = (gs_vec2){0.0f,1.0f}; - else if (gs_platform_key_pressed(GS_KEYCODE_DOWN) && prev_move.x != 0.0f) move = (gs_vec2){0.0f,-1.0f}; + else if (gs_platform_key_pressed(GS_KEYCODE_UP) && prev_move.x != 0) move = (ivec){0,1}; + else if (gs_platform_key_pressed(GS_KEYCODE_DOWN) && prev_move.x != 0) move = (ivec){0,-1}; + else if (gs_platform_key_pressed(GS_KEYCODE_RIGHT) && prev_move.y != 0) move = (ivec){1,0}; + else if (gs_platform_key_pressed(GS_KEYCODE_LEFT) && prev_move.y != 0) move = (ivec){-1,0}; // move snake every 0.2 seconds const uint32_t time_now = gs_platform_elapsed_time() * 0.01f; @@ -295,7 +244,6 @@ gs_app_desc_t gs_main(int32_t argc, char** argv) .window_title = "Gunslinger Snake", .init = init, .update = update, - .shutdown = free_snake, .frame_rate = 9999999999999.f, }; }