jag

snake_c

public

Small snake game in C

Star0
Watch0

Commit d5b77365a624

tarball

Jaglekon <58274093+Jaglekon@users.noreply.github.com>2026-03-29 13:47 UTC

1 file changed+106-79
improved visuals
Modified file: snake.c+106 additions−79 deletions
@@ -64,14 +64,14 @@ typedef struct snake_part {
6464 } snake_part;
6565
6666 typedef struct snake {
67- snake_part position[MAX_LENGTH];
67+ snake_part * position;
6868 uint16_t length;
6969 } snake;
7070
7171
7272 uint8_t update_snake (selected game_size, snake *my_snake, direction shift);
7373 void update_field(snake my_snake, selected game_size,
74- board_state **board, selected fruit);
74+ board_state **board, bool init);
7575 selected new_fruit(selected game_size, board_state **board);
7676
7777 bool start_animation();
@@ -401,9 +401,11 @@ int main(int argc, char *args[]) {
401401
402402 /* initialisation of the game */
403403
404- snake my_snake = {};
404+ snake my_snake;
405405 my_snake.length = STARTING_LENGTH;
406406
407+ my_snake.position = malloc((my_snake.length + 1) * sizeof(snake_part));
408+
407409 direction shift = RIGHT;
408410 direction tmp_direction = shift;
409411
@@ -414,19 +416,17 @@ int main(int argc, char *args[]) {
414416 my_snake.position[0].coords.x = game_size.x >> 1;
415417 my_snake.position[0].directions[0] = shift;
416418 my_snake.position[0].directions[1] = shift;
417- for (i = 1; i < my_snake.length; i++) {
419+ for (i = 1; i <= my_snake.length; i++) {
418420 my_snake.position[i].coords.y = -1;
419421 my_snake.position[i].coords.x = -1;
420422 }
421423 }
422424
423- selected fruit = {-1, -1};
424-
425425 board_state **board = malloc(game_size.y * sizeof(board_state*));
426426 board_state *values = calloc(game_size.y * game_size.x, sizeof(board_state));
427427
428428 if(board == NULL || values == NULL)
429- goto end_of_program;
429+ goto end_of_program;
430430
431431 {
432432 uint8_t i;
@@ -435,11 +435,9 @@ int main(int argc, char *args[]) {
435435 board[i] = values + i * game_size.x;
436436 }
437437
438+ update_field(my_snake, game_size, board, true);
438439
439- update_field(my_snake, game_size, board, fruit);
440-
441- fruit = new_fruit(game_size, board);
442- update_field(my_snake, game_size, board, fruit);
440+ selected fruit = new_fruit(game_size, board);
443441
444442 bool paused = false;
445443
@@ -507,32 +505,36 @@ int main(int argc, char *args[]) {
507505
508506 uint8_t update = update_snake(game_size ,&my_snake, shift);
509507
510- switch (update) {
511- case 0:
512- printf("\nERROR\n");
513- goto end_free;
514- break;
515- case 2:
516- printf("\nHAHA LOST, LOSER");
517- goto end_free;
518- break;
519- default:
520- break;
521- }
522-
523- update_field(my_snake, game_size, board, fruit);
524-
525-
526508 uint8_t head_y = my_snake.position[0].coords.y;
527509 uint8_t head_x = my_snake.position[0].coords.x;
528510
511+
512+ update_field(my_snake, game_size, board, false);
513+
529514 if (head_y == fruit.y && head_x == fruit.x) {
530515 my_snake.length++;
516+ snake_part *tmp = realloc(my_snake.position, (my_snake.length + 1) * sizeof(snake_part));
517+ if (tmp == NULL)
518+ goto end_free;
519+ my_snake.position = tmp;
531520 fruit = new_fruit(game_size, board);
532521 }
533522
534- update_field(my_snake, game_size, board, fruit);
535523 draw_board(game_size, board, current_size, false, false);
524+
525+ switch (update) {
526+ case 0:
527+ printf("\nERROR\n");
528+ goto end_free;
529+ break;
530+ case 2:
531+ printf("\nHAHA LOST, LOSER");
532+ goto end_free;
533+ break;
534+ default:
535+ break;
536+ }
537+
536538 }
537539 }
538540 nanosleep(&milispeed, NULL);
@@ -540,8 +542,9 @@ int main(int argc, char *args[]) {
540542
541543 end_free:
542544
543- free(board);
544- free(values);
545+ free(my_snake.position);
546+ free(board);
547+ free(values);
545548
546549 end_of_program:
547550
@@ -597,47 +600,43 @@ uint8_t update_snake (selected game_size, snake *my_snake, direction shift) {
597600 return 1;
598601 }
599602
600-void update_field(snake my_snake, selected game_size, board_state **board, selected fruit) {
603+void update_field(snake my_snake, selected game_size, board_state **board, bool init) {
601604
602605 uint8_t i, j;
603606
604- for (i = 0; i < game_size.y; i++) {
605- for (j = 0; j < game_size.x; j++) {
606- board[i][j] = AIR;
607- }
608- }
607+ board_state snake_bit[DIRECTIONS][DIRECTIONS] = {
608+ [UP][UP] = VERTICAL,
609+ [DOWN][DOWN] = VERTICAL,
610+
611+ [RIGHT][RIGHT] = HORIZONTAL,
612+ [LEFT][LEFT] = HORIZONTAL,
613+
614+ [DOWN][RIGHT] = BOTTOM_LEFT,
615+ [LEFT][UP] = BOTTOM_LEFT,
616+
617+ [UP][RIGHT] = TOP_LEFT,
618+ [LEFT][DOWN] = TOP_LEFT,
619+
620+ [DOWN][LEFT] = BOTTOM_RIGHT,
621+ [RIGHT][UP] = BOTTOM_RIGHT,
622+
623+ [UP][LEFT] = TOP_RIGHT,
624+ [RIGHT][DOWN] = TOP_RIGHT
625+ };
609626
610- for (i = 0; i < my_snake.length; i++) {
611- int16_t x = my_snake.position[i].coords.x;
612- int16_t y = my_snake.position[i].coords.y;
613- if (x >= 0 && y >= 0) {
614- if (!i) {
615- if (my_snake.position[i].directions[0] == RIGHT) {
616- board[y][x] = HEAD_1;
617- } else {
618- board[y][x] = HEAD_2;
619- }
620- } else {
621627
622- board_state snake_bit[DIRECTIONS][DIRECTIONS] = {
623- [UP][UP] = VERTICAL,
624- [DOWN][DOWN] = VERTICAL,
625-
626- [RIGHT][RIGHT] = HORIZONTAL,
627- [LEFT][LEFT] = HORIZONTAL,
628-
629- [DOWN][RIGHT] = BOTTOM_LEFT,
630- [LEFT][UP] = BOTTOM_LEFT,
631-
632- [UP][RIGHT] = TOP_LEFT,
633- [LEFT][DOWN] = TOP_LEFT,
634-
635- [DOWN][LEFT] = BOTTOM_RIGHT,
636- [RIGHT][UP] = BOTTOM_RIGHT,
637-
638- [UP][LEFT] = TOP_RIGHT,
639- [RIGHT][DOWN] = TOP_RIGHT
640- };
628+ if (init) {
629+ for (i = 0; i < game_size.y; i++) {
630+ for (j = 0; j < game_size.x; j++) {
631+ board[i][j] = AIR;
632+ }
633+ }
634+
635+ for (i = 1; i < my_snake.length; i++) {
636+ int16_t x = my_snake.position[i].coords.x;
637+ int16_t y = my_snake.position[i].coords.y;
638+
639+ if (x >= 0 && y >= 0) {
641640
642641 direction first = my_snake.position[i].directions[0];
643642 direction second = my_snake.position[i].directions[1];
@@ -645,10 +644,34 @@ void update_field(snake my_snake, selected game_size, board_state **board, selec
645644 board[y][x] = snake_bit[first][second];
646645 }
647646 }
647+ } else {
648+
649+ int16_t x = my_snake.position[my_snake.length].coords.x;
650+ int16_t y = my_snake.position[my_snake.length].coords.y;
651+
652+ if (x != -1 && y != -1)
653+ board[y][x] = AIR;
654+
655+
656+ x = my_snake.position[1].coords.x;
657+ y = my_snake.position[1].coords.y;
658+
659+ direction first = my_snake.position[1].directions[0];
660+ direction second = my_snake.position[1].directions[1];
661+
662+ if (x != -1 && y != -1)
663+ board[y][x] = snake_bit[first][second];
648664 }
649665
650- if (fruit.x >= 0 && fruit.y >= 0)
651- board[fruit.y][fruit.x] = FRUIT;
666+
667+ int16_t x = my_snake.position[0].coords.x;
668+ int16_t y = my_snake.position[0].coords.y;
669+
670+ if (my_snake.position[0].directions[0] == RIGHT) {
671+ board[y][x] = HEAD_1;
672+ } else {
673+ board[y][x] = HEAD_2;
674+ }
652675 }
653676
654677 selected new_fruit(selected game_size, board_state **board) {
@@ -667,6 +690,8 @@ selected new_fruit(selected game_size, board_state **board) {
667690
668691 selected fruit = {x, y};
669692
693+ board[fruit.y][fruit.x] = FRUIT;
694+
670695 return fruit;
671696 }
672697
@@ -894,7 +919,7 @@ bool draw_board(
894919 uint8_t i, j;
895920
896921 uint8_t actual_height = game_size.y + 2;
897- uint8_t actual_width = game_size.x * 2 + 2;
922+ uint8_t actual_width = game_size.x * 2 + 1 + 2;
898923
899924 if (actual_width > window_size.ws_col || actual_height > window_size.ws_row) {
900925
@@ -919,30 +944,32 @@ bool draw_board(
919944
920945 for (i = 0; i < horizontal_buffer; i++)
921946 printf(" ");
922- printf("+");
947+ printf("╭");
923948 for (i = 0; i < game_size.x; i++)
924- printf("--");
925- printf("+\n");
949+ printf("──");
950+ printf("─╮\n");
926951
927952 for (i = 0; i < game_size.y; i++) {
928953
929954 for (j = 0; j < horizontal_buffer; j++)
930955 printf(" ");
931956
932- printf("|");
957+ printf("│");
933958
934959 for (j = 0; j < game_size.x; j++)
935960 printf("%s", give_state(board[i][j]));
936961
937- printf("|\n");
962+ printf("%s", give_state(board[i][0]));
963+
964+ printf("\033[%c│\n", LEFT_CODE);
938965 }
939966
940967 for (i = 0; i < horizontal_buffer; i++)
941968 printf(" ");
942- printf("+");
969+ printf("╰");
943970 for (i = 0; i < game_size.x; i++)
944- printf("--");
945- printf("+");
971+ printf("──");
972+ printf("─╯");
946973
947974 if (paused)
948975 draw_pause(window_size, actual_width, actual_height);
@@ -1003,7 +1030,7 @@ char *give_state(board_state square) {
10031030 return "\033[33m═\033[31mX\033[0m";
10041031 break;
10051032 case HEAD_2:
1006- return "\033[31m X\033[0m";
1033+ return "\033[31m\33[CX\033[0m";
10071034 break;
10081035 case VERTICAL:
10091036 return "\033[33m ║\033[0m";
@@ -1024,7 +1051,7 @@ char *give_state(board_state square) {
10241051 return "\033[33m═╗\033[0m";
10251052 break;
10261053 default:
1027- return " ";
1054+ return " ·";
10281055 break;
10291056 }
10301057 }