一、運行界面
二、顯示答案——遞歸介紹
工作流程:
1. 基本情況:函數首先檢查輸入的數字列表 nums 的長度。如果列表中只剩下一個數字,它會判斷這個數字是否接近 24(使用 abs(nums[0] - 24) < 1e-10 來處理浮點數精度問題)。如果是,它返回 True 和這個數字的字符串表示;否則返回 False 和空字符串。
2. 遞歸組合:如果列表中有多個數字,函數會通過雙重循環選擇兩個數字 a 和 b(nums[i] 和 nums[j]),并從列表中移除這兩個數字,形成一個新的數字列表 remaining。
3. 運算符嘗試:接下來,函數會遍歷定義的運算符字典 ops,對選中的兩個數字進行運算。對于每個運算符,函數會嘗試計算 result = ops[op](a, b)。如果運算符是除法,還會檢查除數 b 是否為零,以避免除以零的錯誤。
4. 遞歸調用:如果運算成功,函數會遞歸調用 evaluate,將計算結果 result 和剩余的數字列表 remaining 組合成新的列表進行下一輪計算。如果在遞歸中找到了有效的解法,函數會返回成功的標志和相應的算式字符串。
5. 返回結果:如果所有組合都嘗試過后仍未找到解法,函數會返回 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 operatorclass 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: # 避免除以0continuesuccess, expr = evaluate(remaining + [result])if success:return True, f"({a}{op}{b}){expr}"except:continuereturn 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("錯誤", "請只使用給定的數字!")returnresult = 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. 運行游戲:```bashpython 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構建圖形界面 - 實現了自動求解算法 - 包含輸入驗證和錯誤處理 - 采用面向對象編程方式開發