Adds the Katan screen on top of the WALA-119 engine, built in separable layers
so the look, wording, layout and interaction can each be changed alone:
- CatanStyle: every colour and proportion (light/dark), via LocalCatanStyle
- CatanText: every word on screen (pure functions of state)
- CatanGeometry: lattice -> pixels and tap hit-testing (pure, unit-tested)
- CatanInteraction: what is tappable and what a tap means, derived only from the
engine's legal-move list (pure, unit-tested)
- CatanBoardView / CatanPanels / CatanDialogs: stateless composables
- CatanScreen: wiring to MatchController, portrait and landscape layouts
- CatanPreviews: Android Studio previews of real positions
- docs/UI-catan.md: how to adapt each layer, rules of the road, known gaps
Wiring: PlayScreen branch, GameSetupScreen options (3-4 players, game to
5/8/10/12), and a GameDescriptor.devPreview flag so dev builds can open Katan
while production still hides it until two-device play is verified.
Tests: CatanGeometryTest, CatanInteractionTest, CatanTextTest, CatalogTest.
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01JdMNbY5hLR7FjtfEE712xG
Brings in the Katan rules engine, board, model and AI (WALA-119), its 51 unit
tests and docs/RULES-catan.md. Only conflict was docs/README.md, which the
GitHub-lineage migration had dropped: kept the engine branch's index and
pointed the CI link (docs/CI.md no longer exists) at the root README.
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01JdMNbY5hLR7FjtfEE712xG
The island game as a pure-Kotlin state machine under game/catan/, wired to
the upstream GameRules / GameAi contract and fully unit-tested on the JVM.
- game/catan/: CatanModel (state, moves, phases), CatanBoard (19-hex
geometry, seeded island generation with the 6/8 separation rule, shared
vertex/edge graph), CatanRules (setup, production, the seven and the
robber, domestic and maritime trade, building, development cards,
Longest Road, Largest Army, win detection), CatanAi (a heuristic opponent
that reads only public information).
- GameRules.isLegalMove: a defaulted structural legality check so a game
with a combinatorial move space (Catan's trade offers) is gated the same
way as one with an enumerated move list; MatchController uses it.
- GameCatalog.CATAN: the catalogue entry, listed but not yet available
(descriptor and screen land with the screen task).
- Tests: 51 across CatanBoardTest, CatanRulesTest and CatanAiTest —
geometry invariants, generation balance, setup, production, the
seven/robber, both trade types, development-card timing, Longest Road
edge cases, Largest Army, win detection, and AI games played to a result.
- docs/RULES-catan.md, in the per-game style, with the rule choices and
the known gaps called out.
Two real engine bugs found and fixed while getting the suite green:
VERTEX_EDGES counted each shared edge once per adjacent hex, so an
interior vertex looked like it had six edges (which also double-counted
segments in the Longest Road search and duplicated setup moves); and the
applyRoll seven-transition was a discarded expression, so a seven never
left AWAIT_ROLL. Three test fixtures rolled from the PLAYING phase and two
assumed a two-seat rotation; corrected to the phases and seat order the
engine actually uses.
Verified: ./gradlew :app:testDebugUnitTest --offline — 679 tests, 0 failures.
Co-Authored-By: Paperclip <[email protected]>
Import of ProLibertateGames (upstream main, GPL-3.0) rebranded for
Wallacenet and repointed at git.wallacenet.ca.
- Identity: applicationId ca.wallacenet.pilgrimsofkatan (+ .dev for the dev
channel), launcher names "Pilgrims of Katan" / "Pilgrims of Katan DEV",
neutral hexagon branding replacing the Wallace tartan. Uncial Antiqua keeps
its OFL licence, and the GPL-3.0 LICENSE plus upstream attribution stay.
- OTA: Updater.kt now reads this repo's own Gitea releases
(/api/v1/repos/devadmin/PilgrimsOfKatan/releases...) and BuildConfig.
OTA_ENABLED is on; Gitea answers the same JSON shape the code already parsed.
- Build numbers: versionCode = CI run number + plgVersionRunOffset (1000),
with the tag and versionName derived from the same figure. The offset is
permanent, because Gitea Actions restarts run numbers at 1 and a reset would
otherwise make Android reject the next build as a downgrade.
- CI: ci.yml publishes a dev prerelease from dev, release.yml a production
release from main, both through scripts/publish-release.sh (Gitea REST API,
runnable by hand until an Actions runner is registered).
- Docs: docs/CI.md records the channel, numbering and runner decisions;
docs/README.md seeds the per-game RULES-* conventions; CLAUDE.md carries the
agent ground rules.
Verified: ./gradlew assembleDebug and testDebugUnitTest green on JDK 17 /
compileSdk 34, both variants stamped, installing side by side under the new
identity.
Co-Authored-By: Paperclip <[email protected]>