- 最后登录
- 2024-11-21
- 在线时间
- 938 小时
- 阅读权限
- 40
- 注册时间
- 2008-1-6
- 积分
- 1960
- 帖子
- 1075
- 精华
- 6
- UID
- 17579
- 性别
- 保密
- 积分
- 1960
- 帖子
- 1075
- 精华
- 6
- UID
- 17579
- 性别
- 保密
|
第五层也要,好了,不占楼了。
如果支持者有10位以上,就开始分析了。
感谢大家的支持
夜雨听风
329774632
AlphaCB
mengfl
斜月
yanzi7816
今夜微凉
zbyxzh
dangerxxxx
r_517
臭虫
superflip
superacid
铯_猪哥恐鸣
ggglgq
cube_master
-----------------------------
6.faceletcube
这个类的定义在facecube.cpp中,名称容易引起误会。
let-表示小,facelet是指一个一个的小色块。
我就干脆称其为贴纸了。这个是贴纸水平的魔方。
表现在程序中就是:用户输入一个一个的颜色,程序给魔方贴贴纸。
在有GUI的程序中,就表现为着色了。
一旦用户着色完毕,我们要还原魔方了。没有见过机器人还原魔方的
朋友总是会问:“我把装错了的魔方给机器人,不知道会怎样”。人
们总是好奇的,期望着看笑话。所以,我们程序的第一步,肯定是:
检查着色正确与否,然后还要检查组装正确与否,不然的话,瞎转半天,
不能还原都不知道。
如果不希望做这些步骤,那么可以一开始就用一个完整的魔方,让用户
输入打乱,而不是贴纸颜色;问题是,想还原一个已经打乱的魔方,又
不知道打乱公式,那怎么玩?鸡生蛋,蛋生鸡... ...
检查参数是为了保证数据的完整性。
这个贴纸层的魔方公开的方法有:
着色、检查、输出错误信息、输出魔方的状态、面的名称变为数字。
着色的方法提供给parser用,parser从命令行接受到数据,解开,着色。
输出错误信息、输出魔方状态是很自然要做的。
面的名称变成数字,是这样的顺序 UDLRFB-012345
这个类中,重点是检查,比较精彩的代码也在这里,检查的内容包括:
中心、贴纸、角、棱、角和棱一起。
中心看是否有六个,每个要唯一,不能重复;
贴纸看是否每种颜色都是9片;
角看旋转方向加起来是否被3整除,不整除就是错的;
棱看翻转方向加起来是否被2整除,不整除也是错的;
检查方向其实是很繁琐的事情,这部分工作要格外细致。
角和棱一起,就看是否组装成只有两角交换没有棱陪伴的情况--孤立Parity。
代码中,检查Parity的一段最精彩。没有读过这段代码的朋友,可以试想一下:
你会怎样检查呢?
代码中的方法很朴实,但很有效。一般还想不到,很难想到。
我以前的程序,检查的时候竟然先编了一个盲拧的编码,然后看编码是否正确。冤。
作者的用这个方法很好,值得我们学习。
看过以后,就知道是怎么实现的。隐约知道是正确的。但为什么正确,就讲不清楚了。
请何方高人讲透彻一些?为什么排列中,元素向后两两比较的结果可以用来计算是否有Parity?
关键段落:
// Permutation parity can be computed by counting the number of
// reversals in the permutation sequence, - i.e., the number
// of pairs (p,q) such that p>q and p precedes q. Then
// determine if the result is even or odd. Do this for both
// edges (EPP) and corners (CPP). A configuration is reachable
// if EPP=CPP. (August/September cube.lovers - Vanderschel/Saxe)
int FaceletCube:: PermutationParity(int* permutations, int numberOfCubies)
{
int p, q;
int permutationParity = 0;
for (p = 0; p < numberOfCubies-1; p++)
{
for (q = p+1; q < numberOfCubies; q++)
{
if (permutations[p] > permutations[q])
permutationParity++;
}
}
return permutationParity%2;
}
棱和角都有Parity或者都没有parity,就是正确的。
出现孤立Parity是组装错误。
facecube.h中有一宏值得推荐
#define FacesToCorner(face1, face2, face3) (((face1*6)+face2)*6+face3)
#define FacesToEdge(face1, face2) (face1*6+face2)
这个是传说中的秦九韶记法,很花俏的。
(下转31楼)
[ 本帖最后由 aubell 于 2010-4-19 12:53 编辑 ] |
-
总评分: 经验 + 10
查看全部评分
|