用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 相关文章推荐
Python内置函数bin() oct()等实现进制转换
Dec 30 Python
Python下线程之间的共享和释放示例
May 04 Python
python3+PyQt5实现文档打印功能
Apr 24 Python
python字符串与url编码的转换实例
May 10 Python
python解决字符串倒序输出的问题
Jun 25 Python
win7+Python3.5下scrapy的安装方法
Jul 31 Python
基于Python 中函数的 收集参数 机制
Dec 21 Python
Python 中@property的用法详解
Jan 15 Python
Python各种扩展名区别点整理
Feb 27 Python
python 在sql语句中使用%s,%d,%f说明
Jun 06 Python
plt.figure()参数使用详解及运行演示
Jan 08 Python
Python并发编程实例教程之线程的玩法
Jun 20 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
极典R601SW收音机
2021/03/02 无线电
基于PHP的cURL快速入门教程 (小偷采集程序)
2011/06/02 PHP
php Calender(日历)代码分享
2014/01/03 PHP
搭建Vim为自定义的PHP开发工具的一些技巧
2015/12/11 PHP
php实现的简单数据库操作Model类
2016/11/16 PHP
详解laravel passport OAuth2.0的4种模式
2019/11/04 PHP
js版本A*寻路算法
2006/12/22 Javascript
用javascript实现的支持lrc歌词的播放器
2007/05/17 Javascript
javascript中定义类的方法详解
2015/02/10 Javascript
js实现简单计算器
2015/11/22 Javascript
jQuery动画效果相关方法实例分析
2015/12/31 Javascript
JS中BOM相关知识点总结(必看篇)
2016/11/22 Javascript
如何用js判断dom是否有存在某class的值
2017/02/13 Javascript
基于vue的fullpage.js单页滚动插件
2017/03/20 Javascript
微信小程序开发之麦克风动画 帧动画 放大 淡出
2017/04/18 Javascript
使用webpack搭建react开发环境的方法
2018/05/15 Javascript
详解VUE中常用的几种import(模块、文件)引入方式
2018/07/03 Javascript
对angularJs中2种自定义服务的实例讲解
2018/09/30 Javascript
vue实现与安卓、IOS交互的方法
2018/11/02 Javascript
axios如何利用promise无痛刷新token的实现方法
2019/08/27 Javascript
微信小程序 冒泡事件原理解析
2019/09/27 Javascript
vue中渲染对象中属性时显示未定义的解决
2020/07/31 Javascript
Python端口扫描简单程序
2016/11/10 Python
python编程实现希尔排序
2017/04/13 Python
django ajax json的实例代码
2018/05/29 Python
详解爬虫被封的问题
2019/04/23 Python
python opencv实现gif图片分解的示例代码
2019/12/13 Python
pytorch实现MNIST手写体识别
2020/02/14 Python
浅谈django框架集成swagger以及自定义参数问题
2020/07/07 Python
详解CSS3 Media Queries中媒体属性的使用
2016/02/29 HTML / CSS
英国奢侈品在线精品店:Hervia
2020/09/03 全球购物
应聘医学检验人员自荐信
2013/09/27 职场文书
酒店销售主管岗位职责
2014/01/04 职场文书
员工工作表扬信
2015/05/05 职场文书
Python利用zhdate模块实现农历日期处理
2022/03/31 Python
Python 读取千万级数据自动写入 MySQL 数据库
2022/06/28 Python