局面快照

快照属于终端程序。每轮打印棋盘后附一行 JSON,写入九个棋盘格子、当前玩家和对局结果,供其他程序读取。写入实现在 cli.cpp,解析方是 replay.py;当前入口不进入终端循环,本章保留快照设计与字段说明。

快照字段

JSON 快照供回放等程序逐行解析,中文棋盘末行仍是 对局结果:X 获胜。X 三连后的快照如下:

快照示例
{"version":1,"sequence":5,"cells":["X","X","X","O","O"," "," "," "," "],"player":"X","status":"x_wins","winner":"X"}

快照的每个字段记录一项信息,中文棋盘末行的 对局结果:X 获胜 对应其中的 status 和 winner:

  • version:快照格式版本号,当前是 1。
  • sequence:已落子的次数,每执行一次有效落子加一。
  • cells:按行依次排列的九个棋盘格子,每三个是一行。
  • player:当前轮到的对局玩家,对局结束后不再轮换。
  • status:对局状态,进行中是 in_progress,X 获胜是 x_wins,O 获胜是 o_wins,平局是 draw。
  • winner:获胜方,X 获胜时是 X,O 获胜时是 O,其余为空。

棋盘还原

快照里的九个棋盘格子还原成这张棋盘:

XXX OO
X 三连后的快照还原图:第一行三个 X,第二行两个 O,其余棋盘格子为空。

WriteSnapshot 紧接棋盘文本写出一行 JSON,解析方读取该行的稳定字段。回放脚本 是一个解析方:读入一行快照,按字段还原棋盘与终局。

注意JSON 行与棋盘图的分工

JSON 行给程序:cells、status、winner 等字段逐行可解析,不依赖画面。中文棋盘和图给人看。图按 cells 摆放,不进入快照格式。

常见错误

删掉中文棋盘

把中文棋盘删掉、输出 JSON 时,玩家就看不到行列号。

  • 出错的原因:行列号印在中文棋盘上,JSON 里没有行列信息。
  • 正确的做法:中文棋盘照常打印,JSON 追加在每次打印之后。

先快照后落子

落子前就写快照时,JSON 里还是上一轮的棋盘,当前这一步没有记进去。

  • 出错的原因:快照记录的是写出那一刻的 Game,落子还没发生,字段自然是旧值。
  • 正确的做法:让 Game::TryPlace 接收落子,随后打印棋盘并追加快照。

自测问题

  1. 中文棋盘排版改了之后,其他程序要读九个棋盘格子,读的是中文棋盘那一行还是 JSON 快照那一行?

    查看答案

    读追加的那一行 JSON,取其中的 cells。中文棋盘一改排版,按位置读中文的程序就会读错;JSON 的字段不随排版改变。这一行还把当前玩家和对局结果写明,解析程序核对这里的字段。

本章回顾

你已经能读出快照里的棋盘、当前玩家和对局结果。终端程序接回构建后,代码、测试、运行与快照会重新连成一条可跑的流程。