Python练手项目:计算24点

Python练手项目:计算24点,第1张

Python练手项目:计算24点

        小时候和小伙伴围着板凳玩24点,抢答拍桌把小手拍红。至今遗憾还有好多次算不出来,Python可以帮助我们弄清每一局比赛有解还是无解。

1 编码

        花色编码:0:红桃;1:黑桃;2:梅花;3:方块

        面值编码:J:11;Q:12;K:13;A:14

2 数据结构

用列表存储每一局比赛的四张牌,每张牌是一个二元组[ 面值, 花色]

用字典结构记录上述编码

3 算法

需要解决三个组合问题:

1)四张牌的面值的不重复组合

2)三个四则运算符的可重复排列

3)括号在表达式中的位置组合

表达式的计算问题,简单地可以用Python的eval函数完成,也可以用《数据结构》中讲到的双堆栈方法,建立优先级矩阵,自行编程实现(难点)

4 界面

界面采用tkinter+turtle结合完成,tkinter提供窗口、画布、按钮、Label,turtle负责绘制游戏场景

 

5 程序结构

1)可采用结构化程序设计,将程序功能分解为一定粒度的函数,通过函数调用实现程序。

2)分析程序中的对象和行为,进行职责分配,通过对象实例化和通信实现程序

本文采用结构化程序设计方法。

6 代码

from tkinter import *
import turtle
import random
suit_dict = {'0': '0.gif', '1': '1.gif', '2': '2.gif', '3': '3.gif'}
card_dict = {'2': '2', '3': '3', '4': '4', '5': '5', '6': '6', '7': '7', '8': '8', '9': '9', '10': '10', '11': 'J',
             '12': 'Q', '13': 'K', '14': 'A'}
opr_list = ['+', '-', '*', '/']
def drawcard(card, x, y):
    tu.penup()
    tu.goto(x - 100, y)  # 坐标向左位移100
    tu.shape(card)
    tu.stamp()
def writerank(x, y, rank):
    tu.penup()
    tu.goto(x - 100, y)
    tu.write(rank, font=("Arial", 30, "normal"))
def drawgame(hand_list):  # 绘制一局游戏
    for i in range(4):
        drawcard(suit_dict[hand_list[i][1]], i * 100, 0)  # 牌花色,每张牌间隔100像素
        writerank(i * 100 - 22, -25, card_dict[hand_list[i][0]])  # 牌面值
def opengame():  # 游戏开场 绘制扑克牌背面
    for i in range(4):
        drawcard("back.gif", i * 100, 0)
def deal_cards():  # 随机发牌4张,每张牌是个2元祖[面值,花色]
    global hand_list  # 全局变量
    answer.set("")
    hand_list = [[str(random.randint(2, 14)), str(random.randint(0, 3))] for i in range(4)]
    drawgame(hand_list)
    solve(hand_list)  # 先计算出24点保存起来
def combine_cards(): #计算时不关心花色,只对面值组合
    temp_list = []
    for i in range(4):
        for j in range(4):
            if i == j: continue
            for k in range(4):
                if k == j or k == i: continue
                for l in range(4):
                    if l == k or l == j or l == i: continue
                    temp_list.append([hand_list[i][0], hand_list[j][0], hand_list[k][0], hand_list[l][0]])
    return temp_list
def combine_opr():
    temp_list = []
    for opr1 in opr_list:
        for opr2 in opr_list:
            for opr3 in opr_list:
                temp_list.append([opr1, opr2, opr3])
    return temp_list
def solve(hand_list):  # 解题
    global answer_list
    answer_list = []
    cards_combination = combine_cards()
    opr_combination = combine_opr()
    for card_list in cards_combination:
        opd1, opd2, opd3, opd4 = card_list
        for opr_list in opr_combination:
            opr1, opr2, opr3 = opr_list
            expression_list = [['(', opd1, opr1, opd2, ')', opr2, '(', opd3, opr3, opd4, ')'],
                       ['(', opd1, opr1, opd2, ')', opr2, opd3, opr3, opd4],
                       ['(', opd1, opr1, opd2, opr2, opd3, ')', opr3, opd4]
                       ]  # 加括号,形成表达式
            if opr1 == '-' and int(opd1) < int(opd2):  # 去除负数运算
                expression_list.pop(0)
                expression_list.pop(1)
            for expression in expression_list:
                ex = ''.join(expression)
                try:  # 预防除数为0
                    if eval(ex) == 24 and type(eval(ex)) == int:  # 去除小数运算
                        answer_list.append(ex)
                except:
                    pass
def showanswer():
    if len(answer_list) == 0:
        answer.set("无解")
    else:
        answer.set(answer_list[0]) #只显示第一组答案
hand_list = []
answer_list = []
root = Tk()
root.geometry('520x520+600+300')
root.title('24点游戏')
root.resizable(False, False)
canvas = Canvas(root, width=620, height=400)
canvas.pack()
answer = StringVar()
theScreen = turtle.TurtleScreen(canvas)
theScreen.addshape("back.gif")
theScreen.addshape("0.gif")  # 红心
theScreen.addshape("1.gif")  # 黑桃
theScreen.addshape("2.gif")  # 梅花
theScreen.addshape("3.gif")  # 方块
tu = turtle.RawTurtle(theScreen)
theScreen.tracer(False)
opengame()
bt1 = Button(root, text=' 发牌 ', command=deal_cards)
bt1.place(x=60, y=425)
bt2 = Button(root, text=' 答案 ', command=showanswer)
bt2.place(x=160, y=425)
Label(textvariable=answer).place(x=230, y=428)
root.mainloop()

 7 素材

 

 

 

 

 

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5689294.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存