Skip to content

mendoza/InkMate

Repository files navigation

InkMate

Custom chess firmware for the Xteink X4 e-ink ebook reader (ESP32-C3). Started as a chess engine experiment — can I still write a program from scratch using only documentation? — then became a full playable game on the device's e-paper display.

InkMate mid-game on the X4: move history at top, dithered board with bitmap pieces, status footer

Captured straight from the device framebuffer — see Screenshots.

Features

Chess engine

  • Minimax + alpha-beta pruning
  • Iterative deepening with time limit
  • Transposition table (Zobrist hashing)
  • Move ordering (MVV-LVA)
  • Piece-square table evaluation

Game rules

  • Full move generation: pawns, en passant, castling, promotion
  • Checkmate and stalemate detection
  • 50-move rule draw
  • Insufficient material draw (K vs K, K+minor vs K, same-color bishops)

UI

  • Difficulty: Easy (depth 3 / 400 ms), Medium (depth 5 / 800 ms), Hard (depth 7 / 1500 ms)
  • Play as White, Black, or Random
  • 48×48 bitmap pieces rasterized from the Cburnett SVG set — outline for White, filled silhouette with white detailing for Black
  • Gray dark squares (50% checkerboard dither) with white halo masks so pieces stay crisp on any square
  • Legal move dots on valid destination squares
  • Captured pieces listed above and below the board with material advantage (PPNB +2)
  • Move history in long algebraic notation (e.g. Nb1xc3+), last moves visible during play
  • Game over screen with full move log
  • Auto-sleep after 10 min idle; wake on power button

Hardware

Component Detail
Device Xteink X4
MCU ESP32-C3
Display 1-bit e-ink, portrait orientation
Flash 16 MB
Input D-pad + confirm/back/power buttons

Controls

Button Action
LEFT / RIGHT Switch move direction (ray cycling)
UP / DOWN Walk distance along selected ray
CONFIRM Select piece / confirm move / confirm promotion
BACK Return to menu
POWER Sleep

Build & Flash

Requires PlatformIO and the open-x4-sdk submodule.

# First time — pull the SDK
git submodule update --init

# Build + flash
pio run -t upload

# Serial monitor (115200 baud)
pio device monitor

# Build only (no device needed)
pio run

Screenshots

With the device connected over USB, send S on the serial port and the firmware dumps its framebuffer as hex. tools/screenshot.py automates it:

pip install pyserial pillow
python3 tools/screenshot.py /dev/ttyACM0 screenshot.png

(Close pio device monitor first — only one program can hold the port.)

Chess Engine Tests (no device needed)

src/test.c compiles with plain gcc and runs three suites: perft (move generation correctness), draw detection, and search benchmarks.

make test
./test

Architecture

The chess engine (chess.c / chess.h) is pure C with no Arduino dependencies, so it builds and tests natively. Everything else is C++ / Arduino.

File Responsibility
chess.c Board state, move generation, apply/unmake, minimax search, Zobrist hashing, transposition table
render.cpp Wraps EInkDisplay + Adafruit_GFX; InkGFX subclass applies display rotation in drawPixel
piece_bitmaps.h 48×48 1-bit piece bitmaps (filled / outline / interior masks) generated from Cburnett SVGs
game.cpp Game loop: human vs. engine turns, move input, promotion picker, captured pieces, move history
menu.cpp Difficulty and side selection screen
ui.cpp Shared helpers: idle timer, footer hints, promotion picker, captured row renderer
main.cpp Top-level APP_MENU / APP_GAME state machine; InputManager polling; GPIO wakeup

SDK: open-x4-sdk/ is a git submodule providing EInkDisplay and InputManager, linked into the build via platformio.ini.

Board coordinates: index 0 = a1 (White's back-left corner). rank = index / 8, file = index % 8. White starts at indices 0–15, Black at 48–63.

License

See LICENSE.

About

Xteink X4 Chess Firmware

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages