唠唠闲话

在 B 站看到一个用 Python 复原魔方的视频,觉得还蛮有意思,就自己动手写了个工具,附代码地址。废话不多说,先看演示吧。

  1. 随机打乱一个魔方

  2. 导入工具,一行代码还原魔方

    1
    2
    from rubik import *
    Cube().auto_solve_cube(wait=False)

使用介绍

安装依赖

  1. 安装 Python 包

    1
    2
    pip install pyautogui # 安装自动化工具
    pip install kociemba # 安装魔方工具
  2. Ubuntu 系统还需安装 scrot,用于截图

    1
    sudo apt-get install scrot
  3. 搜索安装谷歌浏览器的插件 Rubik
    深度截图_选择区域_20220128171120

使用方法

  1. 打开浏览器插件,双击进入准备状态
    20220419174040

  2. 初始化类对象 Cube,检测魔方位置

    1
    2
    from rubik import *
    cube = Cude()
  3. 查看魔方定位是否正确

    1
    cube.show_detection()

    output

  4. 检查小面位置

    1
    cube.check_facets()
  5. 检查基本旋转

    1
    cube.check_basic_moves() # 检查基本旋转是否正确
  6. 识别魔方状态,并打印展开图

    1
    2
    3
    # 获取小面分布信息
    state = cube.get_cube_distribution(string_code=True)
    print(expand_cube(state))
  7. 识别并求解魔方

    1
    cube.auto_solve_cube()
  8. 构造给定魔方状态

    1
    2
    state = "UBRLUFFUBLRUFRLLLRDBDRFDBBUDDBUDDLRFBFLDLBFFRFLRUBRDUU"
    cube.to_cube_state(state)

文件说明

  1. src 目录下有四个文件

    文件名 说明介绍
    rubik.py 类对象 Cube
    tools.py 函数工具
    data.py 记录魔方的色块等信息
    scale_match.py 支持比例放缩的图像检测
  2. demo 目录下

    文件名 说明介绍
    demo.jupyter 演示文档
    quick_start.py 快捷调用

工具原理

分两部分内容:

  • pyautogui + cv2 检测魔方位置,识别魔方状态,执行电脑操作
  • kociemba 调用魔方算法

原理细节

  1. 图像检测,识别魔方位置
    test

  2. 计算中心位置 + 中心边长,并推导其他位置信息

  3. 魔方状态码

    • 魔方状态码由字母 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
  4. 识别魔方状态:

    • 将正视图的三面视为 U, L, F,截图识别颜色分布
    • 滑动到背面,获取后三面的颜色分布
    • 两部分信息整合,导出魔方状态码
  5. 魔方公式

    • 调用函数 kociemba.solve ,获取魔方公式
    • 魔方公式为 U, U', U2, R, R', R2... 等构成的列表
    • 其中 U, U', U2 分别代表顶面顺时针旋转 90°,逆时针旋转 90°,以及旋转旋转 180°,其他各面规则同理
  6. 将公式实现为操作

    • 由小面位置和基本向量计算位置参数
    • 用 pyautogui 的函数 moveTodragRel 实现鼠标移动和拖拽

由于函数间需频繁共享位置数据,因而使用面向对象编程,数据作为属性,函数作为方法。


写在最后

这是寒假在家随手做的实战,代码在 Ubuntu 上测试通过,其他平台没有尝试,如果遇到问题欢迎评论交流~

附:代码地址 rubik_cube.py