# 公平模式

> 注入遊戲的用戶端能讀到全圖。公平模式讓 Bot 只看得見視野內的東西 —— 和人類玩家一樣，也和擂台規則一致。

來源: https://war3ai.com/zh-tw/docs/fair-mode/

本專案的觀察能力來自「用戶端持有所有玩家的狀態」：快照裡有整張地圖的所有單位，包括戰爭迷霧中的敵人。這對偵錯很方便，對比賽卻不公平。

**公平模式**讓 SDK 依你的視野過濾：

```bash
python tools/play.py --bot my_bot.py --fair
python -m openwar3 run my_bot.py --inst 5 --fair
```

```python
from openwar3 import Game, run
g = Game(inst=5, fair=True)            # 直接使用 Game
run(MyBot, inst=5, fair=True)          # 或者交給執行器
```

## 過濾了什麼

| 內容 | 公平模式下 |
|---|---|
| 單位 | 我方全部 + 此刻我方看得見的敵方與中立單位 |
| 地上物品 | 只保留我方單位視野內的（白天／夜晚視野依資料表分別計算） |
| 生產表 | 只保留看得見的建築（看不到對手在訓練什麼） |
| 事件 | 自己的；看得見的（或 1 秒內曾經看得見的）；我方造成的傷害 |

## 視野從哪裡來

- 快照裡每個單位都帶有一個**可見性遮罩**：第 p 位 = 玩家 p 此刻看得見它（只計算場上有單位的 0 ~ 11 號；自己的單位對自己永遠可見）。`u.visible_to(g.me())` 直接讀取它，零等待。
- 任意一點：`g.visible(x, y)` 詢問引擎（看得見／戰爭迷霧／黑色遮罩），走快車道，每次約一幀。一拍裡要判斷很多單位時，請用快照裡的 `u.visible_to()`，別逐一呼叫 `g.visible()`。

## 敵人的記憶：`last_seen`

人類玩家會記得「剛才在那邊看到一隊狼騎兵」。SDK 也幫你記：每次刷新快照時，記下我方此刻看得見的敵方與野怪單位（最後位置、血量、時間）；看到它陣亡就刪除，換局時清空。

```python
for u, t, age in g.last_seen(max_age=60):         # 60 遊戲秒內看到過的敵人
    print(u.type, u.x, u.y, f"{age:.0f}s 前")

heroes = [r for r in g.last_seen() if r[0].is_hero]   # 對方英雄上次出現在哪裡
camps  = g.last_seen(owner="creep")                   # 見過的野怪
```

公平模式下，這是你唯一的「對手資訊來源」—— 和人類玩家一樣。一般模式也依視野記錄，所以可以沿用同一套程式碼。

## 以幾號玩家的身分指揮

```bash
python tools/play.py --bot my_bot.py --player 1 --attach
```

`--player N`（或 `Game(player=N)`）讓 Bot 以 N 號玩家的身分指揮，只能指揮 N 號玩家的單位。兩個 AI 對戰，就是在同一局裡開兩條這樣的通道。

> **本機模式下，公平是約定，不是安全邊界**
>
> 在你自己的電腦上，沒有任何辦法阻止一個程式讀取全圖。`--fair` 是你對自己的約束；真正的比賽由[對戰平台](https://war3ai.com/zh-tw/arena/)的裁判行程保證：Bot 永遠碰不到共用記憶體，只能拿到裁判依視野過濾後的觀察，只能提交動作，而且每個動作都會先校驗單位歸屬。

## 為什麼現在就該開啟

- 將來上擂台時規則就是這樣，現在照公平模式寫，到時候一行都不用改；
- 少了全圖資訊，才知道你的 Bot 真正的實力如何（參考大腦目前大量依賴全圖資訊，例如電腦隊長的目標點 —— 這正好是一次檢驗）；
- 在公平模式下寫出來的偵察、記憶與判斷，才是真正有價值的 AI 能力。
