02 贪吃蛇

前言

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

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

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

然后 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);
}
  

实际效果如下图 

游戏结束效果如下

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/572118.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Power BI数据刷新 - 网关 数据源凭据详解

众所周知&#xff0c;如果在Power BI云服务中设置数据源自动刷新&#xff0c;有两种方式供你选择, 分别是&#xff1a; Gateway and cloud connections&#xff08;网关和云连接&#xff09;&#xff1b;Data Source Credentials&#xff08;数据源凭据&#xff09;&#xff1…

分类算法——模型评估(八)

1混淆矩阵 在分类任务下&#xff0c;预测结果与正确标记之间存在四种不同的组合&#xff0c;构成混淆矩阵&#xff08;适用于多分类&#xff09; TP True Possitive FN False Negative 2精确率&#xff08;Precision&#xff09;与召回率&#xff08;Recall&#xff09; 精…

文献速递:肺癌早期诊断---利用低剂量CT扫描的三维概率深度学习系统用于肺癌的检测与诊

Title 题目 A 3D Probabilistic Deep Learning System forDetection and Diagnosis of Lung Cancer Using Low-Dose CT Scans 利用低剂量CT扫描的三维概率深度学习系统用于肺癌的检测与诊 01文献速递介绍 肺癌既是最常见的癌症之一&#xff0c;也是导致癌症死亡的主要原因之…

IDEA 全局查找 ctrl + shift + F 快捷键失效

全局查找&#xff1a;ctrl shift F 需要关闭微软输入法简体/繁体切换&#xff0c;不然被占用了无效 (装了搜狗输入法的同理,找一下是不是这个快捷键冲突了 ) 另外还有 IDEA 中 重构变量名 &#xff1a;shift F6 需要关闭微软输入法最新版本 ( 使用以前版本的微软输入法就没…

IPv4 NAT(含Cisco配置)

IPv4 NAT&#xff08;含Cisco配置&#xff09; IPv4私有空间地址 类RFC 1918 内部地址范围前缀A10.0.0.0 - 10.255.255.25510.0.0.0/8B172.16.0.0 - 172.31.255.255172.16.0.0/12C192.168.0.0 - 192.168.255.255192.168.0.0/16 这些私有地址可在企业或站点内使用&#xff0c…

【项目】仿muduo库One Thread One Loop式主从Reactor模型实现高并发服务器(TcpServer板块)

【项目】仿muduo库One Thread One Loop式主从Reactor模型实现⾼并发服务器&#xff08;TcpServer板块&#xff09; 一、思路图二、模式关系图三、定时器的设计1、Linux本身给我们的定时器2、我们自己实现的定时器&#xff08;1&#xff09;代码部分&#xff08;2&#xff09;思…

机器学习周记(第三十五周:语义分割)2024.4.15~2024.4.21

目录 摘要 ABSTRACT 1 语义分割基本概念 1.1 数据集格式 ​编辑 1.2 语义分割评价指标 1.3 语义分割标注工具 2 转置卷积 3 FCN网络结构基本原理 摘要 本周主要学习了语义分割的基本概念及其在计算机视觉领域中的应用。了解了语义分割的几种经典网络&#xff0c;如全卷…

绝地求生【商城更新】WIA联名上架//专属商店下架

大家好&#xff0c;我是闲游盒. 本周商城将在4.24&#xff08;周三&#xff09;更新&#xff0c;商城内容更新如下&#xff1a; 上架物品 ▲W.I.A联名皮肤大礼包 小礼包如下&#xff1a; 包含3套衣服以及MINI、DBS的联名皮肤&#xff0c;3个头饰还挺有特色的&#xff0c;你喜欢…

Edge浏览器下载文件提示 “无法安全下载” 的解决方法

提示如下&#xff1a; 虽然我们可以通过 "保留" 进行下载&#xff0c;但是每次需要选择&#xff0c;比较麻烦 解决方法&#xff1a; 1、打开注册表 HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft 2、创建2个 "项" Edge\InsecureContentAllowedForUrls…

目前主流的负载均衡器

客户端负载均衡器 Ribbon 客户端根据自己的请求进行负载均衡Ribbon就属于这一类 Ribbon可以帮助你在调用这些服务时进行负载均衡。具体来说&#xff0c;当你通过Ribbon进行服务调用时&#xff0c;它可以根据配置的负载均衡策略&#xff08;如轮询、随机、最少并发数等&#xff…

机器学习笔记(一)基本概念

一、浅谈机器学习 1.1 机器学习简介 机器学习目的并不是为了得到最后的运算结果&#xff0c;而是对计算过程进行分析&#xff0c;总结出一套运算的规则。只要数据量足够多&#xff0c;运算规则就越准确。最后可以根据这套规则对没有通过验证的数据进行预算&#xff0c;得到预算…

Linux编译和NXP官方系统移植

文章目录 一、Linux安装环境配置二、Linux编译流程三、单个.dtb文件编译方法1.修改顶层makefile2.编译设备树文件3.验证 四、NXP官方Linux系统移植1.将NXP官方Linux系统导入到Ubuntu系统中2.解压系统3.编译系统4.验证5.在NXP官方系统中添加自己的板子 五、 CPU 主频和网络驱动修…

数据赋能(67)——概念:数据变现

数据变现是指通过某种方式将数据转化为实际的收益或绩效。数据变现的方式多种多样&#xff0c;可以根据不同的应用场景和业务需求进行选择和组合。 数据变现的主要方式如下&#xff1a; 数据销售与租赁 组织直接出售原始数据或经过处理、整合后的数据给需要的组织或个人。组织…

视频高效批量剪辑视频,支持批量给视频进行添加新封面,让视频制作效率飙升

在当下这个视频内容爆炸的时代&#xff0c;无论是企业宣传、产品推广还是个人创作&#xff0c;高质量、高效率的视频制作都显得尤为重要。但是&#xff0c;传统的视频剪辑方式往往耗时耗力&#xff0c;效率低下&#xff0c;让人头疼不已。如何快速、高效地制作、编辑和推广&…

ETL工具-nifi干货系列 第十七讲 nifi Input PortOut Port 实战教程

1、端口&#xff08;Port&#xff09;&#xff0c;包含输入端口&#xff08;Input Port&#xff09;和输出端口&#xff08;Out Port &#xff09; 使用一个或多个处理组构建的数据流需要一种方式将处理组连接到其他数据流组件。 处理组和处理组之间可以通过使用端口来进行连…

OpenCV实现霍夫变换

返回:OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a;OpenCV 如何实现边缘检测器 下一篇 :OpenCV 实现霍夫圆变换 目标 在本教程中&#xff0c;您将学习如何&#xff1a; 使用 OpenCV 函数 HoughLines()和 HoughLinesP()检测图像中的线条。…

YASKAWA安川机器人DX100轴板维修故障细节分享

随着科技的日新月异&#xff0c;机器人在工业生产中扮演的角色愈发重要。而作为机器人的“大脑”——电路板&#xff0c;其稳定运作对整个系统的可靠性至关重要。面对可能出现的YASKAWA安川机器人DX100轴板故障&#xff0c;如何快速、准确地诊断问题并予以解决呢&#xff1f;下…

数据结构之常见排序算法

目录 一、排序中的概念 二、常见排序算法--升序 1、插入排序 &#xff08;1&#xff09;直接插入排序 &#xff08;2&#xff09;希尔排序 2、选择排序 &#xff08;1&#xff09;单指针选择排序 &#xff08;2&#xff09;双指针选择排序 &#xff08;3&#xff09;堆…

日志集中审计系列(5)--- LogAuditor接收USG设备日志

日志集中审计系列(5)--- LogAuditor接收USG设备日志 前言拓扑图设备选型组网需求配置思路操作步骤结果验证前言 近期有读者留言:“因华为数通模拟器仅能支持USG6000V的防火墙,无法支持别的安全产品,导致很多网络安全的方案和产品功能无法模拟练习,是否有真机操作的实验或…

文旅强势复苏 苏州金龙新V系客车助力湖北“文旅升级”

2024年4月24日&#xff0c;苏州金龙携多款新V系客车登陆素有九省通衢之称的湖北武汉&#xff0c;在当地文旅行业&#xff0c;刮起一场客运品质升级之风。作为“五一”出行热门城市、自然人文资源丰富的旅游大省&#xff0c;武汉乃至湖北旅游市场堪称客运产品的试金石&#xff0…