Small snake game in C
Commit c59c050ea124
tarball4 files changed+342-210
@@ -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 score320401
) {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
+}@@ -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;@@ -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);@@ -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, ESCAPE58
+ ENTER, P_KEY, Q_KEY, ESCAPE, DEL5959
} 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);