jag

snake_c

public

Small snake game in C

Star0
Watch0

Commit e118234aa39b

tarball

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

4 files changed+459-448
divided into seperate files
Modified file: Makefile+1 additions−1 deletions
@@ -1,2 +1,2 @@
11 snake: snake.c
2- gcc -std=c99 -Wall -Wextra -o snake snake.c
2+ gcc -std=c99 -Wall -Wextra -o snake snake.c drawing.c
Added file: drawing.c+364 additions
@@ -0,0 +1,364 @@
1+#include "snake.h"
2+
3+bool start_animation() {
4+
5+ struct winsize current_size;
6+ ioctl(STDOUT_FILENO, TIOCGWINSZ, &current_size);
7+
8+ struct timespec mili10 = {0, 1000000 * 10};
9+
10+ char *snake[3][7] = {
11+ {
12+ " ________ ",
13+ " _/ _ \\_",
14+ "________/ (_) ",
15+ "\\ \\ ",
16+ "/_______/ _ ",
17+ " \\_ (_) _",
18+ " \\________/ "
19+ },
20+ {
21+ " ",
22+ "________",
23+ "\\ /",
24+ " \\ / ",
25+ " \\ / ",
26+ "___\\/___",
27+ " ",
28+ },
29+ {
30+ " ",
31+ "__ ",
32+ " \\_____ ",
33+ " \\",
34+ " _____/",
35+ "__/ ",
36+ " "
37+ }
38+ };
39+
40+ uint8_t width_snake[3] = {};
41+
42+ {
43+ uint8_t i;
44+
45+ for (i = 0; i < 3; i++)
46+ width_snake[i] = (uint8_t) strlen(snake[i][0]);
47+ }
48+
49+ uint8_t middle;
50+
51+ uint8_t height = 7;
52+ uint8_t width = width_snake[0] + width_snake[1] + width_snake[2];
53+
54+ for (middle = 1; width < current_size.ws_col; middle++)
55+ width += width_snake[1];
56+
57+ int32_t end = current_size.ws_col + width;
58+
59+
60+
61+ while (end >= 0) {
62+
63+ ioctl(STDOUT_FILENO, TIOCGWINSZ, &current_size);
64+
65+ int32_t start = end - width;
66+
67+ int32_t i, j;
68+
69+ char string[1000] = {};
70+ ssize_t length_string = read(STDIN_FILENO, string, sizeof(string) - 1);
71+
72+ if (length_string > 0) {
73+
74+ string[length_string] = '\0';
75+
76+
77+ if (toupper(string[0]) == 'Q')
78+ return false;
79+
80+ if (string[0] == '\n')
81+ break;
82+ }
83+
84+ printf("\033[2J\033[H");
85+
86+ for (j = 0; j < ((height > current_size.ws_row) ? current_size.ws_row : height) ; j++) {
87+
88+ for (i = 0; i < current_size.ws_col; i++) {
89+ int32_t index = i - start;
90+
91+ if (index >= 0 && index < width) {
92+ if (index < width_snake[0]) {
93+ printf("%c", snake[0][j][index]);
94+ } else if (index < width_snake[0] + width_snake[1] * middle) {
95+ printf("%c", snake[1][j][(index - width_snake[0]) % width_snake[1]]);
96+ } else {
97+ printf("%c", snake[2][j][index - (width_snake[0] + width_snake[1] * middle)]);
98+ }
99+ } else {
100+ printf(" ");
101+ }
102+ }
103+
104+ printf("\n");
105+
106+ }
107+ fflush(stdout);
108+
109+ end--;
110+
111+ nanosleep(&mili10, NULL);
112+ }
113+ return true;
114+}
115+
116+bool draw_menu(main_menu menu, struct winsize window_size) {
117+
118+ char *menu_string[] = {"NEW GAME", "SETTINGS", "EXIT"};
119+
120+ const uint8_t width_small = 8;
121+ const uint8_t height_small = 5;
122+
123+ char *menu_string_big[][6] = {
124+ {"███╗ ██╗███████╗██╗ ██╗ ██████╗ █████╗ ███╗ ███╗███████╗",
125+ "████╗ ██║██╔════╝██║ ██║ ██╔════╝ ██╔══██╗████╗ ████║██╔════╝",
126+ "██╔██╗ ██║█████╗ ██║ █╗ ██║ ██║ ███╗███████║██╔████╔██║█████╗ ",
127+ "██║╚██╗██║██╔══╝ ██║███╗██║ ██║ ██║██╔══██║██║╚██╔╝██║██╔══╝ ",
128+ "██║ ╚████║███████╗╚███╔███╔╝ ╚██████╔╝██║ ██║██║ ╚═╝ ██║███████╗",
129+ "╚═╝ ╚═══╝╚══════╝ ╚══╝╚══╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝"},
130+ {"███████╗███████╗████████╗████████╗██╗███╗ ██╗ ██████╗ ███████╗",
131+ "██╔════╝██╔════╝╚══██╔══╝╚══██╔══╝██║████╗ ██║██╔════╝ ██╔════╝",
132+ "███████╗█████╗ ██║ ██║ ██║██╔██╗ ██║██║ ███╗███████╗",
133+ "╚════██║██╔══╝ ██║ ██║ ██║██║╚██╗██║██║ ██║╚════██║",
134+ "███████║███████╗ ██║ ██║ ██║██║ ╚████║╚██████╔╝███████║",
135+ "╚══════╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝"},
136+ {"███████╗██╗ ██╗██╗████████╗", "██╔════╝╚██╗██╔╝██║╚══██╔══╝",
137+ "█████╗ ╚███╔╝ ██║ ██║ ", "██╔══╝ ██╔██╗ ██║ ██║ ",
138+ "███████╗██╔╝ ██╗██║ ██║ ", "╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ "}};
139+
140+ const uint8_t height_line = 6;
141+ const uint8_t height_space = 2;
142+
143+ const uint8_t width_text[] = {68, 64, 28};
144+
145+ const uint8_t width_big = width_text[0] /*strlen(menu_string_big[0][0])*/;
146+ const uint8_t height_big =
147+ height_line * MAIN_MENU + height_space * (MAIN_MENU - 1);
148+
149+ printf("\033[2J\033[H");
150+
151+ if (window_size.ws_row < height_small || window_size.ws_col < width_small) {
152+ printf("Too small\n");
153+ return true;
154+ }
155+
156+ uint8_t i, j, k;
157+
158+ if (window_size.ws_row >= height_big && window_size.ws_col >= width_big) {
159+
160+ uint8_t vertical_buffer = (window_size.ws_row - height_big) >> 1;
161+
162+ for (i = 0; i < vertical_buffer; i++)
163+ printf("\n");
164+
165+ for (i = 0; i < MAIN_MENU; i++) {
166+
167+ if (i == menu)
168+ printf("\033[32m");
169+
170+ uint8_t horizontal_buffer = (window_size.ws_col - width_text[i]) >> 1;
171+
172+ for (j = 0; j < height_line; j++) {
173+
174+ for (k = 0; k < horizontal_buffer; k++)
175+ printf(" ");
176+
177+ printf("%s", menu_string_big[i][j]);
178+
179+ if (j != height_line - 1)
180+ printf("\n");
181+ }
182+
183+ printf("\033[0m");
184+
185+ if (i != MAIN_MENU - 1)
186+ printf("\n\n");
187+ }
188+
189+ } else {
190+
191+ uint8_t vertical_buffer = (window_size.ws_row - height_small) >> 1;
192+
193+ for (i = 0; i < vertical_buffer; i++)
194+ printf("\n");
195+
196+ for (i = 0; i < MAIN_MENU; i++) {
197+ if (i == menu)
198+ printf("\033[32m");
199+
200+ uint8_t horizontal_buffer =
201+ (window_size.ws_col - strlen(menu_string[i])) >> 1;
202+
203+ for (j = 0; j < horizontal_buffer; j++)
204+ printf(" ");
205+
206+ printf("%s\033[0m", menu_string[i]);
207+
208+ if (i != MAIN_MENU - 1)
209+ printf("\n\n");
210+ }
211+ }
212+
213+ fflush(stdout);
214+ return false;
215+}
216+
217+bool draw_board(
218+ selected game_size,
219+ board_state **board,
220+ struct winsize window_size,
221+ bool redraw, bool paused
222+) {
223+
224+ uint8_t i, j;
225+
226+ uint8_t actual_height = game_size.y + 2;
227+ uint8_t actual_width = game_size.x * 2 + 1 + 2;
228+
229+ if (actual_width > window_size.ws_col || actual_height > window_size.ws_row) {
230+
231+ printf("\033[2J\033[HToo small\n");
232+ printf("Min width: %i & Min height: %i\n", actual_height, actual_width);
233+
234+ return true;
235+ }
236+
237+ uint8_t vertical_buffer = (window_size.ws_row - actual_height) >> 1;
238+ uint8_t horizontal_buffer = (window_size.ws_col - actual_width) >> 1;
239+
240+ if (redraw) {
241+ printf("\033[2J\033[H");
242+ for (i = 0; i < vertical_buffer; i++)
243+ printf("\n");
244+ } else {
245+ for (i = 0; i < actual_height - 1; i++)
246+ printf("\033[%c", UP_CODE);
247+ printf("\r");
248+ }
249+
250+ for (i = 0; i < horizontal_buffer; i++)
251+ printf(" ");
252+ printf("╭");
253+ for (i = 0; i < game_size.x; i++)
254+ printf("──");
255+ printf("─╮\n");
256+
257+ for (i = 0; i < game_size.y; i++) {
258+
259+ for (j = 0; j < horizontal_buffer; j++)
260+ printf(" ");
261+
262+ printf("│");
263+
264+ for (j = 0; j < game_size.x; j++)
265+ printf("%s", give_state(board[i][j]));
266+
267+ printf("%s", give_state(board[i][0]));
268+
269+ printf("\033[%c│\n", LEFT_CODE);
270+ }
271+
272+ for (i = 0; i < horizontal_buffer; i++)
273+ printf(" ");
274+ printf("╰");
275+ for (i = 0; i < game_size.x; i++)
276+ printf("──");
277+ printf("─╯");
278+
279+ if (paused)
280+ draw_pause(window_size, actual_width, actual_height);
281+
282+ fflush(stdout);
283+
284+ return false;
285+}
286+
287+void draw_pause(struct winsize window_size, uint8_t field_width,
288+ uint8_t field_height) {
289+
290+ const uint8_t height = 5;
291+ const uint8_t width = 14;
292+
293+ const char *pause_menu[] = {
294+ "+------------+",
295+ "| |",
296+ "| PAUSED |",
297+ "| |",
298+ "+------------+"
299+ };
300+
301+ const uint8_t going_up = (field_height + height) >> 1;
302+ const uint8_t going_right = (field_width - width) >> 1;
303+
304+ const uint8_t horizontal_buffer = (window_size.ws_col - field_width) >> 1;
305+
306+ uint8_t i, j;
307+
308+ for (i = 0; i < going_up; i++)
309+ printf("\033[%c", UP_CODE);
310+ printf("\r");
311+
312+ for (i = 0; i < height; i++) {
313+ for (j = 0; j < horizontal_buffer; j++)
314+ printf("\033[%c", RIGHT_CODE);
315+ for (j = 0; j < going_right; j++)
316+ printf("\033[%c", RIGHT_CODE);
317+
318+ printf("\033[37m%s\033[0m\033[%c\r", pause_menu[i], DOWN_CODE);
319+ }
320+
321+ for (i = 0; i < going_up - height; i++)
322+ printf("\033[%c", DOWN_CODE);
323+ printf("\r");
324+
325+ fflush(stdout);
326+}
327+
328+char *give_state(board_state square) {
329+
330+ switch (square) {
331+ case FRUIT:
332+ return "\033[32m O\033[0m";
333+ break;
334+ case HEAD_1:
335+ return "\033[33m═\033[31mX\033[0m";
336+ break;
337+ case HEAD_2:
338+ return "\033[31m\33[CX\033[0m";
339+ break;
340+ case VERTICAL:
341+ return "\033[33m ║\033[0m";
342+ break;
343+ case HORIZONTAL:
344+ return "\033[33m══\033[0m";
345+ break;
346+ case TOP_RIGHT:
347+ return "\033[33m ╚\033[0m";
348+ break;
349+ case TOP_LEFT:
350+ return "\033[33m═╝\033[0m";
351+ break;
352+ case BOTTOM_RIGHT:
353+ return "\033[33m ╔\033[0m";
354+ break;
355+ case BOTTOM_LEFT:
356+ return "\033[33m═╗\033[0m";
357+ break;
358+ default:
359+ return " ·";
360+ break;
361+ }
362+}
363+
364+
Modified file: snake.c+1 additions−447 deletions
@@ -1,89 +1,4 @@
1-#define _POSIX_C_SOURCE 199309L
2-
3-#include <termios.h>
4-#include <unistd.h>
5-
6-#include <stdbool.h>
7-#include <stdint.h>
8-#include <stdio.h>
9-#include <stdlib.h>
10-
11-#include <sys/ioctl.h>
12-
13-#include <time.h>
14-
15-#include <ctype.h>
16-#include <string.h>
17-
18-#define RIGHT_CODE 'C'
19-#define LEFT_CODE 'D'
20-#define UP_CODE 'A'
21-#define DOWN_CODE 'B'
22-
23-#define WIDTH 20
24-#define HEIGHT 20
25-
26-#define MIN_SIZE 10
27-#define MAX_SIZE 100
28-
29-#define STRING_LEN 20
30-
31-#define SPEED 50 /* in ms */
32-
33-#define MAX_LENGTH 1000
34-#define STARTING_LENGTH 2
35-
36-typedef enum { NEW_GAME, SETTINGS, EXIT, MAIN_MENU } main_menu;
37-
38-typedef enum {HEIGHT_S, WIDTH_S, SPEED_S, BACK_S, SETTINGS_MENU} settings;
39-
40-typedef enum {V_FAST, FAST, AVERAGE, SLOW, V_SLOW, SPEED_L} speed;
41-
42-typedef enum {
43- NO_DIRECTION = -1,
44- UP = 0,
45- LEFT = 1,
46- DOWN = 2,
47- RIGHT = 3,
48- DIRECTIONS = 4
49-} direction;
50-
51-typedef enum {
52- AIR, FRUIT, HEAD_1, HEAD_2, HORIZONTAL, VERTICAL,
53- TOP_RIGHT, TOP_LEFT, BOTTOM_RIGHT, BOTTOM_LEFT
54-} board_state;
55-
56-typedef struct selected {
57- int8_t x;
58- int8_t y;
59-} selected;
60-
61-typedef struct snake_part {
62- selected coords;
63- direction directions[2];
64-} snake_part;
65-
66-typedef struct snake {
67- snake_part * position;
68- uint16_t length;
69-} snake;
70-
71-
72-uint8_t update_snake (selected game_size, snake *my_snake, direction shift);
73-void update_field(snake my_snake, selected game_size,
74- board_state **board, bool init);
75-selected new_fruit(selected game_size, board_state **board);
76-
77-bool start_animation();
78-bool draw_menu(main_menu menu, struct winsize window_size);
79-bool draw_board(selected game_size, board_state **board,
80- struct winsize window_size, bool redraw, bool paused);
81-void draw_pause(struct winsize window_size,
82- uint8_t field_width,uint8_t field_height);
83-
84-char *give_state(board_state square);
85-
86-direction read_direction(char *string, bool wasd_enabled);
1+#include "snake.h"
872
883 int main(int argc, char *args[]) {
894
@@ -695,367 +610,6 @@ selected new_fruit(selected game_size, board_state **board) {
695610 return fruit;
696611 }
697612
698-bool start_animation() {
699-
700- struct winsize current_size;
701- ioctl(STDOUT_FILENO, TIOCGWINSZ, &current_size);
702-
703- struct timespec mili10 = {0, 1000000 * 10};
704-
705- char *snake[3][7] = {
706- {
707- " ________ ",
708- " _/ _ \\_",
709- "________/ (_) ",
710- "\\ \\ ",
711- "/_______/ _ ",
712- " \\_ (_) _",
713- " \\________/ "
714- },
715- {
716- " ",
717- "________",
718- "\\ /",
719- " \\ / ",
720- " \\ / ",
721- "___\\/___",
722- " ",
723- },
724- {
725- " ",
726- "__ ",
727- " \\_____ ",
728- " \\",
729- " _____/",
730- "__/ ",
731- " "
732- }
733- };
734-
735- uint8_t width_snake[3] = {};
736-
737- {
738- uint8_t i;
739-
740- for (i = 0; i < 3; i++)
741- width_snake[i] = (uint8_t) strlen(snake[i][0]);
742- }
743-
744- uint8_t middle;
745-
746- uint8_t height = 7;
747- uint8_t width = width_snake[0] + width_snake[1] + width_snake[2];
748-
749- for (middle = 1; width < current_size.ws_col; middle++)
750- width += width_snake[1];
751-
752- int32_t end = current_size.ws_col + width;
753-
754-
755-
756- while (end >= 0) {
757-
758- ioctl(STDOUT_FILENO, TIOCGWINSZ, &current_size);
759-
760- int32_t start = end - width;
761-
762- int32_t i, j;
763-
764- char string[1000] = {};
765- ssize_t length_string = read(STDIN_FILENO, string, sizeof(string) - 1);
766-
767- if (length_string > 0) {
768-
769- string[length_string] = '\0';
770-
771-
772- if (toupper(string[0]) == 'Q')
773- return false;
774-
775- if (string[0] == '\n')
776- break;
777- }
778-
779- printf("\033[2J\033[H");
780-
781- for (j = 0; j < ((height > current_size.ws_row) ? current_size.ws_row : height) ; j++) {
782-
783- for (i = 0; i < current_size.ws_col; i++) {
784- int32_t index = i - start;
785-
786- if (index >= 0 && index < width) {
787- if (index < width_snake[0]) {
788- printf("%c", snake[0][j][index]);
789- } else if (index < width_snake[0] + width_snake[1] * middle) {
790- printf("%c", snake[1][j][(index - width_snake[0]) % width_snake[1]]);
791- } else {
792- printf("%c", snake[2][j][index - (width_snake[0] + width_snake[1] * middle)]);
793- }
794- } else {
795- printf(" ");
796- }
797- }
798-
799- printf("\n");
800-
801- }
802- fflush(stdout);
803-
804- end--;
805-
806- nanosleep(&mili10, NULL);
807- }
808- return true;
809-}
810-
811-bool draw_menu(main_menu menu, struct winsize window_size) {
812-
813- char *menu_string[] = {"NEW GAME", "SETTINGS", "EXIT"};
814-
815- const uint8_t width_small = 8;
816- const uint8_t height_small = 5;
817-
818- char *menu_string_big[][6] = {
819- {"███╗ ██╗███████╗██╗ ██╗ ██████╗ █████╗ ███╗ ███╗███████╗",
820- "████╗ ██║██╔════╝██║ ██║ ██╔════╝ ██╔══██╗████╗ ████║██╔════╝",
821- "██╔██╗ ██║█████╗ ██║ █╗ ██║ ██║ ███╗███████║██╔████╔██║█████╗ ",
822- "██║╚██╗██║██╔══╝ ██║███╗██║ ██║ ██║██╔══██║██║╚██╔╝██║██╔══╝ ",
823- "██║ ╚████║███████╗╚███╔███╔╝ ╚██████╔╝██║ ██║██║ ╚═╝ ██║███████╗",
824- "╚═╝ ╚═══╝╚══════╝ ╚══╝╚══╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝"},
825- {"███████╗███████╗████████╗████████╗██╗███╗ ██╗ ██████╗ ███████╗",
826- "██╔════╝██╔════╝╚══██╔══╝╚══██╔══╝██║████╗ ██║██╔════╝ ██╔════╝",
827- "███████╗█████╗ ██║ ██║ ██║██╔██╗ ██║██║ ███╗███████╗",
828- "╚════██║██╔══╝ ██║ ██║ ██║██║╚██╗██║██║ ██║╚════██║",
829- "███████║███████╗ ██║ ██║ ██║██║ ╚████║╚██████╔╝███████║",
830- "╚══════╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝"},
831- {"███████╗██╗ ██╗██╗████████╗", "██╔════╝╚██╗██╔╝██║╚══██╔══╝",
832- "█████╗ ╚███╔╝ ██║ ██║ ", "██╔══╝ ██╔██╗ ██║ ██║ ",
833- "███████╗██╔╝ ██╗██║ ██║ ", "╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ "}};
834-
835- const uint8_t height_line = 6;
836- const uint8_t height_space = 2;
837-
838- const uint8_t width_text[] = {68, 64, 28};
839-
840- const uint8_t width_big = width_text[0] /*strlen(menu_string_big[0][0])*/;
841- const uint8_t height_big =
842- height_line * MAIN_MENU + height_space * (MAIN_MENU - 1);
843-
844- printf("\033[2J\033[H");
845-
846- if (window_size.ws_row < height_small || window_size.ws_col < width_small) {
847- printf("Too small\n");
848- return true;
849- }
850-
851- uint8_t i, j, k;
852-
853- if (window_size.ws_row >= height_big && window_size.ws_col >= width_big) {
854-
855- uint8_t vertical_buffer = (window_size.ws_row - height_big) >> 1;
856-
857- for (i = 0; i < vertical_buffer; i++)
858- printf("\n");
859-
860- for (i = 0; i < MAIN_MENU; i++) {
861-
862- if (i == menu)
863- printf("\033[32m");
864-
865- uint8_t horizontal_buffer = (window_size.ws_col - width_text[i]) >> 1;
866-
867- for (j = 0; j < height_line; j++) {
868-
869- for (k = 0; k < horizontal_buffer; k++)
870- printf(" ");
871-
872- printf("%s", menu_string_big[i][j]);
873-
874- if (j != height_line - 1)
875- printf("\n");
876- }
877-
878- printf("\033[0m");
879-
880- if (i != MAIN_MENU - 1)
881- printf("\n\n");
882- }
883-
884- } else {
885-
886- uint8_t vertical_buffer = (window_size.ws_row - height_small) >> 1;
887-
888- for (i = 0; i < vertical_buffer; i++)
889- printf("\n");
890-
891- for (i = 0; i < MAIN_MENU; i++) {
892- if (i == menu)
893- printf("\033[32m");
894-
895- uint8_t horizontal_buffer =
896- (window_size.ws_col - strlen(menu_string[i])) >> 1;
897-
898- for (j = 0; j < horizontal_buffer; j++)
899- printf(" ");
900-
901- printf("%s\033[0m", menu_string[i]);
902-
903- if (i != MAIN_MENU - 1)
904- printf("\n\n");
905- }
906- }
907-
908- fflush(stdout);
909- return false;
910-}
911-
912-bool draw_board(
913- selected game_size,
914- board_state **board,
915- struct winsize window_size,
916- bool redraw, bool paused
917-) {
918-
919- uint8_t i, j;
920-
921- uint8_t actual_height = game_size.y + 2;
922- uint8_t actual_width = game_size.x * 2 + 1 + 2;
923-
924- if (actual_width > window_size.ws_col || actual_height > window_size.ws_row) {
925-
926- printf("\033[2J\033[HToo small\n");
927- printf("Min width: %i & Min height: %i\n", actual_height, actual_width);
928-
929- return true;
930- }
931-
932- uint8_t vertical_buffer = (window_size.ws_row - actual_height) >> 1;
933- uint8_t horizontal_buffer = (window_size.ws_col - actual_width) >> 1;
934-
935- if (redraw) {
936- printf("\033[2J\033[H");
937- for (i = 0; i < vertical_buffer; i++)
938- printf("\n");
939- } else {
940- for (i = 0; i < actual_height - 1; i++)
941- printf("\033[%c", UP_CODE);
942- printf("\r");
943- }
944-
945- for (i = 0; i < horizontal_buffer; i++)
946- printf(" ");
947- printf("╭");
948- for (i = 0; i < game_size.x; i++)
949- printf("──");
950- printf("─╮\n");
951-
952- for (i = 0; i < game_size.y; i++) {
953-
954- for (j = 0; j < horizontal_buffer; j++)
955- printf(" ");
956-
957- printf("│");
958-
959- for (j = 0; j < game_size.x; j++)
960- printf("%s", give_state(board[i][j]));
961-
962- printf("%s", give_state(board[i][0]));
963-
964- printf("\033[%c│\n", LEFT_CODE);
965- }
966-
967- for (i = 0; i < horizontal_buffer; i++)
968- printf(" ");
969- printf("╰");
970- for (i = 0; i < game_size.x; i++)
971- printf("──");
972- printf("─╯");
973-
974- if (paused)
975- draw_pause(window_size, actual_width, actual_height);
976-
977- fflush(stdout);
978-
979- return false;
980-}
981-
982-void draw_pause(struct winsize window_size, uint8_t field_width,
983- uint8_t field_height) {
984-
985- const uint8_t height = 5;
986- const uint8_t width = 14;
987-
988- const char *pause_menu[] = {
989- "+------------+",
990- "| |",
991- "| PAUSED |",
992- "| |",
993- "+------------+"
994- };
995-
996- const uint8_t going_up = (field_height + height) >> 1;
997- const uint8_t going_right = (field_width - width) >> 1;
998-
999- const uint8_t horizontal_buffer = (window_size.ws_col - field_width) >> 1;
1000-
1001- uint8_t i, j;
1002-
1003- for (i = 0; i < going_up; i++)
1004- printf("\033[%c", UP_CODE);
1005- printf("\r");
1006-
1007- for (i = 0; i < height; i++) {
1008- for (j = 0; j < horizontal_buffer; j++)
1009- printf("\033[%c", RIGHT_CODE);
1010- for (j = 0; j < going_right; j++)
1011- printf("\033[%c", RIGHT_CODE);
1012-
1013- printf("\033[37m%s\033[0m\033[%c\r", pause_menu[i], DOWN_CODE);
1014- }
1015-
1016- for (i = 0; i < going_up - height; i++)
1017- printf("\033[%c", DOWN_CODE);
1018- printf("\r");
1019-
1020- fflush(stdout);
1021-}
1022-
1023-char *give_state(board_state square) {
1024-
1025- switch (square) {
1026- case FRUIT:
1027- return "\033[32m O\033[0m";
1028- break;
1029- case HEAD_1:
1030- return "\033[33m═\033[31mX\033[0m";
1031- break;
1032- case HEAD_2:
1033- return "\033[31m\33[CX\033[0m";
1034- break;
1035- case VERTICAL:
1036- return "\033[33m ║\033[0m";
1037- break;
1038- case HORIZONTAL:
1039- return "\033[33m══\033[0m";
1040- break;
1041- case TOP_RIGHT:
1042- return "\033[33m ╚\033[0m";
1043- break;
1044- case TOP_LEFT:
1045- return "\033[33m═╝\033[0m";
1046- break;
1047- case BOTTOM_RIGHT:
1048- return "\033[33m ╔\033[0m";
1049- break;
1050- case BOTTOM_LEFT:
1051- return "\033[33m═╗\033[0m";
1052- break;
1053- default:
1054- return " ·";
1055- break;
1056- }
1057-}
1058-
1059613
1060614 direction read_direction(char *string, bool wasd_enabled) {
1061615
Added file: snake.h+93 additions
@@ -0,0 +1,93 @@
1+#ifndef SNAKE_H
2+#define SNAKE_H
3+
4+
5+#define _POSIX_C_SOURCE 199309L
6+
7+#include <termios.h>
8+#include <unistd.h>
9+
10+#include <stdbool.h>
11+#include <stdint.h>
12+#include <stdio.h>
13+#include <stdlib.h>
14+
15+#include <sys/ioctl.h>
16+
17+#include <time.h>
18+
19+#include <ctype.h>
20+#include <string.h>
21+
22+#define RIGHT_CODE 'C'
23+#define LEFT_CODE 'D'
24+#define UP_CODE 'A'
25+#define DOWN_CODE 'B'
26+
27+#define WIDTH 20
28+#define HEIGHT 20
29+
30+#define MIN_SIZE 10
31+#define MAX_SIZE 100
32+
33+#define STRING_LEN 20
34+
35+#define SPEED 50 /* in ms */
36+
37+#define MAX_LENGTH 1000
38+#define STARTING_LENGTH 2
39+
40+typedef enum { NEW_GAME, SETTINGS, EXIT, MAIN_MENU } main_menu;
41+
42+typedef enum {HEIGHT_S, WIDTH_S, SPEED_S, BACK_S, SETTINGS_MENU} settings;
43+
44+typedef enum {V_FAST, FAST, AVERAGE, SLOW, V_SLOW, SPEED_L} speed;
45+
46+typedef enum {
47+ NO_DIRECTION = -1,
48+ UP = 0,
49+ LEFT = 1,
50+ DOWN = 2,
51+ RIGHT = 3,
52+ DIRECTIONS = 4
53+} direction;
54+
55+typedef enum {
56+ AIR, FRUIT, HEAD_1, HEAD_2, HORIZONTAL, VERTICAL,
57+ TOP_RIGHT, TOP_LEFT, BOTTOM_RIGHT, BOTTOM_LEFT
58+} board_state;
59+
60+typedef struct selected {
61+ int8_t x;
62+ int8_t y;
63+} selected;
64+
65+typedef struct snake_part {
66+ selected coords;
67+ direction directions[2];
68+} snake_part;
69+
70+typedef struct snake {
71+ snake_part * position;
72+ uint16_t length;
73+} snake;
74+
75+
76+uint8_t update_snake (selected game_size, snake *my_snake, direction shift);
77+void update_field(snake my_snake, selected game_size,
78+ board_state **board, bool init);
79+selected new_fruit(selected game_size, board_state **board);
80+
81+bool start_animation();
82+bool draw_menu(main_menu menu, struct winsize window_size);
83+bool draw_board(selected game_size, board_state **board,
84+ struct winsize window_size, bool redraw, bool paused);
85+void draw_pause(struct winsize window_size,
86+ uint8_t field_width,uint8_t field_height);
87+
88+char *give_state(board_state square);
89+
90+direction read_direction(char *string, bool wasd_enabled);
91+
92+
93+#endif