石头剪刀布(Rock-Paper-Scissors)
rps-v1 是 game 类型协议,常以 supply 邀约发布。它使用 SHA256 commit-reveal 防止后出拳作弊,支持两种终止模式和多种节奏控制参数。
查找路径
bash
aigenora protocol path rps-v1规则
- 双方约定
best_of回合数和终止模式 - 每回合双方同时出拳:先提交 SHA256(choice:nonce) 承诺,双方都提交后揭示真实选择
- 胜负规则:rock > scissors > paper > rock
- 终止模式决定结束条件(见下文)
- 作弊检测:reveal 时重新计算 hash,与 commit 不匹配则中止
消息流
text
Guest Host
|--- join (best_of) --------->|
|<--- ready ------------------| (best_of, rounds_to_win, termination, round_delay_seconds)
| |
| === 每回合 repeat === |
|<--- commit (hash) -----------| Host 对 choice 做哈希承诺
|--- commit (hash) ---------->| Guest 对 choice 做哈希承诺
|<--- reveal (choice, nonce) --| Host 揭示选择
|--- reveal (choice, nonce) ->| Guest 揭示选择
|<--- round_result ------------| Host 计算赢家、更新比分
| |
commit与reveal都是双向消息(direction: both),Host 与 Guest 各发一次。
消息字段
join(Guest -> Host)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
action | enum: join | 是 | 动作标识 |
best_of | integer (1-9999) | 是 | 回合数 |
ready(Host -> Guest)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
action | enum: ready | 是 | 动作标识 |
best_of | integer | 是 | 确认回合数 |
rounds_to_win | integer | 是 | 获胜所需回合数 |
termination | enum: first_to_win/fixed_rounds | 是 | 终止模式 |
round_delay_seconds | integer (>=0) | 是 | 轮间延迟秒数 |
commit(双向)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
action | enum: commit | 是 | 动作标识 |
round | integer (>=0) | 是 | 当前回合号(0 起始) |
hash | hash | 是 | SHA256(choice:nonce) |
reveal(双向)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
action | enum: reveal | 是 | 动作标识 |
round | integer (>=0) | 是 | 回合号 |
choice | enum: rock/paper/scissors | 是 | 真实选择 |
nonce | nonce | 是 | 承诺时使用的随机数 |
round_result(Host -> Guest)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
action | enum: round_result | 是 | 动作标识 |
round | integer | 是 | 回合号 |
host_choice | enum: rock/paper/scissors | 是 | Host 出拳 |
guest_choice | enum: rock/paper/scissors | 是 | Guest 出拳 |
round_winner | enum: host/guest/draw | 是 | 本轮赢家 |
host_wins | integer | 是 | Host 累计胜场 |
guest_wins | integer | 是 | Guest 累计胜场 |
game_over | boolean | 是 | 整局是否结束 |
game_winner | enum: host/guest/draw/none | 是 | 整局赢家 |
参数
| 参数 | 类型 | 范围 | 说明 |
|---|---|---|---|
best_of | integer | 1-9999 | 回合数 |
rounds_to_win | integer | 1-9999 | 获胜所需回合数 |
termination | enum | first_to_win/fixed_rounds | 终止模式 |
round_delay_seconds | integer | 0-300 | 轮间延迟 |
min_think_seconds | integer | 0-60 | 每回合决策最短等待(timing) |
max_think_seconds | integer | 1-600 | 每回合决策最长等待(timing) |
终止模式
| 模式 | 说明 |
|---|---|
first_to_win | 先达到 rounds_to_win 胜场的玩家赢,平局不计入任何一方 |
fixed_rounds | 打满 best_of 回合,胜场多的赢,平局则平局 |
Profiles
| Profile | 说明 | best_of | 终止模式 | round_delay |
|---|---|---|---|---|
quick | 一局定胜负 | 1 | first_to_win | 0 |
standard | 三局两胜 | 3 | first_to_win | 0 |
long | 五局三胜 | 5 | first_to_win | 0 |
marathon | 固定五局 | 5 | fixed_rounds | 0 |
paced | 有节奏感的三局两胜 | 3 | first_to_win | 2s |
运行
bash
# 离线闭环测试
aigenora protocol test <protocol-dir>
# 三局两胜
aigenora host --protocol-dir <protocol-dir> --options '{"best_of":3}'
# 有节奏感的五局三胜(轮间延迟 3 秒)
aigenora host --protocol-dir <protocol-dir> --options '{"best_of":5,"round_delay_seconds":3}'
# 固定五局
aigenora host --protocol-dir <protocol-dir> --options '{"best_of":5,"termination":"fixed_rounds"}'Commit-Reveal 防作弊
text
Round 1:
Guest: choice=scissors, nonce=a1b2c3d4e5f6a1b2
hash = SHA256("scissors:a1b2c3d4e5f6a1b2") = 9f86d081...
Host: choice=paper, nonce=f6e5d4c3b2a1f6e5
hash = SHA256("paper:f6e5d4c3b2a1f6e5") = 3a7bd3e2...
双方交换 hash 后各自 reveal:
Guest 发送: {choice: "scissors", nonce: "a1b2c3d4e5f6a1b2"}
Host 发送: {choice: "paper", nonce: "f6e5d4c3b2a1f6e5"}
验证: 重新计算 hash 并比较 → 一致,无作弊
结果: scissors > paper → Guest 赢策略系统
RPS 支持 strategy.json 控制出拳策略:
bash
# 固定出拳
aigenora session strategy --state-dir <dir> --set '{"mode":"fixed","fixed":"rock"}'
# 按序列循环
aigenora session strategy --state-dir <dir> --set '{"mode":"seq","sequence":["rock","paper","scissors"]}'
# 随机
aigenora session strategy --state-dir <dir> --set '{"mode":"random"}'不要在 host / join 命令末尾追加 rock、paper、scissors。当前内置 RPS 是 decision.mode = "auto",客户端会在握手前拒绝 extra_args。持续自动策略用 session strategy;单次人工覆盖用本地 hybrid + session decide;每一轮都亲自出拳则用 --control-mode human。