chuk-puzzles-gym 0.10__tar.gz → 0.10.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {chuk_puzzles_gym-0.10/src/chuk_puzzles_gym.egg-info → chuk_puzzles_gym-0.10.1}/PKG-INFO +1 -1
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/pyproject.toml +1 -1
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/binary/game.py +2 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/bridges/game.py +2 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/cryptarithmetic/game.py +5 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/einstein/game.py +2 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/fillomino/game.py +2 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/futoshiki/game.py +2 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/graph_coloring/commands.py +20 -3
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/graph_coloring/game.py +8 -1
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/hidato/game.py +2 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/hitori/game.py +2 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/kakuro/game.py +2 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/kenken/game.py +2 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/killer_sudoku/game.py +2 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/knapsack/game.py +2 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/lights_out/game.py +2 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/logic_grid/game.py +2 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/mastermind/game.py +2 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/minesweeper/game.py +2 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/nonogram/game.py +2 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/nqueens/game.py +5 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/numberlink/game.py +6 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/nurikabe/game.py +2 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/rush_hour/game.py +4 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/scheduler/game.py +2 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/shikaku/game.py +2 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/skyscrapers/game.py +5 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/slitherlink/game.py +2 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/sokoban/game.py +2 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/star_battle/game.py +2 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/sudoku/game.py +2 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/tents/game.py +2 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/server.py +17 -69
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1/src/chuk_puzzles_gym.egg-info}/PKG-INFO +1 -1
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/MANIFEST.in +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/README.md +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/config.yaml +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/setup.cfg +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/constants.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/eval.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/export/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/export/dataset.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/_base/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/_base/commands.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/_base/game.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/binary/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/binary/config.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/bridges/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/bridges/config.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/cryptarithmetic/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/cryptarithmetic/commands.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/cryptarithmetic/config.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/einstein/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/einstein/config.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/einstein/constants.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/einstein/models.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/fillomino/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/fillomino/config.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/futoshiki/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/futoshiki/config.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/graph_coloring/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/graph_coloring/config.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/hidato/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/hidato/config.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/hitori/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/hitori/config.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/kakuro/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/kakuro/config.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/kenken/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/kenken/config.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/kenken/enums.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/kenken/models.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/killer_sudoku/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/killer_sudoku/config.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/killer_sudoku/models.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/knapsack/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/knapsack/config.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/knapsack/enums.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/knapsack/models.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/lights_out/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/lights_out/config.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/logic_grid/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/logic_grid/config.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/logic_grid/constants.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/logic_grid/models.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/mastermind/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/mastermind/config.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/minesweeper/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/minesweeper/config.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/minesweeper/enums.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/nonogram/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/nonogram/config.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/nqueens/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/nqueens/config.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/numberlink/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/numberlink/config.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/nurikabe/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/nurikabe/config.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/nurikabe/enums.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/rush_hour/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/rush_hour/commands.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/rush_hour/config.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/rush_hour/models.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/scheduler/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/scheduler/config.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/scheduler/constants.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/scheduler/enums.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/scheduler/models.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/shikaku/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/shikaku/config.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/skyscrapers/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/skyscrapers/config.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/slitherlink/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/slitherlink/config.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/sokoban/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/sokoban/config.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/star_battle/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/star_battle/config.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/sudoku/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/sudoku/commands.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/sudoku/config.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/tents/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/tents/config.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/gym_env.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/models/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/models/base.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/models/config.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/models/enums.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/models/evaluation.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/models/games.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/trace/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/trace/generator.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/utils/__init__.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym.egg-info/SOURCES.txt +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym.egg-info/dependency_links.txt +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym.egg-info/entry_points.txt +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym.egg-info/requires.txt +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym.egg-info/top_level.txt +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_base_models.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_binary_game.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_bridges.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_command_handlers.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_cryptarithmetic_game.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_deterministic_seeding.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_einstein.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_eval.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_fillomino.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_futoshiki_game.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_game_configs.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_graph_coloring_game.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_gym_env.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_hidato.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_hitori.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_kakuro_game.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_kenken_game.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_killer_sudoku.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_knapsack.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_lights_out.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_logic_grid_game.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_mastermind.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_minesweeper.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_nonogram_game.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_nqueens_game.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_numberlink_game.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_nurikabe.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_puzzle_game.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_rush_hour_game.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_scheduler.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_shikaku.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_skyscrapers_game.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_slitherlink.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_sokoban.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_star_battle.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_sudoku_game.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_tents.py +0 -0
- {chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/tests/test_trace_generator.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "chuk-puzzles-gym"
|
|
7
|
-
version = "0.10"
|
|
7
|
+
version = "0.10.1"
|
|
8
8
|
description = "Multi-game puzzle gym for LLM training and benchmarking - 30 constraint puzzles with synthetic data generation"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -358,6 +358,8 @@ class BinaryPuzzleGame(PuzzleGame):
|
|
|
358
358
|
Returns:
|
|
359
359
|
Tuple of (hint_data, hint_message) or None if puzzle is complete
|
|
360
360
|
"""
|
|
361
|
+
if not self.can_use_hint():
|
|
362
|
+
return None
|
|
361
363
|
empty_cells = [(r, c) for r in range(self.size) for c in range(self.size) if self.grid[r][c] == -1]
|
|
362
364
|
if not empty_cells:
|
|
363
365
|
return None
|
{chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/bridges/game.py
RENAMED
|
@@ -415,6 +415,8 @@ class BridgesGame(PuzzleGame):
|
|
|
415
415
|
|
|
416
416
|
async def get_hint(self) -> tuple[Any, str] | None:
|
|
417
417
|
"""Get a hint for the next move."""
|
|
418
|
+
if not self.can_use_hint():
|
|
419
|
+
return None
|
|
418
420
|
# Find a bridge in the solution that's not yet placed correctly
|
|
419
421
|
for bridge_key, solution_count in self.solution.items():
|
|
420
422
|
current_count = self.bridges.get(bridge_key, 0)
|
{chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/cryptarithmetic/game.py
RENAMED
|
@@ -362,6 +362,11 @@ class CryptarithmeticGame(PuzzleGame):
|
|
|
362
362
|
|
|
363
363
|
return "\n".join(lines)
|
|
364
364
|
|
|
365
|
+
def get_stats(self) -> str:
|
|
366
|
+
"""Get current game statistics."""
|
|
367
|
+
assigned = sum(1 for v in self.player_mapping.values() if v is not None)
|
|
368
|
+
return f"Moves: {self.moves_made} | Assigned: {assigned}/{len(self.letters)} | Seed: {self.seed}"
|
|
369
|
+
|
|
365
370
|
def get_rules(self) -> str:
|
|
366
371
|
return (
|
|
367
372
|
"CRYPTARITHMETIC\n"
|
{chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/einstein/game.py
RENAMED
|
@@ -281,6 +281,8 @@ class EinsteinGame(PuzzleGame):
|
|
|
281
281
|
Returns:
|
|
282
282
|
Tuple of (hint_data, hint_message) or None
|
|
283
283
|
"""
|
|
284
|
+
if not self.can_use_hint():
|
|
285
|
+
return None
|
|
284
286
|
# Find first unassigned attribute in solution
|
|
285
287
|
for i in range(self.num_houses):
|
|
286
288
|
for attr in ATTRIBUTES:
|
{chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/fillomino/game.py
RENAMED
|
@@ -435,6 +435,8 @@ class FillominoGame(PuzzleGame):
|
|
|
435
435
|
Returns:
|
|
436
436
|
Tuple of (hint_data, hint_message) or None if puzzle is complete
|
|
437
437
|
"""
|
|
438
|
+
if not self.can_use_hint():
|
|
439
|
+
return None
|
|
438
440
|
# Find an empty cell
|
|
439
441
|
for r in range(self.size):
|
|
440
442
|
for c in range(self.size):
|
{chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/futoshiki/game.py
RENAMED
|
@@ -288,6 +288,8 @@ class FutoshikiGame(PuzzleGame):
|
|
|
288
288
|
Returns:
|
|
289
289
|
Tuple of (hint_data, hint_message) or None if puzzle is complete
|
|
290
290
|
"""
|
|
291
|
+
if not self.can_use_hint():
|
|
292
|
+
return None
|
|
291
293
|
empty_cells = [(r, c) for r in range(self.size) for c in range(self.size) if self.grid[r][c] == 0]
|
|
292
294
|
if not empty_cells:
|
|
293
295
|
return None
|
|
@@ -4,10 +4,14 @@ from typing import TYPE_CHECKING
|
|
|
4
4
|
|
|
5
5
|
from ...models import GameCommand, MoveResult
|
|
6
6
|
from .._base import CommandResult, GameCommandHandler
|
|
7
|
+
from .game import COLOR_NAMES
|
|
7
8
|
|
|
8
9
|
if TYPE_CHECKING:
|
|
9
10
|
from .game import GraphColoringGame
|
|
10
11
|
|
|
12
|
+
# Build a lookup from lowercase color name to color number
|
|
13
|
+
_COLOR_NAME_TO_NUM = {name.lower(): i + 1 for i, name in enumerate(COLOR_NAMES)}
|
|
14
|
+
|
|
11
15
|
|
|
12
16
|
class GraphColoringCommandHandler(GameCommandHandler):
|
|
13
17
|
"""Handles commands for Graph Coloring game."""
|
|
@@ -36,6 +40,16 @@ class GraphColoringCommandHandler(GameCommandHandler):
|
|
|
36
40
|
else:
|
|
37
41
|
return self.error_result(f"Unknown command: {cmd}")
|
|
38
42
|
|
|
43
|
+
def _parse_color(self, value: str) -> int | None:
|
|
44
|
+
"""Parse a color argument as either an integer or a color name."""
|
|
45
|
+
# Try integer first
|
|
46
|
+
try:
|
|
47
|
+
return int(value)
|
|
48
|
+
except ValueError:
|
|
49
|
+
pass
|
|
50
|
+
# Try color name lookup
|
|
51
|
+
return _COLOR_NAME_TO_NUM.get(value.lower())
|
|
52
|
+
|
|
39
53
|
async def _handle_place(self, args: list[str]) -> CommandResult:
|
|
40
54
|
"""Handle the PLACE command: place <node> <color>."""
|
|
41
55
|
if len(args) != 2:
|
|
@@ -45,10 +59,13 @@ class GraphColoringCommandHandler(GameCommandHandler):
|
|
|
45
59
|
)
|
|
46
60
|
|
|
47
61
|
node = self.parse_int(args[0], "node")
|
|
48
|
-
color = self.
|
|
62
|
+
color = self._parse_color(args[1])
|
|
49
63
|
|
|
50
|
-
if node is None
|
|
51
|
-
return self.error_result("Node
|
|
64
|
+
if node is None:
|
|
65
|
+
return self.error_result("Node must be an integer.")
|
|
66
|
+
if color is None:
|
|
67
|
+
valid = ", ".join(f"{i + 1}={COLOR_NAMES[i]}" for i in range(self.game.num_colors))
|
|
68
|
+
return self.error_result(f"Invalid color. Use a number or name: {valid}")
|
|
52
69
|
|
|
53
70
|
result = await self.game.validate_move(node, color)
|
|
54
71
|
|
{chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/graph_coloring/game.py
RENAMED
|
@@ -289,6 +289,11 @@ class GraphColoringGame(PuzzleGame):
|
|
|
289
289
|
|
|
290
290
|
return "\n".join(lines)
|
|
291
291
|
|
|
292
|
+
def get_stats(self) -> str:
|
|
293
|
+
"""Get current game statistics."""
|
|
294
|
+
colored = sum(1 for n in range(1, self.num_nodes + 1) if self.coloring.get(n, 0) > 0)
|
|
295
|
+
return f"Moves: {self.moves_made} | Colored: {colored}/{self.num_nodes} | Edges: {len(self.edges)} | Seed: {self.seed}"
|
|
296
|
+
|
|
292
297
|
def get_rules(self) -> str:
|
|
293
298
|
return (
|
|
294
299
|
f"GRAPH COLORING ({self.num_nodes} nodes, {self.num_colors} colors)\n"
|
|
@@ -298,9 +303,11 @@ class GraphColoringGame(PuzzleGame):
|
|
|
298
303
|
)
|
|
299
304
|
|
|
300
305
|
def get_commands(self) -> str:
|
|
306
|
+
color_map = ", ".join(f"{i + 1}={COLOR_NAMES[i]}" for i in range(self.num_colors))
|
|
301
307
|
return (
|
|
302
308
|
"Commands:\n"
|
|
303
|
-
f" place <node> <color> - Color a node (
|
|
309
|
+
f" place <node> <color> - Color a node (number or name)\n"
|
|
310
|
+
f" Colors: {color_map}\n"
|
|
304
311
|
" clear <node> - Remove color from a node\n"
|
|
305
312
|
" hint - Get a hint\n"
|
|
306
313
|
" check - Check if solved\n"
|
|
@@ -302,6 +302,8 @@ class HidatoGame(PuzzleGame):
|
|
|
302
302
|
Returns:
|
|
303
303
|
Tuple of (hint_data, hint_message) or None if puzzle is complete
|
|
304
304
|
"""
|
|
305
|
+
if not self.can_use_hint():
|
|
306
|
+
return None
|
|
305
307
|
# Find an empty cell
|
|
306
308
|
empty_cells = [(r, c) for r in range(self.size) for c in range(self.size) if self.grid[r][c] == 0]
|
|
307
309
|
if not empty_cells:
|
|
@@ -395,6 +395,8 @@ class HitoriGame(PuzzleGame):
|
|
|
395
395
|
|
|
396
396
|
async def get_hint(self) -> tuple[Any, str] | None:
|
|
397
397
|
"""Get a hint for the next move."""
|
|
398
|
+
if not self.can_use_hint():
|
|
399
|
+
return None
|
|
398
400
|
# Find a cell that should be shaded but isn't, or vice versa
|
|
399
401
|
for r in range(self.size):
|
|
400
402
|
for c in range(self.size):
|
|
@@ -366,6 +366,8 @@ class KenKenGame(PuzzleGame):
|
|
|
366
366
|
Returns:
|
|
367
367
|
Tuple of (hint_data, hint_message) or None if puzzle is complete
|
|
368
368
|
"""
|
|
369
|
+
if not self.can_use_hint():
|
|
370
|
+
return None
|
|
369
371
|
empty_cells = [(r, c) for r in range(self.size) for c in range(self.size) if self.grid[r][c] == 0]
|
|
370
372
|
if not empty_cells:
|
|
371
373
|
return None
|
{chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/killer_sudoku/game.py
RENAMED
|
@@ -395,6 +395,8 @@ class KillerSudokuGame(PuzzleGame):
|
|
|
395
395
|
Returns:
|
|
396
396
|
Tuple of (hint_data, hint_message) or None if puzzle is complete
|
|
397
397
|
"""
|
|
398
|
+
if not self.can_use_hint():
|
|
399
|
+
return None
|
|
398
400
|
empty_cells = [(r, c) for r in range(9) for c in range(9) if self.grid[r][c] == 0]
|
|
399
401
|
if not empty_cells:
|
|
400
402
|
return None
|
{chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/knapsack/game.py
RENAMED
|
@@ -255,6 +255,8 @@ class KnapsackGame(PuzzleGame):
|
|
|
255
255
|
Returns:
|
|
256
256
|
Tuple of (hint_data, hint_message) or None
|
|
257
257
|
"""
|
|
258
|
+
if not self.can_use_hint():
|
|
259
|
+
return None
|
|
258
260
|
# Suggest selecting an item that's in the optimal solution but not selected
|
|
259
261
|
for i in range(len(self.items)):
|
|
260
262
|
if self.optimal_selection[i] and not self.selection[i]:
|
{chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/lights_out/game.py
RENAMED
|
@@ -173,6 +173,8 @@ class LightsOutGame(PuzzleGame):
|
|
|
173
173
|
Returns:
|
|
174
174
|
Tuple of (hint_data, hint_message) or None if puzzle is complete
|
|
175
175
|
"""
|
|
176
|
+
if not self.can_use_hint():
|
|
177
|
+
return None
|
|
176
178
|
# Find a cell in the solution that should be pressed
|
|
177
179
|
for row in range(self.size):
|
|
178
180
|
for col in range(self.size):
|
{chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/logic_grid/game.py
RENAMED
|
@@ -235,6 +235,8 @@ class LogicGridGame(PuzzleGame):
|
|
|
235
235
|
Returns:
|
|
236
236
|
Tuple of (hint_data, hint_message) or None if puzzle is complete
|
|
237
237
|
"""
|
|
238
|
+
if not self.can_use_hint():
|
|
239
|
+
return None
|
|
238
240
|
# Find a connection that hasn't been marked
|
|
239
241
|
for person in self.categories.person:
|
|
240
242
|
attrs = self.solution[person]
|
{chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/nonogram/game.py
RENAMED
|
@@ -192,6 +192,8 @@ class NonogramGame(PuzzleGame):
|
|
|
192
192
|
Returns:
|
|
193
193
|
Tuple of (hint_data, hint_message) or None if puzzle is complete
|
|
194
194
|
"""
|
|
195
|
+
if not self.can_use_hint():
|
|
196
|
+
return None
|
|
195
197
|
unknown_cells = [(r, c) for r in range(self.size) for c in range(self.size) if self.grid[r][c] == -1]
|
|
196
198
|
if not unknown_cells:
|
|
197
199
|
return None
|
{chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/nqueens/game.py
RENAMED
|
@@ -296,6 +296,11 @@ class NQueensGame(PuzzleGame):
|
|
|
296
296
|
|
|
297
297
|
return "\n".join(lines)
|
|
298
298
|
|
|
299
|
+
def get_stats(self) -> str:
|
|
300
|
+
"""Get current game statistics."""
|
|
301
|
+
placed = sum(1 for r in range(self.size) for c in range(self.size) if self.grid[r][c] == 1)
|
|
302
|
+
return f"Moves: {self.moves_made} | Queens: {placed}/{self.size} | Board: {self.size}x{self.size} | Seed: {self.seed}"
|
|
303
|
+
|
|
299
304
|
def get_rules(self) -> str:
|
|
300
305
|
return (
|
|
301
306
|
f"N-QUEENS ({self.size}x{self.size})\n"
|
{chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/numberlink/game.py
RENAMED
|
@@ -317,6 +317,12 @@ class NumberlinkGame(PuzzleGame):
|
|
|
317
317
|
|
|
318
318
|
return "\n".join(lines)
|
|
319
319
|
|
|
320
|
+
def get_stats(self) -> str:
|
|
321
|
+
"""Get current game statistics."""
|
|
322
|
+
filled = sum(1 for r in range(self.size) for c in range(self.size) if self.grid[r][c] != 0)
|
|
323
|
+
total = self.size * self.size
|
|
324
|
+
return f"Moves: {self.moves_made} | Filled: {filled}/{total} | Pairs: {self.num_pairs} | Seed: {self.seed}"
|
|
325
|
+
|
|
320
326
|
def get_rules(self) -> str:
|
|
321
327
|
return (
|
|
322
328
|
f"NUMBERLINK ({self.size}x{self.size}, {self.num_pairs} pairs)\n"
|
{chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/nurikabe/game.py
RENAMED
|
@@ -479,6 +479,8 @@ class NurikabeGame(PuzzleGame):
|
|
|
479
479
|
Returns:
|
|
480
480
|
Tuple of (hint_data, hint_message) or None
|
|
481
481
|
"""
|
|
482
|
+
if not self.can_use_hint():
|
|
483
|
+
return None
|
|
482
484
|
# Find a cell that differs from solution
|
|
483
485
|
for row in range(self.size):
|
|
484
486
|
for col in range(self.size):
|
{chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/rush_hour/game.py
RENAMED
|
@@ -454,6 +454,10 @@ class RushHourGame(PuzzleGame):
|
|
|
454
454
|
|
|
455
455
|
return "\n".join(lines)
|
|
456
456
|
|
|
457
|
+
def get_stats(self) -> str:
|
|
458
|
+
"""Get current game statistics."""
|
|
459
|
+
return f"Moves: {self.moves_made} | Vehicles: {len(self.vehicles)} | Grid: {self.size}x{self.size} | Seed: {self.seed}"
|
|
460
|
+
|
|
457
461
|
def get_rules(self) -> str:
|
|
458
462
|
return (
|
|
459
463
|
f"RUSH HOUR ({self.size}x{self.size})\n"
|
{chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/scheduler/game.py
RENAMED
|
@@ -316,6 +316,8 @@ class SchedulerGame(PuzzleGame):
|
|
|
316
316
|
Returns:
|
|
317
317
|
Tuple of (hint_data, hint_message) or None
|
|
318
318
|
"""
|
|
319
|
+
if not self.can_use_hint():
|
|
320
|
+
return None
|
|
319
321
|
# Find an unscheduled task that's in the optimal solution
|
|
320
322
|
for task_id in range(self.num_tasks):
|
|
321
323
|
if task_id not in self.schedule and task_id in self.optimal_schedule:
|
{chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/shikaku/game.py
RENAMED
|
@@ -327,6 +327,8 @@ class ShikakuGame(PuzzleGame):
|
|
|
327
327
|
|
|
328
328
|
async def get_hint(self) -> tuple[Any, str] | None:
|
|
329
329
|
"""Get a hint for the next move."""
|
|
330
|
+
if not self.can_use_hint():
|
|
331
|
+
return None
|
|
330
332
|
# Find a rectangle from the solution that hasn't been placed yet
|
|
331
333
|
solution_rects: dict[int, list[tuple[int, int]]] = {}
|
|
332
334
|
for r in range(self.size):
|
{chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/skyscrapers/game.py
RENAMED
|
@@ -255,6 +255,11 @@ class SkyscrapersGame(PuzzleGame):
|
|
|
255
255
|
|
|
256
256
|
return "\n".join(lines)
|
|
257
257
|
|
|
258
|
+
def get_stats(self) -> str:
|
|
259
|
+
"""Get current game statistics."""
|
|
260
|
+
empty = sum(1 for r in range(self.size) for c in range(self.size) if self.grid[r][c] == 0)
|
|
261
|
+
return f"Moves: {self.moves_made} | Empty cells: {empty} | Grid: {self.size}x{self.size} | Seed: {self.seed}"
|
|
262
|
+
|
|
258
263
|
def get_rules(self) -> str:
|
|
259
264
|
return (
|
|
260
265
|
f"SKYSCRAPERS ({self.size}x{self.size})\n"
|
{chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/slitherlink/game.py
RENAMED
|
@@ -272,6 +272,8 @@ class SlitherlinkGame(PuzzleGame):
|
|
|
272
272
|
Returns:
|
|
273
273
|
Tuple of (hint_data, hint_message) or None
|
|
274
274
|
"""
|
|
275
|
+
if not self.can_use_hint():
|
|
276
|
+
return None
|
|
275
277
|
# Find an edge that's in the solution but not set by player
|
|
276
278
|
for row in range(self.size + 1):
|
|
277
279
|
for col in range(self.size):
|
{chuk_puzzles_gym-0.10 → chuk_puzzles_gym-0.10.1}/src/chuk_puzzles_gym/games/star_battle/game.py
RENAMED
|
@@ -301,6 +301,8 @@ class StarBattleGame(PuzzleGame):
|
|
|
301
301
|
Returns:
|
|
302
302
|
Tuple of (hint_data, hint_message) or None if puzzle is complete
|
|
303
303
|
"""
|
|
304
|
+
if not self.can_use_hint():
|
|
305
|
+
return None
|
|
304
306
|
# Find a star location from solution that hasn't been placed
|
|
305
307
|
for r in range(self.size):
|
|
306
308
|
for c in range(self.size):
|
|
@@ -249,6 +249,8 @@ class SudokuGame(PuzzleGame):
|
|
|
249
249
|
Returns:
|
|
250
250
|
Tuple of (hint_data, hint_message) or None if puzzle is complete
|
|
251
251
|
"""
|
|
252
|
+
if not self.can_use_hint():
|
|
253
|
+
return None
|
|
252
254
|
empty_cells = [(r, c) for r in range(9) for c in range(9) if self.grid[r][c] == 0]
|
|
253
255
|
if not empty_cells:
|
|
254
256
|
return None
|
|
@@ -326,6 +326,8 @@ class TentsGame(PuzzleGame):
|
|
|
326
326
|
Returns:
|
|
327
327
|
Tuple of (hint_data, hint_message) or None if puzzle is complete
|
|
328
328
|
"""
|
|
329
|
+
if not self.can_use_hint():
|
|
330
|
+
return None
|
|
329
331
|
# Find a tent location from solution that hasn't been placed
|
|
330
332
|
for r in range(self.size):
|
|
331
333
|
for c in range(self.size):
|