Serve practice mode from the main server, add mode switch, fix touch

Practice mode is now at /practice on server.py instead of a separate
server, with a button in the bottom-right corner of each page to the
other mode. Touch: no double-tap zoom, no sticky hover after a tap, no
long-press selection on the board, and a pressed look on tapped squares.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
tukaunuandClaude Opus 5.5 committed 2026-10-22 01:47:27 +02:00
1 parent c52f30dc59
commit ce6b71eb35
7 files changed
+51 -42

No files matched your search

+7 -8
View File
@@ -12,18 +12,20 @@ python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
.venv/bin/python server.py # http://127.0.0.1:8080
.venv/bin/python server.py --host 0.0.0.0 --port 8080 # reachable on your LAN
.venv/bin/python practice.py # vs the computer: http://127.0.0.1:8081
```
Practice mode (vs the computer) is at `/practice` on the same server. The switch in the
bottom-right corner of each page goes between the two modes.
Tests: `.venv/bin/python -m unittest discover -s tests -t .`
## How it works
- `game.py`: the rules, no networking.
- `server.py`: one aiohttp process. `/ws?game=CODE` is the live connection, and
everything else is static files.
- `practice.py`: a separate server for playing against the computer. It holds no state:
the page sends the position to `POST /api/play` and gets the next one back.
- `server.py`: one aiohttp process. `/ws?game=CODE` is the live connection, `/practice`
and `POST /api/play` are practice mode, and everything else is static files.
- `practice.py`: practice mode's move endpoint, mounted by `server.py`. It holds no
state: the page sends the position to `POST /api/play` and gets the next one back.
- `solver.py`: solves every reachable position (~67k, about a second at startup) so the
computer knows the perfect move everywhere.
- `static/`: the pages. Plain HTML/CSS/JS, no build step. `board.js` is the board
@@ -66,7 +68,6 @@ your home IP. WebSockets work through it without any extra configuration.
cloudflared tunnel login
cloudflared tunnel create moonchess
cloudflared tunnel route dns moonchess moonchess.example.com
cloudflared tunnel route dns moonchess practice.moonchess.example.com # if running practice.py
```
3. `~/.cloudflared/config.yml`:
```yaml
@@ -75,8 +76,6 @@ your home IP. WebSockets work through it without any extra configuration.
ingress:
- hostname: moonchess.example.com
service: http://localhost:8080
- hostname: practice.moonchess.example.com # optional, if you run practice.py
service: http://localhost:8081
- service: http_status:404
```
4. `cloudflared tunnel run moonchess` (or `sudo cloudflared service install` to run it at boot).