Go 2048 Game
知识点
- Go 语言的基本语法
- Go 语言中 package 的创建与引用
游戏设计
逻辑
2048 游戏使用 4x4 的格子来表示需要移动的数字,这不难想到可以使用一个矩阵来表示这些数字,我们使用type G2048 [4][4]int
来表示。
每一次使用方向键来移动数字时,对应方向上的数字需要进行移动和合并,也就是移动和合并G2048
矩阵中的非零值。当按下不同的方向键时,移动的数字也不同。我们一共会向上、向下、向左、向右四个方向移动数字,但是我们可以通过旋转G2048
矩阵将向下、向左、向右的移动都转换为向上的移动,这样能一定程度上简化游戏逻辑。
先让我们分析下,当向上移动的时候怎么样合并数据呢?假如我们有一列数据(这里为了演示方便我们将一列数据转换为了一行数据,同时向上的移动改为向左的移动,但是原理都是一样的)
[2, 2, 0, 2]
,当我们向左移动合并的时候,我们首先会移动数据,然后进行合并,然后再次进行移动,这个过程产生的数字序列如下:
[2, 2, 0, 2]
向左移动后变为[2, 2, 2, 0]
,然后我们进行合并操作后变为[4, 0, 2, 0]
,然后我们再次进行移动操作,则变为[4, 2, 0, 0]
,也就是我们向左移动合并后的最终结果
[2, 2, 0, 2]
-> [2, 2, 2, 0]
-> [4, 0, 2, 0]
-> [4, 2, 0, 0]
我们可以对所有的行(列)执行以上操作完成整个矩阵的移动合并。
那整个游戏的逻辑是怎么样的呢?2048 游戏逻辑如下:
- 首先进入无限循环,检查矩阵中是否有元素的值大于等于 2048,如果有,则游戏胜利,如果没有则游戏会随机将矩阵中值为零的元素的值设置为 2 或者 4
- 然后并监听用户键盘操作,然后将矩阵的所有元素的值打印到中 4x4 的表格中,
- 接着开始监听键盘事件,针对不同的按键做出不同的响应,比如当按下方向键时,游戏将执行矩阵相应方向的移动合并操作,
- 然后再次开始循环。如果按下的是
Esc
键,则退出游戏。
界面
我们开发的 2048 游戏将运行在 console(字符界面控制台,终端,控制台等)下。在 console 中,我们可以控制每一个字符单元的背景色,以及显示的字符。我们可以根据这一点,在 console 中绘制中图形,也就是 2048 游戏的框架:4x4 的空白格子,然后每一个格子是 4 个字符单元,也就是最多能显示四位数字。我们将使用包<git.shiyanlou.com/shiyanlou/termbox-go>进行界面的绘制,termbox-go
能很方便的设置字符单元的属性。
实现
2048 游戏中的难点有两个地方,一个是矩阵中数字的移动合并,另一个则是矩阵的变换,之所以需要对矩阵进行变换,是为了将 2048 游戏中向下的移动,向左的移动和向右的移动都转换成向上的移动操作。
3.1 矩阵的旋转
矩阵的旋转操作是为了将其他三个方向的移动都转换为向上的移动操作。向下 (↓)、向左(←)、向右(→) 转换为向上 (↑) 的操作时,数组需要进行的翻转操作如下所示:
-
↓ → ↑
此类转换可以有多种方法做到:
- 上下翻转矩阵,然后向上移动合并,再次上下翻转矩阵 上下翻转后:
martix_new[n-1-x][y] = martix_old[x][y]
- 顺时针翻转 180 度矩阵,然后向上移动合并,接着逆时针旋转 180 度 此时
martix_new[n-1-x]n-1-y] = martix_old[x][y]
-
← → ↑
此类转换可以将矩阵向右旋转 90 度后,向上移动合并,接着向左旋转 90 度完成
向右旋转 90 度后:martix_new[y][n-x-1] = martix_old[x][y]
向左旋转 90 度后:martix_new[n-y-1][x] = martix_old[x][y]
-
→ → ↑
此类转换可以将矩阵向左旋转 90 度后,向上移动合并,接着向右旋转 90 度完成
运行游戏
go run g2048.go