一、运行界面

二、显示答案------递归介绍
工作流程:
基本情况:函数首先检查输入的数字列表 nums 的长度。如果列表中只剩下一个数字,它会判断这个数字是否接近 24(使用 abs(nums[0] - 24) < 1e-10 来处理浮点数精度问题)。如果是,它返回 True 和这个数字的字符串表示;否则返回 False 和空字符串。
递归组合:如果列表中有多个数字,函数会通过双重循环选择两个数字 a 和 b(nums[i] 和 nums[j]),并从列表中移除这两个数字,形成一个新的数字列表 remaining。
运算符尝试:接下来,函数会遍历定义的运算符字典 ops,对选中的两个数字进行运算。对于每个运算符,函数会尝试计算 result = ops[op](a, b)。如果运算符是除法,还会检查除数 b 是否为零,以避免除以零的错误。
递归调用:如果运算成功,函数会递归调用 evaluate,将计算结果 result 和剩余的数字列表 remaining 组合成新的列表进行下一轮计算。如果在递归中找到了有效的解法,函数会返回成功的标志和相应的算式字符串。
返回结果:如果所有组合都尝试过后仍未找到解法,函数会返回 False 和空字符串。
以输入数字
[4, 2, 3, 1]
为例:
步骤 操作 说明 1 选择4和1进行加法运算 → 5 剩余数字变为[2, 3, 5] 2 选择5和3进行乘法运算 → 15 剩余数字变为[2, 15] 3 选择15和2进行减法运算 → 13 未满足24,回溯尝试其他路径 4 找到有效路径如 (4*(3*(2/1))) 最终返回算式字符串
三、完整代码
"""
24点游戏
这是一个使用tkinter开发的24点游戏,玩家需要使用给定的4个数字和基本运算符(+、-、*、/)计算出24。
"""
import tkinter as tk
from tkinter import messagebox
import random
import itertools
import operator
class TwentyFourGame:
"""
24点游戏的主类
负责创建游戏界面、处理游戏逻辑和用户交互
"""
def __init__(self):
"""
初始化游戏窗口和基本设置
创建主窗口、设置样式、初始化游戏变量
"""
self.window = tk.Tk()
self.window.title("24点游戏")
self.window.geometry("400x500")
self.window.configure(bg="#f0f0f0")
# 设置界面样式
self.style = {
'bg': "#f0f0f0", # 背景色
'button_bg': "#4CAF50", # 按钮背景色
'button_fg': "white", # 按钮文字颜色
'font': ("Arial", 12), # 字体设置
'entry_bg': "white", # 输入框背景色
'entry_fg': "black" # 输入框文字颜色
}
# 创建游戏界面组件
self.create_widgets()
# 初始化游戏数据
self.numbers = [] # 存储当前游戏的4个数字
self.solution = "" # 存储当前游戏的解法
self.new_game() # 开始新游戏
def create_widgets(self):
"""
创建游戏界面的所有组件
包括标题、数字显示区、输入框、按钮等
"""
# 创建游戏标题
title = tk.Label(
self.window,
text="24点游戏",
font=("Arial", 20, "bold"),
bg=self.style['bg']
)
title.pack(pady=20)
# 创建数字显示区域
self.numbers_frame = tk.Frame(self.window, bg=self.style['bg'])
self.numbers_frame.pack(pady=20)
# 创建4个数字标签
self.number_labels = []
for i in range(4):
label = tk.Label(
self.numbers_frame,
text="",
font=self.style['font'],
width=4,
height=2,
relief="solid",
bg=self.style['entry_bg']
)
label.pack(side=tk.LEFT, padx=5)
self.number_labels.append(label)
# 创建算式输入框
self.expression_var = tk.StringVar()
self.expression_entry = tk.Entry(
self.window,
textvariable=self.expression_var,
font=self.style['font'],
width=30,
bg=self.style['entry_bg'],
fg=self.style['entry_fg']
)
self.expression_entry.pack(pady=20)
# 创建按钮区域
button_frame = tk.Frame(self.window, bg=self.style['bg'])
button_frame.pack(pady=20)
# 创建提交答案按钮
submit_btn = tk.Button(
button_frame,
text="提交答案",
command=self.check_answer,
font=self.style['font'],
bg=self.style['button_bg'],
fg=self.style['button_fg'],
width=10
)
submit_btn.pack(side=tk.LEFT, padx=5)
# 创建新游戏按钮
new_game_btn = tk.Button(
button_frame,
text="新游戏",
command=self.new_game,
font=self.style['font'],
bg=self.style['button_bg'],
fg=self.style['button_fg'],
width=10
)
new_game_btn.pack(side=tk.LEFT, padx=5)
# 创建显示答案按钮
show_answer_btn = tk.Button(
button_frame,
text="显示答案",
command=self.show_answer,
font=self.style['font'],
bg=self.style['button_bg'],
fg=self.style['button_fg'],
width=10
)
show_answer_btn.pack(side=tk.LEFT, padx=5)
# 创建提示标签
self.hint_label = tk.Label(
self.window,
text="请输入算式,使用 + - * / 和括号",
font=self.style['font'],
bg=self.style['bg']
)
self.hint_label.pack(pady=10)
def new_game(self):
"""
开始新游戏
随机生成4个1-9之间的数字,并计算一个可能的解法
"""
self.numbers = [random.randint(1, 9) for _ in range(4)]
for i, num in enumerate(self.numbers):
self.number_labels[i].config(text=str(num))
self.expression_var.set("")
self.solution = self.find_solution()
def find_solution(self):
"""
寻找当前数字组合的一个可能解法
使用递归方法尝试所有可能的运算组合
返回:如果找到解法返回算式字符串,否则返回"无解"
"""
# 定义基本运算符
ops = {
'+': operator.add,
'-': operator.sub,
'*': operator.mul,
'/': operator.truediv
}
def evaluate(nums):
"""
递归计算所有可能的运算组合
参数:
nums: 待计算的数字列表
返回:
(是否找到解法, 算式字符串)
"""
if len(nums) == 1:
return abs(nums[0] - 24) < 1e-10, str(nums[0])
# 尝试所有可能的数字组合和运算符
for i in range(len(nums)):
for j in range(i + 1, len(nums)):
a, b = nums[i], nums[j]
remaining = nums[:i] + nums[i + 1:j] + nums[j + 1:]
for op in ops:
try:
result = ops[op](a, b)
if op == '/':
if abs(b) < 1e-10: # 避免除以0
continue
success, expr = evaluate(remaining + [result])
if success:
return True, f"({a}{op}{b}){expr}"
except:
continue
return False, ""
success, expr = evaluate(self.numbers)
return expr if success else "无解"
def check_answer(self):
"""
检查用户输入的答案是否正确
验证:
1. 是否只使用了给定的数字
2. 计算结果是否等于24
"""
try:
expr = self.expression_var.get()
# 移除所有空格
expr = expr.replace(" ", "")
# 检查是否只使用了给定的数字
used_nums = [int(n) for n in expr if n.isdigit()]
if sorted(used_nums) != sorted(self.numbers):
messagebox.showerror("错误", "请只使用给定的数字!")
return
result = eval(expr)
if abs(result - 24) < 1e-10:
messagebox.showinfo("恭喜", "答案正确!")
else:
messagebox.showerror("错误", f"计算结果为 {result},不等于24")
except:
messagebox.showerror("错误", "请输入有效的算式!")
def show_answer(self):
"""
显示当前游戏的一个可能解法
"""
if self.solution:
messagebox.showinfo("答案", f"一个可能的解法:{self.solution}")
else:
messagebox.showinfo("答案", "这组数字无解!")
def run(self):
"""
运行游戏主循环
"""
self.window.mainloop()
if __name__ == "__main__":
game = TwentyFourGame()
game.run()
四、Readme
## 功能特点 - 图形用户界面,操作简单直观 - 随机生成4个1-9之间的数字 - 支持基本的四则运算(+、-、*、/)和括号 - 实时验证答案的正确性 - 提供答案提示功能 - 支持开始新游戏 ## 系统要求 - Python 3.x - Tkinter(Python标准库,通常随Python一起安装) ## 安装说明 1. 确保您的系统已安装Python 3.x 2. 下载或克隆此仓库 3. 运行游戏: ```bash python 24_points_game.py ``` ## 游戏规则 1. 游戏会随机生成4个1-9之间的数字 2. 使用这4个数字,通过加减乘除运算和括号,得到24 3. 每个数字必须且只能使用一次 4. 运算结果必须精确等于24 ## 使用方法 1. 启动游戏后,界面会显示4个随机数字 2. 在输入框中输入您的算式(例如:`(3+5)*(6-3)`) 3. 点击"提交答案"按钮检查答案 4. 如果遇到困难,可以点击"显示答案"查看一个可能的解法 5. 随时可以点击"新游戏"开始新的挑战 ## 注意事项 - 请确保输入的算式格式正确 - 只能使用给定的4个数字 - 每个数字只能使用一次 - 运算结果必须精确等于24 ## 技术实现 - 使用Tkinter构建图形界面 - 实现了自动求解算法 - 包含输入验证和错误处理 - 采用面向对象编程方式开发