失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Python练手项目:计算机自动还原魔方(1)顶部十字

Python练手项目:计算机自动还原魔方(1)顶部十字

时间:2021-05-11 15:47:07

相关推荐

Python练手项目:计算机自动还原魔方(1)顶部十字

上文Python练手项目:玩转魔方提到计算机自动还原魔方,本文先介绍计算机自动还原魔方顶部十字,以此类推,可完全还原魔方。

假设顶部中心块为蓝色,还原顶部十字,是将4个蓝色棱块还原到顶部,构成蓝色十字,并且蓝色棱块对面颜色与所在面的中心块色一致。如下图所示:

当我们面对一个杂乱无章的魔方时,我们的心也是凌乱的。

计算机程序是一个IPO,也就是将输入(I)的数据或状态,经过处理(P),转换为输出(O)的数据或状态。我们现在知道了I和O,现在要寻找P,把I变成O。

魔方有6个面,6种颜色,12条边,12个棱块,12个棱块在12条边上可产生几个亿的组合,从其中找出一种(顶部蓝色十字),可以想象其难度。

计算机专业人士善于将复杂问题简化:

1)将蓝色中心块那一面固定向上,魔方只能以蓝色中心轴整体转动,一次转动90度,类似走马灯;

2)只考虑Right面上的棱块,因为通过魔方的整体转动,其他面可以变成Right面;

3)只考虑right面上的upper、left(front)和down边,因为right边其实是其他面的left边;

4)只考虑4个蓝色棱块

这样简化下来,蓝色棱块在R面3条边的组合状态还有将近400种,比如:

还是太复杂,因为程序要对每一个状态编写相应的代码,能不能再简化?

再观察一下,我们其实关注的是蓝色棱块对面色与right面中心色是不是一致,这样简化下来,就只有3*4=12种状态了。例如:

对每种状态,都有4个转动方向,比如:

这样下来又将形成48种不同的处理操作,还是复杂了,再简化。对于R面的upper和front边的操作的第一步都只能是R‘,对于R面的down边的操作的第一步只能是R‘或D‘.....。最终可以把状态压缩到9钟。

接着就可以为这九种状态设计对应的旋转操作了,比如:

这样旋转操作的目的是:将R面front边上的蓝色棱块转移到R面down边,并且保持魔方的upper面不变,蓝色棱块在down边可以进行D‘旋转,去寻找匹配的中心色,此过程不影响魔方的上两层。

所以总的旋转操作设计原则是:

1)将R面的upper边上不满足条件的蓝色棱块和front边上蓝色棱块旋转到down边;

2)将R面的down边上不满足条件的蓝色棱块D'旋转到front面的down边,去尝试匹配front面

3)将R面的down边上满足条件的蓝色棱块旋转到upper边

4)如果R面的upper、front、down边上没有蓝色棱块,则整体逆时针旋转魔方(right),使得之前的front面变成R面

5)如果R面的upper、front、down边上有1个以上蓝色棱块,则只进行一次操作,然后整体逆时针(right)旋转魔方,使得之前的front面变成R面,

6)设定状态优先级,down>front>upper,可以使蓝色棱块尽快找到匹配的中心色

现在可以编程序了。

方案一

1)数据结构设计

设计一个列表结构表示蓝色棱块,

2)算法

这是一个标准的多分支或switch语句,与上图对应的代码代码(下图第一个if语句)可以这样写:

if blue_edge[1]=='front':Rp()Dp()R()D()right()if blue_edge[1]=='down' and blue_edge[2]=='blue' and blue_edge[0]!=blue_edge[3]:Dp()right()

这样写代码,逻辑过于复杂,模块中有多大9条if语句,且if语句的判断条件复杂,难以调试和维护,所以还需要进一步简化。

方案二

1)数据结构

用字典建立状态转移表,字典的key就是蓝色棱块状态,状态对应的操作序列则为key对应的value。由于Python字典的key不能是列表,所以,需要将上面方案中的数据结构改为字符串结构,存储蓝色棱块状态。

所建立的字典如下:

cross_dict = {'down11': ['Rp', 'Rp', 'right'],'down10': ['Dp', 'right'],'down01': ['Rp', 'Rp', 'right'],'down00': ['Dp', 'right'],'front': ['Rp', 'Dp', 'R', 'D', 'right'],'upper00': ['Rp', 'Rp', 'right'],'upper10': ['Rp', 'Rp', 'right'],'upper01': ['right'],'upper11': ['Rp', 'U', 'Fp', 'Up', 'right']}

2)算法

有了字典结构,就不用写if语句了,简单多了,代码如下

def 第一步顶部十字():while not 出现顶部十字():blue_list=寻找蓝色棱块()if len(blue_list)==0: #如果当前R面没有蓝色棱块right()continueblue_edge=blue_list[0] #按优先级只取一个蓝色棱块操作command_list = cross_dict[blue_edge] #查字典,获得蓝色棱块对应的操作for command in command_list: #依次执行操作列表eval(command)()

运行结果:

1)打乱魔方

2 点击“顶部十字”按钮,瞬间得到顶部蓝色十字

如果觉得《Python练手项目:计算机自动还原魔方(1)顶部十字》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。