You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何无重复更新函数返回变量?Cookie Clicker游戏开发问题

解决Cookie Clicker类游戏中全局变量更新的重复代码问题

问题概述

开发Cookie Clicker类游戏时,为避免重复代码编写了defamountx函数,但遇到变量更新问题:点击按钮时,函数返回的amount、price、cps无法同步更新全局变量。目前只能通过单独定义赋值函数实现,但这会引入重复代码,违背减少冗余的初衷。

原代码片段

import tkinter as tk
root = tk.Tk()

def printt():
    print(amountc, amountg, amountt)

def defamountx(amount, priceconstant, cpsconstant, Name, Button, refresh):
    global cpsall
    old_price = round(priceconstant * 1.15 ** amount)
    if refresh is False:
        amount += 1
    price = round(priceconstant * 1.15 ** amount)
    cps = amount * cpsconstant
    Button["text"] = f"{Name}\n🍪{price}"
    shoptxt["text"] = f"↓Shop↓, {cpsall} c/s"
    print(amount)
    return amount, price, cps
amountc=0
amountg=0
amountt=0
cpsall = 0

shoptxt = tk.Label(root, height=1, width=40)
shoptxt.pack()

clickerbn = tk.Button(root, command=lambda: defamountx(amountc, 5, 0.1, "Clicker", clickerbn, False), width=30, height=2)
amountc, pricec, cpsc = defamountx(amountc, 5, 0.1, "Clicker", clickerbn, True)

grandmabn = tk.Button(root, command=lambda: defamountx(amountg, 75, 1, "Grandma", grandmabn, False), width=30, height=2)
amountg, priceg, cpsg = defamountx(amountg, 75, 1, "Grandma", grandmabn, True)

treebn = tk.Button(root, command=lambda: defamountx(amountt, 500, 5, "Cookie Tree", treebn, False), width=30, height=2)
amountt, pricet, cpst = defamountx(amountt, 500, 5, "Cookie Tree", treebn, True)

printbn = tk.Button(root, command=printt, width=30, height=2, text='print')
printbn.pack()

shoptxt["text"] = f"↓Shop↓, {cpsall} c/s"
buttons = [clickerbn, grandmabn, treebn]
for stf in buttons:
    stf.pack()

root.mainloop()

解决方案:用字典管理升级数据(避免重复代码)

核心思路:Python中整数是不可变类型,函数参数传递的是值副本,无法直接修改全局变量;改用**字典(可变对象)**存储每个升级项的所有数据,函数内直接修改字典元素即可同步更新全局状态,无需手动赋值返回值。

修改后的完整代码:

import tkinter as tk
root = tk.Tk()

# 用字典统一管理所有升级项的数据,避免零散的全局变量
upgrade_data = {
    "clicker": {"amount": 0, "price_constant": 5, "cps_constant": 0.1, "name": "Clicker"},
    "grandma": {"amount": 0, "price_constant": 75, "cps_constant": 1, "name": "Grandma"},
    "tree": {"amount": 0, "price_constant": 500, "cps_constant": 5, "name": "Cookie Tree"}
}
cpsall = 0

def printt():
    # 从字典中提取当前数量打印
    print(
        upgrade_data["clicker"]["amount"],
        upgrade_data["grandma"]["amount"],
        upgrade_data["tree"]["amount"]
    )

def defamountx(upgrade_key, button, refresh):
    global cpsall
    # 获取当前升级项的数据(字典引用,修改会同步全局)
    data = upgrade_data[upgrade_key]
    
    if not refresh:
        data["amount"] += 1
    
    # 计算当前价格和cps
    data["price"] = round(data["price_constant"] * 1.15 ** data["amount"])
    data["cps"] = data["amount"] * data["cps_constant"]
    
    # 更新按钮文本和总cps显示
    button["text"] = f"{data['name']}\n🍪{data['price']}"
    cpsall = sum(item["cps"] for item in upgrade_data.values())
    shoptxt["text"] = f"↓Shop↓, {cpsall:.1f} c/s"
    print(data["amount"])

shoptxt = tk.Label(root, height=1, width=40)
shoptxt.pack()

# 初始化按钮和数据
clickerbn = tk.Button(root, command=lambda: defamountx("clicker", clickerbn, False), width=30, height=2)
defamountx("clicker", clickerbn, True)

grandmabn = tk.Button(root, command=lambda: defamountx("grandma", grandmabn, False), width=30, height=2)
defamountx("grandma", grandmabn, True)

treebn = tk.Button(root, command=lambda: defamountx("tree", treebn, False), width=30, height=2)
defamountx("tree", treebn, True)

printbn = tk.Button(root, command=printt, width=30, height=2, text='print')
printbn.pack()

buttons = [clickerbn, grandmabn, treebn]
for stf in buttons:
    stf.pack()

root.mainloop()

关键改进点

  • 用upgrade_data字典统一存储所有升级项的amount、价格常量、cps常量等数据,避免零散的全局变量
  • 函数defamountx通过升级项的key获取字典引用,修改字典元素直接同步全局状态,无需返回值再手动赋值
  • 自动计算总cps,无需手动维护每个升级项的cps总和
  • 代码结构更清晰,新增升级项只需在字典中添加条目,无需重复编写变量和初始化代码

内容的提问来源于stack exchange,提问作者user20956663

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 06:35:17