Skip to content

boopsa-yu/AIchess

Repository files navigation

AI 国际象棋项目

一个学习项目,第一个版本已大概完成,虽然我觉得它还不是很厉害,但我疑似并不是他的对手emmmmm

总而言之,对于一个完全不懂国际象棋的人,能做出一个比自己还强的AI,神经网络还是挺有趣的

elo 到达 1500 我就满意了

代码执行方式

uvicorn main:app --reload

国际象棋规则简述

棋盘与棋子

  1. 棋盘接结构

    • 棋盘为8×8的64个黑白交替方格,浅色棋格称为“白格”,深色棋格称为“黑格”。摆放时右下角需为白格
    • 横向为“行”(Rank),纵向为“列”(File),由字母a-h(file)和数字1-8(rank)标识每个格子
  2. 棋子配置

    • 双方各执16枚棋子,包括:1王、1后、2车、2象、2马、8兵
    • 初始摆法:白棋位于第1-2行,黑棋位于第7-8行。
    • 白棋的后置于白格;黑棋的后置于黑格。
    • 白棋从左至右棋子摆放顺序为:RNBQKBNR。黑棋与其对应

棋子移动规则

  1. 基础规则

    • 王(King):横、直、斜均可移动一格,不可进入被攻击的格子。特殊情况下可进行[王车易位]
    • 后(Queen):任意方向不限格数移动,威力最大
    • 车(Rook):横、直移动不限格数,不可斜走
    • 象(Bishop):斜线移动不限格数,开局时一象占白格,一象占黑格
    • 马(Knight):走“日”字形(行2列1或列2行1),可越子
    • 兵(Pawn):仅直进,第一步可选一或两格,之后每步一格;吃子时斜进一格
  2. 特殊规则

    • 吃过路兵(En Passant):若敌方兵第一步走两格至己方兵相邻位置,己方可立即斜吃该兵,但仅限下一步执行
    • 兵的升变(Promotion):兵抵达对方底线时,必须升变为己方的后、车、象或马(不可变王或兵)
    • 王车易位(Castling):每局一次,王向车横向移动两格,车越过王至相邻格。需满足以下条件:
      • 王与车未移动过,且位于同一横行(即不能与兵升变的车易位);
      • 中间无其他棋子;
      • 王未被将军,且经过和到达的格子不受敌方棋子攻击

胜负与和局

  1. 胜利条件

    • 将死(Checkmate):使对方王无法避开将军即为胜局
    • 认输或超时:一方主动认输或比赛时间耗尽
  2. 和局判定

    • 逼和(Stalemate):一方未被将军但无合法移动
    • 任何一方以任何合法走法都无法将死对方,这种“和棋”称“死局”
    • 三次重复局面:同一局面出现三次,且轮到同一方行棋
    • 50回合规则:连续50回合未吃子且未移动兵
    • 双方同意和棋:需在行棋时提出,对方接受即生效

FEN 规范解释

使用 board.shredder_fen() 可打印出当前棋局的详细描述

print(board.shredder_fen())
# rnbqkb1r/pp2pppp/2p2n2/3p4/3P1B2/4PN2/PPP2PPP/RN1QKB1R b HAha - 0 4
  • 第一个字符串表示棋子分布每层以 / 分隔,从第八层到第一层
  • 第二个字符串表示行棋方, b 代表 black
  • 第三个字符串表示特殊走法权利
    • 大写 HA 分别表示白方在 H 与 a 文件的车仍保留易位权;
    • 小写 ha 分别表示黑方在 h- 与 a- 文件的车仍保留易位权
    • - 表示无一方具有王车易位权
  • 第四个字符串表示是否有吃过路兵的可能
  • 第五个数字表示半回合计数:自上一次“吃子”或“兵着”之后,已经走过的半回合(half‑move)数,用于五十回合和棋规则
  • 全回合计数记录:目前是第几回合(full move),从1开始计数,每当黑方走完则+1

棋子/棋盘编码

原始棋盘编码

一共 8*8 = 64 个格子

棋子类型:6 + 1(空格子) = 7 种,使用 3 bits 编码

棋子颜色:(0 = 白方,1 = 黑方),使用 1 bit 编码

因此整个棋盘需要 64 * (3 + 1) = 256 bits 编码

再加上一个当前玩家的回合,(0 = 白方,1 = 黑方)

由于 +1 的编码方式有些难以实现,所以多加一个 bit 用于编码

从而需要 64 * (3 + 1 + 1) bits 进行编码

白棋使用 1, 2, 3, 4, 5, 6

黑棋使用 9, 10, 11, 12, 13, 14

空白格为 0

编码为位平面

思路来源于:twichchess

将不同特征(如棋子种类、易位权利、吃过路标记)的多值编码用多个二值通道(bit‑planes)表示,可以让卷积核更容易在局部感受野内学习到这些离散特征

将每个格子的原始编码(0–15)拆分为四条二值位平面(bit‑planes),再加上一个回合平面,共 5 个通道输入给卷积网络。

将王车易位、吃过路兵做特殊编码。

操作评估函数计算

给每个棋子赋分,数据来源:Simplified Evaluation Function

特殊赋分:

  • 孤兵与连通兵
  • 活跃度
  • 被将军惩罚
  • 将死特判

TODO:

  • 特殊操作加权,如 将军、绝杀、吃子、升变

每一步操作的得分评估函数:

更新了,但是暂时没时间写清楚

由于数据范围较大,因此做了简单的归一化,用当前得分除以当前对局得分绝对值的最大值。

训练数据来源

Chess Games

优化方向

  • 将棋局分为:开局、中局、残局。以优化棋局评估函数

  • 更新编码结构,将每一个旗子都编码为一个位面

  • 更新神经网络结构,现在的神经网络结构还是太随机了

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published