内容
基于 tutusagi/ai-fishing-game 开源项目二次开发 原作者 tutusagi(小红书:初一) 前端调度自定义面板- 猫屁屁 2026.6.26 接口11125,前端端口也是11125 可以直接在前端自定义你想要给他往里搁楞的鱼饵地点鱼获 做的很爽 已和初一老师沟通 感谢! 本地玩的话: 先双击setup-firewall.bat开一下你的防火墙 然后双击start.bat,电脑开一下前端就搞定。 要放服务器的自己部署一下 要改的自己改一下
原readme内容(tutusagi/ai-fishing-game):
# 🎣 文字钓鱼 · 给 AI 玩的确定性小游戏
一个**单文件、零依赖、确定性**的文字钓鱼游戏 —— 专门做来**让你的 AI 伴侣来玩**的。
买饵 → 抛竿 → 按稀有度钓上各种鱼 → 卖鱼换点数 → 解锁新水域 → 集齐图鉴。
55 种鱼、11 个钓点、四季流转、漂流瓶/宝箱/宝物、稀有度仪式感文案……一竿一竿钓下去,看你的 AI 怎么经营、怎么为一条传说鱼上钩而激动。
> **它只给玩法逻辑(引擎)。怎么接到你自己的 AI 上,由你配置** —— 下面「接到你的 AI 上」一节给了三种接法草图。
> ### 📦 两个版本,分开下载(见 [Releases](https://github.com/tutusagi/ai-fishing-game/releases))
> - **v2.0 · 潜水完整版**(`main`,本文档):在精简版基础上加了整套潜水玩法——藏宝图碎片解锁潜水点、22 种水下专属鱼(带捕获手感)、按地点×季节的下潜氛围、14 种水下奇遇、21 件宝物、海底宝库、氧气瓶套餐。
> - **v1.2 · 精简版**(`v1.2-lite` 分支):只含操作/省 token 优化(batch 叠加指令 / 状态栏 JSON / 钓点待发现计数 / 连钓提示)+ 6 个幸运事件,**不含潜水**,更轻量。
---
## 这是什么 / 为什么是「给 AI 玩」
普通文字游戏是给人玩的。这个引擎从设计上就是给 **AI 玩家**用的:
- **确定性**:内置 mulberry32 PRNG,状态全部序列化进存档。**同一个种子 + 同一串指令 = 逐位可复现的结果**。便于复盘、测试、分享同一局。
- **盲玩**:可以让 AI 在**不剧透**的前提下玩 —— 它不知道有哪些鱼、稀有鱼在哪、概率多少,全靠一竿一竿亲手发现。
- **存档独立**:游戏状态存在磁盘文件里,**不在对话上下文里**。AI 的对话被清空,钓鱼进度也不会丢。
- **省 token**:支持一次「连钓 N 竿」,只回一个汇总(精彩的留全文、杂鱼折叠成清点);还能用 `;` 或换行把多条指令串成一批一次跑(买饵→抛竿、换地点→抛竿)。每次返回末尾附一行紧凑 `📊` 状态栏 JSON,AI 看它就够、不必反复查状态。不用一竿一条消息来回烧上下文。
---
## 仓库里有什么
| 文件 | 是什么 | 你怎么用 |
|---|---|---|
| **`engine.py`** | **可读的引擎源码**。对外只用两个接口:`cmd("指令")` 返回结果文字、`new_game(seed)` 重开一局。 | 想读懂 / 改数值 / 加鱼加地点,就看这个。也可以直接 `import engine` 当库用。 |
| **`fishing.py`** | **盲玩版**。引擎被打包进文件里、藏起来,只露 `cmd()`/`new_game()`。 | 想让 AI **不剧透**地玩,就把这个文件给它(它读不到鱼谱/概率,只能靠抛竿发现)。 |
| `build_blind.py` | 从 `engine.py` 重新生成 `fishing.py` 的小脚本。 | 改了 `engine.py` 后跑 `python build_blind.py`,让盲玩版跟上。 |
| `tool-schema.json` | `play_fishing` 工具的 JSON Schema(函数调用接法用)。 | 用「函数调用 / tool use」接 AI 时的参考。 |
| `examples/` | 接法示例。 | 照着接。 |
> `engine.py` 和 `fishing.py` 是**同一个游戏**,只是 `fishing.py` 把引擎藏了起来防剧透。二选一即可,或都放着。
---
## 快速开始(自己先玩两把)
需要 Python 3.8+。
```python
import engine # 或 import fishing(盲玩版,接口一样)
print(engine.cmd("help")) # 看规则
print(engine.cmd("status")) # 看当前状态
print(engine.cmd("cast")) # 抛一竿
print(engine.cmd("cast 10")) # 一次连钓 10 竿(只回一个汇总)
print(engine.cmd("cast 20 stop=rare")) # 连钓 20 竿,钓到稀有就停
print(engine.cmd("buy basic_worm 10; cast 10")) # 多条指令串一批、一次跑完
print(engine.new_game(2024)) # 用种子 2024 重开一局
```
> **Windows 用户**:游戏里有中文和 emoji。如果终端打印出现乱码或 `UnicodeEncodeError`,让控制台走 UTF-8 即可,三选一:
> - 设环境变量 `PYTHONUTF8=1` 再运行(推荐);
> - 或在终端先执行 `chcp 65001`;
> - 或在代码开头加 `import sys; sys.stdout.reconfigure(encoding="utf-8")`。
> (文件本身是 UTF-8、引擎没问题,这只是终端显示的事。)
> 任何输入都安全:`cmd("...")` 对乱七八糟的指令也只会**返回一句提示文字**,不会抛异常炸栈;存档读/写出问题(损坏 / 目录不可写)也会在返回里**明确告诉你**,不会假装存好了。
---
## 玩法
- **买饵 → 抛竿(cast)**:抛竿是核心。按稀有度概率钓上常见 / 少见 / 稀有 / 史诗 / 传说 / 神话各档的鱼。
- **每个地点 + 季节出的鱼不同**:想集齐图鉴,得 `goto` 换地点、留意季节(季节随抛竿数推进)。
- **卖鱼 / 卖宝(sell)换点数**,点数用来买好饵、**解锁新水域**。
- **抛竿偶遇**漂流瓶(收集纸条)、宝箱(要钥匙或花点数开)、宝物。
- **幸运时刻**:钓到鱼时小概率触发——分裂鱼钩(一竿上三条)、点石成金(这条价值×3)、渔获热潮(接下来几条翻倍)、河神的祝福(几竿不耗饵)、千载难逢的涨潮(破纪录大鱼)、蚌中生珠(掏出财宝)。
- **潜水远征(dive)**:潜水是后期玩法——**解锁第一个潜水点后,商店才上架氧气瓶**。买氧气瓶(买 5 瓶 8 折、10 瓶 7 折)后 `dive` 开一趟「远征」:带 N 瓶氧气当深度预算,捕获只有水下才有的鱼种(水面钓不到),上岸出一份**远征结算**(渔获/宝物/新发现/氧气花费/净值)。途中遇到**「大遗迹」会暂停**让你 `choose` 抉择——每个选项**消耗不同氧气**(氧气不够就只能放弃),通往不同的鱼种/宝物/故事。`surface` 可随时上浮。每次下潜顶部还有一句当地当季的「下潜实况」(水温/见闻/要不要防护服)。
- **解锁潜水点(藏宝图碎片)**:每个钓点的潜水要先解锁——在该地**水面钓鱼**会随机捞到「藏宝图碎片」,集齐 3~5 块(按水域深浅)自动拼成藏宝图,解锁这里的潜水。碎片也能从**漂流瓶、宝箱**里开出;运气好还能开出**稀有的完整藏宝图**,直接解锁一处潜水点。
- **水下奇遇**:潜水时小概率撞见 14 种水下奇观(珊瑚宫 / 人鱼宫殿 / 沉船墓场 / 鲸落 / 海妖巢穴 / 龙王宫阙 / 失落的钟楼…),捡到珍宝、古遗物、氧气或宝箱(水面不会遇到)。
- **集图鉴**:第一次钓到某种鱼会记入图鉴(卖掉也不丢记录),首次发现还有额外点数奖励。
开局:200 点 + 普通蚯蚓×5,在「月光池塘」(和「芦苇河」已解锁)。
## 指令清单(传给 `cmd("...")`)
| 指令 | 作用 |
|---|---|
| `help` | 看规则 |
| `status` | 点数 / 地点 / 季节 / 鱼饵 / 图鉴进度 |
| `shop` | 看可买鱼饵 |
| `buy <饵id> [数量]` | 买饵,如 `buy glow_bait 2`;买氧气瓶 `buy oxygen 5` |
| `cast [饵id] [次数] [stop=new,rare,event]` | 抛竿。不填饵=用最便宜的;带次数=连钓 N 竿(1~20);`stop=` 遇新种(new)/稀有(rare)/事件(event=漂流瓶·宝箱·宝物·水下奇遇)就提前停,可逗号多选 |
| `dive [带几瓶] [stop=...]` | 开潜水远征(先 `buy oxygen`)。带 N 瓶氧气下水捕水下鱼;遇大遗迹暂停 |
| `choose <编号>` | 在大遗迹处抉择(每个选项耗不同氧气;不带编号=重看选项) |
| `surface` | 主动结束远征、上浮上岸 |
| `goto` | **不带参数 = 列出所有钓点**(价格 / 本季还有几种没见过的鱼,含单列的传说级) |
| `goto <地点id>` | 前往该地点(未解锁则花点数解锁) |
| `inventory` | 渔篓 + 物品 + 待开宝箱 |
| `sell <实例id> \| sell all \| sell species <鱼id> \| sell item <物品id>` | 卖鱼 / 卖财宝换点数 |
| `open <宝箱uid>` | 打开钓上来的宝箱 |
| `encyclopedia` | 图鉴收集进度 |
| `look <id或中文名>` | 细看鱼 / 地点 / 鱼饵 / 季节 / 物品(没钓到的鱼显示 ???) |
| `A; B; C`(`;` 或换行串联) | 把多条指令排成一批、一次按序执行(最多 8 条),如 `buy basic_worm 10; cast 10`、`goto reed_river; cast 8 stop=new` |
### 连钓省 token(重点)
AI 一竿一条消息会反复来回烧上下文。用 `cast <次数>` 一次连钓:
```
cast 10 # 连钓 10 竿
cast glow_bait 15 stop=rare # 用夜光饵连钓 15 竿,钓到稀有及以上就停
```
返回是**一个汇总**:新种 / 稀有 / 事件 / 换季这些**精彩时刻留完整文案**,重复的杂鱼和空军**折叠成一行清点**。一次连钓把「≈2N 次往返」压成「≈2 次」。
### 叠加指令一次跑(batch)
用 `;` 或换行把多条不同指令串成一批、一次按顺序执行(最多 8 条),常见的「买饵→抛竿」「换地点→抛竿」一次搞定:
```
buy basic_worm 10; cast 10 # 先买 10 个蚯蚓,再连钓 10 竿
goto reed_river; cast 8 stop=new # 换到芦苇河,连钓 8 竿、钓到新种就停
```
每段前面带 `▶ 指令` 小标题,按序输出。某条出错只影响那一条、不打断后面的。
### 状态栏 JSON(每次都附)
每次 `cmd()` 返回的**末尾都有一行**紧凑机读状态栏,AI 看它就够、不必再单独 `status`:
```
📊 {"pts": 270, "loc": "芦苇河", "sea": "春", "turn": 6, "enc": "5/55", "bait": {"basic_worm": 2}, "hold": 6}
```
`pts` 点数 · `loc/sea` 当前地点/季节 · `turn` 回合 · `enc` 图鉴进度 · `bait` 余饵 · `hold` 未卖渔获条数(有待开宝箱时多一个 `chest`)。
## 存档 & 确定性
- 状态存在**和脚本同目录**的 `fishing_save.json`。删掉它 = 从头开始。
- 确定性:mulberry32 PRNG,随机状态序列化进存档。**同 seed + 同指令序列 → 结果完全一致**。默认种子 `0x9e3779b9`。
- 想多人各自一局:给每个玩家一个独立的工作目录(各有各的 `fishing_save.json`)。
---
## 接到你的 AI 上(三种接法,自己挑)
引擎只负责玩法逻辑,**怎么让你的 AI 调用它,由你按自己的栈配置**。三种常见姿势:
### ① AI 有代码执行(最简单)
ChatGPT 代码解释器 / Claude 带代码执行 / 自带沙箱的 agent:
把 `fishing.py`(盲玩版)丢给它,让它:
```python
import fishing
print(fishing.cmd("status"))
# 然后根据返回文字决定下一步,循环 cmd("cast")/cmd("buy ...")/cmd("goto ...")
```
见 `examples/play_with_code_interpreter.md`。
### ② 函数调用 / Tool use
把 `tool-schema.json` 里的 `play_fishing` 注册成一个工具。你的工具处理函数收到结构化参数后,转成指令字符串调 `engine.cmd()`,再把返回文字喂回模型:
```python
import engine
def play_fishing(args: dict) -> str:
a = args["action"]
if a in ("cast", "dive"):
parts = [a]
if a == "cast" and args.get("bait_id"): parts.append(args["bait_id"])
if args.get("times"): parts.append(str(args["times"]))
if args.get("stop_on"): parts.append("stop=" + ",".join(args["stop_on"]))
return engine.cmd(" ".join(parts))
if a == "choose": return engine.cmd(f"choose {args.get('choice','')}".strip()) # 大遗迹抉择
if a == "surface": return engine.cmd("surface")
if a == "buy": return engine.cmd(f"buy {args.get('bait_id','')} {args.get('qty',1)}") # bait_id=\"oxygen\" 即买氧气瓶
if a == "goto": return engine.cmd(f"goto {args.get('location_id','')}".strip())
if a == "sell": return engine.cmd(f"sell {args.get('target','')}")
if a == "open": return engine.cmd(f"open {args.get('chest_uid','')}")
if a == "look": return engine.cmd(f"look {args.get('id','')}")
return engine.cmd(a) # status / shop / inventory / encyclopedia
```
**更省事的替代**:不想用结构化参数,就注册一个只有一个字符串参数 `command` 的工具,处理函数直接 `return engine.cmd(command)`。模型自己写 `"cast 10 stop=rare"` 这种指令——这种字符串接法**天然支持叠加指令**,模型直接写 `"buy basic_worm 10; cast 10"` 就一次跑完。(结构化接法要支持 `batch`,就把 `steps` 里每步转成指令串、用 `"; "` 连起来传给一次 `engine.cmd()`。)
### ③ 自己写循环
最朴素:模型输出一条指令 → 你 `engine.cmd(指令)` → 把返回文字塞回对话 → 模型决定下一步 → 循环。
---
## 盲玩说明(防剧透)
想让 AI 像真玩家一样**靠抛竿发现**、而不是提前知道有哪些鱼 / 概率:
- 给它 **`fishing.py`**(引擎藏在打包数据里),别给 `engine.py`。
- 告诉它:只调 `cmd()`,别去解码 / 读文件里那段打包数据。
> 坦白说:打包只是编码、不是加密,铁了心要偷看的模型一行代码就能解开。盲玩本质靠**配合**。正经玩的模型照着说明来就不会剧透。
---
## 内容规模
55 种水面鱼(跨常见 / 少见 / 稀有 / 史诗 / 传说 / 神话 6 档)+ 22 种潜水专属水下鱼(带捕获手感)+ 潜水氛围句(按地点×季节)+ 14 种水下奇遇(含 5 个带抉择的「大遗迹」)+ 25 件宝物 + 8 条遗迹专属鱼 · 11 个钓点(2 个免费 + 9 个 200~800 点解锁)· 4 季节(每 20 竿推进一季)· 3 种鱼饵 + 氧气瓶潜水 · 漂流瓶 / 宝箱 / 宝物事件 · 6 种幸运随机事件 · 物品与点数经济 · 图鉴收集 · 稀有度仪式感播报 + 地点氛围/性格句。
## 改造 / 扩展
所有内容(鱼 / 地点 / 鱼饵 / 季节 / 事件 / 物品)都是 `engine.py` 顶部的纯数据表,加内容只改数据、不动逻辑。
改完 `engine.py` 后,如果你用盲玩版,跑一下让它跟上:
```bash
python build_blind.py # 从 engine.py 重新生成 fishing.py
```
`fishing.py` 的内容就是 `engine.py` 的 base64,两份永远一致、不会分叉。
## License
MIT,详见 `LICENSE`。随便用、随便改、随便接到你和你 AI 的小日子里。🎣
连接信息
猜你喜欢
暂无推荐服务器