一行代码“玩转”魔方 | Python 实战
唠唠闲话
在 B 站看到一个用 Python 复原魔方的视频,觉得还蛮有意思,就自己动手写了个工具,附代码地址。废话不多说,先看演示吧。
-
随机打乱一个魔方
-
导入工具,一行代码还原魔方
1
2from rubik import *
Cube().auto_solve_cube(wait=False)
使用介绍
安装依赖
-
安装 Python 包
1
2pip install pyautogui # 安装自动化工具
pip install kociemba # 安装魔方工具 -
Ubuntu 系统还需安装 scrot,用于截图
1
sudo apt-get install scrot
-
搜索安装谷歌浏览器的插件
Rubik
使用方法
-
打开浏览器插件,双击进入准备状态
-
初始化类对象
Cube
,检测魔方位置1
2from rubik import *
cube = Cude() -
查看魔方定位是否正确
1
cube.show_detection()
-
检查小面位置
1
cube.check_facets()
-
检查基本旋转
1
cube.check_basic_moves() # 检查基本旋转是否正确
-
识别魔方状态,并打印展开图
1
2
3# 获取小面分布信息
state = cube.get_cube_distribution(string_code=True)
print(expand_cube(state)) -
识别并求解魔方
1
cube.auto_solve_cube()
-
构造给定魔方状态
1
2state = "UBRLUFFUBLRUFRLLLRDBDRFDBBUDDBUDDLRFBFLDLBFFRFLRUBRDUU"
cube.to_cube_state(state)
文件说明
-
src
目录下有四个文件文件名 说明介绍 rubik.py
类对象 Cube
tools.py
函数工具 data.py
记录魔方的色块等信息 scale_match.py
支持比例放缩的图像检测 -
demo
目录下文件名 说明介绍 demo.jupyter
演示文档 quick_start.py
快捷调用
工具原理
分两部分内容:
pyautogui + cv2
检测魔方位置,识别魔方状态,执行电脑操作kociemba
调用魔方算法
原理细节
-
图像检测,识别魔方位置
-
计算中心位置 + 中心边长,并推导其他位置信息
-
魔方状态码
- 魔方状态码由字母
URFDLB
构成,分别代表魔方六个面,其中 U 为顶面(up),R 为右面(right),F 为正面(Front),D 为顶面(down),L 为左面(Left),B 为背面(Back) - 状态码按如下展开图的标号顺序读入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21|************|
|*U1**U2**U3*|
|************|
|*U4**U5**U6*|
|************|
|*U7**U8**U9*|
|************|
************|************|************|************
*L1**L2**L3*|*F1**F2**F3*|*R1**R2**R3*|*B1**B2**B3*
************|************|************|************
*L4**L5**L6*|*F4**F5**F6*|*R4**R5**R6*|*B4**B5**B6*
************|************|************|************
*L7**L8**L9*|*F7**F8**F9*|*R7**R8**R9*|*B7**B8**B9*
************|************|************|************
|************|
|*D1**D2**D3*|
|************|
|*D4**D5**D6*|
|************|
|*D7**D8**D9*|
|************| - 比如还原状态为
UUUUUUUUURRRRRRRRRFFFFFFFFFDDDDDDDDDLLLLLLLLLBBBBBBBBB
- 魔方状态码由字母
-
识别魔方状态:
- 将正视图的三面视为
U, L, F
,截图识别颜色分布
- 滑动到背面,获取后三面的颜色分布
- 两部分信息整合,导出魔方状态码
- 将正视图的三面视为
-
魔方公式
- 调用函数
kociemba.solve
,获取魔方公式 - 魔方公式为
U, U', U2, R, R', R2...
等构成的列表 - 其中
U, U', U2
分别代表顶面顺时针旋转 90°,逆时针旋转 90°,以及旋转旋转 180°,其他各面规则同理
- 调用函数
-
将公式实现为操作
- 由小面位置和基本向量计算位置参数
- 用 pyautogui 的函数
moveTo
和dragRel
实现鼠标移动和拖拽
由于函数间需频繁共享位置数据,因而使用面向对象编程,数据作为属性,函数作为方法。
写在最后
这是寒假在家随手做的实战,代码在 Ubuntu 上测试通过,其他平台没有尝试,如果遇到问题欢迎评论交流~
附:代码地址 rubik_cube.py
文章采用 CC BY-NC-SA 4.0 许可协议,转载请注明来自 学习乐园!
评论