用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 相关文章推荐
使用C语言来扩展Python程序和Zope服务器的教程
Apr 14 Python
手把手教你用python抢票回家过年(代码简单)
Jan 21 Python
解决Pycharm下面出现No R interpreter defined的问题
Oct 29 Python
详解python项目实战:模拟登陆CSDN
Apr 04 Python
在Python中预先初始化列表内容和长度的实现
Nov 28 Python
Python函数的默认参数设计示例详解
Dec 01 Python
Python 批量读取文件中指定字符的实现
Mar 06 Python
Python 实现网课实时监控自动签到、打卡功能
Mar 12 Python
使用Keras实现Tensor的相乘和相加代码
Jun 18 Python
Python hashlib和hmac模块使用方法解析
Dec 08 Python
Python 带星号(* 或 **)的函数参数详解
Feb 23 Python
解决tensorflow模型压缩的问题_踩坑无数,总算搞定
Mar 02 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 FOR MYSQL 代码生成助手(根据Mysql里的字段自动生成类文件的)
2011/07/23 PHP
详解php中生成标准uuid(guid)的方法
2019/04/28 PHP
javascript编程起步(第三课)
2007/02/27 Javascript
event对象的方法 兼容多浏览器
2009/06/27 Javascript
一个网马的tips实现分析
2010/11/28 Javascript
Javascript实现动态菜单添加的实例代码
2013/07/05 Javascript
JS实现定时页面弹出类似QQ新闻的提示框
2013/11/07 Javascript
JS删除字符串中重复字符方法
2014/03/09 Javascript
jQuery函数map()和each()介绍及异同点分析
2014/11/08 Javascript
使用javascript实现雪花飘落的效果
2015/01/13 Javascript
Node.js编写组件的三种实现方式
2016/02/25 Javascript
不同js异步函数同步的实现方法
2016/05/28 Javascript
jQuery滚动条美化插件nicescroll简单用法示例
2018/04/18 jQuery
微信小程序仿今日头条导航栏滚动解析
2019/08/20 Javascript
浅谈layui 数据表格前后台传值的问题
2019/09/12 Javascript
微信小程序实现Swiper轮播图效果
2019/11/22 Javascript
vue-cli4项目开启eslint保存时自动格式问题
2020/07/13 Javascript
Python简单实现enum功能的方法
2016/04/25 Python
Python中super函数的用法
2017/11/17 Python
python监控键盘输入实例代码
2018/02/09 Python
Python+Django搭建自己的blog网站
2018/03/13 Python
Python Socket编程之多线程聊天室
2018/07/28 Python
Django 全局的static和templates的使用详解
2019/07/19 Python
PyInstaller的安装和使用的详细步骤
2020/06/02 Python
基于OpenCV的网络实时视频流传输的实现
2020/11/15 Python
Django集成MongoDB实现过程解析
2020/12/01 Python
使用html5制作loading图的示例
2014/04/14 HTML / CSS
SheIn俄罗斯:时尚女装网上商店
2017/02/28 全球购物
日本著名化妆品零售网站:Cosme Land
2019/03/01 全球购物
机电专业毕业生求职信
2013/10/27 职场文书
电子邮箱格式怎么写
2014/01/12 职场文书
产假请假条
2014/04/10 职场文书
家长通知书家长评语
2014/04/17 职场文书
教师考核评语大全
2014/12/31 职场文书
清明节寄语2015
2015/03/23 职场文书
canvas多重阴影发光效果实现
2021/04/20 Javascript