jag

snake_c

public

Small snake game in C

Star0
Watch0
815882c55c3a296801e8b6e846c4dfc2f1e7d1cf
2
ssh://git@git.jaglekon.de:30/jag/snake_c.git
snake.cC773 lines20.1 KB
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 STRING_LEN 20
27
28
#define SPEED 100 /* in ms */
29
30
#define MAX_LENGTH 1000
31
#define STARTING_LENGTH 2
32
33
typedef enum { NEW_GAME, SETTINGS, EXIT, MAIN_MENU } main_menu;
34
35
typedef enum {
36
  NO_DIRECTION = -1,
37
  UP = 0,
38
  LEFT = 1,
39
  DOWN = 2,
40
  RIGHT = 3,
41
  DIRECTIONS = 4
42
} direction;
43
44
typedef struct selected {
45
  int16_t x;
46
  int16_t y;
47
} selected;
48
49
typedef struct snake {
50
  selected position[MAX_LENGTH];
51
  uint16_t length;
52
} snake;
53
54
void update_field(snake my_snake, char board[HEIGHT][WIDTH][STRING_LEN],
55
                  selected fruit);
56
selected new_fruit(char board[HEIGHT][WIDTH][STRING_LEN]);
57
58
bool draw_menu(main_menu menu, struct winsize window_size);
59
60
bool draw_board(char board[HEIGHT][WIDTH][STRING_LEN],
61
                struct winsize window_size, bool redraw, bool paused);
62
void draw_pause(struct winsize window_size, uint8_t field_width,
63
                uint8_t field_height);
64
65
direction read_direction(char *string, bool wasd_enabled);
66
67
int main(int argc, char *args[]) {
68
69
  /* command argument handling */
70
71
  if (argc > 1) {
72
    if (argc > 2) {
73
      printf("Too many parameters\n");
74
      goto help_info;
75
    }
76
77
    if (!strcmp(args[1], "-h") || !strcmp(args[1], "--help")) {
78
79
      printf("This is a small TUI snake game.\n\n");
80
      printf("Controls: Arrow keys/WASD to control the snake.\n");
81
      printf("          P to pause.\n");
82
      printf("          Q to quit.\n");
83
84
      return 0;
85
    }
86
87
    printf("Argument \"%s\" not recognized\n", args[1]);
88
89
  help_info:
90
    printf("Try \"-h\" or \"--help\" for more information\n");
91
    return 1;
92
  }
93
94
  /* Setting up terminal with termios */
95
96
  struct termios old, new;
97
98
  tcgetattr(STDIN_FILENO, &old);
99
100
  new = old;
101
102
  new.c_lflag &= ~(ECHO | ICANON);
103
  new.c_cc[VMIN] = 0;
104
  new.c_cc[VTIME] = 0;
105
106
  tcsetattr(STDIN_FILENO, TCSANOW, &new);
107
108
  srand(time(NULL));
109
110
  printf("\033[?25l");
111
112
  struct winsize init_size, current_size;
113
  ioctl(STDOUT_FILENO, TIOCGWINSZ, &init_size);
114
  current_size = init_size;
115
  bool too_small = false;
116
117
118
  struct timespec mili100 = {0, 1000000 * SPEED};
119
  struct timespec mili10 = {0, 100000 * SPEED};
120
121
  {
122
123
    char *snake[3][7] = {
124
      {
125
        "           ________  ",
126
        "         _/ _      \\_",
127
        "________/  (_)       ",
128
        "\\       \\            ",
129
        "/_______/   _        ",
130
        "        \\_ (_)      _",
131
        "          \\________/ "
132
      },
133
      {
134
        "        ",
135
        "________",
136
        "\\      /",
137
        " \\    / ",
138
        "  \\  /  ",
139
        "___\\/___",
140
        "        ",
141
      },
142
      {
143
        "         ",
144
        "__        ",
145
        "  \\_____ ",
146
        "        \\",
147
        "   _____/",
148
        "__/      ",
149
        "         "
150
      }
151
    };
152
153
    uint8_t width_snake[3] = {};
154
  
155
    {
156
      uint8_t i;
157
  
158
      for (i = 0; i < 3; i++)
159
        width_snake[i] = (uint8_t) strlen(snake[i][0]);
160
    }
161
162
    uint8_t middle;
163
164
    uint8_t height = 7;
165
    uint8_t width = width_snake[0] + width_snake[1] + width_snake[2];
166
167
    for (middle = 1; width < current_size.ws_col; middle++)
168
      width += width_snake[1];
169
170
    int32_t end = current_size.ws_col + width;
171
172
173
174
    while (end >= 0) {
175
176
      ioctl(STDOUT_FILENO, TIOCGWINSZ, &current_size);
177
178
      int32_t start = end - width; 
179
180
      int32_t i, j;
181
   
182
      char string[1000] = {};
183
      ssize_t length_string = read(STDIN_FILENO, string, sizeof(string) - 1);
184
185
       if (length_string > 0) {
186
      
187
        string[length_string] = '\0';
188
189
190
      if (toupper(string[0]) == 'Q')
191
        goto end_of_program;
192
193
      if (string[0] == '\n')
194
        break;
195
      }
196
197
      printf("\033[2J\033[H");
198
199
      for (j = 0; j < ((height > current_size.ws_row) ? current_size.ws_row : height) ; j++) {
200
201
      for (i = 0; i < current_size.ws_col; i++) {
202
        int32_t index = i - start;
203
204
        if (index >= 0 && index < width) {
205
          if (index < width_snake[0]) {
206
            printf("%c", snake[0][j][index]);
207
          } else if (index < width_snake[0] + width_snake[1] * middle) {
208
            printf("%c", snake[1][j][(index - width_snake[0]) % width_snake[1]]);
209
          } else {
210
            printf("%c", snake[2][j][index - (width_snake[0] + width_snake[1] * middle)]);
211
          }
212
        } else {
213
          printf(" ");
214
        }
215
      }      
216
      
217
        printf("\n");
218
219
      }
220
      fflush(stdout);
221
      
222
      end--;
223
224
      nanosleep(&mili10, NULL);
225
    }
226
227
  }
228
229
  /* Menu */
230
231
  bool menu = true;
232
233
  main_menu selected_menu = NEW_GAME;
234
235
  too_small = draw_menu(selected_menu, init_size);
236
237
  while (menu) {
238
239
    bool pressed_enter = false;
240
    bool changed_selected = false;
241
242
    char string[1000] = {};
243
    ssize_t length_string = read(STDIN_FILENO, string, sizeof(string) - 1);
244
245
    direction arrow = NO_DIRECTION;
246
247
248
    if (true) {
249
250
      ioctl(STDOUT_FILENO, TIOCGWINSZ, &current_size);
251
252
      if (current_size.ws_col != init_size.ws_col ||
253
          current_size.ws_row != init_size.ws_row) {
254
        init_size = current_size;
255
        changed_selected = true;
256
      }
257
    }
258
259
    if (length_string > 0 && !too_small) {
260
      string[length_string] = '\0';
261
262
      arrow = read_direction(string, false);
263
264
      switch (arrow) {
265
      case UP:
266
        selected_menu = (selected_menu + (MAIN_MENU - 1)) % MAIN_MENU;
267
        changed_selected = true;
268
        break;
269
      case DOWN:
270
        selected_menu = (selected_menu + 1) % MAIN_MENU;
271
        changed_selected = true;
272
        break;
273
      default:
274
        break;
275
      }
276
277
      if (toupper(string[0]) == 'Q')
278
        goto end_of_program;
279
280
      if (string[0] == '\n')
281
        pressed_enter = true;
282
    }
283
284
    if (changed_selected)
285
      too_small = draw_menu(selected_menu, init_size);
286
287
    if (pressed_enter) {
288
      switch (selected_menu) {
289
      case NEW_GAME:
290
        menu = false;
291
        break;
292
      default:
293
        goto end_of_program;
294
        break;
295
      }
296
    }
297
    nanosleep(&mili100, NULL);
298
  }
299
300
  /* initialisation of the game */
301
302
  snake my_snake = {};
303
  my_snake.length = STARTING_LENGTH;
304
305
  {
306
    uint16_t i;
307
308
    my_snake.position[0].y = HEIGHT >> 1;
309
    my_snake.position[0].x = WIDTH >> 1;
310
    for (i = 1; i < my_snake.length; i++) {
311
      my_snake.position[i].y = -1;
312
      my_snake.position[i].x = -1;
313
    }
314
  }
315
316
  selected fruit = {-1, -1};
317
  char board[HEIGHT][WIDTH][STRING_LEN] = {};
318
319
  update_field(my_snake, board, fruit);
320
321
  fruit = new_fruit(board);
322
  update_field(my_snake, board, fruit);
323
324
  bool paused = false;
325
326
  if ((too_small = draw_board(board, current_size, true, false)))
327
    paused = true;
328
329
  direction shift = RIGHT;
330
  direction tmp_direction = shift;
331
332
  bool run = true;
333
334
  /* start of the actual game loop */
335
336
  while (run) {
337
338
    /* input handling  */
339
340
    if (!too_small) {
341
      char string[1000] = {};
342
      ssize_t length_string = read(STDIN_FILENO, string, sizeof(string) - 1);
343
344
      if (length_string > 0) {
345
        string[length_string] = '\0';
346
347
        if (!paused)
348
          tmp_direction = read_direction(string, true);
349
350
        if (toupper(string[0]) == 'Q')
351
          run = false;
352
353
        if (toupper(string[0]) == 'P') {
354
          paused = !paused;
355
          if (paused)
356
            draw_board(board, current_size, true, paused);
357
        }
358
      }
359
    }
360
361
    /* game logic */
362
363
    /*
364
    struct timeval current;
365
    gettimeofday(&current, NULL);*/
366
367
    if (/*time_diff >= SPEED * 1000*/ true) {
368
369
      ioctl(STDOUT_FILENO, TIOCGWINSZ, &current_size);
370
371
      if (current_size.ws_col != init_size.ws_col ||
372
          current_size.ws_row != init_size.ws_row) {
373
        init_size = current_size;
374
375
        paused = true;
376
        too_small = draw_board(board, current_size, true, paused);
377
      }
378
379
      if (!paused) {
380
381
        if (tmp_direction != NO_DIRECTION &&
382
            ((shift + (DIRECTIONS >> 1)) % DIRECTIONS) != tmp_direction) {
383
          shift = tmp_direction;
384
        }
385
386
        uint16_t i;
387
        for (i = my_snake.length; i > 0; i--) {
388
          my_snake.position[i].y = my_snake.position[i - 1].y;
389
          my_snake.position[i].x = my_snake.position[i - 1].x;
390
        }
391
392
        switch (shift) {
393
        case UP:
394
          my_snake.position[0].y =
395
              ((my_snake.position[0].y + HEIGHT - 1) % HEIGHT);
396
          break;
397
        case DOWN:
398
          my_snake.position[0].y = ((my_snake.position[0].y + 1) % HEIGHT);
399
          break;
400
        case LEFT:
401
          my_snake.position[0].x =
402
              ((my_snake.position[0].x + WIDTH - 1) % WIDTH);
403
          break;
404
        case RIGHT:
405
          my_snake.position[0].x = ((my_snake.position[0].x + 1) % WIDTH);
406
          break;
407
        default:
408
          goto end_of_program;
409
          break;
410
        }
411
412
        uint8_t head_y = my_snake.position[0].y;
413
        uint8_t head_x = my_snake.position[0].x;
414
415
        for (i = 1; i < my_snake.length; i++) {
416
          int16_t x = my_snake.position[i].x;
417
          int16_t y = my_snake.position[i].y;
418
419
          if (x == head_x && y == head_y) {
420
            printf("\n\nHAHA LOST!!!\n\n");
421
            goto end_of_program;
422
          }
423
        }
424
425
        update_field(my_snake, board, fruit);
426
427
        if (head_y == fruit.y && head_x == fruit.x) {
428
          my_snake.length++;
429
          fruit = new_fruit(board);
430
        }
431
432
        update_field(my_snake, board, fruit);
433
        draw_board(board, current_size, false, false);
434
      }
435
    }
436
    nanosleep(&mili100, NULL);
437
  }
438
439
end_of_program:
440
441
  tcsetattr(STDIN_FILENO, TCSANOW, &old);
442
  printf("\033[?25h\n\n");
443
444
  return 0;
445
}
446
447
void update_field(snake my_snake, char board[HEIGHT][WIDTH][STRING_LEN],
448
                  selected fruit) {
449
450
  uint8_t i, j;
451
452
  for (i = 0; i < HEIGHT; i++) {
453
    for (j = 0; j < WIDTH; j++) {
454
      strcpy(board[i][j], "  ");
455
    }
456
  }
457
458
  for (i = 0; i < my_snake.length; i++) {
459
    int16_t x = my_snake.position[i].x;
460
    int16_t y = my_snake.position[i].y;
461
    if (x >= 0 && y >= 0) {
462
      if (!i) {
463
        if (x == (my_snake.position[i + 1].x + 1) % WIDTH) {
464
          strcpy(board[y][x], "\033[33m═\033[31mX\033[0m");
465
        } else {
466
          strcpy(board[y][x], "\033[31m X\033[0m");
467
        }
468
      } else if (i == my_snake.length - 1) {
469
        if (x != my_snake.position[i - 1].x) {
470
          strcpy(board[y][x], "\033[33m══\033[0m");
471
        } else {
472
          strcpy(board[y][x], "\033[33m ║\033[0m");
473
        }
474
      } else {
475
        if (x != my_snake.position[i - 1].x &&
476
            x != my_snake.position[i + 1].x) {
477
          strcpy(board[y][x], "\033[33m══\033[0m");
478
        } else if (y != my_snake.position[i - 1].y &&
479
                   y != my_snake.position[i + 1].y) {
480
          strcpy(board[y][x], "\033[33m ║\033[0m");
481
        } else if ((y == (my_snake.position[i - 1].y + 1) % HEIGHT &&
482
                    x == (my_snake.position[i + 1].x + 1) % WIDTH) ||
483
                   (y == (my_snake.position[i + 1].y + 1) % HEIGHT &&
484
                    x == (my_snake.position[i - 1].x + 1) % WIDTH)) {
485
          strcpy(board[y][x], "\033[33m═╝\033[0m");
486
        } else if ((y == (my_snake.position[i - 1].y + (HEIGHT - 1)) % HEIGHT &&
487
                    x == (my_snake.position[i + 1].x + 1) % WIDTH) ||
488
                   (y == (my_snake.position[i + 1].y + HEIGHT - 1) % HEIGHT &&
489
                    x == (my_snake.position[i - 1].x + 1) % WIDTH)) {
490
          strcpy(board[y][x], "\033[33m═╗\033[0m");
491
        } else if ((y == (my_snake.position[i - 1].y + 1) % HEIGHT &&
492
                    x == (my_snake.position[i + 1].x + (WIDTH - 1)) % WIDTH) ||
493
                   (y == (my_snake.position[i + 1].y + 1) % HEIGHT &&
494
                    x == (my_snake.position[i - 1].x + (WIDTH - 1)) % WIDTH)) {
495
          strcpy(board[y][x], "\033[33m ╚\033[0m");
496
        } else if ((y == (my_snake.position[i - 1].y + (HEIGHT - 1)) % HEIGHT &&
497
                    x == (my_snake.position[i + 1].x + (WIDTH - 1)) % WIDTH) ||
498
                   (y == (my_snake.position[i + 1].y + (HEIGHT - 1)) % HEIGHT &&
499
                    x == (my_snake.position[i - 1].x + (WIDTH - 1)) % WIDTH)) {
500
          strcpy(board[y][x], "\033[33m ╔\033[0m");
501
        }
502
      }
503
    }
504
  }
505
506
  if (fruit.x >= 0 && fruit.y >= 0)
507
    strcpy(board[fruit.y][fruit.x], "\033[32m O\033[0m");
508
}
509
510
selected new_fruit(char board[HEIGHT][WIDTH][STRING_LEN]) {
511
  bool found_space = false;
512
513
  uint8_t x;
514
  uint8_t y;
515
516
  while (!found_space) {
517
    x = rand() % WIDTH;
518
    y = rand() % HEIGHT;
519
520
    if (!strcmp(board[y][x], "  "))
521
      found_space = true;
522
  }
523
524
  selected fruit = {x, y};
525
526
  return fruit;
527
}
528
529
bool draw_menu(main_menu menu, struct winsize window_size) {
530
531
  char *menu_string[] = {"NEW GAME", "SETTINGS", "EXIT"};
532
533
  const uint8_t width_small = 8;
534
  const uint8_t height_small = 5;
535
536
  char *menu_string_big[][6] = {
537
      {"███╗   ██╗███████╗██╗    ██╗     ██████╗  █████╗ ███╗   ███╗███████╗",
538
       "████╗  ██║██╔════╝██║    ██║    ██╔════╝ ██╔══██╗████╗ ████║██╔════╝",
539
       "██╔██╗ ██║█████╗  ██║ █╗ ██║    ██║  ███╗███████║██╔████╔██║█████╗  ",
540
       "██║╚██╗██║██╔══╝  ██║███╗██║    ██║   ██║██╔══██║██║╚██╔╝██║██╔══╝  ",
541
       "██║ ╚████║███████╗╚███╔███╔╝    ╚██████╔╝██║  ██║██║ ╚═╝ ██║███████╗",
542
       "╚═╝  ╚═══╝╚══════╝ ╚══╝╚══╝      ╚═════╝ ╚═╝  ╚═╝╚═╝     ╚═╝╚══════╝"},
543
      {"███████╗███████╗████████╗████████╗██╗███╗   ██╗ ██████╗ ███████╗",
544
       "██╔════╝██╔════╝╚══██╔══╝╚══██╔══╝██║████╗  ██║██╔════╝ ██╔════╝",
545
       "███████╗█████╗     ██║      ██║   ██║██╔██╗ ██║██║  ███╗███████╗",
546
       "╚════██║██╔══╝     ██║      ██║   ██║██║╚██╗██║██║   ██║╚════██║",
547
       "███████║███████╗   ██║      ██║   ██║██║ ╚████║╚██████╔╝███████║",
548
       "╚══════╝╚══════╝   ╚═╝      ╚═╝   ╚═╝╚═╝  ╚═══╝ ╚═════╝ ╚══════╝"},
549
      {"███████╗██╗  ██╗██╗████████╗", "██╔════╝╚██╗██╔╝██║╚══██╔══╝",
550
       "█████╗   ╚███╔╝ ██║   ██║   ", "██╔══╝   ██╔██╗ ██║   ██║   ",
551
       "███████╗██╔╝ ██╗██║   ██║   ", "╚══════╝╚═╝  ╚═╝╚═╝   ╚═╝   "}};
552
553
  const uint8_t height_line = 6;
554
  const uint8_t height_space = 2;
555
556
  const uint8_t width_text[] = {68, 64, 28};
557
558
  const uint8_t width_big = width_text[0] /*strlen(menu_string_big[0][0])*/;
559
  const uint8_t height_big =
560
      height_line * MAIN_MENU + height_space * (MAIN_MENU - 1);
561
562
  printf("\033[2J\033[H");
563
564
  if (window_size.ws_row < height_small || window_size.ws_col < width_small) {
565
    printf("Too small\n");
566
    return true;
567
  }
568
569
  uint8_t i, j, k;
570
571
  if (window_size.ws_row >= height_big && window_size.ws_col >= width_big) {
572
573
    uint8_t vertical_buffer = (window_size.ws_row - height_big) >> 1;
574
575
    for (i = 0; i < vertical_buffer; i++)
576
      printf("\n");
577
578
    for (i = 0; i < MAIN_MENU; i++) {
579
580
      if (i == menu)
581
        printf("\033[32m");
582
583
      uint8_t horizontal_buffer = (window_size.ws_col - width_text[i]) >> 1;
584
585
      for (j = 0; j < height_line; j++) {
586
587
        for (k = 0; k < horizontal_buffer; k++)
588
          printf(" ");
589
590
        printf("%s", menu_string_big[i][j]);
591
592
        if (j != height_line - 1)
593
          printf("\n");
594
      }
595
596
      printf("\033[0m");
597
598
      if (i != MAIN_MENU - 1)
599
        printf("\n\n");
600
    }
601
602
  } else {
603
604
    uint8_t vertical_buffer = (window_size.ws_row - height_small) >> 1;
605
606
    for (i = 0; i < vertical_buffer; i++)
607
      printf("\n");
608
609
    for (i = 0; i < MAIN_MENU; i++) {
610
      if (i == menu)
611
        printf("\033[32m");
612
613
      uint8_t horizontal_buffer =
614
          (window_size.ws_col - strlen(menu_string[i])) >> 1;
615
616
      for (j = 0; j < horizontal_buffer; j++)
617
        printf(" ");
618
619
      printf("%s\033[0m", menu_string[i]);
620
621
      if (i != MAIN_MENU - 1)
622
        printf("\n\n");
623
    }
624
  }
625
626
  fflush(stdout);
627
  return false;
628
}
629
630
bool draw_board(char board[HEIGHT][WIDTH][STRING_LEN],
631
                struct winsize window_size, bool redraw, bool paused) {
632
633
  uint8_t i, j;
634
635
  uint8_t actual_height = HEIGHT + 2;
636
  uint8_t actual_width = WIDTH * 2 + 2;
637
638
  if (actual_width > window_size.ws_col || actual_height > window_size.ws_row) {
639
640
    printf("\033[2J\033[HToo small\n");
641
    printf("Min width: %i & Min height: %i\n", actual_height, actual_width);
642
643
    return true;
644
  }
645
646
  uint8_t vertical_buffer = (window_size.ws_row - actual_height) >> 1;
647
  uint8_t horizontal_buffer = (window_size.ws_col - actual_width) >> 1;
648
649
  if (redraw) {
650
    printf("\033[2J\033[H");
651
    for (i = 0; i < vertical_buffer; i++)
652
      printf("\n");
653
  } else {
654
    for (i = 0; i < actual_height - 1; i++)
655
      printf("\033[%c", UP_CODE);
656
    printf("\r");
657
  }
658
659
  for (i = 0; i < horizontal_buffer; i++)
660
    printf(" ");
661
  printf("+");
662
  for (i = 0; i < WIDTH; i++)
663
    printf("--");
664
  printf("+\n");
665
666
  for (i = 0; i < HEIGHT; i++) {
667
668
    for (j = 0; j < horizontal_buffer; j++)
669
      printf(" ");
670
671
    printf("|");
672
673
    for (j = 0; j < WIDTH; j++)
674
      printf("%s", board[i][j]);
675
676
    printf("|\n");
677
  }
678
679
  for (i = 0; i < horizontal_buffer; i++)
680
    printf(" ");
681
  printf("+");
682
  for (i = 0; i < WIDTH; i++)
683
    printf("--");
684
  printf("+");
685
686
  if (paused)
687
    draw_pause(window_size, actual_width, actual_height);
688
689
  fflush(stdout);
690
691
  return false;
692
}
693
694
void draw_pause(struct winsize window_size, uint8_t field_width,
695
                uint8_t field_height) {
696
697
  const uint8_t height = 5;
698
  const uint8_t width = 14;
699
700
  const char *pause_menu[] = {"+------------+", "|            |",
701
                              "|   PAUSED   |", "|            |",
702
                              "+------------+"};
703
704
  const uint8_t going_up = (field_height + height) >> 1;
705
  const uint8_t going_right = (field_width - width) >> 1;
706
707
  const uint8_t horizontal_buffer = (window_size.ws_col - field_width) >> 1;
708
709
  uint8_t i, j;
710
711
  for (i = 0; i < going_up; i++)
712
    printf("\033[%c", UP_CODE);
713
  printf("\r");
714
715
  for (i = 0; i < height; i++) {
716
    for (j = 0; j < horizontal_buffer; j++)
717
      printf("\033[%c", RIGHT_CODE);
718
    for (j = 0; j < going_right; j++)
719
      printf("\033[%c", RIGHT_CODE);
720
721
    printf("\033[37m%s\033[0m\033[%c\r", pause_menu[i], DOWN_CODE);
722
  }
723
724
  for (i = 0; i < going_up - height; i++)
725
    printf("\033[%c", DOWN_CODE);
726
  printf("\r");
727
728
  fflush(stdout);
729
}
730
731
direction read_direction(char *string, bool wasd_enabled) {
732
733
  if (strlen(string) >= 3) {
734
    if (string[0] == '\033') {
735
      if (string[1] == '[') {
736
737
        switch (string[2]) {
738
        case RIGHT_CODE:
739
          return RIGHT;
740
          break;
741
        case LEFT_CODE:
742
          return LEFT;
743
          break;
744
        case UP_CODE:
745
          return UP;
746
          break;
747
        case DOWN_CODE:
748
          return DOWN;
749
          break;
750
        }
751
      }
752
    }
753
  }
754
755
  if (wasd_enabled) {
756
    switch (toupper(string[0])) {
757
    case 'A':
758
      return LEFT;
759
      break;
760
    case 'D':
761
      return RIGHT;
762
      break;
763
    case 'W':
764
      return UP;
765
      break;
766
    case 'S':
767
      return DOWN;
768
      break;
769
    }
770
  }
771
772
  return NO_DIRECTION;
773
}