魔方CFOP公式匹配算法

1、魔方的原理及其性质

魔方最初是由匈牙利教授厄尔诺鲁比克发明的,之后经过发展,魔方衍化出了多种多样的版本,但最为经典的还是三阶魔方,具有普适性的同时,又是被大家所熟悉的。所以,本文选了三阶魔方作为本文的研究对象,以下如果没有特殊说明,所有的魔方都指的是三阶魔方,在开发魔方的游戏之前,首先要研究魔方的一些重要的性质,这对于魔方的开发是具体非常重大意义和作用的。

1.1魔方的几何结构

1.1.1魔方的机械结构


三阶魔方一般是由富于弹性的硬塑料制成的6面正方体。由一个中心轴、六个中心块、八个角块、十二个棱块共同组成了魔方的整体。中心轴六面都有螺丝孔,中心方块通过螺丝和弹簧连接在中心轴上,可以绕轴旋转。角块及棱块都可以随着中心块转动而转动。魔方的结构如图2-1所示:

图2-1  魔方的结构

1.1.2魔方的配色


目前魔方流行的配色方案有两种,一种就是世界标准配色,即BOY Color Scheme;另一种是日本配色,即BYO Color Scheme。两种配色方案用的颜色都是一样的:红、绿、橙、蓝、黄、白共六种颜色,两种方案不同之处是蓝黄颜色互换,用日本配色做CFOP的时候,一般以蓝色为底做十字,而标准配色下则以白色为底做十字,如图2-2所示:

图2-2  魔方的配色

 鲁比克教授最初发明的魔方的配色其实是日本配色,在魔方传至全世界后,鲁比克公司听取色彩研究者的意见,将配色做了更改,但日本则维持原来的配色,近年来日本也渐渐向世界标准配色统一。

本文的着色标准是按照国际惯例来的,也即是目前国际上默认的着色原则来的,用到颜色分别为:红(#C41E3A)、绿(#009E60)、蓝(#0051BA)、橙(#FF5800)、黄(#FFD500)、白(#FFFFFF)。

1.2魔方的符号描述

研究魔方无可避免要涉及到符号的描述,这里采用了“辛马斯特标记”(Singmaster notation),是由英国原伦敦南岸大学数学教授大卫·辛马斯特(David Breyer Singmaster)于1978年12月在研究魔方问题的同时,发明了魔方转动的记录方法,此后“辛马斯特标记”便成为了通用标准,也就是俗称的“公式符号”。
魔方有6×9=54个面,或者整体来看有上下左右前后6个面,为做区分,这里称为层,当我们与魔方的某个面正对时,则这个面称为F层,当F层被确定后,其余的5个层也随之确定。

                        图2-3  魔方3D图
如图2-3所示,当红色面与我们正对时,则称红色面为F层,其余分别为橙色面(B层)、绿色面(U层)、黄色面(D层)、蓝色面(L层)、白色面(R层),除此之外还有,竖向中层M(在L层与R层之间)、横向中层E(在U层与D层之间)、及中间层S(在F层与B层之间)。

上述的所说的层,起到选择魔方块的作用,例如上图红色面是F层,则红色面F层包含了9个魔方块(所选的魔方块都有红色),当魔方块选择完后,接下的操作就是旋转,旋转类型分为顺时针和逆时针,旋转的操作是在所在的面进行顺/逆时针转动,则公式合成为:层(即字母)+旋转操作。

图2-4  魔方CFOP符号大全

如上图2-4所示,图中的18种公式符号是组成CFOP公式的基础符号,小写表示双层转动,x y z是整体转动;单字母表示顺时针90度转动;字母加’表示逆时针90度转动;字母加2表示顺时针180度转动;字母加’2表示逆时针180度转动;

1.3魔方的状态表示

魔方状态应如何表示?当思考这个问题之前,可以想像一下寺庙的神像是如何摆放的,你该如何去描述它。对的!你可以用位置加旋转角度来描述神像的摆放状态,同理魔方也是如此,用某魔方块所在的位置及旋转角度,即可表示魔方块的状态。

1.3.1魔方的位置表示

图2-5  魔方的位置

魔方由26个魔方块组成:6个中心块、8个角块、12个棱块,当魔方不断发生合法转动(即按上述公式转动) 时,角块及棱块的位置也在时时变化着,但角块只能移动到角块,棱块只能移动到棱块。角块用它的三个面来命名,棱块同样的用它的两个面来命名,如上图2-5所示,这两个块分别叫做角块 UFR,棱块 UR。

棱块的位置有:UF、UR、UB、UL、DF、DR、DB、DL、FR、FL、BR、BL

角块的位置有:UFR、URB、UBL、ULF、DRF、DBR、DLB、DFL

 1.3.2魔方的旋转表示

魔方的角块有3个面,棱块 2个面,当要表示魔方旋转时,必需要有对应的参照物,就像要判断一个物体是否静止,只有参照物不变自身发生改变时才能确定物体是运动的,魔方的旋转也属于运动中一种,则可以设置正方向用于表示魔方的旋转状态。但仅有方向性人类是很难识别它的,例如拿一个完全没有上色的全黑魔方用于转动,虽然26个魔方块都是不同的个体,但差距非常小,人眼几乎判断不出来(类似于判断蚂蚁的不同个体)。

所以魔方上色是非常有必要的,不然魔方就失去它的意义,一个球体上半球涂红色,下半球涂绿色,则当球体的红色在我们所认为上方,球体为正置;反之, 当球体的绿色在我们所认为上方,球体为颠倒,由此魔方块的颜色和所定义的正方向可以表示魔方的旋转状态,如下所示:

棱块的正方向为:U、D、F、B

角块的正方向为:U、D

棱块颜色有:白红、白绿、白蓝、白橙、黄红、黄绿、黄蓝、黄橙、红绿、绿橙、蓝红、橙蓝

角块颜色有:白绿橙、白橙蓝、白蓝红、白红绿、黄绿橙、黄橙蓝、黄蓝红、黄红绿

如白红魔方块:

当它位置处于顶面时,若白色面处于U则为旋转状态为0,红色面处于U则为旋转状态为1;

当它位置处于底面时,若白色面处于D则为旋转状态为0,红色面处于D则为旋转状态为1;

当它位置处于前面时,若白色面处于F则为旋转状态为0,红色面处于F则为旋转状态为1;

当它位置处于后面时,若白色面处于B则为旋转状态为0,红色面处于B则为旋转状态为1;

如白绿红魔方块:

当它位置处于顶面时,若白色面处于U则为旋转状态为0,绿色面处于U则为旋转状态为-1,红色面处于U则为旋转状态为1;

当它位置处于底面时,若白色面处于D则为旋转状态为0,绿色面处于D则为旋转状态为-1,红色面处于D则为旋转状态为1;

1.3.3魔方的状态表示

在明白了上述表述后,即可表示魔方块的状态,例如:白红棱块在UR位置且白色在U面,则记为U白R红; 白红棱块位置相同且红色在U面,则记为U红R白;其中包含了位置和旋转角度的信息,旋转状态应用于颜色的顺序,U白R红和U红R白仅仅是颜色的顺序改变了,但对于计算机来说,颜色不是必要的,因为魔方上的颜色信息在计算机中可映射成位置及旋转信息。
同样,白红棱块在UR位置且白色在U面,则白色面处于U旋转状态为0,也可记为UR; 白红棱块在UR位置且红色在U面,则红色面处于U旋转状态为1,也可记为RU; 旋转状态应用于层的顺序,UR和RU仅仅是顺序改变了,由此得知,用魔方的位置与旋转状态即可表示魔方块的状态,在Unity中位置体现为坐标,旋转状态体现为欧拉角或四元数的数值。
 

2虚拟魔方的创建及其状态表示

2.1虚拟魔方的创建

2.1.1魔方模型的创建

魔方游戏首先需要创建一个虚拟魔方主体,用到的是Unity中的预制体动态地创建3D立体魔方,整个虚拟魔方共有27魔方小块,一个魔方小块的模型可用3Dmax来建模,再用PS给魔方小块的贴图上色,拖入Unity中生成预制体,然后用Instantiate函数动态创建27个魔方小块,这27个魔方小块共同组成了整个虚拟魔方,代码如下图3-1所示:

图3-1  虚拟魔方的生成代码

魔方创建完后,魔方的支架中心块被其余26个魔方块完全包裹,它的坐标为原心(0,0,0),则其余六个中心块坐标为(0, 0, -1)、(0, 0, 1)、(1, 0, 0)、(-1, 0, 0)、(0, 1, 0)、(0, -1, 0),则根据魔方的结构,可得出以下结论:

棱块坐标可用相邻中心块(两个)的坐标相加得到,棱块坐标分为:(-1,-1,0)、(0,-1,-1)、(1,-1,0)、(0,-1,1)、(-1,0,-1)、(1,0,-1)、(1,0,1),(-1,0,1)、(-1,1,0)、(0,1,-1)、(1,1,0)、(0,1,1)。

角块坐标可用相邻中心块(三个)的坐标相加得到,角块坐标分别为:(-1,-1,-1)、(1,-1,-1)、(1,-1,1)、(-1,-1,1)、(-1,1,-1)、(1,1,-1)、(-1,1,1)、(1,1,1)。这样魔方的创建就完成了,可将魔方按层分为三部分,如下图3-2所示:

图3-2  魔方坐标分布图

2.1.2魔方的控制器创建

当魔方创建完后,最为重要的就是魔方转动,魔方转动问题类似于数组操作问题,例如:数组为{1,2,3,4,5},在数组中任选三个数字,形成一个集合后,然后对这个集合进行加、减、乘、除等操作,同理魔方转动就是选择合适的魔方集合进行顺/逆时针旋转,在这里魔方集合被称为魔方控制器。

魔方控制器根据魔方公式符号得出共有18大类,分别为:F/B/R/L/U/D/f/b/r/l/u/d/E/M/S/x/y/z,代表了27个魔方块可形成的合法魔方块集合,可根据Unity中魔方块的坐标来生成控制器,魔方的轴心置于(0,0,0),白色为底面,则会发现这样一个规律:

(a,a,-1)F         (1,a,a)R        (a,1,a)U

(a,a,1)B          (-1,a,a)L        (a,-1,a)D

若要判断F面的方块,只需让27个方块分别一下判断三维坐标的z轴是否等于-1,得到是9个符合条件的方块。

(a,0,a) E        (0,a,a) M        (a,0,a) S

若要判断E面的方块,只需让27个方块分别一下判断三维坐标的y轴是否等于0,得到是9个符合条件的中间方块。

f=S(条件)+ F(条件)        r=M(条件)+R(条件)       u=E(条件)+U(条件)

b=S(条件)+ B(条件)       l=M(条件)+L(条件)        d=E(条件)+D(条件)

若要判断f面的方块,只需让27个方块分别一下判断三维坐标的y轴是否等于0或z轴是否等于-1,得到是18个符合条件的方块。

由上面的规律可得出魔方控制器生成判断条件,且F/B/R/L/U/D与f/b/r/l/u/d的转动方式类似,所以两者可共同一个控制器,由此魔方控制器为12大类,分别为:F/B/R/L/U/D/E/M/S/x/y/z。 懂得了魔方控制器的生成,接下来就是魔方的转动操作,在Unity中有着欧拉角或四元数,但欧拉角有着万向锁问题,则采用四元数对魔方进行旋转操作。

2.2虚拟魔方的旋转

当魔方控制生成后,就可以旋转魔方了,但四元数是非常难理解的,所以魔方的转动仍用欧拉角来表示,用的时候将欧拉角转换四元数,欧拉角表示为(X,Y,Z),X分量就是绕X轴旋转的角度,Y分量就是绕Y轴旋转的角度,Z分量就是绕Z轴旋转的角度,除此还有旋转顺序的不同,对于这三个轴的不同旋转顺序一共有(x-y-z, y-z-x, z-x-y, x-z-y, z-y-x, y-x-z)六种组合,不同的顺序都可能导致结果的不同,可以理解为先扔衣服再开洗衣机与先开洗衣机再扔衣服结果是不同的。

魔方的旋转只是转动X/Y/Z铀中的一个,则可使用Unity默认的向量属性,forward Vector3(0, 0, 1)的简码,也就是向z轴,right Vector3(1, 0, 0)的简码,也就是向x轴,up Vector3(0, 1, 0)的简码,也就是向y轴,除此之外还需一个Int来保存魔方控制器的角度,这个int值保存了上一次的角度,能让魔方的转动保持角度的连惯性,刚开始int值为0,顺时针旋转则加90,逆时针旋转减90,且角度限制在-360度至360度之间,当某一时刻进行顺/逆时旋转,只需将int值与向量属性相乘就可以得到目标旋转欧拉角,然后将此欧拉角转换为四元数使用,即可调用Unity函数对魔方控制器进行旋转操作。

当然仅仅用Unity的四元数函数对魔方操作是会失去过程的,就像闪现一样失去了游戏的真实性,故要对魔方的做出动画效果,这里旋转动画不仅要按时完成且还要保证转到位,这显然有难度,而Unity的协程恰好能很好的解决这个问题,动画代码如下图3-3所示:

图3-3  魔方旋转动画实现

2.3虚拟魔方的观察与转动标识符

虚拟魔方创建并可以转动后,接下来就是魔方的观察问题,在我的设想中魔方是可以360无死角的观察的,但为了不转晕故对Unity的y铀限制在-90度至90之间,实现的思路是用脚本控制主摄像机对魔方整体进行浏览拍摄,这样在虚拟世界中同样可以做到360无死角的观察,魔方的摄像机代码如下图3-4所示:

图3-4  魔方摄像机代码

在CFOP公式中,我们还需要规定F面,才能正确的套用CFOP公式,F面则是当我们与魔方的某一面正相对时,则这个面称为F面,在现实生活中对魔方观察通常只有一个角度,但对虚拟世界中的魔方,则需要多个角度观察,才能达到360度观察的效果,很难确定那一面正与我们相对,解决方案就是创建了一个不会变化魔方转动标识符作为参考,如下图3-5所示:

图3-5  魔方转动标识符

当魔方的转动标识符成了虚拟魔方的一部分,则F面与绿色面、U面与黄色面、R面与橙色面共同构建了魔方的基准, 若魔方必生x/y/z转动,魔方整体会转动,但魔方的转动标识符不会改变,同时魔方转动标识符的外边有着顺/逆时针的旋转标示,让人更容易看懂。

2.4虚拟魔方的状表示

2.4.1魔方状态概述与还原检测

魔方基准确定后,经反复探究魔方的旋转状态与每一魔方块的魔方的状态数有且只有24种,其中一个欧拉角可用两个四元数表示(除原心排外),中心支架魔方块在不断转动中仍保持正确的旋转状态(魔方块正确还原后的角度),1个魔方状态由1个魔方坐标和1个魔方旋转状态组成,1个中心支架、6个中心块、8个角块、12个棱块共同组成了魔方整体,且中心块只能到中心块位置、角块只能到角块位置、棱块只能到棱块位置,则可得:

中心支架块可旋转到位置只有1处,在这个位置有着24种旋转状态,对应的是中心支架块24种不同朝向;

中心块可旋转到位置有6处 ,每一处位置都有着4种旋转状态,对应的是中心块四种不同朝向;

角块可旋转到位置有8处 ,每一处位置都有着3种旋转状态,对应的是角块3个面不同朝向;

棱块可旋转到位置有12处 ,每一处位置都有着2种旋转状态,对应的是棱块2个面不同朝向;

由此,可实现检测魔方块是否被还原,即检测魔方块的位置与旋转状态是否都为正确,下面列举棱块与角块的还原检测方法:

棱块位置还原检测:要检测红白棱块,可以将红色魔方块的中心块的坐标加上白色魔方块的中心块的坐标,得到红白棱块坐标。

角块位置还原检测:要检测红白绿棱块,可以将红色魔方块的中心块的坐标加上白色魔方块的中心块的坐标加上绿色魔方块的中心块的坐标,得到红白绿棱块坐标。

棱块、角块旋转状态还原检测:只要棱块或角块的旋转角度跟魔方中心支架块旋转角度一样即为已还原。

当上述两个检测通过则表示某个魔方块成功被还原,那样能实时检测20个魔方块的实时还原情况。

2.4.2魔方颜色与状态检测

 图3-6  魔方块的坐标与角度

在魔方建立基准后,魔方的颜色与魔方的状态产生了联系,则用魔方的颜色及魔方块在魔方转动标识符所示的位置表示一个魔方块的状态,如上图3-6的白蓝橙角块记为U蓝F橙R白,魔方块的坐标位置与旋转状态角度组成了魔方的状态,魔方状态体现了魔方颜色的分布,当得知魔方的颜色和旋转状态角度,就可得知这颜色在此旋转状态下处于什么位置,所以还需要有一张颜色与旋转状态的对应表,此对应表是以绿色面为F面而推理出的,适用范围有限。

在上述中,需得知颜色与旋转状态的对应表,但魔方的角度是较难辨别的,就像上图3-6中的(270.0,90.0,0.0),为了方便辨别,则将24种旋转角都转为数字编号表示,代码片断如下图3-7所示:

图3-7  魔方状态角转换编号

当完成上述的工作后,就可开始创建颜色与旋转状态的对应表,魔方的中心块有且只有一种颜色,有着6个可旋转位置,每一位置都有着4种旋转状态,是用于建立此表的最佳选项,则用Unity日记输出可得,如下图3-8所示:

图3-8  颜色与旋转状态对应表

则图3-6 的白蓝橙角块旋转角度为(270.0,90.0,0.0),根据图3-7可将(270.0,90.0,0.0)转化为数字编号为21,此角块颜色为白蓝橙,那么可输入颜色根据图3-8中得出相应的位置,输入蓝色旋转角度状态为21,找到U; 输入白色旋转角度状态为21,找到R; 输入橙色旋转角度状态为21,找到F;所以得出U蓝F橙R白,用颜色和旋转状态表推出的U蓝F橙R白与图3-6中的情况一致。同样也可换一种思路,图3-6白蓝橙角块坐标为(1.0,1.0,-1.0),即为UFR位置,此角块颜色为白蓝橙,角块有个面旋转状态也有3种,根据旋转状态的不同则UFR与颜色白蓝橙可形成的3种不同的合法组合。

3魔方CFOP算法基础

通过Unity对虚拟魔方的创建及基准的确定,魔方的状态已经可以准确的表述,也为魔方的CFOP算法的实现打下了坚实的基础,在本论文中对Unity中的虚拟魔方状态及CFOP算法情况的辩识是本论文最大的亮点。

3.1CFOP算法概述

捷克共和国的名为Jessica Fridrich女大学生的女大学生提出了一种目前世界上使用最为广泛魔方复原方法-Fridrich Method(又称Fridrich System,CFOP法),该公式共有119个公式,复原魔方的步骤分为4个步骤,特别适合于手解魔方的竞技比赛,世界魔方速拉比赛选手利用CFOP算法来复原魔方的最好成绩已经突破了20秒的大关。由此可见该方法对魔方的发展起到的非常关键的作用,并且该方法给魔方研究者带来的启发和影响一直持续至今。

Fridrich Method解法的简称就是CFOP,CFOP的字母其实就分别代表了该魔方复原方法的4个关键步骤阶段。C代表Cross,该阶段必须完成魔方的底面拼成“十”字型,F代表F2L(First 2 Layer),该阶段必须完成魔方的前两层拼好,O代表OLL(Orientation of Last Layer),该阶段必须完成魔方的最后一层所有棱块和角块的方向调整,P代表PLL(Permutation of Last Layer),该阶段就完成魔方的最后一层的所有块的位置排列。下图4-1为算法中四个阶段魔方所要达到的目标状态,在本论文中如无特殊说明,还原底皆为白色底。

图4-1  CFOP算法四个阶段的目标状态

Cross底部十字架还原是没有公式的,要使得底层和中间层的棱块颜色是一致的,数据分析表明,对于用单色底的人来说,99.95%的十字情况都可以在七步之内解决,只有0.05%的情况下需要八步还原。

       F2L底两层还原共有41个公式,对应的是一组底棱还原的可用公式,每次还原一组底棱,魔方有着四组底棱,需要还原四次才能将魔方的底两层还原,下图4-2是红蓝组棱块:

图4-2  F2L标准公式

但上述的41公式并没有包括F2L阶段的所以情况,除此41公式之外的情况被称为非标F2L,将棱块和角块是否在第三层作为分类标准,则:

       棱块与角块都在第三层,属于标准F2L;

       棱块在第三层,那么则角块在第一层,角块的可选位置有四种,只有一种是正确的,如F2L的07公式,其余3种都为非标F2L;

       角块在第三层,那么则棱块在第二层,棱块的可选位置同为四种,只有一种是正确的,如F2L的32公式,其余3种都为非标F2L;

       当棱块与角块都不在第三层时,那么棱块与角块只能在一、二层,先判断棱块与角块是否相连,若棱块与角块相连,那可选位置仍为四种,只有一种是正确的,如F2L的4公式,其余3种都为非标F2L;若棱块与角块不相连时,又可根据棱块与角块在一、二层位置是否正确分为3种情况:棱块位置不对,角块位置不对,棱块与角块位置都不对。

       OLL是调整魔方顶层棱块与角块旋转状态的公式,公式共有57个,可使顶层的魔方块旋转状态一致,OLL中的小黑块和小黑条都表示黄色块,如下图4-3所示:

图4-3  OLL公式

PLL是调整魔方顶层棱块与角块位置的公式,公式共有21个,可调整顶层魔方块位置使其正确,PLL中的小黑条表示特征/相同色块,如下图4-4所示:

图4-4  PLL公式

其中,魔方特征相同的色块可理解为不同颜色但种类相同,比如人的肤色有黄、白、黑,物种都是人,同理,用同一个公式对一个已复原魔方进行公式打乱,可选的F面有绿、橙、蓝、红四种,不论选择哪种F面,打乱出的魔方块同属于一种情况(特征相同)。举个例子,当你用PLL的01公式打乱一个以白色为底已复原的魔方,然后分别以绿色面、蓝色面、红色面、橙色面作为F面打乱魔方,最终得出四种情况,这四种情况同属于相同特征,如下图4-5所示:

图4-5  魔方同特征魔方块

3.2读取魔方状态

为了更好的读取魔方块的状态,故要对魔方状态读取方式进行规定,就像手机充电头规定成了USB口,在这里有两种读取方式,一种是无序读取,即输入什么返回什么,另一种是有序读取,输入一组魔方块,得到数据后不立即返回结果,而是根据魔方块位置排序后再返回数据结果。

无序读取也就是按固定位置读取魔方块,先是接收固定位置魔方块名称列表字符串,用Split分割成数组,然后将魔方块按顺序输入MofanStata函数,MofanStata可用魔方的名称,获取魔方块的颜色和旋转状态,而魔方块的颜色和旋转状态又推出魔方的状态(在3.4节中有详解),获取魔方块的相应状态后,再将返回结果拼接成String返回,代码如下图4-6所示。

无序读取相对的则是有序读取,可返回有序的魔方块列表,无序读取与有序读取很类似,只是多了排序的步骤,同样输入魔方块名称列表字符串将其分割成数组,一个一个的去调用MofanStata函数返回魔方块的状态值,再用魔方的坐标作为排序指标,新建一个字符数组,为这个字符数组的每一个下标设置对比值,只有根据坐标读取出的排序指标值与预先设定的对比值相等才给这个字符数组中字符赋值,然后用String的Join函数将此字符数组转为String返回,这样就可以达到一个排序的作用,如下图4-7所示。

图4-6  固定位置读取魔方块

图4-7  有序读取魔方块

3.3魔方的F面与模拟转动

在CFOP公式中时刻要有一个概念,那就是魔方的F面,只有选对了F面才能套用公式正确还原,绿色面作为F面用公式打乱魔方,当还原魔方时仍要选择绿色面作为F面,对虚拟魔方进行y操作相当于在现实中旋转魔方整体,例如,绿色面作为F面以PLL的01公式对魔方打乱后,依次是不操作、y操作一次、y操作两次,y操作三次(相当于y’操作一次),得到图4-8所示:

图4-8  F面情况

图4-9  F面选择不恰当

上图4-8中魔方的F面情况有四种,只有a情况是可以直接套用PLL的02公式进行还原的,b、c、d都需要进行y操作进行转换后才能套用公式,如上图4-9所选的F面是不恰当的, 对应的是图4-8中的d情况,要想让d情况转为a情况,只需对魔方进行y操作即可,F面就从红色面转换成了绿色面,这样就可以使用公式了。

F面会有四种选择情况的发生,为了解决F面选择不恰当的问题,我们还需要对魔方进行模拟转动,魔方的模拟转动即用读取的魔方字符串进行一系列的转换从而得到魔方实际转动后会读取到时的魔方字符串结果,如图4-8中d情况进行y操作后会得到a情况,相应的魔方字符串也会变化,这里就是用d情况读取到的魔方字符串推出a情况的魔方字符串。

首先,使用的是魔方块有序读取的方式,按照ULF、 UL、 UBL、UB、URB、UR、UFR、UF位置次序来读取魔方块的字符串信息,读取方式确认后,图4-8的a情况读取的字符为:L红F绿:L橙:B蓝L红:B蓝:R橙B蓝:R绿:F绿R橙:F红,图4-8的d情况读取的字符为:L蓝F红:L蓝:B橙L蓝:B绿:R绿B橙:R红:F红R绿:F橙,转化有着字符顺序调整和字符内容替换两大部分,这里用魔方的y操作为示例:

第一步字符顺序调整,将每一魔方块所形成的字符串向后推两位(即每个字符向移6位),则d情况转换后变为:F红R绿:F橙:L蓝F红:L蓝:B橙L蓝:B绿:R绿B橙:R红,第二步字符内容替换,y操作字符转化规律为“F”变为“L”、“L”变为“B”、“B”变为“R”、“R”变为“F”,则d情况转换后变为: L红F绿:L橙:B蓝L红:B蓝:R橙B蓝:R绿:F绿R橙:F红, 则d情况经过两步转化后与a情况的字符一致,这样就完成了y操作的模拟旋转,当懂得y操作是怎样被模拟操作后,也就可以推出其它操作符的转换方式,比如:y’操作的转换,第一步同字符顺序调整与上面相同。

第二步是字符内容替换,y’操作字符转化规律为“F”变为“R”、 “R”变为“B”、 “B”变为“L”、 “L”变为“F”,这样y’魔方操作就可以完成了y’操作的模拟旋转。

4CFOP公式匹配算法

CFOP公式有着四个阶段,分别为Cross、F2L、OLL、PLL,Cross是没有公式的,此章节则探讨F2L、OLL、PLL三大部分,从已复原魔方的状态到魔方PLL阶段,再由PLL阶段到魔方OLL阶段,再OLL阶段到魔方F2L阶段,采用的是一种倒序的方式。

4.1PLL/OLL匹配算法概述

图5-1  PLL截取公式

魔方PLL阶段共有21个公式,其本质是调整魔方块的位置顺序而不改变其旋转状态,要区分21个不同公式,则需按位置有序地读取魔方块(在4.2节中详解),在PLL阶段读取的魔方块黄色都在U面,起不到区分作用,故作为冗余将去掉,如图5-1是PLL所截取的01与02公式,这两个PLL公式很相似较难以区分,但只要有序的读取魔方块就可以有效的区分两种情况,读取方式为从左下角的魔方块开始,顺序时针依次读取魔方块,最后读取到左下角魔方块的右边魔方块结束,能区分21个魔方公式后,仍不足包含PLL阶段的所以情况,因为1个PLL公式就可分化出16种情况,这16种情况是由四种同特征颜色块(在4.3中有详解)与四种不同F面(在4.3中有详解)情况相乘而得,由此PLL公式动态匹配分为颜色匹配及模拟转动匹配两部分。

颜色匹配可确定是否为同一类型,在4.1节中的图4-5的四幅图皆为同一类型,四幅图都可进行相互转换,转换的规律为:“红”变为“绿”、“绿”变为“橙”、“橙”变为“蓝”、“蓝”变为“红”,任选一幅图,最多转换3次就判断是否为同一类型。这样同类型颜色判断标准就出来了,即选取一幅图将其转换为字符串贮存起来,再将读取到的魔方字符串与之前预先存贮的字符进行比较,若不相等则进行一次颜色转换然后再去比较,最多比较四次,在四次比较中都不相等,则不是同一类型。

模拟转动匹配可以模拟魔方的转动从而判断是否为正确的F面,若不是则给出正确的转换公式,判断标准为:先贮存正确方位的F面魔方字符串(PLL公式图转换),然后将读取到的魔方字符串与存贮的字符进行比较,若不相等则进行一次模拟转动然后再去比较,最多比较四次,在四次比较中都不相等,则不是这个公式类型的F面错位。

        

图5-2  OLL公式截取

魔方OLL阶段共有57个公式,其本质是调整魔方块的旋转状态使其一致,魔方块读取方式仍然是按照位置来读取魔方(在4.2节中详解),在OLL阶段只读取的魔方块有关黄色块的信息,如右图5-2中是OLL截取的01与02公式,01公式读取为:L黄:L黄:L黄:B黄:R黄:R黄:R黄:F黄,02公式读取为:L黄:L黄:L黄:B黄:B黄:R黄:F黄:F黄,OLL匹配算法与PLL匹配算法很是类似,但OLL没有四种同特征颜色块,所以只需要进行模拟转动匹配即可。

4.2PLL/OLL匹配算法实现

目标是实现读取魔方顶层魔方块的状态字符串,两者都是采用有序读取法,则以白色为底、绿色为F面的魔方为示例,将PLL与OLL公式转换为字符串,如下图5-3所示:

图5-3  PLL公式与OLL公式字符串表述

在实现PLL/OLL匹配算法之前,由上可得知,需要颜色匹配和模拟转动匹配,如下图5-4中的readPOLLArr是读取魔方顶层方块状态函数;PLL阶段不需要U黄字符,OLL阶段只需要关注黄色块,removeExcessStr函数则能很好的起到数据筛选的作用,只保留有效部分, 图5-3中的公式集合就是由readPOLLArr函数读取的、removeExcessStr函数筛选总结而得出的;POLLSwapReStr函数是模拟转动匹配的实现、POLLTypeCom函数是颜色匹配的实现。

图5-4  PLL与OLL基础函数

当基础函数完成后,就可实现PLL/OLL的匹配算法,这两者很是类似,故两者放同一个函数如下图5-5所示,用一个布尔值来区分PLL与OLL两种情况,先将传入的魔方状态字符串转换字符数组,再根据布尔值判断还原阶段筛选出有效数据,再确定对比字符集类型,最后进入对比阶段,先调用POLLTypeCom函数进行颜色匹配,PLL需要颜色匹配且不超四次,而OLL不需要,只要匹配一次即可,然后再进行模拟转动匹配,PLL与OLL都要进行,同样匹配次数不超四次,这样就实现了PLL/OLL的匹配算法。

图5-5  PLL/OLL匹配算法的实现

4.3F2L非标情况转化

魔方的F2L阶段共有41个公式,需要复原四组棱/角块组合,分别为(红绿棱块,白红绿角块)、(绿橙棱块,白绿橙角块)、(蓝红棱块,白蓝红角块)、(橙蓝棱块,白橙蓝角块),F2L采用的是按固定位置的读取方式,即输入什么就返回什么,上述的41个公式并没有包括F2L阶段的所以情况,在4.1节中已经用文字列出了F2L阶段的所以情况,但这种表述很不直观,可将其转换为脑图,如图5-6所示:

图5-6  非标F2L脑图

想要用套用F2L的标准公式,则先要将非标F2L转换为标准F2L,其中有6种非标F2L情况,但总起来非标F2L转换只有二个步骤,步骤一:将棱块或角块从第一、二层移置第三层,步骤二:在不影响第三层原来的棱/角块情况下复原转动的层。

以下若无特殊说明,则都以蓝红棱块及白蓝红角块组合为例子,解释F2L的非标情况,

图5-7  魔方块的读取

在3.4节中MofanStata函数,用的是颜色和旋转状态获取位置,所以传入的颜色是不变的,变化的只有位置,从右图5-7可看出,当颜色读取顺序固定后,只用字母就可以确定棱块、角块的状态,分别为FR、RF、FRD、DFR、RDF,角块与棱块相比多了一个面(也多了一种状态),但这个面是不需要关注的,故可以去除,则变为FR、RF、FR、FR、RF,这样魔方角块的情况就成功转化为了棱块的处理情况。

上述的步骤一,是要将棱块或角块从第一、二层移置第三层,再观察图5-7的上两幅图,转出幅一与幅二中的棱块至魔方第三层,FR和RF情况都可用R或F’操作进行转出,这里只用R操作类型,但如何知道是锁定这R操作类型是个问题,而在2.3节中的魔方块状态定义恰好可以解决这问题,FR与RF顺序是不同的,表现的则是魔方的状态,在2.3节可知FR、LF、BL、RB为状态0,RF、FL、LB、BR为状态1,但是因所要锁定的操作类型与状态相反,则FR、LF、BL、RB返回1,RF、FL、LB、BR返回0,这样做的好处是读取情况就可知锁定的操作类型,如读取的情况是FR,返回为1,以FR作为字符数组输入1读取到的是R; 读取的情况是RF,返回为0, 以RF作为字符数组输入0读取到的仍是R,同理BL与LB读取到的都是B。

图5-8  非标F2L例子

如图5-8所示,这两种非标F2L情况分别是角块位置不对棱块在第三层、棱块位置不对角块在第三层,需要从魔方一、二层移至魔方第三层,从上面已经知道FR与RF采用是R操作,可以使用R U R’或R U’ R’操作对该魔方的非标F2L进行转换,在这里的步骤二就是确定是使用R U R’还是R U’ R’ 操作,因为将错位的棱块或角块移出后,转动的层要复原,如R操作后要R’操作,中间使用U或U’操作,这样底部十字才不会乱,但就是在R’操作中有时会将原本在第三层的角块与棱块重新嵌入进行错误的一、二层,这样之前所做的操作就白做了,仍为非标F2L的情况,所以可以将所有情况列出来,再找出区分为法来决定是使用U还是U’。

图5-9  棱、角分布情况

在上图5-8中蓝红棱块有着四种情况,对应的是右图5-9的第二幅图,图5-8中白蓝红角块有着四种情况,对应的图5-9的第一幅图,情况分别有a、b、c、d与e、f、g、h两大类情况,分别对这八种情况进行R U R’及R U’ R’操作,最终得出b、d、g、h情况U和U’都行,a、f情况只有U可以,c、e情况只有U’可以,则5-9图中的第一幅图默认为U操作,只有e情况为U’操作;图5-9第二幅图默认为U’操作,只有a情况为U操作,这样就可以转化两种非标F2L的情况了。

但非标F2L情况有6种,其中第3、4、5种非标F2L情况处理方式一致,R U R’操作或R U’ R’操作处理,但第1、2种的需要像上面一样判断8种情况,第6种可经过R U R’操作或R U’ R’操作转化为第1、2种情况处理,这样全部非标F2L皆可转换为标准F2L。

 4.4F2L算法的概述

F2L算法的实现,在5.3节的中脑图共列出了F2L的10种情况,6种属于非标F2L,只有4种属于标准F2L,这四种分别为:棱块、角块都在正确位置;角块在正确位置,棱块在第三层;棱块在正确位置,角块在第三层;棱块、角块都在第三层;在这就可大致分为两大类,棱块、角块都在正确位置为一类,其余3种为一类。

棱块、角块都在正确位置,则只需考虑F面的四种选择,只有一种F面是正确的,其余3种皆为错位,则需处理4种情况;其余的3种都有魔方块在第三层,不管是一个还是两个,所出现的情况仅有四种,但同样只有一种是正确的,其余3种皆为错位,加上F面四种选择,则需处理16种情况。

假设,此魔方已还原底十字且F面选择正确,当有魔方块处于第三层时,则最多匹配四次,就可以找到对应的F2L标准情况;还一种情况就是,棱块和角块都在正确位置,那只需匹配一次即可。

当然实际F面选择不一定正确,4种情况都需要F面匹配,最多匹配次数也是四次,则先判断是否属于标准F2L,若是则记录下它的F2L类型,可设为:01、02、03、04四种F2L类型, 先判定一轮U匹配, U匹配即模拟魔方的U操作不断与F2L公式匹配的过程,虽然02、03、04可规为一类,但U操作的模拟是不同的,02变化的只有棱块、03变化的只有角块、04角块和棱块都在变,故要将F2L类型传入来决定U操作的模拟,当然01没有魔方块在第三层是不需要U匹配的。

可先进行一轮 U匹配,匹配上了返回false停止查找,匹配不上返回true,进行一次模拟y操作换一个F面继续进行U匹配,直到匹配次数达到16次为止,16次都匹配不上则说明不属于该条F2L公式,可继续匹配下一条F2L公式直到41条F2L公式匹配完成。

 4.5F2L算法的实现

在后面的研究中发现,当输入的颜色顺序固定后,只用字母字符也表示魔方的状态,如5.3节的图5-7去除颜色后仍能表示魔方的状态,其原理是魔方颜色与位置坐标系建立了关系,在3.3节中的魔方表面的转动标识符相当于位置坐标系,魔方与魔方转动标识符的关系,就像是鱼与鱼缸的关系,鱼是可以自由游动的,鱼缸是静止不动的,鱼代指可随意转运的魔方,而鱼缸代指魔方转动标识符是静止不动的,以鱼缸为参考,就可得知鱼在鱼缸的什么位置,同样以魔方转动标识符为参考,就可得魔方块在不同位置的颜色分布。

由此,去除魔方颜色后仍能表示魔方的状态,也就是说PLL阶段的颜色其实不需要,同特征颜色识别也是可以去掉的,但为了方便理解所以还是将颜色部分陈述了出来,首先,还是将F2L的41公式转换为魔方字符串且去除颜色后,如无特殊说明,下面所调用的都是以蓝红棱块与白蓝红角块为例所进行的,如下图5-10所示:

图5-10  F2L公式字符串

在上述中得知,F2L的情况不止41种,故先要将非标F2L转换为标准F2L,而在5.3中已经说明了F2L的非标公式是如何进行转换的,下面就来实现。

图5-11  F2L范围判定

在上图5-11中,读取到F2L魔方块情况,如F:R:RUB:FR,则先判断是否为F2L的情况,若是则转换为一个数字编号,不是则调用unF2LNoU函数与unF2LStr函数将非标F2L转换为标准F2L,等转换为F2L后,再进行标准F2L公式的套用。

图5-12  F2L的读取与转换

在上图5-12中,以参数为3调用readF2Larr,则读取到F2L的蓝红棱角块情况,再经过图5-11的范围判断,是否为标准F2L,若是则不处理,不是则转换为标准F2L,转换原理在5.3节中有详细的介绍,转换函数为unF2LStr和unF2LNoU两个函数, isCenterU函数作为这两个函数的基础函数。

在完成F2L非标转换后,接下来主就是F2L公式的套用,这里分为两大类,一类是棱块与角块的位置在第一、二层都正确,则无需进行U操作;第二类是有魔方块在第三层,这类又分为三种情况,分别为棱块在第三层转动、角块在第三层转动、棱块和角块都在第三层转动,都需进行U操作的匹配,其中reStrF2L函数就可利用传入的参数不同,从而模拟三种不同情况对魔方U操作的转动,魔方字符串的部分字符也随之变化,这两种类型分别对应着F2LRange函数的0、1、2、3代码返回情况。

如下图5-13中,左边的代码是U操作的匹配,右边的代码是y操作的匹配,在F2LRestore中可以看出,先进行四次U操作匹配,匹配上了则返回结果,匹配不上则进行一次y操作改变F面,再进行四次U操作匹配,上述过程重复16次则完成一条F2L公式的匹配,直至41条F2L公式全部匹配完成,这样F2L阶段的算法全部实现。

图5-13  F2L公式的匹配

5魔方游戏实现与展示

5.1魔方总体框架介绍

开发这个魔方游戏的初忠是让新手能够,更加容易理解魔方的还原基础,快速入门三阶魔方的还原,在玩与学中轻松学会CFOP复原方法。

图6-1  魔方游戏原型设计

如上图6-1所示,图的左上角为目标魔方预览图,共有四幅图分别对应着CFOP复原法的四个阶段,在实际开发中会将其转换为真实的魔方模型,用不同的贴图表示魔方不同的阶段,而魔方的转动方式有很多种,但却只有18种类型,每一种类型分为顺、逆时针两种转动方式,在原型设计中设置了四种为顺时针旋转90度(M)、逆时针旋转90度(M’)、顺时针旋转180度(M2)、逆时针旋转180度(M’2),后面实际开发时发现对操作十分不友好,则只保留了顺时针旋转90度与逆时针旋转90度,默认为顺时针旋转90度,按住ctrl钮切换为逆时针旋转90度,而中间的灰色区域则是一个可操作的虚拟魔方。

 5.2魔方游戏的基础实现

在开始时只想实现魔方的转动,实现魔方的转动首先就要有一个魔方才能操作,则先创建一个虚拟魔方(3.1节中有详细说明),创建完成后仅仅是个模型,要有相应的逻辑才能使魔方转起来,则创建转动逻辑(3.1节与3.2节中有详细说明),这样魔方的转动就解决了,18个按钮默认为顺时针旋转,按下ctrl钮时,旋转方式为逆时针旋转,每个按钮上的字符都会加多一个’字符,如F字符会变为F’字符,当然魔方仅仅会转动是远远不够的,正如实现生活当中,魔方是可以360无死角的观看的,故虚拟魔方也要做到这一点,实现思路是把摄像机当成一个人的眼睛,虚拟魔方在原地不动,摄像机围着这虚拟魔方观看,则按住alt钮加鼠标移动就可360无死角的观察虚拟魔方,这样魔方的游戏的第一版就出来了,如下图6-2所示:

图6-2  第一版魔方游戏

但360无死角的观察功能的出现,也导致了一个问题,那就是分不清楚那面跟那面,如图6-2所示这是魔方游戏刚开始时,绿色面作为F面,对魔方进行F’操作所形成的图,但当你对魔方进行x、y、z操作时,魔方的F面也会随之改变,转到最后你根本分不清那面跟那面,就像是一个不标注点数的骰子,那投掷出的点数是多少就成了一个迷,所以需要一个参照物来确认魔方的方位,由于魔方的第二版就出来了,如下图6-3所示:

图6-3  第二版魔方游戏

在上图6-3中,默认的F面是绿色面,当魔方不进行x/y/z操作时,魔方的绿色面始终作为F面,其余15种操作均不会F面的改变,只有x、y、z才能造成F面的改变,除此之外,魔方的手动打乱很麻烦,故推出随机打乱魔方功能;魔方还原到一半时,不小心转乱了又不想重来,故推出魔方状态保存及魔方状态复原功能;魔方难以设置F面,故推出双击魔方转动标识符快速设F面功能;魔方的视角不好观察,故推出标准魔方视角功能,在魔方状态复原后,视角自动变为标准视角(如上图6-3的魔方视角),双击该中心块后,这中心块所在的面设为F面,视角也自动变为标准视角,由此魔方游戏已经初有成果了,但想要教学他人复原魔方仍有很大的距离,需要有算法的支持,故在第四和第五章详细讲述了CFOP算法的实现。

5.3魔方游戏的进阶实现

这是魔方游戏的第三版也是最后一版,我所想的是怎样才能更好的教学,俗语说实践出真知,所以我采用了此教学方法,将魔方的还原分为四个步骤:Cross、F2L、OLL、PLL,在大多数不会复原的情况下,点击公式提示功能,能够给出下一步正确的还原公式,但由于Cross是没有公式的,对新手来讲是比较难的,对老手来讲很简单,故可以选择性跳过,等学会后面三个阶段再回来学,这里提供了一键Cross功能,一键Cross功能可以自动复原Cross阶段进入F2L阶段。

如下图6-4中界面,中间的操作魔方处于混乱状态,魔方提示框标注了还原阶段与还原目标,但无还原公式,左上角展示的是Cross阶段的魔方还原目标(白色底十字架),按v键加鼠标同样可以360度无死角的观察左上角的目标魔方,取消查看后视角自动复原为标准视角,在这里高手可以手动还原Cross阶段,小白可以按底十字一键Cross功能,但注意只有黄色中心块处于U面时,后续的魔方公式提示刷新功能才能生效。

图6-4  Cross阶段魔方复原

完成Cross阶段后,魔方还原目标变为F2L阶段(底两层还原),若是标准F2L情况,仍会出现F面不对及顶层方位不对的情况,如下图6-5中第二幅图中,魔方公式框的左边的前置公式提示会出现y y U,用公式进行调整后,得到了图6-5的第三幅图,此时的魔方才能套用F2L公式。

图6-5  F2L阶段还原

除了标准F2L情况外,更多的是非标F2L情况,但非标F2L只需要进行一、二步的转换,就可以从非标F2L转换为标准F2L,如图6-5中的第一幅图,魔方的提示框中并没有出现公式图片,公式框的左边的前置公式提示会出现了F U F’ 的提示,用前置公式对魔方进行转动后,魔方情况变为了图6-5的第二幅图,接下来按标准F2L情况处理即可。

当然,要达到F2L阶段的还原目标(底两层还原),需要还原的是4组棱、角块,所以在魔方公式提示框中有上下选择的按钮,这两个按钮只有在F2L阶段才会生效,选择你想还原的棱、角块组合,同时图6-5中的三幅图,左上角展示的都是F2L阶段的魔方还原目标(底两层还原),在F2L阶段左上角目标魔方都不会变,直到还原到其它阶段,这样魔方的F2L阶段的还原就介绍完了。

图6-6  OLL阶段与PLL阶段

如上图6-6所示,第一幅图是OLL阶段,第二图是PLL阶段,两者很是相似,都有着F面错位的可能,当F面错位时,左边的魔方前置公式提示框会给出修复F面错位的公式,使用此公式调整F面正确后,才能正确的套用OLL/PLL公式。

同时,还原目标同为顶层魔方块,OLL调整的是顶层魔方块的旋转状态,PLL调整的是顶层魔方块的位置顺序,而在PLL完成后其实还有一个小阶段,就是顶层的整体有可能位置不对,即对已复原魔方的黄色顶层进行U、U U、U’操作可能得到的结果,这里为了简便合并到了PLL阶段,则OLL左上角显示的是顶层黄色块翻色目标魔方,而PLL左上角显示的是魔方已复原的目标魔方,两者套用公式方式是一致的,有前置公式则说明当前F面不正确,先要套用前置公式,没有则不套用,然后再套用匹配出的OLL/PLL公式,这样魔方的游戏实现在这里就介绍完毕了。

结论与展望

3.1  结论

这魔方游戏起源于我的一个渺小的想法,如何让魔方入门变的更加的简单,由是开始了对这魔方游戏日以继业的编写,其中最难的就是对魔方的状态进行读取的问题,当时就是二和尚摸不着头脑,根据想不出办法,后来随着思考的深入,渐渐意识到魔方块的旋转状态与其魔方块的位置可能存在某种关系,在不断尝试和机缘巧合下,最终推理出魔方状态表示方式和魔方状态的读取方法,在这个最大问题解决后,其中当初许多认为不可能解决的问题也都迎刃而解,而魔方状态读取和CFOP公式匹配是本论文中最大的创新点,也是本论文的精髓所在。

3.2  展望

魔方游戏我投入了太多的精力,当然结果也是我所期望的,但其实能做的更好,可以让魔方游戏的公式匹配能智能的刷新,而不用手动刷新,可以与现实中的魔方产生联动, 联动方式有二种,一种是魔方填色系统,另一种是利用硬件直接进行联动,我个人更倾向第二种,用MR技术与现实的魔方产生互动,一步一步指导你将魔方拼好,还能教导你魔方正确的还原指法及魔方公式训练提速等,这才是我想要的智能魔方,但这是跨学科与跨专业的解决方式,光靠我一个人很难解决,但也不防碍我对魔方未来的畅想,因为我知道只有登上山顶,才能看到那边的风光。

致 谢

在本论文即将完成之际,谨此向我的导师致以衷心的感谢和崇高的敬意!在攻读本科的这三年里,母校为我提供了优越的学习环境和生活环境,使我得以在计算机科学领域中自由翱翔;老师们的悉心指导,在思想上、人生态度和意志品质方面给予了谆谆教诲,这些教益必将激励着我在今后的人生道路上奋勇向前;父母长久的陪伴、温暖的关怀给予我在人生道路不断向前的力量。

       此魔方算法由我一人独立完成,在此期间曾多次想过放弃,但很庆幸,我坚持了下来,并完成了它,很是感谢曾经的自己,有着不达目的誓不罢休的信念,有着在凌晨时分仍能默默编写代码行动力,同时我还要感谢我的学校和老师们,还有我的父母,感谢这个本科阶段你们陪伴我一起成长的岁月,忘不掉你们对我的谆谆教导,忘不掉你们温暖的关怀。

最后,衷心地感谢为评阅本论文而付出宝贵时间和辛勤劳动的专家和教授们!

参  考  文  献

[1]梁小龙. 解魔方算法的研究和系统实现[D].东北大学,2013.

[2]卢昌海. 魔方与 “上帝之数”[EB/OL].

https://changhai.org/articles/science/mathematics/rubikcube.php,2014-09-18

[3] imofang. 魔方的配色方案和色号[EB/OL].

http://www.i-mofang.com/i/?id=24,2016-07-02

[4]Rand_CS. 魔方还原算法(一) 概述[EB/OL].

https://blog.csdn.net/weixin_46645613/article/details/117479516, 2021-06-02

猜你喜欢

转载自blog.csdn.net/qq_39858654/article/details/128757231
今日推荐