Simple single-color 8x8x8 LED Cube with AVRs
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

snake.c 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. #define UP 1
  2. #define DOWN 2
  3. #define LEFT 3
  4. #define RIGHT 4
  5. #define IN 5
  6. #define OUT 6
  7. void snake(void);
  8. void setPixel(uint8_t x, uint8_t y, uint8_t z, uint8_t *buf);
  9. void clearPixel(uint8_t x, uint8_t y, uint8_t z, uint8_t *buf);
  10. uint8_t pixelSet(uint8_t x, uint8_t y, uint8_t z, uint8_t *buf);
  11. void newCoin(uint8_t *x, uint8_t *y, uint8_t *z, uint8_t *buf);
  12. void move(uint8_t *x, uint8_t *y, uint8_t *z, uint8_t dir);
  13. void setPixel(uint8_t x, uint8_t y, uint8_t z, uint8_t *buf) {
  14. buf[(8 * z) + y] |= (1 << x);
  15. }
  16. void clearPixel(uint8_t x, uint8_t y, uint8_t z, uint8_t *buf) {
  17. buf[(8 * z) + y] &= ~(1 << x);
  18. }
  19. uint8_t pixelSet(uint8_t x, uint8_t y, uint8_t z, uint8_t *buf) {
  20. return buf[(8 * z) + y] &= (1 << x);
  21. }
  22. void displayBuffs(uint8_t *a, uint8_t *b) {
  23. uint8_t *buf = (uint8_t *)malloc(64);
  24. uint8_t i;
  25. for (i = 0; i < 64; i++) {
  26. buf[i] = a[i] | b[i];
  27. }
  28. setImage(buf);
  29. free(buf);
  30. }
  31. void newCoin(uint8_t *x, uint8_t *y, uint8_t *z, uint8_t *buf) {
  32. uint8_t tempX, tempY, tempZ;
  33. while (1) {
  34. tempX = (uint8_t)(((rand() / 256) / 32) - 1); // Num from 0 to 7
  35. tempY = (uint8_t)(((rand() / 256) / 32) - 1);
  36. tempZ = (uint8_t)(((rand() / 256) / 32) - 1);
  37. if (!pixelSet(tempX, tempY, tempZ, buf)) {
  38. break;
  39. }
  40. }
  41. *x = tempX;
  42. *y = tempY;
  43. *z = tempZ;
  44. }
  45. void move(uint8_t *x, uint8_t *y, uint8_t *z, uint8_t dir) {
  46. switch (dir) {
  47. case UP:
  48. *y = (*y + 1);
  49. break;
  50. case DOWN:
  51. *y = (*y - 1);
  52. break;
  53. case LEFT:
  54. *x = (*x - 1);
  55. break;
  56. case RIGHT:
  57. *x = (*x + 1);
  58. break;
  59. case IN:
  60. *z = (*z - 1);
  61. break;
  62. case OUT:
  63. *z = (*z + 1);
  64. break;
  65. default:
  66. break;
  67. }
  68. while (*x > 7) {
  69. *x -= 8;
  70. }
  71. while (*y > 7) {
  72. *y -= 8;
  73. }
  74. while (*z > 8) {
  75. *z -= 8;
  76. }
  77. }
  78. uint8_t isSet(uint8_t x, uint8_t y, uint8_t z, uint8_t *buf, uint8_t dir) {
  79. move(&x, &y, &z, dir);
  80. return pixelSet(x, y, z, buf);
  81. }
  82. uint8_t inverse(uint8_t dir) {
  83. if ((dir > 0) && (dir < 7)) {
  84. if ((dir % 2) == 0) {
  85. // even dir
  86. return (dir - 1);
  87. } else {
  88. // odd dir
  89. return (dir + 1);
  90. }
  91. } else {
  92. return 0;
  93. }
  94. }
  95. void clearTail(uint8_t x, uint8_t y, uint8_t z, uint8_t *buf, uint8_t wrongDir) {
  96. // dirs from 1 to 6
  97. uint8_t i;
  98. for (i = 1; i <= 6; i++) {
  99. if (i != wrongDir) {
  100. if (isSet(x, y, z, buf, i)) {
  101. move(&x, &y, &z, i);
  102. clearTail(x, y, z, buf, inverse(i));
  103. return;
  104. }
  105. }
  106. }
  107. // If we reached this point, we are in the last call and clear the pixel
  108. clearPixel(x, y, z, buf);
  109. }
  110. void snake() {
  111. uint8_t *snake = (uint8_t *)malloc(64); // Snake
  112. uint8_t i, xPos = 3, yPos = 3, zPos = 3, dir = UP, length = 1;
  113. uint8_t xCoin = 1, yCoin = 1, zCoin = 1;
  114. char c;
  115. for (i = 0; i < 64; i++) {
  116. snake[i] = 0;
  117. }
  118. setPixel(3, 3, 3, snake);
  119. serialWriteString("Controls: W A S D Q E, x to quit\n");
  120. while(1) {
  121. if (serialHasChar()) {
  122. c = serialGet();
  123. switch (c) {
  124. case 'x':
  125. free(snake);
  126. return;
  127. case 'w':
  128. dir = UP;
  129. break;
  130. case 'a':
  131. dir = LEFT;
  132. break;
  133. case 's':
  134. dir = DOWN;
  135. break;
  136. case 'd':
  137. dir = RIGHT;
  138. break;
  139. case 'q':
  140. dir = IN;
  141. break;
  142. case 'e':
  143. dir = OUT;
  144. break;
  145. default:
  146. break;
  147. }
  148. }
  149. if (isFinished() > 6) {
  150. // Perform next game step and display it
  151. move(&xPos, &yPos, &zPos, dir); // move snake head coords
  152. setPixel(xPos, yPos, zPos, snake); // Add snake head pixel
  153. if ((xPos == xCoin) && (yPos == yCoin) && (zCoin == zPos)) {
  154. newCoin(&xCoin, &yCoin, &zCoin, snake); // Set new coin
  155. if (length < 255) { // change length
  156. length++;
  157. } else {
  158. // You won :)
  159. free(snake);
  160. return;
  161. }
  162. } else {
  163. // Delete last snake pixel to match length
  164. clearTail(xPos, yPos, zPos, snake, 0);
  165. }
  166. setPixel(xCoin, yCoin, zCoin, snake);
  167. setImage(snake); // Display snake and coin
  168. clearPixel(xCoin, yCoin, zCoin, snake);
  169. }
  170. }
  171. free(snake);
  172. }