fix(FifteenPuzzle): guarantee solvable boards; add optional difficulty tiers - #196
Open
borgr wants to merge 3 commits into
Open
fix(FifteenPuzzle): guarantee solvable boards; add optional difficulty tiers#196borgr wants to merge 3 commits into
borgr wants to merge 3 commits into
Conversation
_generate_board did a uniform random.shuffle of all 16 tiles, but only half of the permutations of a sliding puzzle are solvable, so roughly 50% of games were impossible to solve (the agent could never reach the goal and always hit the turn limit). Detect the unsolvable case via inversion/blank-row parity and, when it occurs, swap two non-blank tiles to flip the inversion parity and restore solvability. Verified over 20k boards: 0 unsolvable, 0 trivially-solved, tile integrity preserved.
Add an optional `difficulty` argument (easy/medium/hard) to FifteenPuzzleEnv. When set, the board is scrambled a bounded number of legal slides from the solved layout, so its distance from solved scales with the tier and the result is solvable by construction. The default (difficulty=None) is unchanged: a full random shuffle repaired to a solvable layout, keeping FifteenPuzzle-v0 exactly as before. Register FifteenPuzzle-v0-easy/-medium/-hard alongside the base id. The difficulty-tier idea comes from @MadBonzz (TextArena#169); this reimplements it additively so it composes with the solvable-board generator without changing the existing constructor or registration.
The typing import list carried Union, which is not referenced anywhere in the module.
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.
Problem:
FifteenPuzzleEnv._generate_boardshuffles all 16 tiles with a uniformrandom.shuffle. Only half of the permutations of a sliding puzzle are actually solvable, so ~50% ofFifteenPuzzle-v0episodes are impossible to solve — the agent can never reach the goal state and always runs out to the turn limit. Measured onmain: 9983/20000 ≈ 49.9% solvable.Fix: after shuffling, check solvability via the standard inversion / blank-row parity rule; if the layout is unsolvable, swap two non-blank tiles. A single transposition flips the inversion parity (and doesn't move the blank), which converts an unsolvable board into a solvable one. O(1), no distribution bias beyond the parity correction, and the goal state / tile set are unchanged.
Verification (20,000 generated boards):
ta.make("FifteenPuzzle-v0")→reset→stepstill works end-to-endAdditive difficulty tiers
Layered on top of the solvability fix, this PR also adds an optional
difficultyargument ("easy"/"medium"/"hard") toFifteenPuzzleEnv, and registersFifteenPuzzle-v0-easy,FifteenPuzzle-v0-medium, andFifteenPuzzle-v0-hard.The difficulty-tier idea comes from @MadBonzz in #169. This reimplements it additively so it composes with the solvable-board generator and doesn't change any existing behaviour:
max_turnsargument;difficultydefaults toNone, which is the existing full-shuffle-then-repair path.FifteenPuzzle-v0is registered exactly as before.ValueError.Verification (300 boards per tier + default):
ta.make(...)→reset→stepworks end-to-end for the base id and all three variantsFifteenPuzzleEnv(difficulty="…invalid…")raisesValueErrorThe core solvability change is unchanged from the original scope; the difficulty tiers are purely additive on top of it (new optional kwarg + new registered ids, no change to the prompt, rendering, wrappers, or the existing
FifteenPuzzle-v0registration).