基于树莓派RP2040的24点小游戏
经典的童年小游戏--24点。它始于何年何月已无从考究,但它以自己独具的数学魅力和丰富的内涵正逐渐被越来越多的人们所接受。这种游戏方式简单易学,能健脑益智,是一项极为有益的活动。
标签
嵌入式系统
2022寒假在家练
树莓派RP2040
是宋宋啊
更新2022-03-03
金陵科技学院
965

项目简介:

棋牌类益智游戏,要求四个数字运算结果等于二十四。任意抽取4张牌(称为牌组),用加、减、乘、除(可加括号,高级玩家也可用乘方开方阶乘运算)把牌面上的数算成24。每张牌必须用且只能用一次。如抽出的牌是3、8、8、9,那么算式为(9-8)×8×3=24。它始于何年何月已无从考究,但它以自己独具的数学魅力和丰富的内涵正逐渐被越来越多的人们所接受。这种游戏方式简单易学,能健脑益智,是一项极为有益的活动。

创作思路:

正巧最近在学习Python,硬禾就推出了树莓派RP2040的嵌入式开发板,于是就入手了一块。结合自己所学的Python将儿时喜欢玩的24点小游戏做一下。因才学没多久,所以做的有些简陋。

首先,要有4张牌,也就是4个数字(不超过10),同时也要确保所生成的4个数字可以组成24点。在这里我先将可以组成24的4个数字放在一个数组里,建立一个二维数组,然后使用随机函数随机抽取一个数组当做题目。

#下面的是24点的题库
num=([6, 6, 8, 9],[7, 8, 8, 9],[1,5,6,7],[1,5,6,8],[1,5,7,8],[1,5,9,9])
#随机选取其中一个
random_temp = random.randint(0,5)

接下来,我们就需要将 题目、答题面板、可选择答题按键 打印出来

#填充整个背景为黑色
display.fill(st7789.BLACK)
#画3个矩形
display.rect(0,0,240,60,st7789.WHITE)
display.rect(0,0,240,120,st7789.WHITE)
display.rect(0,0,240,240,st7789.WHITE)

#打印24点题目
for x in range(4):
    display.text(font2, str(num[random_temp][x]), 28+x*56,15,st7789.YELLOW)
#打印答题面板
display.text(font2,"your answer:",1,80,st7789.WHITE)
#打印按键
for x in range(4):
        display.text(font2,str(num[random_temp][x]),28+x*56,150,st7789.WHITE)
#打印加减乘除
        display.text(font2,str(buffer_sign[x]),28+x*56,200,st7789.WHITE)

紧接着就是按键部分与答题面板结合:按键输入的值可以显示到面板上。

FvgzspRwnyvZjkVvXnr9CEtfUYVF

根据电路图,我们可以找到,按键A对应着PIN6,按键B对应着PIN5,以及ADC2、3控制的的滑动按键,定义代码如下(需要引入machine里的Pin):

key_A = Pin(6,Pin.IN,Pin.PULL_UP)
key_B = Pin(5,Pin.IN)#Pin.PULL_DOWN


control_x = machine.ADC(2)
control_y = machine.ADC(3)

按键A为啥要加个上拉呢,因为按键A是用来确定的,为了保证稳定性,用上拉感觉更好些;

按键B是用来切换的,按键我设置了两排,第一排是数字,第二排是算数符号;

滑动按键分X轴和Y轴,因有了切换,所以我只用了Y轴。

定义好了,我们就要解决如何实现按键与面板之间的联系,在这个过程想了很多种方式实现,最后就用数组好一点,所以定义了一个有8个元素的数组用来存放按键输入的数字与算术符号。

#存放按键数字与算数符号
sum_temp = [0,0,0,0,0,0,0,0]
'''
sum_temp[0]、sum_temp[2]、sum_temp[4]、sum_temp[6]为数字
sum_temp[1]、sum_temp[3]、sum_temp[5]、sum_temp[7]为算数符号
'''

实现了按键与面板之间的联系后,接着就是计算输入的值。

这时候上边的数组就有了打的作用,数字与算数符号都在数组中,我们只需将数组的值按算术符号计算即可得到

        sum_temp[7]=sum_temp[0]
        for x in [1,3,5]:
            if sum_temp[x]==0:
                sum_temp[7] = sum_temp[x+1]+sum_temp[7]
            elif sum_temp[x]==1:
                sum_temp[7] = sum_temp[7]-sum_temp[x+1]
            elif sum_temp[x]==2:
                sum_temp[7] = sum_temp[x+1]*sum_temp[7]
            elif sum_temp[x]==3 and sum_temp[x+1]!=0:
                sum_temp[7] = sum_temp[7]/sum_temp[x+1]

最后,判断结果是否为24即可,并显示游戏结果:

if sum_temp[7]==24:
            display.fill(st7789.BLACK)
            display.text(font2,"You WIN!",20,120,st7789.WHITE)
        elif sum_temp[7]!=24:
            display.fill(st7789.BLACK)
            display.text(font2,"You LOSE!",20,120,st7789.WHITE)

整体代码参考:

import uos
import machine
import st7789 as st7789
from fonts import vga2_8x8 as font1
from fonts import vga1_16x32 as font2
import random
import framebuf
from machine import Pin
from time import sleep
st7789_res = 0
st7789_dc  = 1
disp_width = 240
disp_height = 240
CENTER_Y = int(disp_width/2)
CENTER_X = int(disp_height/2)
#print(uos.uname())
spi_sck=machine.Pin(2)
spi_tx=machine.Pin(3)
spi0=machine.SPI(0,baudrate=4000000, phase=1, polarity=1, sck=spi_sck, mosi=spi_tx)
print(spi0)
display = st7789.ST7789(spi0, disp_width, disp_width,
                          reset=machine.Pin(st7789_res, machine.Pin.OUT),
                          dc=machine.Pin(st7789_dc, machine.Pin.OUT),
                          xstart=0, ystart=0, rotation=0)
#填充整个背景为黑色
display.fill(st7789.BLACK)
#画3个矩形
display.rect(0,0,240,60,st7789.WHITE)
display.rect(0,0,240,120,st7789.WHITE)
display.rect(0,0,240,240,st7789.WHITE)


#下面的是24点的题库
num=([6, 6, 8, 9],[3, 3, 6, 9],[1,5,6,7],[1,5,6,8],[1,5,7,8],[1,5,9,9])
'''
(6+6-9)*8|3*3+6+9|6*5-7+1|(1-5+8)*6|(1-5+7)*8|1+5+9+9|
'''
random_temp = random.randint(0,5)
#buffer = (0,1,2,3,4,5,6,7,8,9,10,11,12,13)
buffer_sign = ('+','-','*','/')
#buffer_str = ("0","1","2","3","4","5","6","7","8","9",'+','-','*','/')
#打印24点题目
for x in range(4):
    display.text(font2, str(num[random_temp][x]), 28+x*56,15,st7789.YELLOW)
#打印答题面板
display.text(font2,"your answer:",1,80,st7789.WHITE)
#打印按键
for x in range(4):
        display.text(font2,str(num[random_temp][x]),28+x*56,150,st7789.WHITE)
#打印加减乘除
        display.text(font2,str(buffer_sign[x]),28+x*56,200,st7789.WHITE)
#计算逻辑
key_A = Pin(6,Pin.IN,Pin.PULL_UP)
key_B = Pin(5,Pin.IN)#Pin.PULL_DOWN


control_x = machine.ADC(2)
control_y = machine.ADC(3)
num_temp = 0
keyA_temp = 0
keyB_temp = 0
flag=0
sum_temp = [0,-1,0,-1,0,-1,0,0]
display.text(font2,str(num[random_temp][num_temp]),28+num_temp*56,150,st7789.MAGENTA)
while True:
    #print(key_B.value())
    adc_x = int(control_x.read_u16()/100)
    adc_y = int(control_y.read_u16()/100)   
    sleep(0.1)
    if adc_y>600:
        num_temp = num_temp + 1
        if keyB_temp==0 and num_temp<4:
            display.text(font2,str(num[random_temp][num_temp-1]),28+(num_temp-1)*56,150,st7789.WHITE)
            display.text(font2,str(num[random_temp][num_temp]),28+num_temp*56,150,st7789.MAGENTA)
        elif keyB_temp ==1 and num_temp<4:
            display.text(font2,str(buffer_sign[num_temp-1]),28+(num_temp-1)*56,200,st7789.WHITE)
            display.text(font2,str(buffer_sign[num_temp]),28+num_temp*56,200,st7789.MAGENTA)
        elif keyB_temp ==0 and num_temp >3:
            display.text(font2,str(num[random_temp][3]),28+3*56,150,st7789.WHITE)
            display.text(font2,str(num[random_temp][0]),28,150,st7789.MAGENTA)
            num_temp = 0
        elif keyB_temp ==1 and num_temp >3:
            display.text(font2,str(buffer_sign[3]),28+3*56,200,st7789.WHITE)
            display.text(font2,str(buffer_sign[0]),28,200,st7789.MAGENTA)
            num_temp = 0
            
    elif adc_y<100:
        num_temp = num_temp - 1
        if keyB_temp==0 and num_temp>-1:
            display.text(font2,str(num[random_temp][num_temp+1]),28+(num_temp+1)*56,150,st7789.WHITE)
            display.text(font2,str(num[random_temp][num_temp]),28+num_temp*56,150,st7789.MAGENTA)
        elif keyB_temp ==1 and num_temp>-1:
            display.text(font2,str(buffer_sign[num_temp+1]),28+(num_temp+1)*56,200,st7789.WHITE)
            display.text(font2,str(buffer_sign[num_temp]),28+num_temp*56,200,st7789.MAGENTA)
        elif keyB_temp ==0 and num_temp <0:
            display.text(font2,str(num[random_temp][0]),28,150,st7789.WHITE)
            display.text(font2,str(num[random_temp][3]),28+3*56,150,st7789.MAGENTA)
            num_temp = 3
        elif keyB_temp ==1 and num_temp <0:
            display.text(font2,str(buffer_sign[0]),28,200,st7789.WHITE)
            display.text(font2,str(buffer_sign[3]),28+3*56,200,st7789.MAGENTA)
            num_temp = 3
#按键设置
#A用来确定,B用来切换      
    if key_A.value()==0:
        sleep(0.5)
        while key_A.value()==0:
            keyA_temp = 1
    
    if key_B.value()==0:
        sleep(0.5)
        if key_B.value()==0:
            keyB_temp =(keyB_temp+1)%2
    print(key_A.value(),key_B.value())        
               
    if keyA_temp==1 :
        if keyB_temp==0 :
            sum_temp[flag] = num[random_temp][num_temp]
        elif keyB_temp==1:
            sum_temp[flag] = num_temp
        flag = flag + 1
        keyA_temp=0
        
    print(sum_temp)
    display.text(font2,"((",1,80,st7789.WHITE)
    display.text(font2,")",1+16*5,80,st7789.WHITE)
    display.text(font2,")",1+16*8,80,st7789.WHITE)
    display.text(font2,"=",1+16*11,80,st7789.WHITE)
    for x in range(7):
        if x==0:display.text(font2,str(sum_temp[x]),2*16,80,st7789.WHITE)
        elif x==2:display.text(font2,str(sum_temp[x]),4*16,80,st7789.WHITE)
        elif x==4:display.text(font2,str(sum_temp[x]),7*16,80,st7789.WHITE)
        elif x==6:display.text(font2,str(sum_temp[x]),10*16,80,st7789.WHITE)
        elif x%2==1:
            if sum_temp[x]==0:
                    display.text(font2,"+",(x+1)//2*3*16,80,st7789.WHITE)
            elif sum_temp[x]==1:
                    display.text(font2,"-",(x+1)//2*3*16,80,st7789.WHITE)
            elif sum_temp[x]==2:
                    display.text(font2,"*",(x+1)//2*3*16,80,st7789.WHITE)
            elif sum_temp[x]==3:
                    display.text(font2,"/",(x+1)//2*3*16,80,st7789.WHITE)
            elif sum_temp[x]==-1:
                    display.text(font2,"$",(x+1)//2*3*16,80,st7789.WHITE)
    if flag > 6:
        sum_temp[7]=sum_temp[0]
        for x in [1,3,5]:
            if sum_temp[x]==0:
                sum_temp[7] = sum_temp[x+1]+sum_temp[7]
            elif sum_temp[x]==1:
                sum_temp[7] = sum_temp[7]-sum_temp[x+1]
            elif sum_temp[x]==2:
                sum_temp[7] = sum_temp[x+1]*sum_temp[7]
            elif sum_temp[x]==3 and sum_temp[x+1]!=0:
                sum_temp[7] = sum_temp[7]/sum_temp[x+1]
        display.text(font2,str(sum_temp[7]),1+12*16,80,st7789.WHITE)
        if sum_temp[7]==24:
            display.fill(st7789.BLACK)
            display.text(font2,"You WIN!",20,120,st7789.WHITE)
        elif sum_temp[7]!=24:
            display.fill(st7789.BLACK)
            display.text(font2,"You LOSE!",20,120,st7789.WHITE)
        break;


        

程序流程图:

Fj5ZEoARvhhHlHWYnXc46YGp-DFv

执行后,实际展示图为下图:

FoXXYK92JDFze2i-PC4z-pbOPNV8

PS:视频我分为两个部分来讲了,第一部分为实物展示,第二部分为代码讲解

软硬件
电路图
附件下载
game2040-V3-20211228.pdf
RP2040电路图
24点小游戏.py
最终代码.rar
团队介绍
爱吃猫的鱼,只有小白一枚
团队成员
是宋宋啊
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号