Advertisement
Guest User

Untitled

a guest
Jan 22nd, 2020
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.75 KB | None | 0 0
  1. /* ID: 208957837 Name: Alon Doron */
  2.  
  3. #include <stdio.h>
  4. #include <conio.h>
  5. #include <stdlib.h>
  6. #include <stdbool.h>
  7. #include <time.h>
  8.  
  9. #pragma region Structs
  10.  
  11. typedef struct _Cell {
  12.     int x;
  13.     int y;
  14.     struct _Cell *next;
  15. } Snake_Cell;
  16.  
  17. typedef struct _List {
  18.     Snake_Cell *head;
  19.     Snake_Cell *tail;
  20.     int count;
  21. } Snake;
  22.  
  23. #pragma endregion
  24.  
  25. #pragma region Consts
  26.  
  27. #define ROWS 25
  28. #define COLS 75
  29.  
  30. #define BORDER_SIGN '#'
  31. #define SNAKE_SIGN '@'
  32.  
  33. #define SLEEP_TIMER 1
  34. #define CREATE_NEW_CELL_TIMER 0.5
  35.  
  36. #pragma endregion
  37.  
  38. #pragma region Declarations
  39.  
  40. // This function clears the screen.
  41. void clearScreen(void);
  42.  
  43. // This function starts the game.
  44. void playGame(void);
  45.  
  46. // Moves the cursor to position (x,y) on screen.
  47. // Parameters:
  48. //     x: the row of the posiiton.
  49. //     y: the column of the posiiton.
  50. void gotoxy(int x, int y);
  51.  
  52. // Delays the execution of the program.
  53. // Parameters:
  54. //     secs: the length of the delay in seconds.
  55. void sleep(float secs);
  56.  
  57. //This function goes to desired row and col, and prints a char.
  58. void gotoxyAndPrint(int row, int col, char sign);
  59.  
  60. // This function prints the board's first state.
  61. void initBoard();
  62.  
  63. //This function prints the board boundries.
  64. void printBoardBorders(void);
  65.  
  66. // This function prints a full horizontal line of '#' at a given row.
  67. void printHorizontalBorder(int row);
  68.  
  69. // This function prints a full vertical line of '#' at a given col.
  70. void printVerticalBorder(int col);
  71.  
  72. //This function inits a snake object in a desired position and returns it.
  73. Snake* initSnakeObject(int x, int y);
  74.  
  75. //This function creates a new cell.
  76. Snake_Cell* createNewSnakeCell(int x, int y);
  77.  
  78. //This function inserts a cell into the snake.
  79. void insertCellToSnake(Snake* snake, Snake_Cell* newCellToAdd);
  80.  
  81. // This function removes the tail from the snake.
  82. void removeTailFromSnake(Snake* snake);
  83.  
  84. // This function checks if the snake's head collided with a border.
  85. bool isSnakeCollisionedWithBorder(Snake* snake);
  86.  
  87. // This function checks if the snake collisoned with himself.
  88. bool isSnakeCollisionedWithItself(Snake* snake, Snake_Cell* futureCell);
  89.  
  90. // This function prints the whole snake!
  91. void printSnake(Snake* snake);
  92.  
  93. //This function gets the time since the snake's newest cell was created.
  94. double getTimeSinceLastCreatedCell(clock_t currentClock);
  95.  
  96. // This function prints that the user has lost the game.
  97. void printGameOver(void);
  98.  
  99. //This function gets a row and col and returns the updated data depending on the user's direction input.
  100. void updateRowAndCol(int* row, int* col, char keyPressed);
  101.  
  102. #pragma endregion
  103.  
  104. #pragma region Main
  105.  
  106. int main()
  107. {
  108.     initBoard();
  109.     playGame();
  110.  
  111.     return 0;
  112. }
  113.  
  114. #pragma endregion
  115.  
  116. #pragma region Implementations
  117.  
  118. void clearScreen(void) {
  119.     system("cls");
  120. }
  121.  
  122. void initBoard() {
  123.     clearScreen();
  124.     printBoardBorders();
  125. }
  126.  
  127. void playGame(void) {
  128.     char c = 'd', prevC = 'd';
  129.     int row = ROWS / 2, col = COLS / 2;
  130.     clock_t secondsTimer;
  131.     double timeSpent;
  132.  
  133.     secondsTimer = clock();
  134.  
  135.     Snake* snake = initSnakeObject(row, col);
  136.  
  137.     Snake_Cell* NewSnakeCellToAdd;
  138.  
  139.     while (!isSnakeCollisionedWithBorder(snake)) {
  140.         printSnake(snake);
  141.         sleep(SLEEP_TIMER);
  142.  
  143.         if (_kbhit())
  144.             c = _getch();
  145.  
  146.         if (c != 'd' && c != 'a' && c != 'w' && c != 's')
  147.             c = prevC;
  148.  
  149.         updateRowAndCol(&row, &col, c);
  150.  
  151.         prevC = c;
  152.  
  153.         NewSnakeCellToAdd = createNewSnakeCell(row, col);
  154.  
  155.         if (isSnakeCollisionedWithItself(snake, NewSnakeCellToAdd)) {
  156.             break;
  157.         }
  158.  
  159.         insertCellToSnake(snake, NewSnakeCellToAdd);
  160.  
  161.         if (snake->count > 1) {
  162.             removeTailFromSnake(snake);
  163.         }
  164.  
  165.  
  166.         timeSpent = getTimeSinceLastCreatedCell(secondsTimer);
  167.  
  168.         if (timeSpent >= CREATE_NEW_CELL_TIMER) {
  169.             updateRowAndCol(&row, &col, c);
  170.             NewSnakeCellToAdd = createNewSnakeCell(row, col);
  171.             insertCellToSnake(snake, NewSnakeCellToAdd);
  172.             timeSpent = 0.0;
  173.             secondsTimer = clock();
  174.         }
  175.     }
  176.  
  177.     printGameOver();
  178. }
  179.  
  180. void gotoxy(int x, int y) {
  181.     printf("\x1b[%d;%df", x, y);
  182. }
  183.  
  184. void sleep(float secs) {
  185.     clock_t clocks_start = clock();
  186.  
  187.     while (clock() - clocks_start < secs*CLOCKS_PER_SEC);
  188. }
  189.  
  190. void gotoxyAndPrint(int row, int col, char sign) {
  191.     gotoxy(row, col);
  192.     printf("%c", sign);
  193. }
  194.  
  195. void printBoardBorders(void) {
  196.     printHorizontalBorder(0);
  197.     printVerticalBorder(0);
  198.     printHorizontalBorder(ROWS);
  199.     printVerticalBorder(COLS);
  200. }
  201.  
  202. void printHorizontalBorder(int row) {
  203.     int i;
  204.  
  205.     for (i = 0; i < COLS; i++) {
  206.         gotoxyAndPrint(row, i, BORDER_SIGN);
  207.     }
  208. }
  209.  
  210. void printVerticalBorder(int col) {
  211.     int i;
  212.  
  213.     for (i = 0; i < ROWS; i++) {
  214.         gotoxyAndPrint(i, col, BORDER_SIGN);
  215.     }
  216. }
  217.  
  218. Snake* initSnakeObject(int x, int y)
  219. {
  220.     Snake_Cell* snakeHead = createNewSnakeCell(x, y);
  221.  
  222.     Snake* snake = (Snake*)malloc(sizeof(Snake));
  223.  
  224.     snake->head = snakeHead;
  225.     snake->tail = snakeHead;
  226.     snake->count = 1;
  227.  
  228.     return snake;
  229. }
  230.  
  231. Snake_Cell* createNewSnakeCell(int x, int y)
  232. {
  233.     Snake_Cell* newCell = (Snake_Cell*)malloc(sizeof(Snake_Cell));
  234.  
  235.     newCell->x = x;
  236.     newCell->y = y;
  237.     newCell->next = NULL;
  238.  
  239.     return newCell;
  240. }
  241.  
  242. void insertCellToSnake(Snake * snake, Snake_Cell * newCellToAdd) {
  243.     Snake_Cell* currentHead = snake->head;
  244.     snake->head = newCellToAdd;
  245.     newCellToAdd->next = currentHead;
  246.     snake->count++;
  247. }
  248.  
  249. void removeTailFromSnake(Snake * snake) {
  250.     Snake_Cell* currentCell = snake->head;
  251.     Snake_Cell* snakeTail = snake->tail;
  252.  
  253.     while (currentCell->next != snake->tail)
  254.         currentCell = currentCell->next;
  255.  
  256.     gotoxyAndPrint(snakeTail->x, snakeTail->y, ' ');
  257.     free(snakeTail);
  258.     currentCell->next = NULL;
  259.     snake->tail = currentCell;
  260.     snake->count--;
  261. }
  262.  
  263. bool isSnakeCollisionedWithBorder(Snake * snake) {
  264.     if (snake->head->x == ROWS || snake->head->x == 1 ||
  265.         snake->head->y == COLS || snake->head->y == 1)
  266.         return true;
  267.  
  268.     return false;
  269. }
  270.  
  271. bool isSnakeCollisionedWithItself(Snake * snake, Snake_Cell* futureCell) {
  272.     Snake_Cell* currentCell = snake->head;
  273.  
  274.     while (currentCell != NULL) {
  275.         if (futureCell->x == currentCell->x && futureCell->y == currentCell->y)
  276.             return true;
  277.  
  278.         currentCell = currentCell->next;
  279.     }
  280.  
  281.     return false;
  282. }
  283.  
  284. void printSnake(Snake* snake) {
  285.     Snake_Cell* head = snake->head;
  286.  
  287.     while (head != NULL) {
  288.         gotoxyAndPrint(head->x, head->y, SNAKE_SIGN);
  289.  
  290.         head = head->next;
  291.     }
  292. }
  293.  
  294. double getTimeSinceLastCreatedCell(clock_t curretTimer) {
  295.     return (double)(clock() - curretTimer) / CLOCKS_PER_SEC;
  296. }
  297.  
  298. void printGameOver(void) {
  299.     clearScreen();
  300.     printBoardBorders();
  301.     gotoxy(ROWS / 2, COLS / 2 - 3);
  302.     printf("GAME OVER!");
  303.     gotoxy(ROWS + 1, 0);
  304. }
  305.  
  306. void updateRowAndCol(int * row, int * col, char keyPressed) {
  307.     switch (keyPressed)
  308.     {
  309.     case 'd':
  310.         *col += 1;
  311.         break;
  312.     case 'a':
  313.         *col -= 1;
  314.         break;
  315.     case 'w':
  316.         *row -= 1;
  317.         break;
  318.     case 's':
  319.         *row += 1;
  320.         break;
  321.     }
  322. }
  323.  
  324. #pragma endregion
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement