这是我去年选修python程序设计时候的作业三,当时是皇甫伟老师教的然后范茜莹姐姐当的助教还代了两节课(虽然我作为颜狗沉迷颜值没好好听就是了),但是,python程序设计还是值得我来安利的,大二计通贝壳er都去选!!!
前文链接:
目录
作业要求
设计思路
心得体会
源代码附上
作业要求
设计思路
(1)模仿老师上课的课件,尝试用python完成数字华容道游戏的编写,但是发现老师用的时PyQt4,而Anaconda自带的是PyQt5,于是只能上网查找相关用法,好在两个库的差别不大,基本上用法没什么区别。
(2)首先,我们定义了方向类来识别用户操作
(3)然后对华容道主主体类进行定义,包括初始化并打乱数组,检测按键并移动数字以及检测是否完成等功能函数,以及UI的基本设置:
# 初始化
def onInit(self):
# 顺序数组1-16
self.numbers = list(range(1, 16))
self.numbers.append(0)
# 将数字添加到二维数组
for row in range(4):
self.blocks.append([])
for column in range(4):
temp = self.numbers[row * 4 + column]
if temp == 0:
self.zero_row = row
self.zero_column = column
self.blocks[row].append(temp)
# 打乱数组
for i in range(1000):
random_num = random.randint(0, 3)
self.move(Direction(random_num))
self.updatePanel()
# 检测按键
def keyPressEvent(self, event):
key = event.key()
if(key == Qt.Key_Up):
self.move(Direction.UP)
if(key == Qt.Key_Down):
self.move(Direction.DOWN)
if(key == Qt.Key_Left):
self.move(Direction.LEFT)
if(key == Qt.Key_Right):
self.move(Direction.RIGHT)
self.updatePanel()
if self.checkResult():
if QMessageBox.Ok == QMessageBox.information(self, '挑战结果', '恭喜完成本次挑战!'):
self.onInit()
# 方块移动
def move(self, direction):
if(direction == Direction.UP): # 上
if self.zero_row != 3:
self.blocks[self.zero_row][self.zero_column] = self.blocks[self.zero_row + 1][self.zero_column]
self.blocks[self.zero_row + 1][self.zero_column] = 0
self.zero_row += 1
if(direction == Direction.DOWN): # 下
if self.zero_row != 0:
self.blocks[self.zero_row][self.zero_column] = self.blocks[self.zero_row - 1][self.zero_column]
self.blocks[self.zero_row - 1][self.zero_column] = 0
self.zero_row -= 1
if(direction == Direction.LEFT): # 左
if self.zero_column != 3:
self.blocks[self.zero_row][self.zero_column] = self.blocks[self.zero_row][self.zero_column + 1]
self.blocks[self.zero_row][self.zero_column + 1] = 0
self.zero_column += 1
if(direction == Direction.RIGHT): # 右
if self.zero_column != 0:
self.blocks[self.zero_row][self.zero_column] = self.blocks[self.zero_row][self.zero_column - 1]
self.blocks[self.zero_row][self.zero_column - 1] = 0
self.zero_column -= 1
# 检测完成
def checkResult(self):
# 右下角是否为0
if self.blocks[3][3] != 0:
return False
for row in range(4):
for column in range(4):
# 右下角已经为0,pass
if row == 3 and column == 3:
pass
#值是否对应
elif self.blocks[row][column] != row * 4 + column + 1:
return False
return True
(4)对数字方块类中的定义图形界面初始化设置。
二、运行结果
(1)刚打开时:
(2)完成数字华容道时
心得体会
在调试过程中,整体上比较顺利,中间遇到了几个问题简单总结以下:
一开始我是直接随机1-15的二维数组,但后来发现可能无解,于是改写了初始化数组部分的编写,先令二维数组按位置摆放好,再随机打乱1000次,并以此为开局确保存在解法。
源代码附上:
import sys
import random
from enum import IntEnum
from PyQt5.QtWidgets import QLabel, QWidget, QApplication, QGridLayout, QMessageBox
from PyQt5.QtGui import QFont, QPalette
from PyQt5.QtCore import Qt
# 方向类
class Direction(IntEnum):
UP = 0
DOWN = 1
LEFT = 2
RIGHT = 3
# 数字华容道
class NumberHuaRong(QWidget):
def __init__(self):
super().__init__()
self.blocks = []
self.zero_row = 0
self.zero_column = 0
self.gltMain = QGridLayout()
self.initUI()
def initUI(self):
# 方块间隔
self.gltMain.setSpacing(10)
self.onInit()
# 布局
self.setLayout(self.gltMain)
# 宽高
self.setFixedSize(400, 400)
# 标题
self.setWindowTitle('数字华容道')
# 背景颜色
self.setStyleSheet("background-color:white;")
self.show()
# 初始化
def onInit(self):
# 顺序数组1-16
self.numbers = list(range(1, 16))
self.numbers.append(0)
# 将数字添加到二维数组
for row in range(4):
self.blocks.append([])
for column in range(4):
temp = self.numbers[row * 4 + column]
if temp == 0:
self.zero_row = row
self.zero_column = column
self.blocks[row].append(temp)
# 打乱数组
for i in range(1000):
random_num = random.randint(0, 3)
self.move(Direction(random_num))
self.updatePanel()
# 检测按键
def keyPressEvent(self, event):
key = event.key()
if(key == Qt.Key_Up):
self.move(Direction.UP)
if(key == Qt.Key_Down):
self.move(Direction.DOWN)
if(key == Qt.Key_Left):
self.move(Direction.LEFT)
if(key == Qt.Key_Right):
self.move(Direction.RIGHT)
self.updatePanel()
if self.checkResult():
if QMessageBox.Ok == QMessageBox.information(self, '挑战结果', '恭喜完成本次挑战!'):
self.onInit()
# 方块移动
def move(self, direction):
if(direction == Direction.UP): # 上
if self.zero_row != 3:
self.blocks[self.zero_row][self.zero_column] = self.blocks[self.zero_row + 1][self.zero_column]
self.blocks[self.zero_row + 1][self.zero_column] = 0
self.zero_row += 1
if(direction == Direction.DOWN): # 下
if self.zero_row != 0:
self.blocks[self.zero_row][self.zero_column] = self.blocks[self.zero_row - 1][self.zero_column]
self.blocks[self.zero_row - 1][self.zero_column] = 0
self.zero_row -= 1
if(direction == Direction.LEFT): # 左
if self.zero_column != 3:
self.blocks[self.zero_row][self.zero_column] = self.blocks[self.zero_row][self.zero_column + 1]
self.blocks[self.zero_row][self.zero_column + 1] = 0
self.zero_column += 1
if(direction == Direction.RIGHT): # 右
if self.zero_column != 0:
self.blocks[self.zero_row][self.zero_column] = self.blocks[self.zero_row][self.zero_column - 1]
self.blocks[self.zero_row][self.zero_column - 1] = 0
self.zero_column -= 1
def updatePanel(self):
for row in range(4):
for column in range(4):
self.gltMain.addWidget(Block(self.blocks[row][column]), row, column)
self.setLayout(self.gltMain)
# 检测完成
def checkResult(self):
# 右下角是否为0
if self.blocks[3][3] != 0:
return False
for row in range(4):
for column in range(4):
# 右下角已经为0,pass
if row == 3 and column == 3:
pass
#值是否对应
elif self.blocks[row][column] != row * 4 + column + 1:
return False
return True
# 数字方块
class Block(QLabel):
def __init__(self, number):
super().__init__()
self.number = number
self.setFixedSize(80, 80)
# 字体
font = QFont()
font.setFamily("Arial")
font.setPointSize(30)
font.setBold(True)
self.setFont(font)
# 颜色
pa = QPalette()
pa.setColor(QPalette.WindowText, Qt.white)
self.setPalette(pa)
# 文字位置
self.setAlignment(Qt.AlignCenter)
# 样式
if self.number == 0:
self.setStyleSheet("background-color:grey;border-radius:10px;")
else:
self.setStyleSheet("background-color:cyan;border-radius:10px;")
self.setText(str(self.number))
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = NumberHuaRong()
sys.exit(app.exec_())