用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 相关文章推荐
Python3基础之条件与循环控制实例解析
Aug 13 Python
Python使用shelve模块实现简单数据存储的方法
May 20 Python
各个系统下的Python解释器相关安装方法
Oct 12 Python
基于Python的XSS测试工具XSStrike使用方法
Jul 29 Python
python 3.7.0 下pillow安装方法
Aug 27 Python
对pyqt5之menu和action的使用详解
Jun 20 Python
大家都说好用的Python命令行库click的使用
Nov 07 Python
Python3监控windows,linux系统的CPU、硬盘、内存使用率和各个端口的开启情况详细代码实例
Mar 18 Python
深入了解NumPy 高级索引
Jul 24 Python
Python3读写ini配置文件的示例
Nov 06 Python
python使用PySimpleGUI设置进度条及控件使用
Jun 10 Python
python百行代码实现汉服圈图片爬取
Nov 23 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
一条久听不愿放下的DIY森海MX500,三言两语话神奇
2021/03/02 无线电
咖啡知识 咖啡养豆要养多久 排气又是什么
2021/03/06 新手入门
用PHP书写安全的脚本代码
2012/02/05 PHP
PHP编程中的__clone()方法使用详解
2015/11/27 PHP
php 无限级分类 获取顶级分类ID
2016/03/13 PHP
php使用str_shuffle()函数生成随机字符串的方法分析
2017/02/17 PHP
PHP实现的简单组词算法示例
2018/04/10 PHP
PHP的PDO错误与错误处理
2019/01/27 PHP
js模拟弹出效果代码修正版
2008/08/07 Javascript
JavaScript 笔记二 Array和Date对象方法
2010/05/22 Javascript
JavaScript学习历程和心得小结
2010/08/16 Javascript
Prototype源码浅析 Enumerable部分之each方法
2012/01/16 Javascript
jquery拖动插件(jquery.drag)使用介绍
2013/06/18 Javascript
jquery实现叠层3D文字特效代码分享
2015/08/21 Javascript
jquery实现select选择框内容左右移动代码分享
2015/11/21 Javascript
基于javascript实现图片预加载
2016/01/05 Javascript
canvas实现手机端用来上传用户头像的代码
2016/10/20 Javascript
JavaScript使用atan2来绘制箭头和曲线的实例
2017/09/14 Javascript
浅谈Vue Element中Select下拉框选取值的问题
2018/03/01 Javascript
Node.js动手撸一个静态资源服务器的方法
2019/03/09 Javascript
jQuery删除/清空指定元素的所有子节点实例代码
2019/07/04 jQuery
Vue 根据条件判断van-tab的显示方式
2020/08/03 Javascript
Vue使用轮询定时发送请求代码
2020/08/10 Javascript
解决Python传递中文参数的问题
2015/08/04 Python
详谈套接字中SO_REUSEPORT和SO_REUSEADDR的区别
2018/04/28 Python
Python3.x爬虫下载网页图片的实例讲解
2018/05/22 Python
windows下搭建python scrapy爬虫框架步骤
2018/12/23 Python
浅析matlab中imadjust函数
2020/02/27 Python
python实现引用其他路径包里面的模块
2020/03/09 Python
python else语句在循环中的运用详解
2020/07/06 Python
python爬虫beautifulsoup解析html方法
2020/12/07 Python
python画图时设置分辨率和画布大小的实现(plt.figure())
2021/01/08 Python
详解使用双缓存解决Canvas clearRect引起的闪屏问题
2019/04/29 HTML / CSS
英国门把手公司:Door Handle Company
2019/05/12 全球购物
幼儿园老师辞职信
2014/01/20 职场文书
悬崖上的金鱼姬观后感
2015/06/15 职场文书