热门标签 | 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太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 关键词:Golang, Cookie, 跟踪位置, net/http/cookiejar, package main, golang.org/x/net/publicsuffix, io/ioutil, log, net/http, net/http/cookiejar ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • Spring学习(4):Spring管理对象之间的关联关系
    本文是关于Spring学习的第四篇文章,讲述了Spring框架中管理对象之间的关联关系。文章介绍了MessageService类和MessagePrinter类的实现,并解释了它们之间的关联关系。通过学习本文,读者可以了解Spring框架中对象之间的关联关系的概念和实现方式。 ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • c语言\n不换行,c语言printf不换行
    本文目录一览:1、C语言不换行输入2、c语言的 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • 如何在跨函数中使用内存?
    本文介绍了在跨函数中使用内存的方法,包括使用指针变量、动态分配内存和静态分配内存的区别。通过示例代码说明了如何正确地在不同函数中使用内存,并提醒程序员在使用动态分配内存时要手动释放内存,以防止内存泄漏。 ... [详细]
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社区 版权所有