jag

snake_c

public

Small snake game in C

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