Python练手项目:计算机自动还原魔方(4)还原底部两层+顶面

20 篇文章 3 订阅
17 篇文章 2 订阅

上文还原了底部两层,接着还原顶面。

按前文所述,假定在绿色为底的情况下,还原了两层,整体翻转为蓝色为底,现要还原顶部绿色面,如下图:

1 算法

算法采用前文引用的参考文献(参考文献的顶部颜色为黄色):

图1

图2

先还原顶部十字,然后还原整个顶部面,总共用到了三个公式。

1.1 还原顶部十字

还原顶部十字比较简单,只有一个公式,检查魔方顶部符合图中三个条件之一,就可以套用公式,直到出现顶部十字。算法设计如下:

def formula_cmd(command_list):
    try:
        for command in command_list:
            eval(command)()
    except:
        pass
def 出现顶部绿十字():
    color_list=[cube_list[1][3][0],cube_list[2][4][0],cube_list[1][5][0],cube_list[0][4][0]]
    if color_list.count('green')==4:
        return True
    else:
        return False
def 顶部一字绿():
    color_list = [cube_list[1][3][0], cube_list[1][4][0], cube_list[1][5][0]]
    if color_list.count('green')==3 and cube_list[3][4][0]=='green':
        return True
    else:
        return False
def 还原顶部绿十字():
    while not 出现顶部绿十字():
        if (cube_list[3][4][0]!='green' or cube_list[3][7][0]!='green'):
                if not 顶部一字绿():
                    right()
                    continue
        formula_cmd(["F", "R", "U", "Rp", "Up", "Fp"])
    pass

1.2 还原顶部面

这一步较难,公式有两个,对应两个顶部状态,这两个公式的作用是可以分别将三个顶部棱侧面的颜色翻到顶部面,如果符合两个状态,则可以还原顶部。但是,顶部状态不只这两个,对于其他状态,也可以通过反复调用这两个公式,将其他状态转换为图中的两个状态,并最终还原顶部面。

传统的思维方法是采用OOA中的方法,建立状态转换图,然后根据状态转换图,建立“状态-动作‘’判定表,就可以解决此问题,但问题是状态有点多,需要分析出全部状态,和全部状态转换,工作量太大,因而不适合,需要转换思路。状态转换图(局部)如下(此例顶部为蓝色):

思路转换方法:观察图2中的状态,通过实验,发现不管顶部状态怎么变化,都可以按蓝色块的数目来分类:5、6、7三种,顶部状态在这三种蓝色块数之间转换,我们需要的是蓝色块数为6的状态,此状态在两种公式之一的转换下,必能还原整个顶部面。所以算法只需要按照图2中的公式,预先计算状态变换前、后的顶部蓝色块数,尽可能朝6靠近,就可以得到我们想要的状态,并最终还原整个顶部面。算法描述如下:

def 顶部绿块数(): #计算顶部绿色块数
    count=0
    for i in range(3):
        for j in range(3,6):
            if cube_list[i][j][0]=='green':
                count+=1
    return count
def planA绿块数(): #计算如果使用公式1,顶部达到的绿色块数
    blue_cell_number=顶部绿块数()
    color_list=[[cube_list[3][5][0],cube_list[2][5][0]],
                [cube_list[3][2][0],cube_list[2][3][0]],
                [cube_list[3][11][0],cube_list[0][3][0]]]
    for i in range(3):
        if color_list[i][0]=='green':
            blue_cell_number+=1
        else:
            if color_list[i][1]=='green': #原来的顶部面的蓝色块被翻到侧面去了
               blue_cell_number-=1
    return blue_cell_number
def planB绿块数(): #计算如果使用公式2,顶部达到的绿色块数
    blue_cell_number=顶部绿块数()
    color_list=[[cube_list[3][3][0],cube_list[2][3][0]],
                [cube_list[3][6][0],cube_list[2][5][0]],
                [cube_list[3][9][0],cube_list[0][5][0]]
                ]
    for i in range(3):
        if color_list[i][0]=='green':
            blue_cell_number+=1
        else:
            if color_list[i][1]=='green':
               blue_cell_number-=1
    return blue_cell_number
def 还原顶部绿面():
    while True:
        if 顶部绿块数()!=6:
            if planA绿块数()==6:
                formula_cmd(["L", "U", "Lp", "U","L","U","U","Lp"])
                continue
            if planB绿块数()==6:
                formula_cmd(["Rp", "Up", "R", "Up", "Rp", "U", "U", "R"])
                continue
            formula_cmd(["L", "U", "Lp", "U", "L", "U", "U", "Lp"]) 
        else:  
            if planA绿块数()==9:
                formula_cmd(["L", "U", "Lp", "U", "L", "U", "U", "Lp"])
                break
            if planB绿块数()==9:
                formula_cmd(["Rp", "Up", "R", "Up", "Rp", "U", "U", "R"])
                break
            right()

2 运行结果

现在离最终计算机自动还原魔方只有两个步骤了。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值