main.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <termios.h>
  4. #include <stdlib.h>
  5. #include <ctype.h>
  6. #include <string.h>
  7. #include <time.h>
  8. #include <stdbool.h>
  9. #include "./utils/utils.h"
  10. #include "./snake/snake.h"
  11. #include "./board/board.h"
  12. #include "globals.h"
  13. static const float VERSION = 1.1f;
  14. const char SNAKE_VIS = '#';
  15. boardInfo brdInfo;
  16. playableBoardInfo plBrdInfo;
  17. void cmd_args(int argc, char** argv);
  18. int main(int argc, char** argv) {
  19. cmd_args(argc, argv);
  20. const clock_t initClock = clock();
  21. // Board Constraints
  22. printf("Set board size (15 - 60): ");
  23. scanf("%d", &brdInfo.y);
  24. if (!(brdInfo.y >= 15 && brdInfo.y <= 60)) {
  25. printf("Invalid input. Board size must be greater than 0.\n");
  26. exit(0);
  27. }
  28. brdInfo.x = brdInfo.y * 2;
  29. printf("brdInfo.x: %d\n", brdInfo.x);
  30. printf("brdInfo.y: %d\n", brdInfo.y);
  31. char board[brdInfo.y][brdInfo.x];
  32. plBrdInfo.xs = 1;
  33. plBrdInfo.xe = brdInfo.x - 2;
  34. plBrdInfo.ys = 1;
  35. plBrdInfo.ye = brdInfo.y - 2;
  36. // Termios setup
  37. struct termios attr;
  38. tcgetattr(STDIN_FILENO, &attr);
  39. const struct termios ATTR_ORIG = attr;
  40. attr.c_lflag &= ~(ECHO | ICANON);
  41. attr.c_cc[VMIN] = 0;
  42. attr.c_cc[VTIME] = 0;
  43. tcsetattr(STDIN_FILENO, 0, &attr);
  44. // Game board setup
  45. setBoardBorders(board);
  46. int points = 0;
  47. int gameSpeed = 0;
  48. const int sleepInterval = 200;
  49. // Snake head setup
  50. snakePart* snakeHead = (snakePart*) malloc(sizeof(snakePart));
  51. snakeHead->x = randomX(initClock);
  52. snakeHead->y = randomY(initClock);
  53. snakeHead->visChar = '&';
  54. snakeHead->dir = 'w';
  55. snakeHead->order = (order*) malloc(sizeof(order));
  56. snakeHead->order->dir = snakeHead->dir;
  57. snakeHead->order->delay = -1;
  58. snakeHead->order->next = NULL;
  59. snakeHead->next = NULL;
  60. board[snakeHead->y][snakeHead->x] = snakeHead->visChar;
  61. // Food setup
  62. struct {
  63. int x;
  64. int y;
  65. char visChar;
  66. } food;
  67. food.x = randomX(initClock);
  68. food.y = randomY(initClock);
  69. food.visChar = '$';
  70. board[food.y][food.x] = food.visChar;
  71. // Screen init
  72. system("clear");
  73. // Game loop
  74. while (1) {
  75. fflush(stdout);
  76. char buf[1] = {0};
  77. // Food collision
  78. if (snakeHead->x == food.x
  79. && snakeHead->y == food.y) {
  80. points++;
  81. if (points % 5 == 0)
  82. gameSpeed += 15;
  83. do {
  84. food.x = randomX(initClock);
  85. food.y = randomY(initClock);
  86. } while (checkCollision(snakeHead, food.x, food.y));
  87. addSnakePart(board, snakeHead);
  88. }
  89. // Input handling
  90. if (read(STDIN_FILENO, buf, 1) != 0 && isalpha(buf[0])) {
  91. char input = buf[0];
  92. input = tolower(input);
  93. if (
  94. (input == 'w' && snakeHead->dir != 's')
  95. || (input == 's' && snakeHead->dir != 'w')
  96. || (input == 'a' && snakeHead->dir != 'd')
  97. || (input == 'd' && snakeHead->dir != 'a')
  98. ) {
  99. snakeHead->dir = input;
  100. addOrders(snakeHead, input);
  101. }
  102. }
  103. // Update board
  104. board[food.y][food.x] = food.visChar;
  105. mvSnakeParts(board, snakeHead);
  106. // Snake collision
  107. if (snakeHead->next != NULL) {
  108. snakePart* current = snakeHead->next;
  109. while (1) {
  110. if (current->x == snakeHead->x
  111. && current->y == snakeHead->y)
  112. goto game_over;
  113. if (current->next == NULL)
  114. break;
  115. current = current->next;
  116. }
  117. }
  118. system("clear");
  119. printBoard(board);
  120. printf("Points: %d\n", points);
  121. printf("Game Speed: %d\n", gameSpeed);
  122. sleep_ms(sleepInterval - gameSpeed);
  123. }
  124. game_over:
  125. // Game over
  126. system("clear");
  127. printBoard(board);
  128. printf("Final Points: %d\n", points);
  129. printf("Final Game Speed: %d\n", gameSpeed);
  130. tcsetattr(STDIN_FILENO, 0, &ATTR_ORIG);
  131. return 0;
  132. }
  133. void cmd_args(int argc, char** argv) {
  134. if (argc == 1) {
  135. return;
  136. }
  137. if (
  138. strcmp(argv[1], "--version") == 0
  139. || strcmp(argv[1], "-v") == 0
  140. )
  141. {
  142. printf("Sanke version %g\n", VERSION);
  143. exit(0);
  144. }
  145. }