基于树莓派RP2040实现经典游戏“锯齿数独”的移植项目
一、项目介绍
这是我参加“硬禾学堂2022寒假在家练”活动所完成的项目,项目使用的是树莓派RP2040开发板。
项目实现的总体功能是将经典益智小游戏“锯齿数独”移植到树莓派RP2040开发板上,具体需求如下所示:
※绘制游戏封面,设置游戏背景颜色;
※按下B键后开始游戏;
※生成一个5X5的矩阵方块;
※初始化界面,并由self.chess函数插入数值;
※将遥控杆设置为移动和数值是加减,通过按键B来实现模式切换;
※将已有数字的左和上边缘若出现数字则画粗线,形成锯齿方格;
※通过range函数检测最终结果是否正确
二、设计框图
三、简单的软硬件介绍
1、元器件
项目所使用的元器件为树莓派RP2040开发板,该开发板是由树莓派基金会推出的双核Arm Cortex MO+微控制器,有133MHz的时钟速率以及264KB的SRAM,支持C/C++、MicroPython编程。
2、软件
项目所使用的开发语言为MicroPython,MicroPython是一款编程语言兼容Python3的软件,用C写成的,能够运行在微控制器的硬件上并进行了相应的优化。
3、工具
项目所使用的开发工具为Thonny。Thonny是一款针对初学者的 Python IDE工具。
Thonny 的官方网站: https: / /thonnv.org/
四、实现功能及图片展示
1.游戏封面
2.按下按键B开始游戏
3.游戏胜利图片
五、主要代码片段及说明
1.初始化以及数值插入代码
STAGE = 5 # 数独的阶
BOX = int(240 / STAGE)
class ShuDu():
def __init__(self):
# 初始化一个5阶数独
self.chess = {}
self.editpos = [0, 0] # 当前编辑位置
self.isedit = False # 当前是否编辑状态
def reset(self): # 初始化数独
'''
数独数据使用dict来表示。
key用来指 位置坐标(x,y) 从0开始
value使用list。第一个值为0 代表初始值,不显示。第二个值代表 分组
:return: 无
'''
self.chess = {(0, 0): [0, 1], (0, 1): [1, 1], (0, 2): [0, 1], (0, 3): [0, 2], (0, 4): [0, 2],
(1, 0): [3, 1], (1, 1): [4, 3], (1, 2): [0, 1], (1, 3): [0, 2], (1, 4): [0, 2],
(2, 0): [0, 3], (2, 1): [0, 3], (2, 2): [1, 3], (2, 3): [0, 2], (2, 4): [0, 4],
(3, 0): [0, 5], (3, 1): [0, 3], (3, 2): [2, 4], (3, 3): [0, 4], (3, 4): [0, 4],
(4, 0): [0, 5], (4, 1): [0, 5], (4, 2): [0, 5], (4, 3): [0, 5], (4, 4): [4, 4]}
# self.chess = {(0, 0): [2, 1], (0, 1): [1, 1], (0, 2): [4, 1], (0, 3): [3, 2], (0, 4): [5, 2],
# (1, 0): [3, 1], (1, 1): [4, 3], (1, 2): [5, 1], (1, 3): [1, 2], (1, 4): [2, 2],
# (2, 0): [5, 3], (2, 1): [2, 3], (2, 2): [1, 3], (2, 3): [4, 2], (2, 4): [3, 4],
# (3, 0): [4, 5], (3, 1): [3, 3], (3, 2): [2, 4], (3, 3): [5, 4], (3, 4): [1, 4],
# (4, 0): [1, 5], (4, 1): [5, 5], (4, 2): [3, 5], (4, 3): [2, 5], (4, 4): [4, 4]}
# 已有数字的不可被编辑
for val in self.chess.values():
if val[0] == 0:
val.append(True)
else:
val.append(False)
2.定义按键代码
def action(self, act): # 动作有上下左右和按键 0,1,2,3 代表上下左右 4 代表按键
'''
分两种模式,非编辑状态下 上下左右 移动当前的editpos
编辑状态:上左 增加当前值,下右减少当前值
按键 切换当前的编辑和非编辑状态
:return: 变化了的位置信息
'''
if act == 4: # 交换 可编辑状态
if self.chess[tuple(self.editpos)][2]: # 可编辑
self.isedit = bool(1 - self.isedit)
return True, self.editpos, self.editpos
else: # 不可编辑
return False, None, None
if self.isedit: # 可编辑状态
val = self.chess[tuple(self.editpos)][0] # 当前值
if act == 0 or act == 3:
val = int((val + 1) % (STAGE + 1))
else:
val = int((val - 1) % (STAGE + 1))
print(val)
self.chess[tuple(self.editpos)][0] = val
return True, self.editpos, self.editpos
else: # 非可编辑状态
curpos = self.editpos.copy()
if act == 0: # 上
if curpos[1] == 0:
return False, None, None
else:
self.editpos[1] -= 1
return True, curpos, self.editpos
if act == 1: # 下
if curpos[1] == STAGE - 1:
return False, None, None
else:
self.editpos[1] += 1
return True, curpos, self.editpos
if act == 2: # 左
if curpos[0] == 0:
return False, None, None
else:
self.editpos[0] -= 1
return True, curpos, self.editpos
if act == 3: # 右
if curpos[0] == STAGE - 1:
return False, None, None
else:
self.editpos[0] += 1
return True, curpos, self.editpos
3.结果检测代码
def isSuccess(self): # 检查是否胜利
answer = STAGE
for i in range(1, STAGE):
answer += i # 计算正确答案
# 检查每一行、列 的和是否为正确答案
for x in range(STAGE):
linecol = 0
linerow = 0
for y in range(STAGE):
linecol += self.chess[(x, y)][0]
linerow += self.chess[(y, x)][0]
if linecol != answer or linerow != answer:
return False
# 检查组的和是否为正确答案
groupadd = []
for groupnum in range(STAGE):
groupadd.append(0)
for val in self.chess.values():
groupadd[val[1] - 1] += val[0]
for num in groupadd:
if num != answer:
return False
return True
六、项目总结
通过这个项目,很大程度上提升了我对嵌入式的兴趣,以及学到了很多关于树莓派RP2040的相关知识,在项目移植过程中也是遇到了很多问题,不断请教,上网查资料解决了问题,受益匪浅。