Lazy loaded image
Task 6 -
Words 1160Read Time 3 min
2025-5-29
我们将实现 4 个与国际象棋数据分析相关的函数,帮助朋友 Binh 分析 lichess.org 的数据。数据采用 PGN 格式,表示一盘棋的元信息与走法。以下是每一部分的解释:

✅ Part 1: read_pgn(file_name: str) -> list[dict]

目标: 读取一个 .pgn 文件,输出一个包含棋局信息的字典列表,每个字典对应一局棋。
输入: .pgn 文件路径
输出: 包含如下 key 的字典列表:
  • 元信息字段(7 个):event, white, black, result, whiteelo, blackelo, opening
  • 走法字段(40 个):w1w20b1b20
细节说明:
  • 如果某一回合没有白棋或黑棋走子,用 '-' 占位。
  • 所有 40 个字段都必须存在(即使游戏早就结束)。
具体细节:
❓:.png 文件的格式是怎样的?
  1. 每一场游戏以换行间隔
  1. 每场游戏又分为两个部分:赛事基本信息 以及 下棋详细步骤 , 也已换行间隔
  1. 每场游戏的具体细节:
    1. 每场游戏具体长什么样子:
      可以观察到的特点:
      1. 赛事基本信息:
        1. [ ] 包裹每条信息 ➡️ .strip()
        2. 每条信息的名称和内容用空格分割 ➡️ .split()
        3. 信息的type ➡️ …(自己想吧。在 part1 就想好, part2 3 4 就不用想了)
       
❓:要求的list格式是怎样的?
  1. list的结构:list [ dict { str: str } ] 思考:dict 的 value 一定要是 str 吗?
  1. keys:
    ❓:具体实操细节?
    1. 注意换行分割的内容有什么不同?
    1. 注意key的大小写?
    1. 文件中赛事具体细节中每一条的内容已经包含了 ?

    ✅ Part 2: win_loss_by_opening(games: list[dict]) -> dict

    目标: 统计每种开局的胜负情况。
    输入: 上一步生成的棋局字典列表。
    输出: 一个字典,key = opening namevalue = (白胜场数, 黑胜场数)
    判断胜负的方法:
    • result == '1-0' 表示白胜
    • result == '0-1' 表示黑胜
    • result == '1/2-1/2' 表示平局(忽略)
    具体细节:
    注意:
    1. 返回的dict结构:dict{str: tuple}
    1. result 有几种情况?思考:只有两种吗?面对不同result统计时应该怎样加分?
     

    ✅ Part 3: win_loss_by_elo(games: list[dict], lower: int, upper: int) -> tuple[int, int]

    目标: 在某个 ELO 差距区间内,统计低分选手 vs 高分选手 的胜负场数。
    输入:
    • games: 棋局列表
    • lower, upper: ELO 差值区间 (lower < |elo1 - elo2| < upper)
    输出: (低分胜场, 高分胜场)
    细节说明:
    • 需要跳过 whiteeloblackelo'?' 的记录
    • 比较两个数值,找出低分和高分选手,看谁赢了
    具体细节:
    注意:
    1. 返回的tuple结构:tuple[int, int]
    1. 注意elo差值上下限?
    1. 要求的返回类型是tuple,一开始就一定要定义返回类型为tuple吗?

    ✅ Part 4: win_loss_by_moves(games: list[dict], moves: list[str]) -> tuple[int, int]

    目标: 给定一个走法序列(从开局开始),统计这种局面下白胜和黑胜的数量。
    输入:
    • games: 棋局列表
    • moves: 走法列表,如:['e4', 'e5', 'Nf3']
    输出: (白胜场数, 黑胜场数)
    具体细节:
    注意:
    1. 返回的tuple结构:tuple[int, int]
    1. 要求的返回类型是tuple,一开始就一定要定义返回类型为tuple吗?
    1. 怎么判断 moves 是否为 某场游戏的步骤 的子集?这是否涉及到对于遍历字典时,不知道下一个key具体是什么的情况下, 访问value?如果不涉及到这个问题,还能怎么做?