热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

go语言(使用了cgo与硬件交互),算上空行和注释共200行代码

go语言(使用了cgo与硬件交互),算上空行和注释共200行代码实现了贪吃蛇的基本功能,好吧你不能指望我还加上声音啥的,我不会啊很多时间花在”图形”界面上了,其实时间还可以缩短的p

go语言(使用了cgo与硬件交互),算上空行和注释共200行代码
实现了贪吃蛇的基本功能,好吧你不能指望我还加上声音啥的,我不会啊
很多时间花在”图形”界面上了,其实时间还可以缩短的

package main
import (
"fmt"
"math/rand"
"os"
"time"
)
/*
#include
#include
// 使用了WinAPI来移动控制台的光标
void gotoxy(int x,int y)
{
COORD c;
c.X=x,c.Y=y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),c);
}
// 从键盘获取一次按键,但不显示到控制台
int direct()
{
return _getch();
}
*/
import "C" // go中可以嵌入C语言的函数
// 表示光标的位置
type loct struct {
i, j int
}
var (
area = [20][20]byte{} // 记录了蛇、食物的信息
food bool // 当前是否有食物
lead byte // 当前蛇头移动方向
head loct // 当前蛇头位置
tail loct // 当前蛇尾位置
size int // 当前蛇身长度
)
// 随机生成一个位置,来放置食物
func place() loct {
k := rand.Int() % 400
return loct{k / 20, k % 20}
}
// 用来更新控制台的显示,在指定位置写字符,使用错误输出避免缓冲
func draw(p loct, c byte) {
C.gotoxy(C.int(p.i*2+4), C.int(p.j+2))
fmt.Fprintf(os.Stderr, "%c", c)
}
func init() {
// 初始化蛇的位置和方向、首尾;初始化随机数
head, tail = loct{4, 4}, loct{4, 4}
lead, size = 'R', 1
area[4][4] = 'H'
rand.Seed(int64(time.Now().Unix()))
// 输出初始画面
fmt.Fprintln(os.Stderr,
`
#-----------------------------------------#
| |
| |
| |
| |
| * |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
#-----------------------------------------#
`)
// 我们使用一个单独的go程来捕捉键盘的动作,因为是单独的,不怕阻塞
go func() {
for { // 函数只写入lead,外部只读取lead,无需设锁
switch byte(C.direct()) {
case 72:
lead = 'U'
case 75:
lead = 'L'
case 77:
lead = 'R'
case 80:
lead = 'D'
case 32:
lead = 'P'
}
}
}()
}
func main() {
// 主程序
for {
// 程序更新周期,400毫秒
time.Sleep(time.Millisecond * 400)
// 暂停,还是要有滴
if lead == 'P' {
continue
}
// 放置食物
if !food {
give := place()
if area[give.i][give.j] == 0 { // 食物只能放在空闲位置
area[give.i][give.j] = 'F'
draw(give, '$') // 绘制食物
food = true
}
}
// 我们在蛇头位置记录它移动的方向
area[head.i][head.j] = lead
// 根据lead来移动蛇头
switch lead {
case 'U':
head.j--
case 'L':
head.i--
case 'R':
head.i++
case 'D':
head.j++
}
// 判断蛇头是否出界
if head.i <0 || head.i >= 20 || head.j <0 || head.j >= 20 {
C.gotoxy(0, 23) // 让光标移动到画面下方
break // 跳出死循环
}
// 获取蛇头位置的原值,来判断是否撞车,或者吃到食物
eat := area[head.i][head.j]
if eat == 'F' { // 吃到食物
food = false
// 增加蛇的尺寸,并且不移动蛇尾
size++
} else if eat == 0 { // 普通移动
draw(tail, ' ') // 擦除蛇尾
// 注意我们记录了它移动的方向
dir := area[tail.i][tail.j]
// 我们需要擦除蛇尾的记录
area[tail.i][tail.j] = 0
// 移动蛇尾
switch dir {
case 'U':
tail.j--
case 'L':
tail.i--
case 'R':
tail.i++
case 'D':
tail.j++
}
} else { // 撞车了
C.gotoxy(0, 23)
break
}
draw(head, '*') // 绘制蛇头
}
// 收尾了
switch {
case size <22:
fmt.Fprintf(os.Stderr, "Faild! You've eaten %d $\n", size-1)
case size <42:
fmt.Fprintf(os.Stderr, "Try your best! You've eaten %d $\n", size-1)
default:
fmt.Fprintf(os.Stderr, "Congratulations! You've eaten %d $\n", size-1)
}
}

 


推荐阅读
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • Commit1ced2a7433ea8937a1b260ea65d708f32ca7c95eintroduceda+Clonetraitboundtom ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文介绍了在处理不规则数据时如何使用Python自动提取文本中的时间日期,包括使用dateutil.parser模块统一日期字符串格式和使用datefinder模块提取日期。同时,还介绍了一段使用正则表达式的代码,可以支持中文日期和一些特殊的时间识别,例如'2012年12月12日'、'3小时前'、'在2012/12/13哈哈'等。 ... [详细]
author-avatar
du-qhy
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有