Small snake game in C
Commit e118234aa39b
tarball4 files changed+459-448
@@ -1,2 +1,2 @@
11
snake: snake.c2
- gcc -std=c99 -Wall -Wextra -o snake snake.c2
+ gcc -std=c99 -Wall -Wextra -o snake snake.c drawing.c@@ -0,0 +1,364 @@
1
+#include "snake.h"2
+3
+bool start_animation() { 4
+5
+ struct winsize current_size;6
+ ioctl(STDOUT_FILENO, TIOCGWINSZ, ¤t_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, ¤t_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 paused222
+) {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
+@@ -1,89 +1,4 @@
1
-#define _POSIX_C_SOURCE 199309L2
-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 2024
-#define HEIGHT 2025
-26
-#define MIN_SIZE 1027
-#define MAX_SIZE 10028
-29
-#define STRING_LEN 2030
-31
-#define SPEED 50 /* in ms */32
-33
-#define MAX_LENGTH 100034
-#define STARTING_LENGTH 235
-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 = 449
-} direction;50
-51
-typedef enum {52
- AIR, FRUIT, HEAD_1, HEAD_2, HORIZONTAL, VERTICAL, 53
- TOP_RIGHT, TOP_LEFT, BOTTOM_RIGHT, BOTTOM_LEFT54
-} 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, ¤t_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, ¤t_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 paused917
-) {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
@@ -0,0 +1,93 @@
1
+#ifndef SNAKE_H2
+#define SNAKE_H3
+4
+5
+#define _POSIX_C_SOURCE 199309L6
+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 2028
+#define HEIGHT 2029
+30
+#define MIN_SIZE 1031
+#define MAX_SIZE 10032
+33
+#define STRING_LEN 2034
+35
+#define SPEED 50 /* in ms */36
+37
+#define MAX_LENGTH 100038
+#define STARTING_LENGTH 239
+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 = 453
+} direction;54
+55
+typedef enum {56
+ AIR, FRUIT, HEAD_1, HEAD_2, HORIZONTAL, VERTICAL, 57
+ TOP_RIGHT, TOP_LEFT, BOTTOM_RIGHT, BOTTOM_LEFT58
+} 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