main.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #include <ctype.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <termios.h>
  5. #include <time.h>
  6. #include <unistd.h>
  7. #include "Board.h"
  8. #include "BoardPiece.h"
  9. #include "Snake.h"
  10. #include "args.h"
  11. #include "food.h"
  12. #include "utils.h"
  13. #define TERMIOS 1
  14. #define MIN_SLEEP_TIME_MS 60
  15. const char snake_vis = '#';
  16. struct termios set_termios();
  17. int main(int argc, char** argv) {
  18. Arguments args = cmd_args(argc, argv);
  19. srand(time(NULL));
  20. // Termios setup
  21. #if TERMIOS
  22. const struct termios attr_orig = set_termios();
  23. #endif // TERMIOS
  24. // Game model init
  25. const int board_w = args.width;
  26. const int board_h = args.height;
  27. Board board = board_alloc(board_w, board_h);
  28. Snake snake = snake_alloc(board_w * board_h, 0, 0, 'd');
  29. BoardPiece food = { .vis_char = '$' };
  30. food_new_location(&board, &food, &snake);
  31. unsigned int score = 0;
  32. unsigned int sleep_time = args.sleep_ms;
  33. // Screen init
  34. system("clear");
  35. #ifdef DEBUG
  36. unsigned long long frame = 0;
  37. #endif // DEBUG
  38. while (true) {
  39. system("clear");
  40. // Process input
  41. char input = '0';
  42. read(STDIN_FILENO, &input, 1);
  43. if (isalpha(input)) {
  44. if (
  45. (input == 'w' && snake.dir != 's')
  46. || (input == 'a' && snake.dir != 'd')
  47. || (input == 's' && snake.dir != 'w')
  48. || (input == 'd' && snake.dir != 'a')) {
  49. snake_change_direction(&snake, input);
  50. }
  51. }
  52. snake_move(&snake, board.width, board.height);
  53. board_clear(&board);
  54. board_draw_snake(&board, &snake);
  55. board_set_square(&board, food.x, food.y, food.vis_char);
  56. print_board(&board);
  57. printf("Score: %d\n", score);
  58. BoardPiece snake_head = snake_get_part(&snake, 0);
  59. if (snake_collides_with_tail(&snake)) {
  60. printf("GAME OVER\n");
  61. break;
  62. }
  63. if (pieces_collide(&snake_head, &food)) {
  64. score++;
  65. snake_add_part(&snake);
  66. food_new_location(&board, &food, &snake);
  67. const unsigned int new_sleep_time = sleep_time - 5;
  68. if (new_sleep_time >= MIN_SLEEP_TIME_MS) {
  69. sleep_time = new_sleep_time;
  70. }
  71. }
  72. #ifdef DEBUG
  73. printf("input: %c\n", input);
  74. printf("Frame: %lld\n", frame);
  75. printf("sleep_ms: %u\n", sleep_time);
  76. snake_print_info(&snake);
  77. board_piece_print_info(&food, "Food");
  78. frame++;
  79. #endif // DEBUG
  80. sleep_ms(sleep_time);
  81. }
  82. #if TERMIOS
  83. tcsetattr(STDIN_FILENO, 0, &attr_orig);
  84. #endif // TERMIOS
  85. board_free(&board);
  86. snake_free(&snake);
  87. return 0;
  88. }
  89. struct termios set_termios() {
  90. struct termios attr;
  91. tcgetattr(STDIN_FILENO, &attr);
  92. const struct termios attr_orig = attr;
  93. attr.c_lflag &= ~(ECHO | ICANON);
  94. attr.c_cc[VMIN] = 0;
  95. attr.c_cc[VTIME] = 0;
  96. tcsetattr(STDIN_FILENO, 0, &attr);
  97. return attr_orig;
  98. }