testsAndMisc-archive/python_pkg/puzzle_solver/main.py
Krzysztof kuhy Rudnicki e5fd82c822 Reduce per-file-ignores by fixing lint violations across codebase
Fix ruff violations in ~15 source files and ~60+ test files to minimize
per-file-ignores in pyproject.toml. Remaining ignores are justified with
comments explaining why each suppression is necessary.

Source fixes: FBT003 (keyword args), S310 (URL validation), SLF001
(private access), T201 (print→logging), C901 (complexity), E501 (line
length), E402 (import order).

Test fixes: SIM117 (combined with), FBT (boolean args), PERF203 (try in
loop), S310/S607 (URLs/executables), E402/E501 (imports/lines), S108
(tmp paths), PLR0913 (too many args), ARG (unused args), ANN (type
annotations), RUF059 (unused unpacked vars), PT019 (fixture naming).

Remaining per-file-ignores (with justifications):
- Tests: ARG, D, PLC0415, PLR2004, S101, SLF001
- music_gen sources: PLC0415 (heavy ML lazy imports)
- moviepy_showcase: PLC0415 (circular dependency)
- generate_images: PLR0913 (matplotlib helpers need many params)
- praca_magisterska_video: E501, E402 (long paths, mpl.use)
2026-03-25 18:58:05 +01:00

109 lines
3.5 KiB
Python

"""CLI for the sliding-square puzzle solver.
Usage
-----
# 1) Parse a screenshot → JSON (review & hand-edit if needed)
python puzzle_solver/main.py parse screenshot.png -o puzzle.json
# 2) Solve from JSON
python puzzle_solver/main.py solve puzzle.json
# 3) One-shot: parse + solve (skip manual review)
python puzzle_solver/main.py run screenshot.png
# 4) Draw debug overlay showing detected squares
python puzzle_solver/main.py debug screenshot.png -o debug.png
"""
from __future__ import annotations
import argparse
from collections import Counter
import json
from pathlib import Path
import sys
from python_pkg.puzzle_solver.parse_image import draw_debug, parse_image, save_puzzle
from python_pkg.puzzle_solver.solver import Puzzle, print_puzzle, print_solution, solve
def cmd_parse(args: argparse.Namespace) -> None:
"""Parse a screenshot into editable puzzle JSON."""
puzzle = parse_image(args.image, threshold=args.threshold)
out = args.output or args.image.rsplit(".", 1)[0] + "_puzzle.json"
save_puzzle(puzzle, out)
if puzzle.get("notes"):
for _n in puzzle["notes"]:
pass
def cmd_solve(args: argparse.Namespace) -> None:
"""Solve a puzzle from a JSON file."""
with Path(args.puzzle).open() as f:
data = json.load(f)
puzzle = Puzzle.from_json(data)
print_puzzle(puzzle)
moves = solve(puzzle)
if moves is None:
sys.exit(1)
print_solution(puzzle, moves)
def cmd_run(args: argparse.Namespace) -> None:
"""Parse a screenshot and solve in one shot."""
data = parse_image(args.image, threshold=args.threshold)
if data.get("notes"):
for _n in data["notes"]:
pass
puzzle = Puzzle.from_json(data)
print_puzzle(puzzle)
moves = solve(puzzle)
if moves is None:
out = args.image.rsplit(".", 1)[0] + "_puzzle.json"
save_puzzle(data, out)
sys.exit(1)
print_solution(puzzle, moves)
def cmd_debug(args: argparse.Namespace) -> None:
"""Draw a debug overlay showing detected square types."""
data = parse_image(args.image, threshold=args.threshold)
out = args.output or args.image.rsplit(".", 1)[0] + "_debug.png"
draw_debug(args.image, data, out)
counts = Counter(sq["type"] for sq in data["squares"])
for _t, _n in counts.most_common():
pass
def main() -> None:
"""Entry point for the puzzle solver CLI."""
ap = argparse.ArgumentParser(description="Sliding-square puzzle solver")
sub = ap.add_subparsers(dest="command", required=True)
p_parse = sub.add_parser("parse", help="Parse screenshot → puzzle JSON")
p_parse.add_argument("image")
p_parse.add_argument("-o", "--output", help="Output JSON path")
p_parse.add_argument("-t", "--threshold", type=int, default=55)
p_solve = sub.add_parser("solve", help="Solve puzzle from JSON")
p_solve.add_argument("puzzle", help="Puzzle JSON file")
p_run = sub.add_parser("run", help="Parse + solve in one shot")
p_run.add_argument("image")
p_run.add_argument("-t", "--threshold", type=int, default=55)
p_debug = sub.add_parser("debug", help="Draw debug overlay on image")
p_debug.add_argument("image")
p_debug.add_argument("-o", "--output", help="Output image path")
p_debug.add_argument("-t", "--threshold", type=int, default=55)
args = ap.parse_args()
{"parse": cmd_parse, "solve": cmd_solve, "run": cmd_run, "debug": cmd_debug}[
args.command
](args)
if __name__ == "__main__":
main()