snake.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdbool.h>
  4. #include "snake.h"
  5. extern char SNAKE_VIS;
  6. extern boardInfo brdInfo;
  7. extern playableBoardInfo plBrdInfo;
  8. void mvSnakeParts(char board[][brdInfo.x], snakePart* head) {
  9. snakePart* part = head;
  10. while (1) {
  11. order* orderHead = part->order;
  12. if (orderHead->next != NULL) {
  13. if (orderHead->next->delay == 0) {
  14. part->dir = orderHead->next->dir;
  15. removeOrder(orderHead);
  16. }
  17. }
  18. if (orderHead->next != NULL) {
  19. order* current = orderHead->next;
  20. while (1) {
  21. if (current->delay > 0)
  22. current->delay--;
  23. if (current->next == NULL)
  24. break;
  25. current = current->next;
  26. }
  27. }
  28. int x = part->x;
  29. int y = part->y;
  30. board[y][x] = ' ';
  31. switch (part->dir) {
  32. case 'w':
  33. y = y - 1 < plBrdInfo.ys ? plBrdInfo.ye : y - 1;
  34. break;
  35. case 's':
  36. y = y + 1 > plBrdInfo.ye ? plBrdInfo.ys : y + 1;
  37. break;
  38. case 'a':
  39. x = x - 2 < plBrdInfo.xs ? plBrdInfo.xe - 1 : x - 2;
  40. break;
  41. case 'd':
  42. x = x + 2 > plBrdInfo.xe ? plBrdInfo.xs : x + 2;
  43. break;
  44. default:
  45. printf("ERROR in func mvSnakeParts\n");
  46. printf("dir: %c\n", part->dir);
  47. exit(1);
  48. }
  49. part->x = x;
  50. part->y = y;
  51. board[y][x] = part->visChar;
  52. if (part->next == NULL)
  53. return;
  54. part = part->next;
  55. }
  56. }
  57. void addSnakePart(char board[][brdInfo.x], snakePart* head) {
  58. snakePart* tail = head;
  59. while (tail->next != NULL)
  60. tail = tail->next;
  61. snakePart* newTail = (snakePart*) malloc(sizeof(snakePart));
  62. newTail->visChar = SNAKE_VIS;
  63. newTail->dir = tail->dir;
  64. // Order head
  65. newTail->order = (order*) malloc(sizeof(order));
  66. newTail->order->dir = newTail->dir;
  67. newTail->order->delay = -1;
  68. // First order if exists
  69. if (tail->order->next != NULL)
  70. copyOrders(tail->order, newTail->order);
  71. switch (newTail->dir) {
  72. case 'w':
  73. newTail->x = tail->x;
  74. newTail->y = tail->y + 1;
  75. break;
  76. case 's':
  77. newTail->x = tail->x;
  78. newTail->y = tail->y - 1;
  79. break;
  80. case 'a':
  81. newTail->x = tail->x + 2;
  82. newTail->y = tail->y;
  83. break;
  84. case 'd':
  85. newTail->x = tail->x - 2;
  86. newTail->y = tail->y;
  87. break;
  88. default:
  89. printf("Invalid direction in func addSnakePart\n");
  90. exit(1);
  91. }
  92. newTail->next = NULL;
  93. tail->next = newTail;
  94. board[newTail->y][newTail->x] = newTail->visChar;
  95. }
  96. void pushOrder(order* head, char dir, int delay) {
  97. order* current = head;
  98. while (current->next != NULL)
  99. current = current->next;
  100. order* newOrder = (order*) malloc(sizeof(order));
  101. newOrder->dir = dir;
  102. newOrder->delay = delay;
  103. newOrder->next = NULL;
  104. current->next = newOrder;
  105. }
  106. void removeOrder(order* head) {
  107. order* newFirstOrder = head->next->next;
  108. free(head->next);
  109. head->next = newFirstOrder;
  110. }
  111. void addOrders(snakePart* head, char dir) {
  112. snakePart* current = head;
  113. int i = 1;
  114. while (1) {
  115. if (current->next == NULL)
  116. break;
  117. current = current->next;
  118. pushOrder(current->order, dir, i);
  119. i++;
  120. }
  121. }
  122. void copyOrders(order* srcHead, order* destHead) {
  123. if (srcHead->next == NULL) {
  124. printf("ERROR in copyOrders: no orders to copy\n");
  125. exit(1);
  126. }
  127. order* srcCurrent = srcHead;
  128. order* destCurrent = destHead;
  129. order* destPrev = destHead;
  130. while (srcCurrent->next != NULL) {
  131. srcCurrent = srcCurrent->next;
  132. destPrev = destCurrent;
  133. destCurrent = (order*) malloc(sizeof(order));
  134. destPrev->next = destCurrent;
  135. destCurrent->dir = srcCurrent->dir;
  136. destCurrent->delay = srcCurrent->delay + 1;
  137. destCurrent->next = NULL;
  138. }
  139. }
  140. bool checkCollision(snakePart* head, int x, int y) {
  141. snakePart* current = head;
  142. while (1) {
  143. if (current->x == x && current->y == y)
  144. return true;
  145. if (current->next == NULL)
  146. break;
  147. current = current->next;
  148. }
  149. return false;
  150. }