jag

snake_c

public

Small snake game in C

Star0
Watch0

Commit c59c050ea124

tarball

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

4 files changed+342-210
integrating score
Modified file: drawing.c+228 additions−75 deletions
@@ -73,12 +73,13 @@ bool start_animation() {
7373
7474 string[length_string] = '\0';
7575
76+ direction pressed_key = read_direction(string, true);
7677
77- if (toupper(string[0]) == 'Q')
78- return false;
78+ if (pressed_key == Q_KEY || pressed_key == ESCAPE)
79+ return false;
7980
80- if (string[0] == '\n')
81- break;
81+ if (pressed_key == ENTER)
82+ break;
8283 }
8384
8485 printf("\033[2J\033[H");
@@ -115,9 +116,9 @@ bool start_animation() {
115116
116117 bool draw_menu(main_menu menu, struct winsize window_size) {
117118
118- char *menu_string[] = {"NEW GAME", "SETTINGS", "EXIT"};
119+ char *menu_string[] = {"NEW GAME", "SETTINGS", "HIGHSCORE", "EXIT"};
119120
120- const uint8_t width_small = 8;
121+ const uint8_t width_small = 9;
121122 const uint8_t height_small = 5;
122123
123124 char *menu_string_big[][6] = {
@@ -133,16 +134,26 @@ bool draw_menu(main_menu menu, struct winsize window_size) {
133134 "╚════██║██╔══╝ ██║ ██║ ██║██║╚██╗██║██║ ██║╚════██║",
134135 "███████║███████╗ ██║ ██║ ██║██║ ╚████║╚██████╔╝███████║",
135136 "╚══════╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝"},
136- {"███████╗██╗ ██╗██╗████████╗", "██╔════╝╚██╗██╔╝██║╚══██╔══╝",
137- "█████╗ ╚███╔╝ ██║ ██║ ", "██╔══╝ ██╔██╗ ██║ ██║ ",
138- "███████╗██╔╝ ██╗██║ ██║ ", "╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ "}};
137+ {"██╗ ██╗██╗ ██████╗ ██╗ ██╗███████╗ ██████╗ ██████╗ ██████╗ ███████╗",
138+ "██║ ██║██║██╔════╝ ██║ ██║██╔════╝██╔════╝██╔═══██╗██╔══██╗██╔════╝",
139+ "███████║██║██║ ███╗███████║███████╗██║ ██║ ██║██████╔╝█████╗ ",
140+ "██╔══██║██║██║ ██║██╔══██║╚════██║██║ ██║ ██║██╔══██╗██╔══╝ ",
141+ "██║ ██║██║╚██████╔╝██║ ██║███████║╚██████╗╚██████╔╝██║ ██║███████╗",
142+ "╚═╝ ╚═╝╚═╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝"},
143+ {"███████╗██╗ ██╗██╗████████╗",
144+ "██╔════╝╚██╗██╔╝██║╚══██╔══╝",
145+ "█████╗ ╚███╔╝ ██║ ██║ ",
146+ "██╔══╝ ██╔██╗ ██║ ██║ ",
147+ "███████╗██╔╝ ██╗██║ ██║ ",
148+ "╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ "}
149+ };
139150
140151 const uint8_t height_line = 6;
141152 const uint8_t height_space = 2;
142153
143- const uint8_t width_text[] = {68, 64, 28};
154+ const uint8_t width_text[] = {68, 64, 69, 28};
144155
145- const uint8_t width_big = width_text[0] /*strlen(menu_string_big[0][0])*/;
156+ const uint8_t width_big = width_text[2] /*strlen(menu_string_big[0][0])*/;
146157 const uint8_t height_big =
147158 height_line * MAIN_MENU + height_space * (MAIN_MENU - 1);
148159
@@ -215,99 +226,169 @@ bool draw_menu(main_menu menu, struct winsize window_size) {
215226 }
216227
217228
218-void draw_settings(settings selected_setting, speed game_speed, selected game_size) {
229+void draw_settings(settings selected_setting, speed game_speed, selected game_size, struct winsize window_size) {
230+
231+ char *title[] = {
232+ " ___ ___ _____ _____ ___ _ _ ___ ___ ",
233+ "/ __| __|_ _|_ _|_ _| \\| |/ __/ __|",
234+ "\\__ \\ _| | | | | | || .` | (_ \\__ \\",
235+ "|___/___| |_| |_| |___|_|\\_|\\___|___/",
236+
237+ };
219238
220239 char *setting_string[] = {
221- " HEIGHT ",
222- " WIDTH ",
223- " SPEED ",
224- " BACK "
240+ "HEIGHT",
241+ "WIDTH",
242+ "SPEED",
243+ "BACK"
225244 };
226245
227246 char *speed_char[] = {
228- " VERY FAST ",
229- " FAST ",
230- " AVERAGE ",
231- " SLOW ",
232- " VERY SLOW "
247+ "VERY FAST",
248+ "FAST",
249+ "AVERAGE",
250+ "SLOW",
251+ "VERY SLOW"
233252 };
234253
235- uint8_t width = (uint8_t) strlen(setting_string[0]);
236- uint8_t width_setting = (uint8_t) strlen(speed_char[0]);
254+
255+ uint8_t title_height = 4;
256+ uint8_t title_width = strlen(title[0]);
257+
258+
259+ uint8_t setting_width;
260+ if (title_width % 2 == 0) {
261+ setting_width = (title_width + 2) >> 1;
262+ } else {
263+ setting_width = (title_width + 1) >> 1;
264+ }
265+
266+ uint8_t settings_height = SETTINGS_MENU * 2 + 1;
267+
268+ uint16_t full_height = title_height + settings_height + 2;
269+ uint16_t full_width = setting_width * 2 + 3;
237270
238271 uint8_t i, j;
239272
240273 printf("\033[2J\033[H");
241274
242-
243- for (i = 0; i < SETTINGS_MENU; i++) {
275+ if (window_size.ws_col < full_width || window_size.ws_row < full_height) {
276+ printf("Too small!\n");
277+ printf("Min: x: %d y: %d", full_width, full_height);
278+ fflush(stdout);
279+ return;
280+ }
244281
245- printf("+");
246- for (j = 0; j < width; j++)
247- printf("-");
248- printf("+");
282+ uint8_t vertical_buffer = (window_size.ws_row - full_height) >> 1;
283+ uint8_t horizontal_buffer = (window_size.ws_col - full_width) >> 1;
249284
250- if (i != BACK_S) {
251- printf (" +");
285+ for(i = 0; i < vertical_buffer; i++)
286+ printf("\n");
252287
253- for (j = 0; j < width_setting; j++)
254- printf("-");
255- printf("+");
288+
289+ for(i = 0; i < title_height + 2; i++) {
290+ for (j = 0; j < horizontal_buffer; j++)
291+ printf(" ");
292+ if (!i) {
293+ printf("┏");
294+ for(j = 0; j < full_width - 2; j++)
295+ printf("━");
296+ printf("┓\n");
297+ } else {
298+ printf("┃ ");
299+ if (i == title_height + 1) {
300+ for(j = 0; j < title_width; j++)
301+ printf(" ");
302+ } else {
303+ printf("\033[31;1m%s\033[0m", title[i - 1]);
304+ }
305+ if (title_width % 2 == 0)
306+ printf(" ");
307+ printf(" ┃\n");
256308 }
309+ }
310+
311+ for (i = 0; i < settings_height; i++) {
257312
258- printf("\n|");
313+ for (j = 0; j < horizontal_buffer; j++)
314+ printf(" ");
259315
260- if (i == selected_setting)
261- printf("\033[32m");
316+ if (i % 2 == 0) {
262317
263- printf("%s\033[0m", setting_string[i]);
318+ if (i == 0) {
319+ printf("┣");
320+ for(j = 0; j < setting_width; j++)
321+ printf("━");
322+ printf("┯");
323+ for(j = 0; j < setting_width; j++)
324+ printf("━");
325+ printf("┫\n");
264326
265- printf("|");
327+ } else if (i == settings_height - 1) {
328+ printf("┗");
329+ for(j = 0; j < setting_width * 2 + 1; j++)
330+ printf("━");
331+ printf("┛");
266332
267- if (i != BACK_S) {
268- printf(" |");
269- if (selected_setting == i)
270- printf("\033[32m");
333+ } else {
334+
335+ printf("┠");
336+ for(j = 0; j < setting_width; j++)
337+ printf("─");
338+ printf("%s", i == settings_height - 3 ? "┴" : "┼");
339+ for(j = 0; j < setting_width; j++)
340+ printf("─");
341+ printf("┨\n");
342+ }
271343
272- switch (i) {
273- case SPEED_S:
274- printf("%s", speed_char[game_speed]);
275- break;
344+ } else {
276345
277- case WIDTH_S:
278- case HEIGHT_S:
279- for (j = 0; j < (width_setting - 3) >> 1; j++)
280- printf(" ");
281- printf("%3d", (i == WIDTH_S) ? game_size.x : game_size.y);
282- for (j = 0; j < width_setting - ((width_setting - 3) >> 1) - 3; j++)
283- printf(" ");
346+ settings current_setting = (i - 1) >> 1;
284347
285- }
348+ printf("┃");
349+
350+ if (current_setting == selected_setting)
351+ printf("\033[32m");
352+
353+ print_buffer(current_setting != BACK_S ? setting_width : 2 * setting_width + 1,
354+ setting_string[current_setting]);
355+
286356 printf("\033[0m");
287- printf("|");
288- }
289357
290- printf("\n");
358+ if (current_setting != BACK_S) {
291359
292- if (i != HEIGHT_S) {
293-
294- printf("+");
295- for (j = 0; j < width; j++)
296- printf("-");
297- printf("+");
360+ printf("│");
361+
362+ if (current_setting == selected_setting)
363+ printf("\033[32m");
364+
365+ char *pointer;
298366
299- if (i != BACK_S) {
300- printf (" +");
367+ char number[5];
368+
369+ switch (current_setting) {
370+ case SPEED_S:
371+ pointer = speed_char[game_speed];
372+ break;
373+ case WIDTH_S:
374+ sprintf(number, "%d", game_size.x);
375+ pointer = number;
376+ break;
377+ case HEIGHT_S:
378+ sprintf(number, "%d", game_size.y);
379+ pointer = number;
380+ break;
381+ default:
382+ break;
383+ }
301384
302- for (j = 0; j < width_setting; j++)
303- printf("-");
304- printf("+");
385+ print_buffer(setting_width, pointer);
305386 }
306387
307- if (i < SETTINGS_MENU - 1)
308- printf("\n");
388+ printf("\033[0m┃\n");
309389 }
310390 }
391+
311392 fflush(stdout);
312393 }
313394
@@ -315,7 +396,7 @@ bool draw_board(
315396 selected game_size,
316397 board_state **board,
317398 struct winsize window_size,
318- bool redraw, bool paused,
399+ bool redraw, uint8_t paused,
319400 uint16_t score
320401 ) {
321402
@@ -388,7 +469,7 @@ bool draw_board(
388469 printf("─╯");
389470
390471 if (paused)
391- draw_pause(window_size, actual_width, actual_height);
472+ draw_pause(window_size, actual_width, actual_height, paused);
392473
393474 fflush(stdout);
394475
@@ -396,7 +477,7 @@ bool draw_board(
396477 }
397478
398479 void draw_pause(struct winsize window_size, uint8_t field_width,
399- uint8_t field_height) {
480+ uint8_t field_height, uint8_t game_over) {
400481
401482 const uint8_t height = 5;
402483 const uint8_t width = 14;
@@ -409,6 +490,8 @@ void draw_pause(struct winsize window_size, uint8_t field_width,
409490 "+------------+"
410491 };
411492
493+ const char *game_over_menu = "| GAME OVER |";
494+
412495 const uint8_t going_up = (field_height + height) >> 1;
413496 const uint8_t going_right = (field_width - width) >> 1;
414497
@@ -426,7 +509,11 @@ void draw_pause(struct winsize window_size, uint8_t field_width,
426509 for (j = 0; j < going_right; j++)
427510 printf("\033[%c", RIGHT_CODE);
428511
429- printf("\033[37m%s\033[0m\033[%c\r", pause_menu[i], DOWN_CODE);
512+ if (i == 2 && game_over == 2) {
513+ printf("\033[37m%s\033[0m\033[%c\r", game_over_menu, DOWN_CODE);
514+ } else {
515+ printf("\033[37m%s\033[0m\033[%c\r", pause_menu[i], DOWN_CODE);
516+ }
430517 }
431518
432519 for (i = 0; i < going_up - height; i++)
@@ -436,6 +523,55 @@ void draw_pause(struct winsize window_size, uint8_t field_width,
436523 fflush(stdout);
437524 }
438525
526+void draw_highscore (int16_t new_score, score leader_board[SCORE_NUMBER]) {
527+
528+ uint8_t i;
529+
530+ printf("\033[2J\033[H");
531+
532+ for (i = 0; i < SCORE_NUMBER; i++) {
533+ printf("%-10s %05d\n", leader_board[i].name, leader_board[i].points);
534+ }
535+
536+ if (new_score != -1) {
537+ for (i = SCORE_NUMBER - new_score; i > 0; i--)
538+ printf("\033[%c", UP_CODE);
539+ printf("\r_");
540+ fflush(stdout);
541+
542+ uint8_t number_characters = 0;
543+
544+ while(true) {
545+ char string[STRING_LEN] = {};
546+ ssize_t length_string = read(STDIN_FILENO, string, sizeof(string) - 1);
547+
548+ if (length_string > 0) {
549+
550+ direction pressed_key = read_direction(string, false);
551+
552+ if (pressed_key == ENTER) {
553+ leader_board[new_score].name[number_characters] = '\0';
554+ break;
555+ }
556+
557+ if (pressed_key == DEL && number_characters > 0) {
558+ printf("\033[%c \033[%c\033[%c_", LEFT_CODE, LEFT_CODE, LEFT_CODE);
559+ leader_board[new_score].name[--number_characters] = '\0';
560+ }
561+
562+ if (isalnum(string[0]) && number_characters < SCORE_LEN - 2) {
563+ printf("\033[%c%c_", LEFT_CODE, string[0]);
564+ leader_board[new_score].name[number_characters++] = string[0];
565+ }
566+ }
567+ fflush(stdout);
568+ struct timespec mili100 = {0, 1000000 * 100};
569+ nanosleep(&mili100, NULL);
570+ }
571+ }
572+}
573+
574+
439575 char *give_state(board_state square) {
440576
441577 switch (square) {
@@ -472,4 +608,21 @@ char *give_state(board_state square) {
472608 }
473609 }
474610
611+bool print_buffer(uint16_t width, char *string) {
612+ uint16_t len = strlen(string);
613+ uint16_t i;
614+
615+ if (width < len)
616+ return false;
475617
618+ uint16_t prebuffer = (width - len) >> 1;
619+ uint16_t postbuffer = width - len - prebuffer;
620+
621+ for (i = 0; i < prebuffer; i++)
622+ printf(" ");
623+ printf("%s", string);
624+ for (i = 0; i < postbuffer; i++)
625+ printf(" ");
626+
627+ return true;
628+}
Modified file: logic.c+2 additions
@@ -192,6 +192,8 @@ direction read_direction(char *string, bool wasd_enabled) {
192192 case '\n':
193193 return ENTER;
194194 break;
195+ case 127:
196+ return DEL;
195197 default:
196198 return DIRECTIONS;
197199 break;
Modified file: snake.c+103 additions−130 deletions
@@ -37,6 +37,8 @@ int main(int argc, char *args[]) {
3737 score leader_board[SCORE_NUMBER] = {};
3838 uint16_t score = 0;
3939
40+ /* Handling Files to store settings & highscores */
41+
4042 char *env;
4143 char *folder_path;
4244
@@ -54,10 +56,10 @@ int main(int argc, char *args[]) {
5456 folder_path = malloc(strlen(env) + strlen(local) +
5557 strlen(share) + strlen(SETTINGS_FOLDER) + 2);
5658
57- sprintf(folder_path, "%s/.local", env);
59+ sprintf(folder_path, "%s%s", env, local);
5860 error += make_folder(folder_path);
5961
60- strcat(folder_path, "/share");
62+ strcat(folder_path, share);
6163 error += make_folder(folder_path);
6264
6365 if (error <= 1) {
@@ -117,9 +119,12 @@ int main(int argc, char *args[]) {
117119 if (score_input[0] != '\0') {
118120 uint8_t j;
119121 for(j = 0; score_input[j] != '\0'; j++) {
120- if (score_input[j] == '\n')
121- score_input[j] = ' ';
122+ if (score_input[j] == '\n' || score_input[j] == ' ' || score_input[j] == '\t') {
123+ score_input[j] = '\0';
124+ break;
125+ }
122126 }
127+ score_input[SCORE_LEN - 1] = '\0';
123128 strncpy(leader_board[i].name, score_input, SCORE_LEN);
124129 }
125130
@@ -154,9 +159,6 @@ int main(int argc, char *args[]) {
154159 bool too_small = false;
155160
156161
157- struct timespec mili100 = {0, 1000000 * 100};
158-
159-
160162 /* Animation at the start */
161163 if (!start_animation())
162164 goto end_of_program;
@@ -165,12 +167,16 @@ int main(int argc, char *args[]) {
165167 /* Menu */
166168
167169 bool menu = true;
168- bool setting = false;
170+ main_menu setting = MAIN_MENU;
169171 bool change_menu = true;
170172
171173 main_menu selected_menu = NEW_GAME;
172174 settings selected_setting = HEIGHT_S;
173175
176+ struct timespec mili100 = {0, 1000000 * 100};
177+
178+menu_start:
179+
174180 while (menu) {
175181
176182 direction pressed_key = DIRECTIONS;
@@ -194,11 +200,11 @@ int main(int argc, char *args[]) {
194200 pressed_key = read_direction(string, false);
195201 }
196202
197- if (pressed_key == Q_KEY)
203+ if (pressed_key == Q_KEY || pressed_key == ESCAPE)
198204 goto end_of_program;
199205
200206
201- if (!setting) {
207+ if (setting == MAIN_MENU) {
202208
203209 if (!too_small) {
204210 switch (pressed_key) {
@@ -226,22 +232,25 @@ int main(int argc, char *args[]) {
226232 menu = false;
227233 break;
228234 case SETTINGS:
229- setting = true;
230- change_menu = true;
235+ setting = SETTINGS;
236+ break;
237+ case HIGHSCORE:
238+ setting = HIGHSCORE;
231239 break;
232240 default:
233241 goto end_of_program;
234242 break;
235243 }
244+ change_menu = true;
236245 }
237246
238- } else {
247+ } else if (setting == SETTINGS) {
239248
240249 /* Settings Menu */
241250
242251 if (change_menu) {
243252
244- draw_settings(selected_setting, game_speed, game_size);
253+ draw_settings(selected_setting, game_speed, game_size, init_size);
245254
246255 change_menu = false;
247256 }
@@ -306,18 +315,58 @@ int main(int argc, char *args[]) {
306315 if (pressed_key == ENTER) {
307316 switch (selected_setting) {
308317 case BACK_S:
309- setting = false;
318+ setting = MAIN_MENU;
310319 break;
311320 default:
312321 break;
313322 }
314323 change_menu = true;
315324 }
325+ } else if (setting == HIGHSCORE) {
326+
327+ if(change_menu) {
328+ uint8_t i;
329+
330+ for (i = 0; i < SCORE_NUMBER; i++) {
331+ if (score > leader_board[i].points)
332+ break;
333+ }
334+
335+ if (i < SCORE_NUMBER) {
336+
337+ uint8_t new_score = i;
338+
339+ for (i = SCORE_NUMBER - 1; i > new_score; i--) {
340+ leader_board[i] = leader_board[i -1];
341+ }
342+
343+ leader_board[new_score].points = score;
344+ leader_board[new_score].name[0] = '\0';
345+
346+ draw_highscore (new_score, leader_board);
347+
348+ } else {
349+ draw_highscore (-1, leader_board);
350+ }
351+ }
352+
353+ if(pressed_key == ENTER) {
354+ setting = MAIN_MENU;
355+ change_menu = true;
356+ }
357+ } else if(setting == NEW_GAME) {
358+
359+ if(pressed_key == ENTER) {
360+ setting = HIGHSCORE;
361+ change_menu = true;
362+ }
316363 }
317364
318365 nanosleep(&mili100, NULL);
319366 }
320367
368+ menu = true;
369+
321370 /* initialisation of the game */
322371
323372 snake my_snake;
@@ -356,45 +405,48 @@ int main(int argc, char *args[]) {
356405
357406 update_field(my_snake, game_size, board, true);
358407
359- bool paused = false;
408+ uint8_t paused = 0;
360409
361410
362- if ((too_small = draw_board(game_size, board, current_size, true, false, score)))
363- paused = true;
411+ if ((too_small = draw_board(game_size, board, current_size, true, 0, score)))
412+ paused = 1;
364413
414+ bool run = true;
365415
366416 struct timespec milispeed = {0, 1000000 * (SPEED + game_speed * 25)};
367417
368- bool run = true;
369-
370418 /* start of the actual game loop */
371419
372420 while (run) {
373421
374422 /* input handling */
375423
376-
377- char string[STRING_LEN] = {};
378- ssize_t length_string = read(STDIN_FILENO, string, sizeof(string) - 1);
379424
380- if (length_string > 0) {
381- string[length_string] = '\0';
425+ direction pressed_key;
382426
383- if (!too_small) {
384- if (toupper(string[0]) == 'P' || string[0] == '\n') {
385- paused = !paused;
386- if (paused)
387- draw_board(game_size, board, current_size, true, paused, score);
388- }
427+ char string[STRING_LEN] = {};
428+ ssize_t length_string = read(STDIN_FILENO, string, sizeof(string) - 1);
389429
390- if (!paused)
391- tmp_direction = read_direction(string, true);
392- }
430+ if (length_string > 0) {
431+ string[length_string] = '\0';
393432
394- if (toupper(string[0]) == 'Q')
395- run = false;
433+ pressed_key = read_direction(string, true);
434+
435+ if (!too_small) {
436+ if (pressed_key == P_KEY || pressed_key == ENTER) {
437+ paused = (paused == 1) ? 0 : 1;
438+ if (paused)
439+ draw_board(game_size, board, current_size, true, paused, score);
440+ }
441+
442+ if (!paused && pressed_key < DIRECTIONS)
443+ tmp_direction = pressed_key;
396444 }
397-
445+
446+ if (pressed_key == Q_KEY || pressed_key == ESCAPE)
447+ run = false;
448+ }
449+
398450
399451 /* game logic */
400452
@@ -410,7 +462,7 @@ int main(int argc, char *args[]) {
410462 current_size.ws_row != init_size.ws_row) {
411463 init_size = current_size;
412464
413- paused = true;
465+ paused = 1;
414466 too_small = draw_board(game_size, board, current_size, true, paused, score);
415467 }
416468
@@ -443,15 +495,15 @@ int main(int argc, char *args[]) {
443495
444496 update_field(my_snake, game_size, board, false);
445497
446- draw_board(game_size, board, current_size, false, false, score);
498+ draw_board(game_size, board, current_size, false, 0, score);
447499
448500 switch (update) {
449501 case 0:
450- printf("\nERROR\n");
451502 goto end_free;
452503 break;
453504 case 2:
454- printf("\nHAHA LOST, LOSER");
505+ setting = NEW_GAME;
506+ draw_board(game_size, board, current_size, false, 2, score);
455507 goto end_free;
456508 break;
457509 default:
@@ -465,94 +517,14 @@ int main(int argc, char *args[]) {
465517
466518 end_free:
467519
468- free(my_snake.position);
469- free(board);
470- free(values);
471-
472-end_of_program:
473-
474-
475- {
476-
477- uint8_t i;
478-
479- for (i = 0; i < SCORE_NUMBER; i++) {
480- if (score > leader_board[i].points)
481- break;
482- }
483-
484- if (i < SCORE_NUMBER) {
485-
486- uint8_t new_score = i;
487-
488- for (i = SCORE_NUMBER - 1; i > new_score; i--) {
489- leader_board[i] = leader_board[i -1];
490- }
491-
492- leader_board[new_score].points = score;
493- leader_board[new_score].name[0] = '\0';
494-
495- printf("\033[2J\033[H");
496-
497- for (i = 0; i < SCORE_NUMBER; i++) {
498- printf("%-10s %05d\n", leader_board[i].name, leader_board[i].points);
499- }
500-
501- for (i = SCORE_NUMBER - new_score; i > 0; i--)
502- printf("\033[%c", UP_CODE);
503- printf("\r_");
504- fflush(stdout);
505-
506- uint8_t number_characters = 0;
507-
508- while(true) {
509- char string[STRING_LEN] = {};
510- ssize_t length_string = read(STDIN_FILENO, string, sizeof(string) - 1);
511-
512- if (length_string > 0) {
513-
514- if (string[0] == '\n'){
515- leader_board[new_score].name[number_characters] = '\0';
516- break;
517- }
518-
519- if (string[0] == 127 && number_characters > 0) {
520- printf("\033[%c \033[%c\033[%c_", LEFT_CODE, LEFT_CODE, LEFT_CODE);
521- leader_board[new_score].name[--number_characters] = '\0';
522- }
523-
524- if (isalnum(string[0]) && number_characters < SCORE_LEN - 2) {
525- printf("\033[%c%c_", LEFT_CODE, string[0]);
526- leader_board[new_score].name[number_characters++] = string[0];
527- }
528- }
529- fflush(stdout);
530- nanosleep(&milispeed, NULL);
531- }
532- } else {
533-
534- printf("\033[2J\033[H");
535-
536- for (i = 0; i < SCORE_NUMBER; i++) {
537- printf("%-10s %05d\n", leader_board[i].name, leader_board[i].points);
538- }
539-
540-
541-
542- while(true) {
543- char string[STRING_LEN] = {};
544- ssize_t length_string = read(STDIN_FILENO, string, sizeof(string) - 1);
545-
546- if (length_string > 0) {
547- if (string[0] == '\n')
548- break;
549- }
550- }
551- }
552-}
553-
520+ free(my_snake.position);
521+ free(board);
522+ free(values);
554523
524+ if (setting == NEW_GAME)
525+ goto menu_start;
555526
527+end_of_program:
556528
557529 tcsetattr(STDIN_FILENO, TCSANOW, &old);
558530 printf("\033[?25h\n\n");
@@ -565,9 +537,8 @@ end_of_program:
565537 FILE* setting_file = fopen(settings_path, "w");
566538
567539 fprintf(setting_file, "%d\n%d\n%d", game_speed, game_size.x, game_size.y);
568- }
569-
570- {
540+
541+ fclose(setting_file);
571542
572543 FILE* score_file = fopen(score_path, "w");
573544 uint8_t i;
@@ -575,6 +546,8 @@ end_of_program:
575546 for (i = 0; i < SCORE_NUMBER; i++) {
576547 fprintf(score_file, "%s\n%i\n", leader_board[i].name, leader_board[i].points);
577548 }
549+
550+ fclose(score_file);
578551 }
579552
580553 free(settings_path);
Modified file: snake.h+9 additions−5 deletions
@@ -47,7 +47,7 @@
4747 #define SCORE_FILE "score"
4848 #define SETTINGS_FOLDER "snake_c"
4949
50-typedef enum { NEW_GAME, SETTINGS, EXIT, MAIN_MENU } main_menu;
50+typedef enum { NEW_GAME, SETTINGS, HIGHSCORE, EXIT, MAIN_MENU } main_menu;
5151
5252 typedef enum {HEIGHT_S, WIDTH_S, SPEED_S, BACK_S, SETTINGS_MENU} settings;
5353
@@ -55,7 +55,7 @@ typedef enum {V_FAST, FAST, AVERAGE, SLOW, V_SLOW, SPEED_L} speed;
5555
5656 typedef enum {
5757 UP, LEFT, DOWN, RIGHT, DIRECTIONS,
58- ENTER, P_KEY, Q_KEY, ESCAPE
58+ ENTER, P_KEY, Q_KEY, ESCAPE, DEL
5959 } direction;
6060
6161 typedef enum {
@@ -91,13 +91,17 @@ selected new_fruit(selected game_size, board_state **board);
9191 bool start_animation();
9292
9393 bool draw_menu(main_menu menu, struct winsize window_size);
94-void draw_settings(settings selected_setting, speed game_speed, selected game_size);
94+void draw_settings(settings selected_setting, speed game_speed, selected game_size, struct winsize window_size);
9595
9696 bool draw_board(selected game_size, board_state **board,
97- struct winsize window_size, bool redraw, bool pause, uint16_t score);
97+ struct winsize window_size, bool redraw, uint8_t pause, uint16_t score);
9898
9999 void draw_pause(struct winsize window_size,
100- uint8_t field_width,uint8_t field_height);
100+ uint8_t field_width,uint8_t field_height, uint8_t game_over);
101+void draw_highscore (int16_t new_score,
102+ score leader_board[SCORE_NUMBER]);
103+
104+bool print_buffer(uint16_t width, char *string);
101105
102106 char *give_state(board_state square);