
起因
我儿子非常喜欢魔方。他能解 8×8 魔方,连号称世界上最难的魔方也解开过。我也想至少学会三阶魔方,但卡在了解法的第 8 步,原理也一直没怎么弄明白。
于是我决定做一个程序:在画面上直接做出魔方,用照片读取真实的魔方,再一步一步地展示解法。
3D 魔方
- 用 Qt6 和 OpenGL 绘制。用鼠标拖动时整个魔方旋转;左键点击某一格,那一层就左右转动,右键点击则上下转动。
- 起初,即使点同一格,有时转得对,有时却转反了。原因是魔方倾斜时,把正面和侧面判断错了。我们用旋转方向模拟器(simulate_moves)测试了所有方向之后才修好。
- 由于光照和阴影,白色看起来像灰色,底面看起来发黑,所以去掉了光照效果。
两张照片就能得到 54 格
从角的方向拍魔方,一张照片能看到三个面。再从相对的角拍一张,六个面就全部出来了。
- 照片 1:黄色朝上放置,拍上、前、右
- 照片 2:翻转成白色朝上,拍下、后、左
每个面的中心格无论怎么转都不会移动,所以用中心颜色来确定是哪个面。配色是上黄、下白、前绿、右橙、左红、后蓝。
规则检查
如果照片读错,就会得到一个实际上根本拼不出来的魔方。所以收到展开图后,先检查规则。
- 中心 6 格必须是规定的颜色。
- 8 个角块的三个面颜色必须各不相同,相对的颜色(黄与白、绿与蓝、红与橙)不能出现在同一个块上。
- 12 个棱块也按同样的方式检查,同一个块也不能出现两次。
不符合规则的格子用红色边框标出。点击那一格,周围会环形弹出六种颜色,可以马上修改。

这是读取韩国发售版魔方照片后的初始画面。红色边框就是不符合规则的格子。
求解
通过规则检查后,用 Kociemba 两阶段搜索求解。这不是人背的那种解法,而是利用预先生成的表来寻找短解的算法。用 25 步打乱的 60 个魔方全部解开了,平均 20.7 步,最长的解是 22 步。每次求解耗时的中位数是 6ms。用画面下方的“◀ 上一步 / 下一步 ▶”按钮可以一步一步地查看。
我们也做了一个更接近人类解法的初学者逐层求解器。但同样的 60 个中它只解开了 6 个(10%),解开的也要 203~311 步。所以应用先用 Kociemba,只有失败时才换用其他方法。

时间图表使用的是对数刻度。
这一阶段的实际代码
这是角块检查。三个面的颜色有重复时,三格都会被标出。
src/CubePhotoReconstructor.cpp
// 2) 코너 (8개): 세 면 색은 모두 달라야 하고, 서로 다른 축 색이어야 함
for (int x : {-1, 1}) {
for (int y : {-1, 1}) {
for (int z : {-1, 1}) {
const int fx = (x == 1) ? 0 : 1;
const int fy = (y == 1) ? 2 : 3;
const int fz = (z == 1) ? 4 : 5;
const int cx = colorOnFace(faces, fx, x, y, z);
const int cy = colorOnFace(faces, fy, x, y, z);
const int cz = colorOnFace(faces, fz, x, y, z);
if (cx < 0 || cy < 0 || cz < 0)
continue;
if (cx == cy || cy == cz || cx == cz) {
v.ok = false;
v.errors << QStringLiteral(
"· %1+%2+%3 모서리: 한 조각에 같은 색이 두 면 — "
"전개도에서 이 세 칸이 「왼|앞|오른」 접힘에 맞게 붙어 있는지 확인")
.arg(QString::fromUtf8(CubeModel::faceNameKo(fx)),
QString::fromUtf8(CubeModel::faceNameKo(fy)),
QString::fromUtf8(CubeModel::faceNameKo(fz)));
markCell(v, fx, x, y, z);
markCell(v, fy, x, y, z);
markCell(v, fz, x, y, z);
}求解时先调用 Kociemba。
src/Oracle.cpp
// 0) Kociemba two-phase — 임의 스크램블/사진 상태용 확실한 해법
if (!timedOut()) {
auto koc = KociembaSolver::solve(start, 24, 8);
if (!koc.empty())
return compress(koc);
}下一篇是“2. 用颜色分割代替 VLM,以及性格不同的两个魔方”。
COMMENTS · CHAPTER 01
制作 3D 魔方,并用两张照片读取状态 评论 0
还没有评论。阅读时有疑问或想补充的内容,欢迎留言。
发表评论前,请用 Google 开始并登记昵称和邮箱。
用 Google 开始