前言
呵呵 这是不知道 在哪里看到的 别人做的一个贪吃蛇
因此 也把我 之前的 贪吃蛇 移植上来了
当然 这个不过是为了 简单的入门了解, 呵呵
然后 c++版本的贪吃蛇 需要先移植成 c 版本, 然后 再根据 单片机相关 设计调整
比如 led 点阵的输出, 比如 c99 语法的一些不兼容
主控制程序
整体程序的结构如下, Test02Snake 是主控制程序, utils 是公共的东西
snake 是贪吃蛇的相关实现
Test02Snake.c
#include "utils.h"
#include "snake.h"
/**
* main related
*/
long counter = 1;
u8 gled_end[8] = {0x38,0x7C,0x7E,0x3F,0x3F,0x7E,0x7C,0x38};
void main() {
int i;
u8 xList[8] = {1, 2, 3, 4, 6}, yList[8] = {1, 2, 3, 4, 7};
u8 word[8];
Snake snakeIns;
Snake *snake = &snakeIns;
// snake = snakeInit();
snakeInit(snake);
snake->init(snake);
snake->setMap(snake);
snake->createFood(snake);
ledToggle(6);
while (1) {
// snake->print(snake);
snake->running(snake, counter);
if (snake->isOver(snake))
break;
delay_ms(5);
counter++;
}
while(1) {
lightTubeByInt(snake->grade);
printLedWord(8, gled_end);
}
}
utils.h
#ifndef _utils_H
#define _utils_H
#include "reg52.h"
#include "stdlib.h"
typedef unsigned int u16;
typedef unsigned char u8;
typedef unsigned long u32;
// led dot related
sbit SHIFT_REG_INPUT = P3 ^6;
sbit STORE_REG_INPUT = P3 ^5;
sbit SERIAL_PORT_INPUT = P3 ^4;
#define LEDDZ_COL_PORT P0
// tube related
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
#define SMG_A_DP_PORT P0
// keyboard matrix related
#define KEY_MATRIX_PORT P1
/**
* delay $delayIn10Us us
* @param ten_us
*/
void delay_10us(u16 ten_us);
/**
* delay $delayInMs ms
* @param ms
*/
void delay_ms(u16 ms);
/**
* control led[pos] on/off
* @param pos
* @param on
*/
void ledCtl(u8 pos, u8 on);
/**
* toggle led[pos] on/off
* @param pos
* @param on
*/
void ledToggle(u8 pos);
/**
* random number
* @param seed
* @param max
* @param min
*/
unsigned int randomInt(unsigned int seed, unsigned int max, unsigned int min);
/**
* printLedWord
*
* @param wordLength
* @param word
*/
void printLedWord(int wordLength, u8 *word);
/**
* lightTube
* @param word
*/
void lightTube(u8 *word);
/**
* lightTubeByInt
* @param word
*/
void lightTubeByInt(u16 value);
/**
* lightTubeByIntNTimes
* @param word
*/
void lightTubeByIntSeconds(u16 value, u16 s);
/**
* keyboardMatrixFlipScan
* @return
*/
u8 keyboardMatrixFlipScan(void);
#endif
utils.c
#include "utils.h"
u8 gled_col[8] = {0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe};
u8 gsmg_code[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void hc595_write_data(u8 dat);
void delay_10us(u16 ten_us) {
while (ten_us--);
}
void delay_ms(u16 ms) {
u16 i, j;
for (i = ms; i > 0; i--)
for (j = 110; j > 0; j--);
}
void ledCtl(u8 pos, u8 on) {
if(on == 0) {
P2 |= (1 << pos);
return;
}
P2 &= (~(1 << pos));
}
void ledToggle(u8 pos) {
P2 ^= (1 << pos);
}
unsigned int randomInt(unsigned int seed, unsigned int min, unsigned int max) {
return rand() % (max + 1 - min) + min;
}
void printLedWord(int wordLength, u8 *word) {
u8 i;
for (i = 0; i < wordLength; i++) {
LEDDZ_COL_PORT = gled_col[i];
hc595_write_data(word[i]);
delay_10us(10);
hc595_write_data(0x00);
}
}
void hc595_write_data(u8 dat) {
u8 i = 0;
for (i = 0; i < 8; i++) {
SERIAL_PORT_INPUT = dat >> 7;
dat <<= 1;
SHIFT_REG_INPUT = 0;
delay_10us(1);
SHIFT_REG_INPUT = 1;
delay_10us(1);
}
STORE_REG_INPUT = 1;
delay_10us(1);
STORE_REG_INPUT = 0;
}
void lightTube(u8 *word) {
u8 i=0;
for(i=0;i<8;i++) {
switch(i) {
case 0: LSC=1;LSB=1;LSA=1;break;
case 1: LSC=1;LSB=1;LSA=0;break;
case 2: LSC=1;LSB=0;LSA=1;break;
case 3: LSC=1;LSB=0;LSA=0;break;
case 4: LSC=0;LSB=1;LSA=1;break;
case 5: LSC=0;LSB=1;LSA=0;break;
case 6: LSC=0;LSB=0;LSA=1;break;
case 7: LSC=0;LSB=0;LSA=0;break;
}
SMG_A_DP_PORT = gsmg_code[word[i]];
delay_10us(10);
SMG_A_DP_PORT=0x00;
}
}
void lightTubeByInt(u16 value) {
u16 i;
u8 idx = 7;
u8 word[8];
for(i=0; i<8; i++) {
word[i] = 0;
}
i = value;
while(i > 0) {
word[idx --] = i % 10;
i = i / 10;
}
lightTube(word);
}
void lightTubeByIntSeconds(u16 value, u16 s) {
u16 i, j;
for (i = s * 8; i > 0; i--)
for (j = 110; j > 0; j--)
lightTubeByInt(value);
}
u8 keyboardMatrixFlipScan(void) {
static u8 result = 0;
KEY_MATRIX_PORT=0x0f;
if(KEY_MATRIX_PORT!=0x0f) {
delay_10us(1000);
if(KEY_MATRIX_PORT!=0x0f) {
KEY_MATRIX_PORT=0x0f;
switch(KEY_MATRIX_PORT) {
case 0x07: result=1;break;
case 0x0b: result=2;break;
case 0x0d: result=3;break;
case 0x0e: result=4;break;
}
KEY_MATRIX_PORT=0xf0;
switch(KEY_MATRIX_PORT) {
case 0x70: result=result;break;
case 0xb0: result=result+4;break;
case 0xd0: result=result+8;break;
case 0xe0: result=result+12;break;
}
while(KEY_MATRIX_PORT!=0xf0);
}
}
else
result=0;
return result;
}
贪吃蛇的实现
snake.h
#ifndef _snake_H
#define _snake_H
#include "utils.h"
typedef struct Node {
int x;
int y;
} Node;
typedef struct Snake {
struct Node *head;
struct Node *food;
int flag;
int grade;
int level;
int direction;
void (*setMap)(struct Snake *snake);
int (*isOver)(struct Snake *snake);
void (*go)(struct Snake *snake);
void (*running)(struct Snake *snake, int counter);
void (*isKeyPressed)(struct Snake *snake);
void (*init)(struct Snake *snake);
void (*addNode)(struct Snake *snake, int x, int y);
void (*moveTo)(struct Snake *snake, int direction);
void (*createFood)(struct Snake *snake);
int (*getFood)(struct Snake *snake);
int (*isFoodCover)(struct Snake *snake);
int (*isSuccess)(struct Snake *snake);
void (*print)(struct Snake *snake);
} Snake;
void snakeInit(struct Snake *snake);
#endif
snake.c
如下 就是 贪吃蛇的初始化, 生成食物, 运行, 等等 相关
#include "snake.h"
void position(int, int);
struct Node *nodeInit(int, int y);
void snakeInit(Snake *snake);
void setMap(struct Snake *snake);
int isOver(struct Snake *snake);
void go(struct Snake *snake);
void running(struct Snake *snake, int counter);
void isKeyPressed(struct Snake *snake);
void init(struct Snake *snake);
void addNode(struct Snake *snake, int x, int y);
void moveTo(struct Snake *snake, int direction);
void createFood(struct Snake *snake);
int getFood(struct Snake *snake);
int isFoodCover(struct Snake *snake);
int isSuccess(struct Snake *snake);
void print(struct Snake *snake);
int snakeHeadInitX = 2;
int snakeHeadInitY = 2;
int gameRangeXMax = 8;
int gameRangeYMax = 8;
int snakeNodeXOffset = 1;
int snakeNodeYOffset = 1;
Node nodeList[100];
Node foodNodeIns;
Node *foodNode = &foodNodeIns;
void snakeInit(struct Snake *snake) {
// struct Snake *result = malloc(sizeof(struct Snake));
// snake->head = nodeInit(snakeHeadInitX, snakeHeadInitY);
snake->head = &nodeList[0];
snake->level = 0;
addNode(snake, snakeHeadInitX, snakeHeadInitY);
snake->flag = 0;
snake->direction = 2;
snake->grade = 0;
snake->setMap = setMap;
snake->isOver = isOver;
snake->go = go;
snake->running = running;
snake->isKeyPressed = isKeyPressed;
snake->init = init;
snake->addNode = addNode;
snake->moveTo = moveTo;
snake->createFood = createFood;
snake->getFood = getFood;
snake->isFoodCover = isFoodCover;
snake->isSuccess = isSuccess;
snake->print = print;
}
void setMap(struct Snake *snake) {
}
void init(struct Snake *snake) {
int i;
struct Node *p = snake->head;
for (i = 1; i <= 2; i++) {
addNode(snake, p->x - (i * snakeNodeXOffset), p->y);
}
}
void addNode(struct Snake *snake, int x, int y) {
nodeList[snake->level].x = x;
nodeList[snake->level].y = y;
snake->level ++;
snake->grade = snake->grade + 5 * (snake->level + 1);
}
void moveTo(struct Snake *snake, int direction) {
u8 i;
for(i = snake->level - 1; i > 0; i--) {
nodeList[i].x = nodeList[i-1].x;
nodeList[i].y = nodeList[i-1].y;
}
snake->direction = direction;
if ((snake->direction + 2) % 2 == 1) {
snake->head->y -= snake->direction;
} else {
snake->head->x += (snake->direction / 2);
}
}
int isOver(struct Snake *snake) {
struct Node *head = snake->head;
struct Node *p;
u8 i;
if (head->x >= (gameRangeXMax * snakeNodeXOffset) || head->x < 0
|| head->y >= (gameRangeYMax * snakeNodeYOffset) || head->y < 0)
return 1;
for(i=2; i<snake->level; i++) {
p = &nodeList[i];
if (head->x == p->x && head->y == p->y) return 1;
}
if (snake->level >= 10) return 1;
return 0;
}
void createFood(struct Snake *snake) {
do {
foodNode->x = randomInt(0, 0, (gameRangeXMax-1) * snakeNodeXOffset);
foodNode->y = randomInt(0, 0, (gameRangeYMax-1) * snakeNodeYOffset);
} while (snake->isFoodCover(snake));
}
int getFood(struct Snake *snake) {
struct Node *head = snake->head;
struct Node *p;
if (head->x == foodNode->x && head->y == foodNode->y) {
p = &nodeList[snake->level-1];
addNode(snake, p->x, p->y);
return 1;
}
return 0;
}
int isFoodCover(struct Snake *snake) {
u8 i;
struct Node *p = snake->head;
struct Node *food = foodNode;
for(i=0; i<snake->level; i++) {
p = &nodeList[i];
if (food->x == p->x && food->y == p->y) return 1;
}
return 0;
}
void go(struct Snake *snake) {
struct Node *head = snake->head;
struct Node *p;
snake->moveTo(snake, snake->direction);
snake->print(snake);
}
long snakeTurnNextThreshold = 1;
int snakeMaxRowCount = 50;
int snakeCurrentRowIdx = 1;
void running(struct Snake *snake, int counter) {
struct Node *p;
if (counter % snakeTurnNextThreshold == 0) {
snakeCurrentRowIdx = (snakeCurrentRowIdx + 1) % snakeMaxRowCount;
}
snake->isKeyPressed(snake);
if(snakeCurrentRowIdx > 0) {
snake->print(snake);
return ;
}
snake->print(snake);
snake->go(snake);
if (snake->getFood(snake)) {
snake->createFood(snake);
}
}
void isKeyPressed(struct Snake *snake) {
u8 keyPressed = 0;
keyPressed = keyboardMatrixFlipScan();
// UP
if (keyPressed == 2 && snake->direction != 1) snake->direction = -1;
// LEFT
else if (keyPressed == 5 && snake->direction != 2) snake->direction = -2;
// DOWN
else if (keyPressed == 6 && snake->direction != -1) snake->direction = 1;
// RIGHT
else if (keyPressed == 7 && snake->direction != -2) snake->direction = 2;
if (keyPressed == 16) {
while (1) {
keyPressed = keyboardMatrixFlipScan();
snake->print(snake);
if (keyPressed == 16) break;
}
}
}
int isSuccess(struct Snake *snake) {
if (snake->level >= 10) return 1;
return 0;
}
void print(struct Snake *snake) {
struct Node *p;
u8 word[8];
u8 i;
for(i=0; i<8; i++) {
word[i] = 0;
}
for(i=0; i<snake->level; i++) {
p = &nodeList[i];
word[p->x] |= (1 << p->y);
}
p = foodNode;
word[p->x] |= (1 << p->y);
printLedWord(8, word);
}
实际效果如下图
游戏结束效果如下
完