Chinese chess with a native vector board, hot-seat play and the OpenSpiel rule engine
  • Emacs Lisp 68.4%
  • Python 30.7%
  • Makefile 0.8%
Find a file
Kinneyzhang 032d0f552f
Some checks failed
Repository structure / structure (push) Has been cancelled
fix(xiangqi): point the runtime remedy at the install command
The doctor looked for a cache directory and told users to run a make target
in the framework checkout, which an archive installation cannot run. It now
checks the program that etaf-gamekit-openspiel-python-program names, the
same value the launch validates, and prints M-x
etaf-gamekit-install-openspiel as the remedy. The README prerequisites and
installation steps match.

Validation: make check passes (structure, byte compilation, 19 of 19
acceptance scenarios, 9 API declarations). Doctor reports the installed
environment and the new remedy text.
2026-11-06 17:28:11 +08:00
.githooks feat(xiangqi): add the standalone hot-seat xiangqi application 2026-10-11 14:40:58 +08:00
.github/workflows chore(scripts): sync shared workspace tooling 2026-10-19 12:49:38 +08:00
benchmarks feat(xiangqi): make solo play the default with a computer opponent 2026-10-13 14:09:55 +08:00
docs docs(xiangqi): point the examples at the flat workspace paths 2026-10-19 12:57:17 +08:00
examples docs(xiangqi): document installation, controls and screenshots 2026-10-13 00:35:23 +08:00
lisp refactor: resolve the board appearance through etaf-appearance-mode 2026-10-24 11:25:12 +08:00
scripts chore(scripts): sync shared workspace tooling 2026-10-22 13:16:16 +08:00
tests chore(xiangqi): follow the flat workspace layout 2026-10-19 12:49:01 +08:00
.editorconfig feat(xiangqi): add the standalone hot-seat xiangqi application 2026-10-11 14:40:58 +08:00
.gitignore feat(xiangqi): add the standalone hot-seat xiangqi application 2026-10-11 14:40:58 +08:00
etaf-xiangqi.el fix(xiangqi): point the runtime remedy at the install command 2026-11-06 17:28:11 +08:00
LICENSE feat(xiangqi): add the standalone hot-seat xiangqi application 2026-10-11 14:40:58 +08:00
Makefile feat(xiangqi): pace computer replies with native ETAF animations 2026-10-13 17:37:53 +08:00
README.md fix(xiangqi): point the runtime remedy at the install command 2026-11-06 17:28:11 +08:00

Chu He · 中国象棋

Chinese chess (xiangqi) with a native ETAF board and the OpenSpiel rule engine, built as an independent GameKit application. Play the computer or a friend: pick a stone, click a highlighted point, and the bridge answers for the computer's side or hands the turn to the other local player.

OpenSpiel owns legality, check, repetition and history, and its adapter owns the computer's search; this application owns the board, both palettes, selection, the move list, the opponent settings and the launcher. It never re-implements a move.

The board in the paper light theme

The same match in the night dark theme

Capabilities

  • A native board for the OpenSpiel xiangqi rule set with an optional legal-move list beside the board.
  • A computer opponent in easy, normal and hard search levels. It moves by itself on its turn, and the opponent dialog switches sides or hands both sides to local players without restarting the match.
  • Readable computer turns: at least 0.6 seconds before the reply appears, a smooth ETAF move animation, persistent origin/destination marks and a caption naming the move and any capture. Search still runs immediately in the backend.
  • Hot-seat play in one window; after every accepted move the view switches to the side to move.
  • A check that explains itself: the status line says 被将军, the general carries a danger frame, and pressing a stone that cannot answer the check says so in the caption instead of doing nothing.
  • Paper and night palettes; switching the theme never resets the match.
  • Undo and redo that restore the turn (against the computer, one step restores your own last round), and explicit local snapshots through C-s and C-o.

Prerequisites

Requirement Why Check
Emacs 29.1 or newer the ETAF runtime emacs --version
ecss, ebox, etaf, etaf-ui the framework and catalog components every root entry is on load-path
etaf-gamekit and its OpenSpiel backend rule engine, game instance and state publication M-x etaf-gamekit-install-openspiel
Python 3.11 or newer the OpenSpiel runtime python3.11 --version

Installation

git clone https://github.com/emacs-taf/ecss.git
git clone https://github.com/emacs-taf/ebox.git
git clone https://github.com/emacs-taf/etaf.git
git clone https://github.com/emacs-taf/etaf-ui.git
git clone https://github.com/emacs-taf/etaf-gamekit.git
git clone https://github.com/emacs-taf/etaf-xiangqi.git

Then install the OpenSpiel runtime once from the package itself with M-x etaf-gamekit-install-openspiel; it writes only under ~/.cache/emacs-taf/game-engines.

Add every provider root and this repository to load-path:

(add-to-list 'load-path "/path/to/ecss")
(add-to-list 'load-path "/path/to/ebox")
(add-to-list 'load-path "/path/to/etaf")
(add-to-list 'load-path "/path/to/etaf-ui")
(add-to-list 'load-path "/path/to/etaf-gamekit")
(add-to-list 'load-path "/path/to/etaf-xiangqi")
(require 'etaf-xiangqi)

(global-set-key (kbd "C-c x") #'etaf-xiangqi-open)

M-x etaf-xiangqi-open starts an independent match and fits the board to its window; it accepts an optional integer seed for a reproducible opening.

Keys

Input Action
Click a stone / Enter Select it and highlight its legal targets
Click a highlighted point Submit that native move
走法 → select a move Open the legal-move list and submit that move directly
U / Y Undo or redo the last local round (one move each in hot-seat play)
N or New match Start a fresh match with a random seed
O or 设置 Choose the opponent (hot-seat, computer sides) and difficulty
C-s / C-o Save or load an explicit local snapshot
T or Light–Dark Switch between the paper and night palettes
?, F1 or 规则 Open searchable rules and effective controls in the current buffer
Q Close the match

Red (bottom) moves first. etaf-xiangqi-opponent chooses who plays which side in new matches: computer-black (the default, with the human on red), computer-red, or hot-seat; etaf-xiangqi-level selects easy, normal (the default) or hard. Both are switchable at runtime from the opponent dialog. etaf-xiangqi-appearance selects the initial palette: auto, the default, follows the frame's background mode. Short windows remove vertical gaps and keep the board scrolled rather than stretched, and closing makes no implicit save.

Checks

make check   # structure, compilation, API and real-backend behavior scenarios

The manual documents the maintained GUI acceptance workflow separately.

Documentation

  • Chu He manual — the board, window adaptation and GUI acceptance.
  • Package entry — the supported API inventory.
  • GameKit — the shared game framework, its adapters and backend installation.

License

GPL-3.0-or-later; see LICENSE.