今天来分析一个益智游戏,数字华容道。

用python写出一个猜数字的游戏(用python写游戏之200行代码写个数字华容道)(1)

当初对这个游戏颇有印象还是在最强大脑节目上面,何猷君以几十秒就完成了这个游戏。前几天写2048的时候,又想起了这个游戏,想着来研究一下。

游戏玩法

用尽量少的步数,尽量短的时间,将棋盘上的数字方块,按照从左到右、从上到下的顺序重新排列整齐。

效果图

用python写出一个猜数字的游戏(用python写游戏之200行代码写个数字华容道)(2)

游戏操作方式

第一种是通过键盘的按键来移动数字,比如按上键,需要做的操作是把13移上去。

第二种是通过鼠标点击13,13移上去。不论采取哪种操作方式,可移动数字只能往固定的方向移动,做的操作都是把13和0位置互换即可。考虑到操作性,我们选用鼠标点击这种更为简单的操作方式。

用python写出一个猜数字的游戏(用python写游戏之200行代码写个数字华容道)(3)

自定义棋盘

定义棋盘的大小:4 * 4, 当然我把这个棋盘的大小做成了可自定义的属性,如果你觉得4*4没有挑战性, 还可以5 * 5 、6 * 6等等,下面以4 * 4为例做介绍。

看过我之前2048那篇文章的,一定明白接下来应该怎么做。没错,忽略棋盘背景,把棋盘看作一个4*4的二维矩阵,空白格用数字0填充:

用python写出一个猜数字的游戏(用python写游戏之200行代码写个数字华容道)(4)

接下来,我们应该考虑的问题是,数字的移动该怎么做?看上图的状态,此时只有0的上,右,下三格可以移动,别的都不能动。这里大家可以停顿一下考虑考虑,看看能不能找到一个移动的算法方案?

数字移动

通过数字在二维矩阵中的下标来表示数字的位置,比如8的位置是第一行、第一列即(0,0)(列表元素的下标从0开始), 第二行、第一列是(1, 0)。可以看下图:

用python写出一个猜数字的游戏(用python写游戏之200行代码写个数字华容道)(5)

图中,13的坐标是(3,0)。当鼠标点击13时,13和0交换位置,13的位置变成(2,0)。从(3,0)到(2,0)可以看作加了一个矢量(-1,0)。那如果点击不是13, 而是(1,0)位置的3,发生的变化就是(1,0)变成(2,0),矢量是(1,0),同理(2,1)位置移到(2, 0) 矢量是(0, -1),我们得到了一个上下左右的矢量集合, 上(-1, 0), 下(1, 0), 左(0, -1), 右(0, 1) 。

用python写出一个猜数字的游戏(用python写游戏之200行代码写个数字华容道)(6)

游戏逻辑

游戏的逻辑就变成了,当我们随便点击一个数字时,判断该数字的位置分别在加上4个矢量后的位置上的数字是否为0,是0,就把两个位置的数字交换,不是0,不做任何变动即可。

为什么会变成这样,因为一个数字可移动的方向只有0个或者1个。

数据矩阵存放

缕清了游戏的逻辑,那在记录数据二维矩阵时,就需要记录每个数字在矩阵中的位置下标。所以我们不打算采用2048中的矩阵的记录方式,而是采用python中的dict, 把位置作为key,把数字作为value。

用python写出一个猜数字的游戏(用python写游戏之200行代码写个数字华容道)(7)

整个操作的逻辑就是,当我们鼠标点击时,首先获取点击的坐标(x, y),通过坐标(x, y),获取到点击了哪一行,哪一列,得到(row_index, col_index)。然后把(row_index, col_index)分别加四个矢量, 判断加矢量后的位置(row_index vector, col_index vector) 在不在上图中的dict中且值是否等于0, 如果等于0, 使(row_index, col_index) 和 (row_index vector, col_index vector)的值互换。

如何判断游戏胜利?

判断dict中的最后一位是否为0,且0之前的所有值,是否按照顺序排序, 即为胜利。字典考虑到需要顺序,所以可以采用collections库中的OrderedDict 有序字典的数据格式。

代码开撸

1. 定义全局变量

用python写出一个猜数字的游戏(用python写游戏之200行代码写个数字华容道)(8)

2. 定义逻辑,初始化棋盘数据

用python写出一个猜数字的游戏(用python写游戏之200行代码写个数字华容道)(9)

在初始化过程中,首先要生成一个已胜利的数据顺序,然后随机移动一千次。如果是随机生成数据,有可能数据无解。

3. 初始化点击数据,和移动逻辑

用python写出一个猜数字的游戏(用python写游戏之200行代码写个数字华容道)(10)

4. 点击移动和判断游戏胜利的逻辑

用python写出一个猜数字的游戏(用python写游戏之200行代码写个数字华容道)(11)

5. 监控事件,自定义了定时器,记录游戏时间。监控鼠标点击事件,获取坐标,移动数字。

用python写出一个猜数字的游戏(用python写游戏之200行代码写个数字华容道)(12)

6. 主函数

用python写出一个猜数字的游戏(用python写游戏之200行代码写个数字华容道)(13)

不到两百行,代码完成。完整源代码私信回复 华容道 即可获取。

游戏运行

用python写出一个猜数字的游戏(用python写游戏之200行代码写个数字华容道)(14)

2048文章链接:用python写游戏之 2048

,