• 02 贪吃蛇


    前言

    呵呵 这是不知道 在哪里看到的 别人做的一个贪吃蛇 

    因此 也把我 之前的 贪吃蛇 移植上来了 

    当然 这个不过是为了 简单的入门了解, 呵呵 

    然后 c++版本的贪吃蛇 需要先移植成 c 版本, 然后 再根据 单片机相关 设计调整

    比如 led 点阵的输出, 比如 c99 语法的一些不兼容 

    主控制程序

    整体程序的结构如下, Test02Snake 是主控制程序, utils 是公共的东西 

    snake 是贪吃蛇的相关实现 

    Test02Snake.c

    1. #include "utils.h"
    2. #include "snake.h"
    3. /**
    4. * main related
    5. */
    6. long counter = 1;
    7. u8 gled_end[8] = {0x38,0x7C,0x7E,0x3F,0x3F,0x7E,0x7C,0x38};
    8. void main() {
    9. int i;
    10. u8 xList[8] = {1, 2, 3, 4, 6}, yList[8] = {1, 2, 3, 4, 7};
    11. u8 word[8];
    12. Snake snakeIns;
    13. Snake *snake = &snakeIns;
    14. // snake = snakeInit();
    15. snakeInit(snake);
    16. snake->init(snake);
    17. snake->setMap(snake);
    18. snake->createFood(snake);
    19. ledToggle(6);
    20. while (1) {
    21. // snake->print(snake);
    22. snake->running(snake, counter);
    23. if (snake->isOver(snake))
    24. break;
    25. delay_ms(5);
    26. counter++;
    27. }
    28. while(1) {
    29. lightTubeByInt(snake->grade);
    30. printLedWord(8, gled_end);
    31. }
    32. }

    utils.h

    1. #ifndef _utils_H
    2. #define _utils_H
    3. #include "reg52.h"
    4. #include "stdlib.h"
    5. typedef unsigned int u16;
    6. typedef unsigned char u8;
    7. typedef unsigned long u32;
    8. // led dot related
    9. sbit SHIFT_REG_INPUT = P3 ^6;
    10. sbit STORE_REG_INPUT = P3 ^5;
    11. sbit SERIAL_PORT_INPUT = P3 ^4;
    12. #define LEDDZ_COL_PORT P0
    13. // tube related
    14. sbit LSA=P2^2;
    15. sbit LSB=P2^3;
    16. sbit LSC=P2^4;
    17. #define SMG_A_DP_PORT P0
    18. // keyboard matrix related
    19. #define KEY_MATRIX_PORT P1
    20. /**
    21. * delay $delayIn10Us us
    22. * @param ten_us
    23. */
    24. void delay_10us(u16 ten_us);
    25. /**
    26. * delay $delayInMs ms
    27. * @param ms
    28. */
    29. void delay_ms(u16 ms);
    30. /**
    31. * control led[pos] on/off
    32. * @param pos
    33. * @param on
    34. */
    35. void ledCtl(u8 pos, u8 on);
    36. /**
    37. * toggle led[pos] on/off
    38. * @param pos
    39. * @param on
    40. */
    41. void ledToggle(u8 pos);
    42. /**
    43. * random number
    44. * @param seed
    45. * @param max
    46. * @param min
    47. */
    48. unsigned int randomInt(unsigned int seed, unsigned int max, unsigned int min);
    49. /**
    50. * printLedWord
    51. *
    52. * @param wordLength
    53. * @param word
    54. */
    55. void printLedWord(int wordLength, u8 *word);
    56. /**
    57. * lightTube
    58. * @param word
    59. */
    60. void lightTube(u8 *word);
    61. /**
    62. * lightTubeByInt
    63. * @param word
    64. */
    65. void lightTubeByInt(u16 value);
    66. /**
    67. * lightTubeByIntNTimes
    68. * @param word
    69. */
    70. void lightTubeByIntSeconds(u16 value, u16 s);
    71. /**
    72. * keyboardMatrixFlipScan
    73. * @return
    74. */
    75. u8 keyboardMatrixFlipScan(void);
    76. #endif

    utils.c

    1. #include "utils.h"
    2. u8 gled_col[8] = {0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe};
    3. u8 gsmg_code[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
    4. void hc595_write_data(u8 dat);
    5. void delay_10us(u16 ten_us) {
    6. while (ten_us--);
    7. }
    8. void delay_ms(u16 ms) {
    9. u16 i, j;
    10. for (i = ms; i > 0; i--)
    11. for (j = 110; j > 0; j--);
    12. }
    13. void ledCtl(u8 pos, u8 on) {
    14. if(on == 0) {
    15. P2 |= (1 << pos);
    16. return;
    17. }
    18. P2 &= (~(1 << pos));
    19. }
    20. void ledToggle(u8 pos) {
    21. P2 ^= (1 << pos);
    22. }
    23. unsigned int randomInt(unsigned int seed, unsigned int min, unsigned int max) {
    24. return rand() % (max + 1 - min) + min;
    25. }
    26. void printLedWord(int wordLength, u8 *word) {
    27. u8 i;
    28. for (i = 0; i < wordLength; i++) {
    29. LEDDZ_COL_PORT = gled_col[i];
    30. hc595_write_data(word[i]);
    31. delay_10us(10);
    32. hc595_write_data(0x00);
    33. }
    34. }
    35. void hc595_write_data(u8 dat) {
    36. u8 i = 0;
    37. for (i = 0; i < 8; i++) {
    38. SERIAL_PORT_INPUT = dat >> 7;
    39. dat <<= 1;
    40. SHIFT_REG_INPUT = 0;
    41. delay_10us(1);
    42. SHIFT_REG_INPUT = 1;
    43. delay_10us(1);
    44. }
    45. STORE_REG_INPUT = 1;
    46. delay_10us(1);
    47. STORE_REG_INPUT = 0;
    48. }
    49. void lightTube(u8 *word) {
    50. u8 i=0;
    51. for(i=0;i<8;i++) {
    52. switch(i) {
    53. case 0: LSC=1;LSB=1;LSA=1;break;
    54. case 1: LSC=1;LSB=1;LSA=0;break;
    55. case 2: LSC=1;LSB=0;LSA=1;break;
    56. case 3: LSC=1;LSB=0;LSA=0;break;
    57. case 4: LSC=0;LSB=1;LSA=1;break;
    58. case 5: LSC=0;LSB=1;LSA=0;break;
    59. case 6: LSC=0;LSB=0;LSA=1;break;
    60. case 7: LSC=0;LSB=0;LSA=0;break;
    61. }
    62. SMG_A_DP_PORT = gsmg_code[word[i]];
    63. delay_10us(10);
    64. SMG_A_DP_PORT=0x00;
    65. }
    66. }
    67. void lightTubeByInt(u16 value) {
    68. u16 i;
    69. u8 idx = 7;
    70. u8 word[8];
    71. for(i=0; i<8; i++) {
    72. word[i] = 0;
    73. }
    74. i = value;
    75. while(i > 0) {
    76. word[idx --] = i % 10;
    77. i = i / 10;
    78. }
    79. lightTube(word);
    80. }
    81. void lightTubeByIntSeconds(u16 value, u16 s) {
    82. u16 i, j;
    83. for (i = s * 8; i > 0; i--)
    84. for (j = 110; j > 0; j--)
    85. lightTubeByInt(value);
    86. }
    87. u8 keyboardMatrixFlipScan(void) {
    88. static u8 result = 0;
    89. KEY_MATRIX_PORT=0x0f;
    90. if(KEY_MATRIX_PORT!=0x0f) {
    91. delay_10us(1000);
    92. if(KEY_MATRIX_PORT!=0x0f) {
    93. KEY_MATRIX_PORT=0x0f;
    94. switch(KEY_MATRIX_PORT) {
    95. case 0x07: result=1;break;
    96. case 0x0b: result=2;break;
    97. case 0x0d: result=3;break;
    98. case 0x0e: result=4;break;
    99. }
    100. KEY_MATRIX_PORT=0xf0;
    101. switch(KEY_MATRIX_PORT) {
    102. case 0x70: result=result;break;
    103. case 0xb0: result=result+4;break;
    104. case 0xd0: result=result+8;break;
    105. case 0xe0: result=result+12;break;
    106. }
    107. while(KEY_MATRIX_PORT!=0xf0);
    108. }
    109. }
    110. else
    111. result=0;
    112. return result;
    113. }

    贪吃蛇的实现

    snake.h 

    1. #ifndef _snake_H
    2. #define _snake_H
    3. #include "utils.h"
    4. typedef struct Node {
    5. int x;
    6. int y;
    7. } Node;
    8. typedef struct Snake {
    9. struct Node *head;
    10. struct Node *food;
    11. int flag;
    12. int grade;
    13. int level;
    14. int direction;
    15. void (*setMap)(struct Snake *snake);
    16. int (*isOver)(struct Snake *snake);
    17. void (*go)(struct Snake *snake);
    18. void (*running)(struct Snake *snake, int counter);
    19. void (*isKeyPressed)(struct Snake *snake);
    20. void (*init)(struct Snake *snake);
    21. void (*addNode)(struct Snake *snake, int x, int y);
    22. void (*moveTo)(struct Snake *snake, int direction);
    23. void (*createFood)(struct Snake *snake);
    24. int (*getFood)(struct Snake *snake);
    25. int (*isFoodCover)(struct Snake *snake);
    26. int (*isSuccess)(struct Snake *snake);
    27. void (*print)(struct Snake *snake);
    28. } Snake;
    29. void snakeInit(struct Snake *snake);
    30. #endif

    snake.c 

    如下 就是 贪吃蛇的初始化, 生成食物, 运行, 等等 相关 

    1. #include "snake.h"
    2. void position(int, int);
    3. struct Node *nodeInit(int, int y);
    4. void snakeInit(Snake *snake);
    5. void setMap(struct Snake *snake);
    6. int isOver(struct Snake *snake);
    7. void go(struct Snake *snake);
    8. void running(struct Snake *snake, int counter);
    9. void isKeyPressed(struct Snake *snake);
    10. void init(struct Snake *snake);
    11. void addNode(struct Snake *snake, int x, int y);
    12. void moveTo(struct Snake *snake, int direction);
    13. void createFood(struct Snake *snake);
    14. int getFood(struct Snake *snake);
    15. int isFoodCover(struct Snake *snake);
    16. int isSuccess(struct Snake *snake);
    17. void print(struct Snake *snake);
    18. int snakeHeadInitX = 2;
    19. int snakeHeadInitY = 2;
    20. int gameRangeXMax = 8;
    21. int gameRangeYMax = 8;
    22. int snakeNodeXOffset = 1;
    23. int snakeNodeYOffset = 1;
    24. Node nodeList[100];
    25. Node foodNodeIns;
    26. Node *foodNode = &foodNodeIns;
    27. void snakeInit(struct Snake *snake) {
    28. // struct Snake *result = malloc(sizeof(struct Snake));
    29. // snake->head = nodeInit(snakeHeadInitX, snakeHeadInitY);
    30. snake->head = &nodeList[0];
    31. snake->level = 0;
    32. addNode(snake, snakeHeadInitX, snakeHeadInitY);
    33. snake->flag = 0;
    34. snake->direction = 2;
    35. snake->grade = 0;
    36. snake->setMap = setMap;
    37. snake->isOver = isOver;
    38. snake->go = go;
    39. snake->running = running;
    40. snake->isKeyPressed = isKeyPressed;
    41. snake->init = init;
    42. snake->addNode = addNode;
    43. snake->moveTo = moveTo;
    44. snake->createFood = createFood;
    45. snake->getFood = getFood;
    46. snake->isFoodCover = isFoodCover;
    47. snake->isSuccess = isSuccess;
    48. snake->print = print;
    49. }
    50. void setMap(struct Snake *snake) {
    51. }
    52. void init(struct Snake *snake) {
    53. int i;
    54. struct Node *p = snake->head;
    55. for (i = 1; i <= 2; i++) {
    56. addNode(snake, p->x - (i * snakeNodeXOffset), p->y);
    57. }
    58. }
    59. void addNode(struct Snake *snake, int x, int y) {
    60. nodeList[snake->level].x = x;
    61. nodeList[snake->level].y = y;
    62. snake->level ++;
    63. snake->grade = snake->grade + 5 * (snake->level + 1);
    64. }
    65. void moveTo(struct Snake *snake, int direction) {
    66. u8 i;
    67. for(i = snake->level - 1; i > 0; i--) {
    68. nodeList[i].x = nodeList[i-1].x;
    69. nodeList[i].y = nodeList[i-1].y;
    70. }
    71. snake->direction = direction;
    72. if ((snake->direction + 2) % 2 == 1) {
    73. snake->head->y -= snake->direction;
    74. } else {
    75. snake->head->x += (snake->direction / 2);
    76. }
    77. }
    78. int isOver(struct Snake *snake) {
    79. struct Node *head = snake->head;
    80. struct Node *p;
    81. u8 i;
    82. if (head->x >= (gameRangeXMax * snakeNodeXOffset) || head->x < 0
    83. || head->y >= (gameRangeYMax * snakeNodeYOffset) || head->y < 0)
    84. return 1;
    85. for(i=2; i<snake->level; i++) {
    86. p = &nodeList[i];
    87. if (head->x == p->x && head->y == p->y) return 1;
    88. }
    89. if (snake->level >= 10) return 1;
    90. return 0;
    91. }
    92. void createFood(struct Snake *snake) {
    93. do {
    94. foodNode->x = randomInt(0, 0, (gameRangeXMax-1) * snakeNodeXOffset);
    95. foodNode->y = randomInt(0, 0, (gameRangeYMax-1) * snakeNodeYOffset);
    96. } while (snake->isFoodCover(snake));
    97. }
    98. int getFood(struct Snake *snake) {
    99. struct Node *head = snake->head;
    100. struct Node *p;
    101. if (head->x == foodNode->x && head->y == foodNode->y) {
    102. p = &nodeList[snake->level-1];
    103. addNode(snake, p->x, p->y);
    104. return 1;
    105. }
    106. return 0;
    107. }
    108. int isFoodCover(struct Snake *snake) {
    109. u8 i;
    110. struct Node *p = snake->head;
    111. struct Node *food = foodNode;
    112. for(i=0; i<snake->level; i++) {
    113. p = &nodeList[i];
    114. if (food->x == p->x && food->y == p->y) return 1;
    115. }
    116. return 0;
    117. }
    118. void go(struct Snake *snake) {
    119. struct Node *head = snake->head;
    120. struct Node *p;
    121. snake->moveTo(snake, snake->direction);
    122. snake->print(snake);
    123. }
    124. long snakeTurnNextThreshold = 1;
    125. int snakeMaxRowCount = 50;
    126. int snakeCurrentRowIdx = 1;
    127. void running(struct Snake *snake, int counter) {
    128. struct Node *p;
    129. if (counter % snakeTurnNextThreshold == 0) {
    130. snakeCurrentRowIdx = (snakeCurrentRowIdx + 1) % snakeMaxRowCount;
    131. }
    132. snake->isKeyPressed(snake);
    133. if(snakeCurrentRowIdx > 0) {
    134. snake->print(snake);
    135. return ;
    136. }
    137. snake->print(snake);
    138. snake->go(snake);
    139. if (snake->getFood(snake)) {
    140. snake->createFood(snake);
    141. }
    142. }
    143. void isKeyPressed(struct Snake *snake) {
    144. u8 keyPressed = 0;
    145. keyPressed = keyboardMatrixFlipScan();
    146. // UP
    147. if (keyPressed == 2 && snake->direction != 1) snake->direction = -1;
    148. // LEFT
    149. else if (keyPressed == 5 && snake->direction != 2) snake->direction = -2;
    150. // DOWN
    151. else if (keyPressed == 6 && snake->direction != -1) snake->direction = 1;
    152. // RIGHT
    153. else if (keyPressed == 7 && snake->direction != -2) snake->direction = 2;
    154. if (keyPressed == 16) {
    155. while (1) {
    156. keyPressed = keyboardMatrixFlipScan();
    157. snake->print(snake);
    158. if (keyPressed == 16) break;
    159. }
    160. }
    161. }
    162. int isSuccess(struct Snake *snake) {
    163. if (snake->level >= 10) return 1;
    164. return 0;
    165. }
    166. void print(struct Snake *snake) {
    167. struct Node *p;
    168. u8 word[8];
    169. u8 i;
    170. for(i=0; i<8; i++) {
    171. word[i] = 0;
    172. }
    173. for(i=0; i<snake->level; i++) {
    174. p = &nodeList[i];
    175. word[p->x] |= (1 << p->y);
    176. }
    177. p = foodNode;
    178. word[p->x] |= (1 << p->y);
    179. printLedWord(8, word);
    180. }

    实际效果如下图 

    游戏结束效果如下

  • 相关阅读:
    Java Spring Redis实现过期键监听回调
    SpringBoot整合WebService(服务端+客户端)
    程序员开发必备,开发资源资料分享【4】
    DevOps(九)Selenium 介绍和Jenkins集成
    大数据学习之Spark基础
    Java数据审计工具:Envers and JaVers比较
    NetCore使用Dapper查询数据
    MySQL explain SQL分析工具详解与最佳实践
    【计算机网络笔记】网络层服务模型——虚电路网络
    FF14 XIVLauncher 启动器与 Dalamud 卫月框架使用教程
  • 原文地址:https://blog.csdn.net/u011039332/article/details/130784012