1、需求来源
某天娃拿着华容道板块来,喊她爹我求解,大概如图这样的一个东西,我:…,一把年纪了,和你玩这个破东西?自己一边玩去。
花了一支烟时间想了下,算了,帮你写一个程序来破解吧,后面别来烦我就行了。
2、初步建模
面板大小为 4 X 5 的数组,角色我们称为卡片。 我们观察角色有:曹操、关羽、张飞、黄忠、马超和4个卒(为了表示方便,四个卒我们认为是四个不同角色)。 用一个二维数组表示游戏状态,为每个角色定义一个值。 角色值定义,卒用小写字母表示(谁叫你不是大佬?),大将们用大写字母表示,空白用 0 表示。(其实如何定义都没关系,主要是为了方便阅读和同名不冲突) 如下:
# "0":空
# "a":卒1
# "b":卒2
# "c":卒3
# "d":卒4
# "M":马超
# "H":黄忠
# "Z":张飞
# "Y":赵云
# "G":关羽
# "C":曹操
除了 0 值,其他相邻的相同值,我们认为是不可分割的一块,根据定义,我们构造其中一个初始化局面如下:
[ ["H","C","C","Y"],
["H","C","C","Y"],
["Z","G","G","M"],
["Z","b","c","M"],
["a","0","0","d"]
]
从初始状态开始,遍历每个可以移动的卡片进行下一个状态生成,得到一个状态树。
最终生成树下如果把“曹操”角色移动到(1,3)、(2,3)(1,4)、(2,4)(如下图,蓝色数据移动到红色位置)表示结束,拿到答案了:
3、抽象对象化
在状态树图中,如何从一个状态生成另一个状态?如果用上面的一个二维数组来做逻辑处理,比较复杂,如:
1) 除了0,相同的值的移动需要一起移动;
2) 移动向的领域不能超出4X5区域范围并且目标要是0(空白);
3) 离开的区域,需要设置为0 等等。
基于二维数组做这些状态表逻辑处理,略微复杂,将它们抽象简化下。
细想华容道游戏,包含一个面板,多个角色卡片,和两个空白位置这几种不同数据。我们如何把"面板"、“角色卡片”、"空白点"这三类有机的组合起来?步骤如下:
1)从卡片开始,我们定义一个Card 对象,它有角色值,有位置,有大小;
class Card:
def __init__(self, role, x, y, width, height):
self.role = role
self.x = x