小时候和小伙伴围着板凳玩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 素材
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)