Go语言实现1024终端游戏-不到400行代码

先放源码地址,喜欢看源码翻源码,喜欢看文章的继续继续看文章

https://github.com/taadis/go1024 - go1024

使用 go 语言实现的 1024 终端游戏,不到400行代码,代码简洁,以便理解和学习和掌握 go 语言开发.

安装和运行

要运行这个程序,你需要先安装依赖:

复制代码
go mod tidy

然后运行程序即可:

复制代码
go run main.go

游戏运行如下:

复制代码
     2     0     0     0

     4     2     0     0

     8    32     4     2

    32    16     8    16

Score: 380
请使用方向键操作,按快捷键 Ctrl+C 可退出游戏.

游戏实现

当前游戏实现了以下内容:

  1. 基于 go 语言的跨平台、可移植的终端游戏、包管理
  2. 1024游戏的核心逻辑
  3. 基于 ANSI 的终端颜色显示
  4. 键盘控制
  5. 得分计算
  6. 游戏结束检测
  7. 跨平台兼容性
  8. 基本的错误处理

随机数生成

我们使用 rand 来生成随机数。在本游戏中随机数主要有两个作用:

  1. 随机生成新数字的位置:
go 复制代码
slot := emptySlots[rand.Intn(len(emptySlots))]
  1. 随机决定生成2还是4:
go 复制代码
if rand.Float64() > 0.95 {
    value = 4  // 5%的概率生成4
} else {
    value = 2  // 95%的概率生成2
}

如果不设置随机数种子,每次运行游戏时随机数生成器都会使用相同的默认种子,这样:

  1. 每次游戏开始时数字出现的位置都会相同
  2. 新数字的值(2或4)的出现顺序也会相同
  3. 游戏失去了随机性,变得可预测

使用当前时间的纳秒数作为种子,可以确保每次运行游戏时都会得到不同的随机序列,使游戏更有趣和不可预测性。

颜色表示

根据数字的大小返回不同的颜色代码.

我们使用的数字是 ANSI 转义序列中的颜色代码。在终端中,我们使用 \033[ 开头的转义序列来控制文本的显示效果。

ANSI 转义序列的颜色代码是有限的,主要分为这几组:

  1. 基本前景色:30-37
  2. 基本背景色:40-47
  3. 高亮前景色:90-97
  4. 高亮背景色:100-107

98、99 和 108 以后的数字并不是标准的 ANSI 颜色代码,不会产生颜色效果。

具体解释:

  1. \033[ 是转义序列的开始标记(ESC 字符)
  2. 后面的数字是颜色代码:
    • 30-37:基本前景色(文字颜色)
      • 31: 红色
      • 32: 绿色
      • 33: 黄色
      • 34: 蓝色
      • 35: 紫色
      • 36: 青色
      • 37: 白色
    • 90-97:高亮前景色
      • 90: 亮灰色
      • 91: 亮红色
      • 92: 亮绿色
        等等...

在代码中:

go 复制代码
fmt.Printf("\033[%dm%6d\033[0m", color, g.Board[i][j])
  • \033[%dm 设置颜色
  • %6d 显示数字(6位宽度)
  • \033[0m 重置所有属性

所以当我们使用 color = 90 时,就会显示亮灰色文字,这在游戏中用来表示空位(值为0的格子)。

如果需要更丰富的颜色,可以使用:

  1. 24位真彩色:\033[38;2;R;G;Bm
  2. 256色:\033[38;5;Nm(N是0-255之间的数字)

例如:

go 复制代码
// 24位真彩色(红色)
fmt.Printf("\033[38;2;255;0;0m文本\033[0m")

// 256色(第100号颜色)
fmt.Printf("\033[38;5;100m文本\033[0m")

但这些高级颜色特性可能不是所有终端都支持,所以在通用程序中一般还是使用基本的 ANSI 颜色代码(30-37, 90-97)。

退出游戏

退出游戏主要通过监听取消信息来实现

  1. 添加了 os/signal 和 syscall 包
  2. 使用 signal.Notify 来捕获 SIGINT (Ctrl+C) 和 SIGTERM 信号
  3. 启动一个 goroutine 来处理信号,收到信号时:
    • 关闭键盘监听
    • 退出程序
  4. 移除了原有的 Ctrl+C 检查代码

这样修改后,无论在程序的任何时刻按下 Ctrl+C,都能正确退出程序。同时也会确保键盘资源被正确释放。

后面改为使用 github.com/eiannone/keyboard 包了,简化逻辑处理.

相关推荐
我不会起名字3226 小时前
Redis 从 0 到 1(十七):订单 30 分钟不支付自动关闭——ZSet 延迟队列 Go 实现
redis·go·延迟队列·zset·订单
FungLeo8 小时前
成为全栈·Go 后端篇·从 Node SQLite 到 PostgreSQL:把迁移做成独立交付物
postgresql·golang·sqlite·go·数据库迁移·成为全栈
皓月盈江14 小时前
GO使用Gin框架实现模板定义、解析与渲染
linux·golang·go·gin·定义模板·解析模板·渲染模板
我不会起名字32215 小时前
Redis 从 0 到 1(十九):JWT 还是 Redis Session?登录态存储的 Go 实现
redis·go·jwt·session·登录态
hourinX15 小时前
一张只有两种颜色的头像,为什么还要用 NRGBA?—— `gdenticon` 重构日志(四)
go
我不会起名字32215 小时前
Redis 从 0 到 1(十六):1 亿 UV 只占 12KB?计数去重三件套的 Go 实测
redis·go·uv·布隆过滤器·hyperloglog
FungLeo18 小时前
成为全栈·Go 后端篇·换后端不改前端:四个客户端如何做兼容回归
flutter·golang·go·成为全栈·兼容测试·taro 小程序
我不会起名字32218 小时前
Redis 从 0 到 1(二十一):P99 涨到 80ms,慢查询日志 5 步定位法 + Go 采集器
redis·go·慢查询·排查·slowlog
我不会起名字32219 小时前
Redis 从 0 到 1(十八):List、Pub/Sub、Stream 为什么生产只用 Stream?Go 实操
redis·消息队列·go·stream·pub/sub
孔令飞20 小时前
AI 岗位类别、要求、技能及学习路线
云原生·go·ai编程