用Python简陋模拟n阶魔方


Posted in Python onApril 17, 2021

一、前言

终于整完了毕业论文,忙里偷闲半小时摸了个魔方模拟程序,支持模拟任意阶魔方,自动打乱,输入指令旋转。显示方面不会弄3D的,用opencv整了个展开图。

用Python简陋模拟n阶魔方

二、效果

五阶魔方打乱20步

用Python简陋模拟n阶魔方

震撼人心50阶,打乱100步

用Python简陋模拟n阶魔方

三、代码

import cv2
import numpy as np
from random import randint


class Cube:
    def __init__(self, order=3, size=50):  # 魔方阶数、显示尺寸
        self.img = np.zeros((4 * size * order, 3 * size * order, 3), dtype=np.uint8)
        self.order = order
        self.size = size
        self.len = size * order
        self.top = [['y'] * order for _ in range(order)]
        self.front = [['r'] * order for _ in range(order)]
        self.left = [['b'] * order for _ in range(order)]
        self.right = [['g'] * order for _ in range(order)]
        self.back = [['o'] * order for _ in range(order)]
        self.bottom = [['w'] * order for _ in range(order)]
        self.axis_rotate = (self.base_rotate_x, self.base_rotate_y, self.base_rotate_z)
        self.color = {'y': (0, 255, 255), 'r': (0, 0, 255), 'b': (255, 0, 0),
                      'g': (0, 255, 0), 'o': (0, 128, 255), 'w': (255, 255, 255)}

    def check(self):  # 检测魔方是否还原
        for i in range(self.order):
            for j in range(self.order):
                if self.top[i][j] != self.top[0][0]:
                    return False
                if self.back[i][j] != self.back[0][0]:
                    return False
                if self.front[i][j] != self.front[0][0]:
                    return False
                if self.left[i][j] != self.left[0][0]:
                    return False
                if self.right[i][j] != self.right[0][0]:
                    return False
                if self.bottom[i][j] != self.bottom[0][0]:
                    return False
        return True

    def show(self, wait=0):  # 显示魔方展开图
        for i in range(self.order):
            for j in range(self.order):
                # back
                x, y = self.len + i * self.size, j * self.size
                cv2.rectangle(self.img, (x, y), (x + self.size, y + self.size), self.color[self.back[j][i]], -1)
                cv2.rectangle(self.img, (x, y), (x + self.size, y + self.size), (10, 10, 10), 1)
                # left
                x, y = i * self.size, self.len + j * self.size
                cv2.rectangle(self.img, (x, y), (x + self.size, y + self.size), self.color[self.left[j][i]], -1)
                cv2.rectangle(self.img, (x, y), (x + self.size, y + self.size), (10, 10, 10), 1)
                # top
                x, y = self.len + i * self.size, self.len + j * self.size
                cv2.rectangle(self.img, (x, y), (x + self.size, y + self.size), self.color[self.top[j][i]], -1)
                cv2.rectangle(self.img, (x, y), (x + self.size, y + self.size), (10, 10, 10), 1)
                # right
                x, y = 2 * self.len + i * self.size, self.len + j * self.size
                cv2.rectangle(self.img, (x, y), (x + self.size, y + self.size), self.color[self.right[j][i]], -1)
                cv2.rectangle(self.img, (x, y), (x + self.size, y + self.size), (10, 10, 10), 1)
                # front
                x, y = self.len + i * self.size, 2 * self.len + j * self.size
                cv2.rectangle(self.img, (x, y), (x + self.size, y + self.size), self.color[self.front[j][i]], -1)
                cv2.rectangle(self.img, (x, y), (x + self.size, y + self.size), (10, 10, 10), 1)
                # bottom
                x, y = self.len + i * self.size, 3 * self.len + j * self.size
                cv2.rectangle(self.img, (x, y), (x + self.size, y + self.size), self.color[self.bottom[j][i]], -1)
                cv2.rectangle(self.img, (x, y), (x + self.size, y + self.size), (10, 10, 10), 1)
        cv2.imshow('cube', self.img)
        cv2.waitKey(wait)

    def shuffle(self, times):  # 打乱魔方
        for _ in range(times):
            self.rotate(randint(0, 2), randint(0, self.order - 1), randint(0, 3))

    def rotate(self, axis, index, times):  # 旋转魔方:axis轴,第index层,逆时针times次
        for _ in range(times):
            self.axis_rotate[axis](index)

    def count(self, color='y'):
        count = 0
        for i in range(self.order):
            for j in range(self.order):
                if self.top[i][j] == color:
                    count += 1
        return count

    @staticmethod
    def _column_trans(surface, index, col):
        for i, r in enumerate(surface):
            r[index] = col[i]

    def base_rotate_x(self, index):
        if index == 0:
            self.left = [list(c) for c in zip(*self.left)][::-1]
        elif index == self.order - 1:
            self.right = [list(c)[::-1] for c in zip(*self.right)]
        temp = [r[index] for r in self.top]
        self._column_trans(self.top, index, [r[index] for r in self.front])
        self._column_trans(self.front, index, [r[index] for r in self.bottom])
        self._column_trans(self.bottom, index, [r[index] for r in self.back])
        self._column_trans(self.back, index, temp)

    def base_rotate_y(self, index):
        if index == 0:
            self.back = [list(c)[::-1] for c in zip(*self.back)]
        elif index == self.order - 1:
            self.front = [list(c) for c in zip(*self.front)][::-1]
        temp = self.left[index][::-1]
        self.left[index] = self.top[index]
        self.top[index] = self.right[index]
        self.right[index] = self.bottom[self.order - index - 1][::-1]
        self.bottom[self.order - index - 1] = temp

    def base_rotate_z(self, index):
        if index == 0:
            self.top = [list(c) for c in zip(*self.top)][::-1]
        elif index == self.order - 1:
            self.bottom = [list(c)[::-1] for c in zip(*self.bottom)]
        temp = self.front[index][::-1]
        self.front[index] = [r[self.order - index - 1] for r in self.left]
        self._column_trans(self.left, self.order - index - 1, self.back[self.order - index - 1][::-1])
        self.back[self.order - index - 1] = [r[index] for r in self.right]
        self._column_trans(self.right, index, temp)


cube = Cube(3, 50)
cube.shuffle(100)
while True:
    cube.show(1)
    cube.rotate(*(int(c) for c in input('axis,index,times:').split()))
    if cube.check():
        break
print('Congratulations')
cube.show(0)

到此这篇关于用Python简陋模拟n阶魔方的文章就介绍到这了,更多相关pytho模拟魔方内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
wxPython框架类和面板类的使用实例
Sep 28 Python
老生常谈python之鸭子类和多态
Jun 13 Python
python 实现登录网页的操作方法
May 11 Python
Python BS4库的安装与使用详解
Aug 08 Python
python按行读取文件并找出其中指定字符串
Aug 08 Python
python批量读取文件名并写入txt文件中
Sep 05 Python
Flask中endpoint的理解(小结)
Dec 11 Python
浅谈Python的方法解析顺序(MRO)
Mar 05 Python
Python爬虫爬取微信朋友圈
Aug 06 Python
Selenium 安装和简单使用的实现
Dec 04 Python
详解Django的MVT设计模式
Apr 29 Python
Python机器学习之基础概述
May 19 Python
Python OpenCV快速入门教程
python小程序之飘落的银杏
Python Numpy之linspace用法说明
Apr 17 #Python
用Python的绘图库(matplotlib)绘制小波能量谱
用基于python的appium爬取b站直播消费记录
解决numpy数组互换两行及赋值的问题
Apr 17 #Python
用Python实现Newton插值法
Apr 17 #Python
You might like
PHP SPL标准库之数据结构栈(SplStack)介绍
2015/05/12 PHP
WordPress开发中短代码的实现及相关函数使用技巧
2016/01/05 PHP
谈谈PHP连接Access数据库的注意事项
2016/08/12 PHP
PHP PDOStatement::fetch讲解
2019/01/31 PHP
JavaScript iframe的相互操作浅析
2009/10/14 Javascript
13 个JavaScript 性能提升技巧分享
2012/07/26 Javascript
三种方式实现瀑布流布局
2017/02/10 Javascript
详解在Vue中通过自定义指令获取dom元素
2017/03/04 Javascript
jQuery用户头像裁剪插件cropbox.js使用详解
2017/06/07 jQuery
JS沙箱模式实例分析
2017/09/04 Javascript
vue项目中使用tinymce编辑器的步骤详解
2018/09/11 Javascript
vue中使用elementUI组件手动上传图片功能
2019/12/13 Javascript
vue项目创建步骤及路由router
2020/01/14 Javascript
安装多版本Vue-CLI的实现方法
2020/03/24 Javascript
JS数组降维的实现Array.prototype.concat.apply([], arr)
2020/04/28 Javascript
vue实现移动端项目多行文本溢出省略
2020/07/29 Javascript
解决vue addRoutes不生效问题
2020/08/04 Javascript
Vue+element-ui添加自定义右键菜单的方法示例
2020/12/08 Vue.js
[04:19]完美世界携手游戏风云打造 卡尔工作室模型介绍篇
2013/04/24 DOTA
浅谈pytorch和Numpy的区别以及相互转换方法
2018/07/26 Python
python根据list重命名文件夹里的所有文件实例
2018/10/25 Python
计算机二级python学习教程(1) 教大家如何学习python
2019/05/16 Python
pytorch读取图像数据转成opencv格式实例
2020/06/02 Python
python如何用matplotlib创建三维图表
2021/01/26 Python
Python使用tkinter制作在线翻译软件
2021/02/22 Python
使用Html5实现异步上传文件,支持跨域,带有上传进度条
2016/09/17 HTML / CSS
世界上最值得信赖的多日游在线市场:TourRadar
2018/07/20 全球购物
什么时候需要进行强制类型转换
2016/09/03 面试题
保密工作实施方案
2014/02/24 职场文书
服装采购员岗位职责
2014/03/15 职场文书
合作协议书怎么写
2014/04/18 职场文书
教师敬业奉献模范事迹材料
2014/05/18 职场文书
2014年小学国庆节活动方案
2014/09/16 职场文书
授权委托书(法人单位用)
2014/09/29 职场文书
2015年护士医德医风自我评价
2015/03/03 职场文书
巾帼建功标兵先进事迹材料
2016/02/29 职场文书