Skip to content

v0.3.1 update#46

Merged
SmilingWayne merged 3 commits intomainfrom
basic-dev
Feb 8, 2026
Merged

v0.3.1 update#46
SmilingWayne merged 3 commits intomainfrom
basic-dev

Conversation

@SmilingWayne
Copy link
Owner

@SmilingWayne SmilingWayne commented Feb 8, 2026

  • new solvers
  • (wip) new solver (cuts added model) for hitori, heyawake for worst case.

Note

Medium Risk
Adds multiple new solvers and changes core solving infrastructure (new iterative MIP/cut loop) and the hitori implementation, which can affect correctness/performance and introduce new failure modes in solving/verification.

Overview
Bumps PuzzleKit to 0.3.1 and expands supported puzzle types by registering new parsers/verifiers/viz handlers and adding new solver implementations (e.g. castle_wall, mejilink, mid_loop, kurotto, nurimisaki, aqre, canal_view, plus slitherlink_duality).

Introduces an IterativePuzzleSolver base that uses OR-Tools MIP (pywraplp/SCIP) with cutting-plane iterations, adds MIP analytics and connectivity-cut utilities, and rewires HitoriSolver to the new iterative cut-based approach.

Updates tooling/docs: scripts/benchmark.py now consumes unified {Puzzle}_dataset.json assets and only verifies when a non-empty solution is present; adds scripts/gen_mkdocs_nav.py and nav markers in mkdocs.yml, tweaks plotting scaling, refreshes quick-start/README references, and adds a metadata-driven test harness with per-puzzle smoke tests.

Written by Cursor Bugbot for commit 483ca80. This will update automatically on new commits. Configure here.

@SmilingWayne SmilingWayne merged commit 0343cd0 into main Feb 8, 2026
2 checks passed
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 4 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

This PR is being reviewed by Cursor Bugbot

Details

You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

e.g., Hitori solver checks if the current solution satisfies the connectivity constraint.
If satisfied, return True.
"""
pass
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Abstract method signature mismatches its only call site

Medium Severity

The _check_and_add_cuts abstract method in IterativePuzzleSolver declares a current_solution_values: Dict parameter, but solve() calls it as self._check_and_add_cuts() with no arguments. The HitoriSolver implementation also takes no parameter (def _check_and_add_cuts(self) -> bool). Any future subclass following the abstract signature would get a TypeError at runtime. Additionally, the docstring says to return False when not satisfied and True when satisfied, but the actual convention (matching the call site) is the opposite.

Additional Locations (2)

Fix in Cursor Fix in Web

# Default behavior: run all if no arguments specified
target_puzzle = args.puzzle
run_all = args.all
run_all = args.all or (not target_puzzle and not run_all)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Self-referencing variable causes NameError on default path

Medium Severity

run_all = args.all or (not target_puzzle and not run_all) references run_all before it has been assigned. When args.all is False and target_puzzle is None (the default case of running with no arguments), Python's short-circuit evaluation reaches not run_all and raises a NameError. The old code correctly used run_all = args.all followed by a separate conditional.

Fix in Cursor Fix in Web

def _add_inside_outside_vars(self):
R, C = self.num_rows, self.num_cols
self.face_rows = max(0, 2 * R - 2)
self.face_cols = max(0, 2 * C - 2)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Castle Wall face grid too small for border cells

High Severity

face_rows = 2 * R - 2 and face_cols = 2 * C - 2 produce a face grid that cannot represent cells in the last row or column. Cell (r, c) maps to face index (2*r, 2*c), but for r = R-1, 2*r = 2*R-2 = face_rows, which is out of bounds. The clamping in _face_index_for_cell maps these border cells to an adjacent cell's face element, causing incorrect inside/outside constraints. The test input has a clue at row 9 of a 10×10 grid that is affected.

Additional Locations (1)

Fix in Cursor Fix in Web

# puzzle_type=self.puzzle_type,
# puzzle_data=vars(self).copy(),
# solution_data=solution_dict
# )
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hundreds of lines of commented-out code committed

Low Severity

hitori.py has 223 lines and kurotto.py has 98 lines of fully commented-out old implementations at the top of their files. ortools_utils.py has an 80-line commented-out alternative of add_connectivity_cut_node_based. These are previous implementations that have been replaced and add significant dead code that makes the files harder to navigate and maintain.

Additional Locations (2)

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant