Metadata-Version: 2.5
Name: magmacrunch-checkers
Version: 0.1.0
Summary: Checkers against the computer. Terminal version.
Project-URL: Homepage, https://magmacrunch.com/arcade/checkers/
Author: magmacrunch media
License-Expression: PolyForm-Noncommercial-1.0.0
License-File: LICENSE
License-File: NOTICE
Keywords: arcade,board,checkers,games,terminal,tui
Requires-Python: >=3.10
Requires-Dist: magmacrunch>=0.7.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Requires-Dist: websockets>=14.0; extra == 'dev'
Provides-Extra: online
Requires-Dist: websockets>=14.0; extra == 'online'
Description-Content-Type: text/markdown

# Checkers (terminal)

Checkers against the computer, in a terminal. The second version of the game
beside `web/`, on the [magmacrunch](https://github.com/magmacrunch-media/magmacrunch)
engine's terminal backend: a cabinet in the magmacrunch arcade and its own
command, the same either way.

```
pipx install magmacrunch-checkers
checkers
```

For working on it, from this folder:

```
pip install -e ".[dev]"
python -m checkers
```

## Keys

| key | |
|---|---|
| `←` `↑` `↓` `→` | move the cursor |
| `ENTER` | pick up the piece under the cursor; on a marked square, put it down |
| `Esc` | put the piece back; with nothing picked up, the title (and from there, the arcade) |
| `R` | new game |
| `Q` | quit |

You play cyan, from the bottom, and move first. Marked squares are where the
piece you picked up may go: green for a step, yellow for a jump. The cursor is
bracketed as well as shaded, so it shows under `NO_COLOR`. The computer
answers after half a second, as it does on the page.

## Playing a person online (a prototype)

PLAY ONLINE on the title, or `checkers --online`, connects to the arcade's
own multiplayer server, the one behind the page's PLAY ONLINE button, so a
terminal and a browser can share a room. Type a name, then press `C` to create
a room and read its four-letter code to your opponent, or `J` to join one by
its code. The host plays red and moves first. Your own pieces are always
cyan, and black sees the board turned round, arrows included. `X` then `Y`
resigns.

```
pip install "magmacrunch-checkers[online]"     # websockets, only for this
checkers --online
checkers --online --server ws://127.0.0.1:8770  # a web/server.py on this machine
```

The server keeps the rules. This client sends a move and draws the board the
server sends back, so it cannot disagree with the browser about a capture.
The two are clients of one referee. `checkers/online.py` holds the protocol,
split into `Table` (the server's state, with no I/O) and `Connection` (the
WebSocket, on its own thread, polled once a frame).

`tests/test_online.py` runs `web/server.py` in-process on a free port and
plays it over real sockets. It covers:

- a random game checked move for move against `rules.py`, double jumps included;
- out-of-turn and illegal moves, which the server ignores;
- a wrong room code;
- an opponent leaving;
- two complete terminal sessions, through the lobby to a resignation, using
  keys alone.

It never contacts the live server. By hand, the real page in headless
Chromium has played a terminal client 40 moves deep, kings included, and the
two boards still matched.

What a prototype has not done yet:

- **Nobody has played the live server from a terminal**, only a copy of it
  run locally. The default address is `wss://magmacrunch.duckdns.org/checkers`,
  which is what `mpServerFor('checkers', 8770)` gives the public site.
- **No reconnect.** A dropped connection says so, and the game is lost.
- **No chat**, which the browser has.
- **Moves the server drops are dropped silently.** It allows ten game
  actions per address every three seconds, so two players behind one address
  can go over that, and it ignores an illegal move without replying. This
  client draws a move only once the server takes it, so a dropped one just
  doesn't happen, and you play it again. (The page used to draw it anyway and
  then wait forever. It now resends an unanswered move, and after six seconds
  goes back to the server's board and says so.)

## It is the browser's game, and the browser's opponent

`checkers/rules.py` is `web/js/board.js`, `ai.js` and `game.js`, ported
function for function. `tests/test_oracle.py` holds it to them:
`tools/js_oracle.mjs` loads those files unmodified, plays 120 games through
`Game`'s own API (half against a random player, half against a careful one
who wins some), and the test replays every move through the port and requires
the same board, state, turn and result after each. About 20,000 moves.

## Double jumps, and no draws

- **A jump may carry on.** After jumping, a piece that can jump again may,
  over as many pieces as the chain allows; each stop along the way is also a
  move, so you may stop early. This is the multiplayer server's rule, and it
  became the single-player rule too when `getMultiJumps` in `board.js` was
  fixed (it looked for the piece on the square the first jump landed on,
  where the piece had not moved, so no second jump was ever offered).
  `tests/test_server_parity.py` holds this port to `web/server.py`'s moves on
  3,000 random positions, so single-player and online cannot drift apart
  again unnoticed.
- **No draws.** There is no move limit and no repetition rule, so two sides
  with kings can chase each other for ever. In the oracle's careful-player
  games that is most of them.

There is no score table: the page keeps none for checkers.

Needs a 66x19 terminal.

## Licence

[PolyForm Noncommercial 1.0.0](LICENSE), as the rest of this repository. See
[NOTICE](NOTICE).
