Add Game "Fox and Geese" - #1583
Open
Stochastic-Batman wants to merge 6 commits into
Open
Conversation
Adds the initial file structure, header declarations, and build setup for the Fox and Geese game. - Created `fox_and_geese.h` with state space calculations (that I posted on Mathematics Stack Exchange: https://math.stackexchange.com/questions/5145511/fox-and-geese-state-space-calculation) and game parameters - Added `fox_and_geese` library target to `CMakeLists.txt` - Registered new game in Python bindings test suite
Replace the copied tic-tac-toe initialization with Fox and Geese setup: - Add a compile-time mask for the 33-point cross (7x7 grid minus the four 2x2 corners) and use it to mark out-of-bounds cells. - Add the nested traditional geese layout table, read as a prefix of length num_geese, with the fox on the center point. - Wire up the num_foxes/num_geese parameters and reject anything other than one fox and 13, 15, or 17 geese. - Fix the cell state helpers for the fox/goose/out-of-bounds enum. - Drop the tic-tac-toe line-win logic and IsFull(); IsTerminal() now reads outcome_ only. Move generation, win conditions, undo, and the struct-based constructor are still stubbed and do not compile yet.
Replace the placeholder placement logic with the real rules. - Add compile-time adjacency and jump tables. Diagonals exist only on lines incident to the five hub points, and are recorded in both directions; jumps are derived edge by edge rather than assumed, so hub-to-hub lines like (3,1)-(2,2)-(1,3) are included and off-board ones like (3,3)-(2,2)-(1,1) are not. - Encode actions as (from, to) pairs plus a reserved end-turn action, and update NumDistinctActions and the action struct to match. - Generate fox steps and jumps, and geese steps restricted to forward and sideways in the 15- and 17-goose games. - Keep the move with the fox while further jumps are available, since captures are optional and may be chained. - Set the outcome when the geese fall below kMinGeeseToTrapFox or the player to move has no legal action, and draw at the move limit. - Reverse moves, captures, and chain state via an undo record stack. - Rebuild the struct-based constructor around the board shape and the real piece counts. - Add the games.md entry.
- Start with the geese to move, per the majority of rule sets. - Carry continue_jump_from through the state struct so a fox partway through a jump chain survives serialization, and reject values that no reachable state could produce. - Serialize the stored current player rather than CurrentPlayer(), which reports kTerminalPlayerId and so made terminal states fail to round-trip. - Document that a player with no legal move loses and that reaching the move limit is a draw.
Add fox_and_geese_test.cc covering: - game parameters and the num_foxes/num_geese validators - all three starting layouts (13/15/17 geese) against expected board strings, piece counts, and opening move counts - board geometry (diagonal vs non-diagonal points) via legal-move counts from isolated positions - optional captures and multi-jump chains, including kEndTurnAction - goose movement restrictions in the 15/17-goose games - both win conditions and the no-legal-move rule - UndoAction for steps and captures - state/observation/action struct JSON round-trips, including a mid-jump-chain state - RandomSimTest and RandomSimTestWithUndo across all three configs
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
Collaborator
|
Thanks! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements Fox and Geese, an asymmetric, zero-sum, perfect-information hunting game played on a 33-point cross-shaped board (7x7 grid with the four 2x2 corners removed). One fox tries to capture geese by jumping over them; the geese try to trap the fox so it has no legal move. The fox wins if it reduces the geese below the number needed to trap it (4); the geese win by immobilizing the fox; a player with no legal move loses; games reaching the move limit are declared a draw.
Here's the starting position (13 geese, the traditional default):
Only the classic one-fox game is implemented, with the three traditional starting configurations (13/15/17 geese, selectable via the
num_geeseparameter). The two-fox Scandinavian variant (Halatafl/Rävspelet) and Asalto are out of scope - they have different win conditions and board rules, and are separate games rather than parameterizations of this one.Captures are optional and may be chained (a jump keeps the turn if a further jump is available); geese in the 15/17-goose configurations are restricted to forward/sideways movement, per the historical rules that offset the extra material.
Closes #1581.
Testing
fox_and_geese_test,pyspiel_test.py, andapi_test.py.fox_and_geese_test.cccovers all three starting layouts, board geometry (diagonal vs. orthogonal points), optional and chained captures, goose movement restrictions, both win conditions, undo, and JSON struct round-trips (including mid-jump-chain states), plusRandomSimTest/RandomSimTestWithUndoacross all configurations.num_foxes/num_geesevalues are rejected at construction with explanatory errors; verified viapyspiel.load_game.exampleandmcts_example, including 1000-simulation MCTS self-play across all three configurations, which exercised multi-jump chains (up to 5 captures in a single turn) end to end.playthrough_test.py.