jag

snake_c

public

Small snake game in C

Star0
Watch0

Commit 985e3c37c168

tarball

Jaglekon <jaglekon@jaglekon.de>2026-03-23 10:30 UTC

1 file changed+202-259
fixed flickering
Modified file: snake.c+202 additions−259 deletions
@@ -1,19 +1,18 @@
1-#include <unistd.h>
21 #include <termios.h>
2+#include <unistd.h>
33
4-#include <stdio.h>
5-#include <stdint.h>
64 #include <stdbool.h>
5+#include <stdint.h>
6+#include <stdio.h>
77 #include <stdlib.h>
88
99 #include <sys/ioctl.h>
1010
11-#include <time.h>
1211 #include <sys/time.h>
12+#include <time.h>
1313
14-#include <string.h>
1514 #include <ctype.h>
16-
15+#include <string.h>
1716
1817 #define RIGHT_CODE 'C'
1918 #define LEFT_CODE 'D'
@@ -28,18 +27,20 @@
2827 #define ACTUAL_WIDTH ((WIDTH * 2) + 2)
2928 #define ACTUAL_HEIGHT (HEIGHT + 2)
3029
31-
3230 #define SPEED 100 /* in ms */
3331
3432 #define MAX_LENGTH 1000
3533 #define STARTING_LENGTH 2
3634
37-typedef enum {
38- NEW_GAME, SETTINGS, EXIT, MAIN_MENU
39-} main_menu;
35+typedef enum { NEW_GAME, SETTINGS, EXIT, MAIN_MENU } main_menu;
4036
4137 typedef enum {
42- NO_DIRECTION = -1, UP = 0, LEFT = 1, DOWN = 2, RIGHT = 3, DIRECTIONS = 4
38+ NO_DIRECTION = -1,
39+ UP = 0,
40+ LEFT = 1,
41+ DOWN = 2,
42+ RIGHT = 3,
43+ DIRECTIONS = 4
4344 } direction;
4445
4546 typedef struct selected {
@@ -52,24 +53,22 @@ typedef struct snake {
5253 uint16_t length;
5354 } snake;
5455
55-
56-
57-void update_field(snake my_snake, char board[HEIGHT][WIDTH][STRING_LEN], selected fruit);
56+void update_field(snake my_snake, char board[HEIGHT][WIDTH][STRING_LEN],
57+ selected fruit);
5858 selected new_fruit(char board[HEIGHT][WIDTH][STRING_LEN]);
5959
6060 bool draw_menu(main_menu menu, struct winsize window_size);
6161
62-void draw_board(char board[HEIGHT][WIDTH][STRING_LEN], struct winsize window_size);
62+void draw_board(char board[HEIGHT][WIDTH][STRING_LEN],
63+ struct winsize window_size, bool redraw);
6364 void draw_pause(struct winsize window_size);
6465
65-direction read_direction (char* string, bool wasd_enabled);
66-
67-
66+direction read_direction(char *string, bool wasd_enabled);
6867
6968 int main(int argc, char *args[]) {
7069
7170 /* command argument handling */
72-
71+
7372 if (argc > 1) {
7473 if (argc > 2) {
7574 printf("Too many parameters\n");
@@ -93,7 +92,6 @@ int main(int argc, char *args[]) {
9392 return 1;
9493 }
9594
96-
9795 /* Setting up terminal with termios */
9896
9997 struct termios old, new;
@@ -112,25 +110,21 @@ int main(int argc, char *args[]) {
112110
113111 printf("\033[?25l");
114112
115-
116113 struct winsize init_size, current_size;
117114 ioctl(STDOUT_FILENO, TIOCGWINSZ, &init_size);
118115 current_size = init_size;
119116 bool too_small = false;
120117
121-
122-
123118 struct timeval start;
124119 gettimeofday(&start, NULL);
125120
126-
127121 /* Menu */
128122
129123 bool menu = true;
130124
131125 main_menu selected_menu = NEW_GAME;
132-
133- too_small =draw_menu(selected_menu, init_size);
126+
127+ too_small = draw_menu(selected_menu, init_size);
134128
135129 while (menu) {
136130
@@ -139,83 +133,76 @@ int main(int argc, char *args[]) {
139133
140134 char string[1000] = {};
141135 ssize_t length_string = read(STDIN_FILENO, string, sizeof(string) - 1);
142-
143- direction arrow = NO_DIRECTION;
144136
137+ direction arrow = NO_DIRECTION;
145138
146139 /* Check for window size */
147-
140+
148141 struct timeval current;
149142 gettimeofday(&current, NULL);
150143
151- uint64_t time_diff = (current.tv_sec - start.tv_sec) * 1000000 + (current.tv_usec - start.tv_usec);
144+ uint64_t time_diff = (current.tv_sec - start.tv_sec) * 1000000 +
145+ (current.tv_usec - start.tv_usec);
152146
153147 if (time_diff >= SPEED * 1000) {
154-
148+
155149 ioctl(STDOUT_FILENO, TIOCGWINSZ, &current_size);
156150
157- if (
158- current_size.ws_col != init_size.ws_col ||
159- current_size.ws_row != init_size.ws_row
160- ) {
151+ if (current_size.ws_col != init_size.ws_col ||
152+ current_size.ws_row != init_size.ws_row) {
161153 init_size = current_size;
162154 changed_selected = true;
163155 }
164156 }
165157
166-
167158 if (length_string > 0 && !too_small) {
168159 string[length_string] = '\0';
169-
160+
170161 arrow = read_direction(string, false);
171-
172162
173163 switch (arrow) {
174- case UP:
175- selected_menu = (selected_menu + (MAIN_MENU - 1)) % MAIN_MENU;
176- changed_selected = true;
177- break;
178- case DOWN:
179- selected_menu = (selected_menu + 1) % MAIN_MENU;
180- changed_selected = true;
181- break;
182- default:
183- break;
164+ case UP:
165+ selected_menu = (selected_menu + (MAIN_MENU - 1)) % MAIN_MENU;
166+ changed_selected = true;
167+ break;
168+ case DOWN:
169+ selected_menu = (selected_menu + 1) % MAIN_MENU;
170+ changed_selected = true;
171+ break;
172+ default:
173+ break;
184174 }
185-
175+
186176 if (toupper(string[0]) == 'Q')
187177 goto end_of_program;
188-
178+
189179 if (string[0] == '\n')
190180 pressed_enter = true;
191181 }
192-
193182
194183 if (changed_selected)
195184 too_small = draw_menu(selected_menu, init_size);
196-
185+
197186 if (pressed_enter) {
198187 switch (selected_menu) {
199- case NEW_GAME:
200- menu = false;
201- break;
202- default:
203- goto end_of_program;
204- break;
188+ case NEW_GAME:
189+ menu = false;
190+ break;
191+ default:
192+ goto end_of_program;
193+ break;
205194 }
206195 }
207196 }
208197
209-
210-
211198 /* initialisation of the game */
212199
213- snake my_snake = {};
200+ snake my_snake = {};
214201 my_snake.length = STARTING_LENGTH;
215202
216203 {
217204 uint16_t i;
218-
205+
219206 my_snake.position[0].y = HEIGHT >> 1;
220207 my_snake.position[0].x = WIDTH >> 1;
221208 for (i = 1; i < my_snake.length; i++) {
@@ -226,99 +213,95 @@ int main(int argc, char *args[]) {
226213
227214 selected fruit = {-1, -1};
228215 char board[HEIGHT][WIDTH][STRING_LEN] = {};
229-
216+
230217 update_field(my_snake, board, fruit);
231-
218+
232219 fruit = new_fruit(board);
233220 update_field(my_snake, board, fruit);
234221
235-
236222 bool paused = false;
237223
238- if (current_size.ws_row < ACTUAL_HEIGHT || current_size.ws_col < ACTUAL_WIDTH) {
224+ if (current_size.ws_row < ACTUAL_HEIGHT ||
225+ current_size.ws_col < ACTUAL_WIDTH) {
239226 too_small = true;
240227 paused = true;
241228
242229 printf("\033[2J\033[HToo small\n");
243230 printf("Min width: %i & Min height: %i\n", ACTUAL_WIDTH, ACTUAL_WIDTH);
244231 } else {
245- draw_board(board, current_size);
232+ draw_board(board, current_size, true);
246233 }
247234
248235 direction shift = RIGHT;
249236 direction tmp_direction = shift;
250237
251-
252238 bool run = true;
253239
254240 /* start of the actual game loop */
255241
256242 while (run) {
257243
258-
259244 /* input handling */
260245
261246 if (!too_small) {
262247 char string[1000] = {};
263248 ssize_t length_string = read(STDIN_FILENO, string, sizeof(string) - 1);
264-
249+
265250 if (length_string > 0) {
266251 string[length_string] = '\0';
267-
252+
268253 if (!paused)
269254 tmp_direction = read_direction(string, true);
270255
271256 if (toupper(string[0]) == 'Q')
272257 run = false;
273258
274- if (toupper(string[0]) == 'P') {
275- paused = !paused;
259+ if (toupper(string[0]) == 'P') {
260+ paused = !paused;
261+ if (paused)
262+ draw_pause(current_size);
276263 }
277264 }
278-
279- if (paused)
280- draw_pause(current_size);
281265 }
282266
283-
284267 /* game logic */
285268
286269 struct timeval current;
287270 gettimeofday(&current, NULL);
288271
289- uint64_t time_diff = (current.tv_sec - start.tv_sec) * 1000000 + (current.tv_usec - start.tv_usec);
272+ uint64_t time_diff = (current.tv_sec - start.tv_sec) * 1000000 +
273+ (current.tv_usec - start.tv_usec);
290274
291275 if (time_diff >= SPEED * 1000) {
292-
276+
293277 ioctl(STDOUT_FILENO, TIOCGWINSZ, &current_size);
294-
295- if (
296- current_size.ws_col != init_size.ws_col ||
297- current_size.ws_row != init_size.ws_row
298- ) {
278+
279+ if (current_size.ws_col != init_size.ws_col ||
280+ current_size.ws_row != init_size.ws_row) {
299281 init_size = current_size;
300-
282+
301283 paused = true;
302-
303- if (current_size.ws_row < ACTUAL_HEIGHT || current_size.ws_col < ACTUAL_WIDTH) {
284+
285+ if (current_size.ws_row < ACTUAL_HEIGHT ||
286+ current_size.ws_col < ACTUAL_WIDTH) {
304287 too_small = true;
305-
288+
306289 printf("\033[2J\033[HToo small\n");
307- printf("Min width: %i & Min height: %i\n", ACTUAL_WIDTH, ACTUAL_WIDTH);
290+ printf("Min width: %i & Min height: %i\n", ACTUAL_WIDTH,
291+ ACTUAL_WIDTH);
308292 } else {
309293 too_small = false;
310-
311- draw_board(board, current_size);
294+
295+ draw_board(board, current_size, true);
296+ draw_pause(current_size);
312297 }
313298 }
314299
315300 if (!paused) {
316-
301+
317302 start = current;
318- if (
319- tmp_direction != NO_DIRECTION &&
320- ((shift + (DIRECTIONS >> 1)) % DIRECTIONS) != tmp_direction
321- ) {
303+ if (tmp_direction != NO_DIRECTION &&
304+ ((shift + (DIRECTIONS >> 1)) % DIRECTIONS) != tmp_direction) {
322305 shift = tmp_direction;
323306 }
324307
@@ -329,23 +312,25 @@ int main(int argc, char *args[]) {
329312 }
330313
331314 switch (shift) {
332- case UP:
333- my_snake.position[0].y = ((my_snake.position[0].y + HEIGHT - 1) % HEIGHT);
334- break;
335- case DOWN:
336- my_snake.position[0].y = ((my_snake.position[0].y + 1) % HEIGHT);
337- break;
338- case LEFT:
339- my_snake.position[0].x = ((my_snake.position[0].x + WIDTH - 1) % WIDTH);
340- break;
341- case RIGHT:
342- my_snake.position[0].x = ((my_snake.position[0].x + 1) % WIDTH);
343- break;
344- default:
345- goto end_of_program;
346- break;
315+ case UP:
316+ my_snake.position[0].y =
317+ ((my_snake.position[0].y + HEIGHT - 1) % HEIGHT);
318+ break;
319+ case DOWN:
320+ my_snake.position[0].y = ((my_snake.position[0].y + 1) % HEIGHT);
321+ break;
322+ case LEFT:
323+ my_snake.position[0].x =
324+ ((my_snake.position[0].x + WIDTH - 1) % WIDTH);
325+ break;
326+ case RIGHT:
327+ my_snake.position[0].x = ((my_snake.position[0].x + 1) % WIDTH);
328+ break;
329+ default:
330+ goto end_of_program;
331+ break;
347332 }
348-
333+
349334 uint8_t head_y = my_snake.position[0].y;
350335 uint8_t head_x = my_snake.position[0].x;
351336
@@ -353,10 +338,7 @@ int main(int argc, char *args[]) {
353338 int16_t x = my_snake.position[i].x;
354339 int16_t y = my_snake.position[i].y;
355340
356- if (
357- x == head_x &&
358- y == head_y
359- ) {
341+ if (x == head_x && y == head_y) {
360342 printf("\n\nHAHA LOST!!!\n\n");
361343 goto end_of_program;
362344 }
@@ -369,14 +351,12 @@ int main(int argc, char *args[]) {
369351 fruit = new_fruit(board);
370352 }
371353
372-
373354 update_field(my_snake, board, fruit);
374- draw_board(board, current_size);
355+ draw_board(board, current_size, false);
375356 }
376357 }
377358 }
378359
379-
380360 end_of_program:
381361
382362 tcsetattr(STDIN_FILENO, TCSANOW, &old);
@@ -385,22 +365,17 @@ end_of_program:
385365 return 0;
386366 }
387367
368+void update_field(snake my_snake, char board[HEIGHT][WIDTH][STRING_LEN],
369+ selected fruit) {
388370
389-
390-
391-
392-void update_field(snake my_snake, char board[HEIGHT][WIDTH][STRING_LEN], selected fruit) {
393-
394371 uint8_t i, j;
395372
396373 for (i = 0; i < HEIGHT; i++) {
397- for (j = 0; j < WIDTH; j++) {
374+ for (j = 0; j < WIDTH; j++) {
398375 strcpy(board[i][j], " ");
399376 }
400377 }
401378
402-
403-
404379 for (i = 0; i < my_snake.length; i++) {
405380 int16_t x = my_snake.position[i].x;
406381 int16_t y = my_snake.position[i].y;
@@ -413,59 +388,46 @@ void update_field(snake my_snake, char board[HEIGHT][WIDTH][STRING_LEN], selecte
413388 }
414389 } else if (i == my_snake.length - 1) {
415390 if (x != my_snake.position[i - 1].x) {
416- strcpy(board[y][x], "\033[33m══\033[0m");
391+ strcpy(board[y][x], "\033[33m══\033[0m");
417392 } else {
418- strcpy(board[y][x], "\033[33m ║\033[0m");
393+ strcpy(board[y][x], "\033[33m ║\033[0m");
419394 }
420395 } else {
421- if (
422- x != my_snake.position[i - 1].x &&
423- x != my_snake.position[i + 1].x
424- ) {
425- strcpy(board[y][x], "\033[33m══\033[0m");
426- } else if (
427- y != my_snake.position[i - 1].y &&
428- y != my_snake.position[i + 1].y
429- ) {
396+ if (x != my_snake.position[i - 1].x &&
397+ x != my_snake.position[i + 1].x) {
398+ strcpy(board[y][x], "\033[33m══\033[0m");
399+ } else if (y != my_snake.position[i - 1].y &&
400+ y != my_snake.position[i + 1].y) {
430401 strcpy(board[y][x], "\033[33m ║\033[0m");
431- } else if (
432- (y == (my_snake.position[i - 1].y + 1) % HEIGHT &&
433- x == (my_snake.position[i + 1].x + 1) % WIDTH) ||
434- (y == (my_snake.position[i + 1].y + 1) % HEIGHT &&
435- x == (my_snake.position[i - 1].x + 1) % WIDTH)
436- ) {
402+ } else if ((y == (my_snake.position[i - 1].y + 1) % HEIGHT &&
403+ x == (my_snake.position[i + 1].x + 1) % WIDTH) ||
404+ (y == (my_snake.position[i + 1].y + 1) % HEIGHT &&
405+ x == (my_snake.position[i - 1].x + 1) % WIDTH)) {
437406 strcpy(board[y][x], "\033[33m═╝\033[0m");
438- } else if (
439- (y == (my_snake.position[i - 1].y + (HEIGHT - 1)) % HEIGHT &&
440- x == (my_snake.position[i + 1].x + 1) % WIDTH) ||
441- (y == (my_snake.position[i + 1].y + HEIGHT - 1) % HEIGHT &&
442- x == (my_snake.position[i - 1].x + 1) % WIDTH)
443- ) {
407+ } else if ((y == (my_snake.position[i - 1].y + (HEIGHT - 1)) % HEIGHT &&
408+ x == (my_snake.position[i + 1].x + 1) % WIDTH) ||
409+ (y == (my_snake.position[i + 1].y + HEIGHT - 1) % HEIGHT &&
410+ x == (my_snake.position[i - 1].x + 1) % WIDTH)) {
444411 strcpy(board[y][x], "\033[33m═╗\033[0m");
445- } else if (
446- (y == (my_snake.position[i - 1].y + 1) % HEIGHT &&
447- x == (my_snake.position[i + 1].x + (WIDTH - 1)) % WIDTH) ||
448- (y == (my_snake.position[i + 1].y + 1) % HEIGHT &&
449- x == (my_snake.position[i - 1].x + (WIDTH - 1)) % WIDTH)
450- ) {
412+ } else if ((y == (my_snake.position[i - 1].y + 1) % HEIGHT &&
413+ x == (my_snake.position[i + 1].x + (WIDTH - 1)) % WIDTH) ||
414+ (y == (my_snake.position[i + 1].y + 1) % HEIGHT &&
415+ x == (my_snake.position[i - 1].x + (WIDTH - 1)) % WIDTH)) {
451416 strcpy(board[y][x], "\033[33m ╚\033[0m");
452- } else if (
453- (y == (my_snake.position[i - 1].y + (HEIGHT - 1)) % HEIGHT &&
454- x == (my_snake.position[i + 1].x + (WIDTH - 1)) % WIDTH) ||
455- (y == (my_snake.position[i + 1].y + (HEIGHT - 1)) % HEIGHT &&
456- x == (my_snake.position[i - 1].x + (WIDTH - 1)) % WIDTH)
457- ) {
417+ } else if ((y == (my_snake.position[i - 1].y + (HEIGHT - 1)) % HEIGHT &&
418+ x == (my_snake.position[i + 1].x + (WIDTH - 1)) % WIDTH) ||
419+ (y == (my_snake.position[i + 1].y + (HEIGHT - 1)) % HEIGHT &&
420+ x == (my_snake.position[i - 1].x + (WIDTH - 1)) % WIDTH)) {
458421 strcpy(board[y][x], "\033[33m ╔\033[0m");
459422 }
460423 }
461424 }
462425 }
463-
426+
464427 if (fruit.x >= 0 && fruit.y >= 0)
465428 strcpy(board[fruit.y][fruit.x], "\033[32m O\033[0m");
466429 }
467430
468-
469431 selected new_fruit(char board[HEIGHT][WIDTH][STRING_LEN]) {
470432 bool found_space = false;
471433
@@ -485,46 +447,29 @@ selected new_fruit(char board[HEIGHT][WIDTH][STRING_LEN]) {
485447 return fruit;
486448 }
487449
488-
489450 bool draw_menu(main_menu menu, struct winsize window_size) {
490451
491- char *menu_string[] = {
492- "NEW GAME",
493- "SETTINGS",
494- "EXIT"
495- };
496-
452+ char *menu_string[] = {"NEW GAME", "SETTINGS", "EXIT"};
453+
497454 const uint8_t width_small = 8;
498455 const uint8_t height_small = 5;
499456
500-
501-
502457 char *menu_string_big[][6] = {
503- {
504- "███╗ ██╗███████╗██╗ ██╗ ██████╗ █████╗ ███╗ ███╗███████╗",
505- "████╗ ██║██╔════╝██║ ██║ ██╔════╝ ██╔══██╗████╗ ████║██╔════╝",
506- "██╔██╗ ██║█████╗ ██║ █╗ ██║ ██║ ███╗███████║██╔████╔██║█████╗ ",
507- "██║╚██╗██║██╔══╝ ██║███╗██║ ██║ ██║██╔══██║██║╚██╔╝██║██╔══╝ ",
508- "██║ ╚████║███████╗╚███╔███╔╝ ╚██████╔╝██║ ██║██║ ╚═╝ ██║███████╗",
509- "╚═╝ ╚═══╝╚══════╝ ╚══╝╚══╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝"
510- },
511- {
512- "███████╗███████╗████████╗████████╗██╗███╗ ██╗ ██████╗ ███████╗",
513- "██╔════╝██╔════╝╚══██╔══╝╚══██╔══╝██║████╗ ██║██╔════╝ ██╔════╝",
514- "███████╗█████╗ ██║ ██║ ██║██╔██╗ ██║██║ ███╗███████╗",
515- "╚════██║██╔══╝ ██║ ██║ ██║██║╚██╗██║██║ ██║╚════██║",
516- "███████║███████╗ ██║ ██║ ██║██║ ╚████║╚██████╔╝███████║",
517- "╚══════╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝"
518- },
519- {
520- "███████╗██╗ ██╗██╗████████╗",
521- "██╔════╝╚██╗██╔╝██║╚══██╔══╝",
522- "█████╗ ╚███╔╝ ██║ ██║ ",
523- "██╔══╝ ██╔██╗ ██║ ██║ ",
524- "███████╗██╔╝ ██╗██║ ██║ ",
525- "╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ "
526- }
527- };
458+ {"███╗ ██╗███████╗██╗ ██╗ ██████╗ █████╗ ███╗ ███╗███████╗",
459+ "████╗ ██║██╔════╝██║ ██║ ██╔════╝ ██╔══██╗████╗ ████║██╔════╝",
460+ "██╔██╗ ██║█████╗ ██║ █╗ ██║ ██║ ███╗███████║██╔████╔██║█████╗ ",
461+ "██║╚██╗██║██╔══╝ ██║███╗██║ ██║ ██║██╔══██║██║╚██╔╝██║██╔══╝ ",
462+ "██║ ╚████║███████╗╚███╔███╔╝ ╚██████╔╝██║ ██║██║ ╚═╝ ██║███████╗",
463+ "╚═╝ ╚═══╝╚══════╝ ╚══╝╚══╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝"},
464+ {"███████╗███████╗████████╗████████╗██╗███╗ ██╗ ██████╗ ███████╗",
465+ "██╔════╝██╔════╝╚══██╔══╝╚══██╔══╝██║████╗ ██║██╔════╝ ██╔════╝",
466+ "███████╗█████╗ ██║ ██║ ██║██╔██╗ ██║██║ ███╗███████╗",
467+ "╚════██║██╔══╝ ██║ ██║ ██║██║╚██╗██║██║ ██║╚════██║",
468+ "███████║███████╗ ██║ ██║ ██║██║ ╚████║╚██████╔╝███████║",
469+ "╚══════╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝"},
470+ {"███████╗██╗ ██╗██╗████████╗", "██╔════╝╚██╗██╔╝██║╚══██╔══╝",
471+ "█████╗ ╚███╔╝ ██║ ██║ ", "██╔══╝ ██╔██╗ ██║ ██║ ",
472+ "███████╗██╔╝ ██╗██║ ██║ ", "╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ "}};
528473
529474 const uint8_t height_line = 6;
530475 const uint8_t height_space = 2;
@@ -532,9 +477,8 @@ bool draw_menu(main_menu menu, struct winsize window_size) {
532477 const uint8_t width_text[] = {68, 64, 28};
533478
534479 const uint8_t width_big = width_text[0] /*strlen(menu_string_big[0][0])*/;
535- const uint8_t height_big =
536- height_line * MAIN_MENU + height_space * (MAIN_MENU - 1);
537-
480+ const uint8_t height_big =
481+ height_line * MAIN_MENU + height_space * (MAIN_MENU - 1);
538482
539483 printf("\033[2J\033[H");
540484
@@ -543,26 +487,24 @@ bool draw_menu(main_menu menu, struct winsize window_size) {
543487 return true;
544488 }
545489
546-
547490 uint8_t i, j, k;
548491
549492 if (window_size.ws_row >= height_big && window_size.ws_col >= width_big) {
550-
493+
551494 uint8_t vertical_buffer = (window_size.ws_row - height_big) >> 1;
552-
495+
553496 for (i = 0; i < vertical_buffer; i++)
554497 printf("\n");
555498
556499 for (i = 0; i < MAIN_MENU; i++) {
557-
500+
558501 if (i == menu)
559502 printf("\033[32m");
560503
561- uint8_t horizontal_buffer =
562- (window_size.ws_col - width_text[i]) >> 1;
504+ uint8_t horizontal_buffer = (window_size.ws_col - width_text[i]) >> 1;
505+
506+ for (j = 0; j < height_line; j++) {
563507
564- for (j = 0; j < height_line; j++) {
565-
566508 for (k = 0; k < horizontal_buffer; k++)
567509 printf(" ");
568510
@@ -571,7 +513,7 @@ bool draw_menu(main_menu menu, struct winsize window_size) {
571513 if (j != height_line - 1)
572514 printf("\n");
573515 }
574-
516+
575517 printf("\033[0m");
576518
577519 if (i != MAIN_MENU - 1)
@@ -589,8 +531,8 @@ bool draw_menu(main_menu menu, struct winsize window_size) {
589531 if (i == menu)
590532 printf("\033[32m");
591533
592- uint8_t horizontal_buffer =
593- (window_size.ws_col - strlen(menu_string[i])) >> 1;
534+ uint8_t horizontal_buffer =
535+ (window_size.ws_col - strlen(menu_string[i])) >> 1;
594536
595537 for (j = 0; j < horizontal_buffer; j++)
596538 printf(" ");
@@ -606,27 +548,35 @@ bool draw_menu(main_menu menu, struct winsize window_size) {
606548 return false;
607549 }
608550
551+void draw_board(char board[HEIGHT][WIDTH][STRING_LEN],
552+ struct winsize window_size, bool redraw) {
609553
610-void draw_board (char board[HEIGHT][WIDTH][STRING_LEN], struct winsize window_size) {
611-
612- uint8_t i, j;
554+ uint8_t i, j;
613555
614- uint8_t vertical_buffer = (window_size.ws_row - ACTUAL_HEIGHT) >> 1;
615- uint8_t horizontal_buffer = (window_size.ws_col - ACTUAL_WIDTH) >> 1;
556+ uint8_t actual_height = HEIGHT + 2;
557+ uint8_t actual_width = WIDTH * 2 + 2;
616558
617- printf("\033[2J\033[H");
559+ uint8_t vertical_buffer = (window_size.ws_row - actual_height) >> 1;
560+ uint8_t horizontal_buffer = (window_size.ws_col - actual_width) >> 1;
618561
619- for (i = 0; i < vertical_buffer; i++)
620- printf("\n");
562+ if (redraw) {
563+ printf("\033[2J\033[H");
564+ for (i = 0; i < vertical_buffer; i++)
565+ printf("\n");
566+ } else {
567+ for (i = 0; i < actual_height - 1; i++)
568+ printf("\033[%c", UP_CODE);
569+ printf("\r");
570+ }
621571
622572 for (i = 0; i < horizontal_buffer; i++)
623- printf(" ");
573+ printf(" ");
624574 printf("+");
625575 for (i = 0; i < WIDTH; i++)
626576 printf("--");
627577 printf("+\n");
628578
629- for ( i = 0; i < HEIGHT; i++) {
579+ for (i = 0; i < HEIGHT; i++) {
630580
631581 for (j = 0; j < horizontal_buffer; j++)
632582 printf(" ");
@@ -648,20 +598,14 @@ void draw_board (char board[HEIGHT][WIDTH][STRING_LEN], struct winsize window_si
648598 fflush(stdout);
649599 }
650600
651-
652601 void draw_pause(struct winsize window_size) {
653602
654603 const uint8_t height = 5;
655604 const uint8_t width = 14;
656605
657- const char *pause_menu [] = {
658- "+------------+",
659- "| |",
660- "| PAUSED |",
661- "| |",
662- "+------------+"
663- };
664-
606+ const char *pause_menu[] = {"+------------+", "| |",
607+ "| PAUSED |", "| |",
608+ "+------------+"};
665609
666610 const uint8_t going_up = (ACTUAL_HEIGHT + height) >> 1;
667611 const uint8_t going_right = (ACTUAL_WIDTH - width) >> 1;
@@ -690,45 +634,44 @@ void draw_pause(struct winsize window_size) {
690634 fflush(stdout);
691635 }
692636
693-direction read_direction (char* string, bool wasd_enabled) {
637+direction read_direction(char *string, bool wasd_enabled) {
694638
695639 if (strlen(string) >= 3) {
696640 if (string[0] == '\033') {
697641 if (string[1] == '[') {
698-
642+
699643 switch (string[2]) {
700- case RIGHT_CODE:
701- return RIGHT;
702- break;
703- case LEFT_CODE:
704- return LEFT;
705- break;
706- case UP_CODE:
707- return UP;
708- break;
709- case DOWN_CODE:
710- return DOWN;
711- break;
712- }
644+ case RIGHT_CODE:
645+ return RIGHT;
646+ break;
647+ case LEFT_CODE:
648+ return LEFT;
649+ break;
650+ case UP_CODE:
651+ return UP;
652+ break;
653+ case DOWN_CODE:
654+ return DOWN;
655+ break;
656+ }
713657 }
714658 }
715659 }
716660
717-
718661 if (wasd_enabled) {
719662 switch (toupper(string[0])) {
720- case 'A':
721- return LEFT;
722- break;
723- case 'D':
724- return RIGHT;
725- break;
726- case 'W':
727- return UP;
728- break;
729- case 'S':
730- return DOWN;
731- break;
663+ case 'A':
664+ return LEFT;
665+ break;
666+ case 'D':
667+ return RIGHT;
668+ break;
669+ case 'W':
670+ return UP;
671+ break;
672+ case 'S':
673+ return DOWN;
674+ break;
732675 }
733676 }