style: 引入 ruff,474 项告警清零

配置见 pyproject.toml:
- line-length=100:贴着现有代码定。若用默认的 88 会重排 122 行,
  噪音淹没真正有价值的修复。
- 启用 E/W/F/I/UP/B/C4/SIM/RET/PERF/RUF;**不**启用 PTH。因为本项目的路径
  多是"字符串身份"——要塞进 subprocess 命令行、写进 JSON 存档、打印给用户,
  全换 pathlib 只是包一层再拆一层,换来 70 处纯风格改动。
- 忽略 RUF001/002/003:中文全角标点是正确写法,不是"歧义字符"。
- 忽略 PERF203:剩下两处都是"逐项容错"语义(逐个牧场存档要立刻上报失败、
  收获全部要跳过失败地块)。把 try 提到循环外会毁掉"一项失败不影响其它项"
  这个行为,是错的优化。

自动修复 358 项:Dict/List/Optional 换成 PEP 585/604 写法、导入排序、
失效的 noqa、空占位 f-string 等。

手工修复的(这些是真问题,不是风格偏好):
- B904 x9:except 中 raise 补异常链。刻意区分——网络/IO 失败用 from exc 保留
  根因;参数解析失败用 from None,因为底层 ValueError 对玩家只是噪音。
- RUF012 x2:StateView 的 plots/animals 原本是**类级共享可变列表**,
  改成在 __init__ 里初始化(apply({}) 会提前返回,所以必须显式摆好)。
- F841:TUI 里一个赋值后再没用过的死变量。
- SIM105 x11:try/except/pass 统一改成 contextlib.suppress。
- SIM115:日志句柄改用 with。Popen 已把 fd 复制给子进程,父进程可安全关闭。
- E501 x7:拆超长行;main.py 那处顺手提取变量,避免超长嵌套表达式。
- E741:把 l/r 改成 left_line/right_line。
- 其余:RUF046 / PERF401 / RET504 / RUF005 / UP031 / B007。

ruff format 重排 24 个文件。

验证:97 项测试全绿。
This commit is contained in:
snowy-yang committed 2026-09-18 21:18:22 +08:00
1 parent c7c8a6308a
commit fcd4cb4649
25 files changed
+1204 -794

No files matched your search

+80 -39
View File
@@ -6,32 +6,32 @@
from __future__ import annotations
from typing import Any, Dict
from typing import Any
# --------------------------------------------------------------------------
# 基础经济参数
# --------------------------------------------------------------------------
START_GOLD = 120 # 初始金币
START_LEVEL = 1 # 初始等级
START_AP = 10 # 每天行动点上限
START_FEED = 5 # 初始饲料库存
START_GOLD = 120 # 初始金币
START_LEVEL = 1 # 初始等级
START_AP = 10 # 每天行动点上限
START_FEED = 5 # 初始饲料库存
BASE_PLOTS = 6 # 初始土地数量
MAX_PLOTS = 16 # 土地数量硬上限
PLOT_BASE_PRICE = 200 # 第一块新地的价格
BASE_PLOTS = 6 # 初始土地数量
MAX_PLOTS = 16 # 土地数量硬上限
PLOT_BASE_PRICE = 200 # 第一块新地的价格
PLOT_PRICE_GROWTH = 1.75 # 每多买一块,价格乘以该系数
FEED_UNIT_PRICE = 6 # 主动购买饲料的单价
FEED_UNIT_PRICE = 6 # 主动购买饲料的单价
FEED_EMERGENCY_PRICE = 9 # 自动补货(缺饲料时喂食)的惩罚单价
FEED_BULK = 10 # 一次购买饲料的默认批量
FEED_BULK = 10 # 一次购买饲料的默认批量
WATER_CAPACITY = 3 # 一次浇水可支撑的天数
WATER_CAPACITY = 3 # 一次浇水可支撑的天数
PLANT_INITIAL_MOISTURE = 2 # 播种后地块自带的水分
PRICE_VOLATILITY = 0.18 # 每天价格波动幅度(±18%)
LUCKY_CHANCE = 0.12 # 丰收暴击概率(产出翻倍)
MAX_LOG_ENTRIES = 300 # 内存中保留的事件条数上限
MAX_FEED_PURCHASE = 200 # 单次购买饲料的数量上限
PRICE_VOLATILITY = 0.18 # 每天价格波动幅度(±18%)
LUCKY_CHANCE = 0.12 # 丰收暴击概率(产出翻倍)
MAX_LOG_ENTRIES = 300 # 内存中保留的事件条数上限
MAX_FEED_PURCHASE = 200 # 单次购买饲料的数量上限
# 每级提供的土地上限(基础 6 + 2/级,封顶 MAX_PLOTS)
PLOTS_PER_LEVEL = 2
@@ -48,11 +48,13 @@ AP_COST = {
"buy_feed": 0,
}
# 经验曲线:升到 level+1 所需经验
def exp_to_next(level: int) -> int:
"""返回从 level 升到 level+1 所需的经验值。"""
return int(80 * (max(1, level) ** 1.6))
# 升级奖励金币
def level_up_bonus(level: int) -> int:
"""升到 level 时发放的金币奖励。"""
@@ -70,30 +72,54 @@ def level_up_bonus(level: int) -> int:
# exp : 每次收获获得的经验
# level_req : 解锁所需等级
CROPS: Dict[str, Dict[str, Any]] = {
CROPS: dict[str, dict[str, Any]] = {
"wheat": {
"name": "小麦", "seed_cost": 5, "grow_days": 2,
"base_price": 14, "exp": 3, "level_req": 1,
"name": "小麦",
"seed_cost": 5,
"grow_days": 2,
"base_price": 14,
"exp": 3,
"level_req": 1,
},
"carrot": {
"name": "胡萝卜", "seed_cost": 8, "grow_days": 3,
"base_price": 26, "exp": 5, "level_req": 1,
"name": "胡萝卜",
"seed_cost": 8,
"grow_days": 3,
"base_price": 26,
"exp": 5,
"level_req": 1,
},
"tomato": {
"name": "番茄", "seed_cost": 16, "grow_days": 4,
"base_price": 52, "exp": 9, "level_req": 2,
"name": "番茄",
"seed_cost": 16,
"grow_days": 4,
"base_price": 52,
"exp": 9,
"level_req": 2,
},
"corn": {
"name": "玉米", "seed_cost": 28, "grow_days": 6,
"base_price": 95, "exp": 14, "level_req": 3,
"name": "玉米",
"seed_cost": 28,
"grow_days": 6,
"base_price": 95,
"exp": 14,
"level_req": 3,
},
"pumpkin": {
"name": "南瓜", "seed_cost": 45, "grow_days": 8,
"base_price": 180, "exp": 22, "level_req": 4,
"name": "南瓜",
"seed_cost": 45,
"grow_days": 8,
"base_price": 180,
"exp": 22,
"level_req": 4,
},
"strawberry": {
"name": "草莓", "seed_cost": 70, "grow_days": 10,
"base_price": 320, "exp": 35, "level_req": 5,
"name": "草莓",
"seed_cost": 70,
"grow_days": 10,
"base_price": 320,
"exp": 35,
"level_req": 5,
},
}
@@ -119,21 +145,36 @@ GROWTH_STAGES = [
# exp : 每次收集产出获得的经验
# level_req : 解锁所需等级
ANIMALS: Dict[str, Dict[str, Any]] = {
ANIMALS: dict[str, dict[str, Any]] = {
"chicken": {
"name": "鸡", "cost": 90, "product": "鸡蛋",
"base_price": 15, "cycle": 1, "feed_per_day": 1,
"exp": 4, "level_req": 1,
"name": "鸡",
"cost": 90,
"product": "鸡蛋",
"base_price": 15,
"cycle": 1,
"feed_per_day": 1,
"exp": 4,
"level_req": 1,
},
"sheep": {
"name": "羊", "cost": 220, "product": "羊毛",
"base_price": 55, "cycle": 2, "feed_per_day": 1,
"exp": 9, "level_req": 2,
"name": "羊",
"cost": 220,
"product": "羊毛",
"base_price": 55,
"cycle": 2,
"feed_per_day": 1,
"exp": 9,
"level_req": 2,
},
"cow": {
"name": "牛", "cost": 480, "product": "牛奶",
"base_price": 72, "cycle": 1, "feed_per_day": 2,
"exp": 15, "level_req": 3,
"name": "牛",
"cost": 480,
"product": "牛奶",
"base_price": 72,
"cycle": 1,
"feed_per_day": 2,
"exp": 15,
"level_req": 3,
},
}
@@ -147,7 +188,7 @@ MAX_ANIMALS = 8 # 牧场总容量
DEFAULT_TICK_SECONDS = 15.0 # 自动推进一天所需的真实秒数
MIN_TICK_SECONDS = 3.0
MAX_TICK_SECONDS = 600.0
SLEEP_COOLDOWN = 2.0 # 手动"休息"推进一天的冷却(秒)
SLEEP_COOLDOWN = 2.0 # 手动"休息"推进一天的冷却(秒)
# --------------------------------------------------------------------------