multi-puzzle-solver 0.8.6__tar.gz → 0.9.0__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.
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/PKG-INFO +126 -45
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/README.md +125 -44
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/src/multi_puzzle_solver.egg-info/PKG-INFO +126 -45
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/src/multi_puzzle_solver.egg-info/SOURCES.txt +6 -2
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/src/puzzle_solver/__init__.py +4 -2
- multi_puzzle_solver-0.9.0/src/puzzle_solver/puzzles/chess_range/chess_melee.py +7 -0
- multi_puzzle_solver-0.8.6/src/puzzle_solver/puzzles/chess_sequence/chess_sequence.py → multi_puzzle_solver-0.9.0/src/puzzle_solver/puzzles/chess_range/chess_range.py +169 -30
- multi_puzzle_solver-0.9.0/src/puzzle_solver/puzzles/chess_range/chess_solo.py +9 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/src/puzzle_solver/puzzles/inertia/parse_map/parse_map.py +8 -8
- multi_puzzle_solver-0.9.0/tests/test_chess_melee.py +37 -0
- multi_puzzle_solver-0.9.0/tests/test_chess_range.py +33 -0
- multi_puzzle_solver-0.9.0/tests/test_chess_solo.py +23 -0
- multi_puzzle_solver-0.8.6/tests/test_chess_sequence.py +0 -14
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/pyproject.toml +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/setup.cfg +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/src/multi_puzzle_solver.egg-info/dependency_links.txt +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/src/multi_puzzle_solver.egg-info/requires.txt +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/src/multi_puzzle_solver.egg-info/top_level.txt +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/src/puzzle_solver/core/utils.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/src/puzzle_solver/core/utils_ortools.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/src/puzzle_solver/puzzles/bridges/bridges.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/src/puzzle_solver/puzzles/dominosa/dominosa.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/src/puzzle_solver/puzzles/filling/filling.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/src/puzzle_solver/puzzles/guess/guess.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/src/puzzle_solver/puzzles/inertia/inertia.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/src/puzzle_solver/puzzles/inertia/tsp.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/src/puzzle_solver/puzzles/keen/keen.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/src/puzzle_solver/puzzles/light_up/light_up.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/src/puzzle_solver/puzzles/magnets/magnets.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/src/puzzle_solver/puzzles/map/map.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/src/puzzle_solver/puzzles/minesweeper/minesweeper.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/src/puzzle_solver/puzzles/mosaic/mosaic.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/src/puzzle_solver/puzzles/nonograms/nonograms.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/src/puzzle_solver/puzzles/pearl/pearl.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/src/puzzle_solver/puzzles/range/range.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/src/puzzle_solver/puzzles/signpost/signpost.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/src/puzzle_solver/puzzles/singles/singles.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/src/puzzle_solver/puzzles/sudoku/sudoku.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/src/puzzle_solver/puzzles/tents/tents.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/src/puzzle_solver/puzzles/towers/towers.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/src/puzzle_solver/puzzles/tracks/tracks.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/src/puzzle_solver/puzzles/undead/undead.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/src/puzzle_solver/puzzles/unruly/unruly.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/tests/test_bridges.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/tests/test_dominosa.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/tests/test_filling.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/tests/test_guess.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/tests/test_inertia.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/tests/test_keen.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/tests/test_light_up.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/tests/test_magnets.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/tests/test_map.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/tests/test_minesweeper.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/tests/test_mosaic.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/tests/test_nonograms.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/tests/test_pearl.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/tests/test_range.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/tests/test_signpost.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/tests/test_singles.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/tests/test_sudoku.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/tests/test_tents.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/tests/test_towers.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/tests/test_tracks.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/tests/test_undead.py +0 -0
- {multi_puzzle_solver-0.8.6 → multi_puzzle_solver-0.9.0}/tests/test_unruly.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: multi-puzzle-solver
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.9.0
|
4
4
|
Summary: Efficient solvers for numerous popular and esoteric logic puzzles using CP-SAT
|
5
5
|
Author: Ar-Kareem
|
6
6
|
Project-URL: Homepage, https://github.com/Ar-Kareem/puzzle_solver
|
@@ -206,12 +206,18 @@ These are all the puzzles that are implemented in this repo. <br> Click on any o
|
|
206
206
|
</a>
|
207
207
|
</td>
|
208
208
|
<td align="center">
|
209
|
-
<a href="#chess-
|
210
|
-
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/
|
209
|
+
<a href="#chess-range-puzzle-type-23"><b>Chess Range</b><br><br>
|
210
|
+
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/chess_range_unsolved.png" alt="Chess range" height="120">
|
211
211
|
</a>
|
212
212
|
</td>
|
213
|
+
<td align="center">
|
214
|
+
<a href="#chess-solo-puzzle-type-24"><b>Chess Solo</b><br><br>
|
215
|
+
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/chess_solo_unsolved.png" alt="Chess solo" height="120">
|
216
|
+
</a>
|
217
|
+
</td>
|
218
|
+
<td align="center">
|
213
219
|
|
214
|
-
</td
|
220
|
+
</td>
|
215
221
|
</tr>
|
216
222
|
</table>
|
217
223
|
|
@@ -249,9 +255,10 @@ These are all the puzzles that are implemented in this repo. <br> Click on any o
|
|
249
255
|
- [Bridges (Puzzle Type #20)](#bridges-puzzle-type-20)
|
250
256
|
- [Inertia (Puzzle Type #21)](#inertia-puzzle-type-21)
|
251
257
|
- [Guess (Puzzle Type #22)](#guess-puzzle-type-22)
|
252
|
-
- [Chess
|
258
|
+
- [Chess Range (Puzzle Type #23)](#chess-range-puzzle-type-23)
|
259
|
+
- [Chess Solo (Puzzle Type #24)](#chess-solo-puzzle-type-24)
|
260
|
+
- [Chess Melee (Puzzle Type #25)](#chess-melee-puzzle-type-25)
|
253
261
|
- [Why SAT / CP-SAT?](#why-sat--cp-sat)
|
254
|
-
- [What’s Inside](#whats-inside)
|
255
262
|
- [Testing](#testing)
|
256
263
|
- [Contributing](#contributing)
|
257
264
|
- [Build and push to PyPI](#build-and-push-to-pypi)
|
@@ -1935,7 +1942,7 @@ In the case when there's only one possible choice left, the solver will inform y
|
|
1935
1942
|
|
1936
1943
|
---
|
1937
1944
|
|
1938
|
-
## Chess
|
1945
|
+
## Chess Range (Puzzle Type #23)
|
1939
1946
|
|
1940
1947
|
* [**Play online**](https://www.puzzle-chess.com/chess-ranger-11/)
|
1941
1948
|
|
@@ -1946,22 +1953,23 @@ In the case when there's only one possible choice left, the solver will inform y
|
|
1946
1953
|
|
1947
1954
|
You are given a chess board with $N$ pieces distributed on it. Your aim is to make $N-1$ sequence of moves where each move is a legal chess move and captures another piece.
|
1948
1955
|
|
1949
|
-
|
1950
|
-
|
1951
|
-
|
1956
|
+
- Pieces move as standard chess pieces.
|
1957
|
+
- You can perform only capture moves. A move that does not capture another piece is not allowed.
|
1958
|
+
- You are allowed to capture the king.
|
1959
|
+
- The goal is to end up with one single piece on the board.
|
1952
1960
|
|
1953
1961
|
</details>
|
1954
1962
|
|
1955
1963
|
**Unsolved puzzle**
|
1956
1964
|
|
1957
|
-
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/
|
1965
|
+
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/chess_range_unsolved.png" alt="Chess range unsolved" width="500">
|
1958
1966
|
|
1959
1967
|
Code to utilize this package and solve the puzzle:
|
1960
1968
|
|
1961
1969
|
(Note that this puzzle does not typically have a unique solution. Thus, we specify here that we only want the first valid solution that the solver finds.)
|
1962
1970
|
|
1963
1971
|
```python
|
1964
|
-
from puzzle_solver import
|
1972
|
+
from puzzle_solver import chess_range_solver as solver
|
1965
1973
|
# algebraic notation
|
1966
1974
|
board = ['Qe7', 'Nc6', 'Kb6', 'Pb5', 'Nf5', 'Pg4', 'Rb3', 'Bc3', 'Pd3', 'Pc2', 'Rg2']
|
1967
1975
|
binst = solver.Board(board)
|
@@ -1976,12 +1984,114 @@ Solution found
|
|
1976
1984
|
['Rg2->Pc2', 'Rc2->Bc3', 'Rc3->Pd3', 'Kb6->Pb5', 'Pg4->Nf5', 'Rd3->Rb3', 'Rb3->Kb5', 'Nc6->Qe7', 'Ne7->Pf5', 'Rb5->Nf5']
|
1977
1985
|
Solutions found: 1
|
1978
1986
|
status: FEASIBLE
|
1979
|
-
Time taken:
|
1987
|
+
Time taken: 1.16 seconds
|
1988
|
+
```
|
1989
|
+
|
1990
|
+
**Solved puzzle**
|
1991
|
+
|
1992
|
+
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/chess_range_solved.png" alt="Chess range solved" width="500">
|
1993
|
+
|
1994
|
+
---
|
1995
|
+
|
1996
|
+
## Chess Solo (Puzzle Type #24)
|
1997
|
+
|
1998
|
+
* [**Play online**](https://www.puzzle-chess.com/solo-chess-11/)
|
1999
|
+
|
2000
|
+
* [**Solver Code**][24]
|
2001
|
+
|
2002
|
+
<details>
|
2003
|
+
<summary><strong>Rules</strong></summary>
|
2004
|
+
|
2005
|
+
You are given a chess board with $N$ pieces distributed on it. Your aim is to make $N-1$ sequence of moves where each move is a legal chess move and captures another piece and end up with the king as the only piece on the board. You are not allowed to move a piece more than twice.
|
2006
|
+
|
2007
|
+
- Pieces move as standard chess pieces.
|
2008
|
+
- You can perform only capture moves. A move that does not capture another piece is not allowed.
|
2009
|
+
- You can move a piece only twice.
|
2010
|
+
- You are NOT allowed to capture the king.
|
2011
|
+
- The goal is to end up with one single piece (the king) on the board.
|
2012
|
+
|
2013
|
+
</details>
|
2014
|
+
|
2015
|
+
**Unsolved puzzle**
|
2016
|
+
|
2017
|
+
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/chess_solo_unsolved.png" alt="Chess solo unsolved" width="500">
|
2018
|
+
|
2019
|
+
Code to utilize this package and solve the puzzle:
|
2020
|
+
|
2021
|
+
(Note that this puzzle does not typically have a unique solution. Thus, we specify here that we only want the first valid solution that the solver finds.)
|
2022
|
+
|
2023
|
+
```python
|
2024
|
+
# algebraic notation
|
2025
|
+
board = ['Kc6', 'Rc5', 'Rc4', 'Pb3', 'Bd3', 'Pd2', 'Pe3', 'Nf2', 'Ng2', 'Qg3', 'Pg6']
|
2026
|
+
binst = solver.Board(board)
|
2027
|
+
solutions = binst.solve_and_print(max_solutions=1)
|
2028
|
+
```
|
2029
|
+
**Script Output**
|
2030
|
+
|
2031
|
+
The output is in the form of "pos -> pos" where "pos" is the algebraic notation of the position.
|
2032
|
+
|
2033
|
+
```python
|
2034
|
+
Solution found
|
2035
|
+
['Qg3->Pg6', 'Qg6->Bd3', 'Pd2->Pe3', 'Ng2->Pe3', 'Nf2->Qd3', 'Ne3->Rc4', 'Pb3->Nc4', 'Nd3->Rc5', 'Kc6->Nc5', 'Kc5->Pc4']
|
2036
|
+
Solutions found: 1
|
2037
|
+
status: FEASIBLE
|
2038
|
+
Time taken: 0.47 seconds
|
1980
2039
|
```
|
1981
2040
|
|
1982
2041
|
**Solved puzzle**
|
1983
2042
|
|
1984
|
-
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/
|
2043
|
+
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/chess_solo_solved.png" alt="Chess solo solved" width="500">
|
2044
|
+
|
2045
|
+
---
|
2046
|
+
|
2047
|
+
## Chess Melee (Puzzle Type #25)
|
2048
|
+
|
2049
|
+
* [**Play online**](https://www.puzzle-chess.com/chess-melee-13/)
|
2050
|
+
|
2051
|
+
* [**Solver Code**][25]
|
2052
|
+
|
2053
|
+
<details>
|
2054
|
+
<summary><strong>Rules</strong></summary>
|
2055
|
+
|
2056
|
+
You are given a chess board with $N$ pieces distributed on it (equal white and black pieces, one more black if $N$ is odd). Your aim is to make $N-1$ sequence of moves where each move is a legal chess move and captures another piece of the opposite color and end up with a single piece on the board. White starts and colors alternate as usual.
|
2057
|
+
|
2058
|
+
- Pieces move as standard chess pieces.
|
2059
|
+
- White moves first.
|
2060
|
+
- You can perform only capture moves. A move that does not capture another piece of the opposite color is not allowed.
|
2061
|
+
- The goal is to end up with one single piece on the board.
|
2062
|
+
|
2063
|
+
</details>
|
2064
|
+
|
2065
|
+
**Unsolved puzzle**
|
2066
|
+
|
2067
|
+
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/chess_melee_unsolved.png" alt="Chess melee unsolved" width="500">
|
2068
|
+
|
2069
|
+
Code to utilize this package and solve the puzzle:
|
2070
|
+
|
2071
|
+
(Note that this puzzle does not typically have a unique solution. Thus, we specify here that we only want the first valid solution that the solver finds.)
|
2072
|
+
|
2073
|
+
```python
|
2074
|
+
# algebraic notation
|
2075
|
+
board = ['Pb7', 'Nc7', 'Bc6', 'Ne6', 'Pb5', 'Rc4', 'Qb3', 'Rf7', 'Rb6', 'Pe5', 'Nc3', 'Pd3', 'Nf3']
|
2076
|
+
colors = ['B', 'B', 'B', 'B', 'B', 'B', 'B', 'W', 'W', 'W', 'W', 'W', 'W']
|
2077
|
+
binst = solver.Board(board, colors)
|
2078
|
+
solutions = binst.solve_and_print()
|
2079
|
+
```
|
2080
|
+
**Script Output**
|
2081
|
+
|
2082
|
+
The output is in the form of "pos -> pos" where "pos" is the algebraic notation of the position.
|
2083
|
+
|
2084
|
+
```python
|
2085
|
+
Solution found
|
2086
|
+
['Rf7->Nc7', 'Ne6->Rc7', 'Pd3->Rc4', 'Qb3->Nc3', 'Pc4->Pb5', 'Qc3->Pe5', 'Nf3->Qe5', 'Nc7->Pb5', 'Ne5->Bc6', 'Pb7->Nc6', 'Rb6->Nb5', 'Pc6->Rb5']
|
2087
|
+
Solutions found: 1
|
2088
|
+
status: OPTIMAL
|
2089
|
+
Time taken: 6.24 seconds
|
2090
|
+
```
|
2091
|
+
|
2092
|
+
**Solved puzzle**
|
2093
|
+
|
2094
|
+
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/chess_melee_solved.png" alt="Chess melee solved" width="500">
|
1985
2095
|
|
1986
2096
|
---
|
1987
2097
|
|
@@ -1999,36 +2109,6 @@ This repo builds those constraints in Python and uses SAT/CP-SAT (e.g., OR-Tools
|
|
1999
2109
|
|
2000
2110
|
---
|
2001
2111
|
|
2002
|
-
## What’s Inside
|
2003
|
-
|
2004
|
-
Each sub directory in `src/puzzle_solver/puzzles/` targets a different puzzle type. The following are the sub directories:
|
2005
|
-
|
2006
|
-
* `nonograms` — Picross/Griddlers (run-length constraints). ([Chapter 10][1])
|
2007
|
-
* `sudoku` — Sudoku (rows/cols/blocks all-different). ([Chapter 11][2])
|
2008
|
-
* `minesweeper` — Minesweeper (mines + counts). ([Chapter 12][3])
|
2009
|
-
* `guess` — Guess (similar to wordle, guess the colored circles). ([Chapter 15][22])
|
2010
|
-
* `dominosa` — Dominosa (dominoes + counts). ([Chapter 17][4])
|
2011
|
-
* `light_up` — *Akari* / Light Up (lighting & adjacency). ([Chapter 21][5])
|
2012
|
-
* `map` — Map (region coloring). ([Chapter 22][18])
|
2013
|
-
* `inertia` — Inertia (collect all gems without dying (with least number of moves; my addition)). ([Chapter 24][21])
|
2014
|
-
* `tents` — Tents (tree-tent matching). ([Chapter 25][6])
|
2015
|
-
* `bridges` — Bridges (island connections). ([Chapter 26][20])
|
2016
|
-
* `filling` — Filling (Fillomino-style), region sizes. ([Chapter 29][7])
|
2017
|
-
* `keen` — Keen (arithmetic operations). ([Chapter 30][8])
|
2018
|
-
* `towers` — Skyscrapers (permutation + visibility). ([Chapter 31][9])
|
2019
|
-
* `singles` — Singles (hiding numbers). ([Chapter 32][10])
|
2020
|
-
* `magnets` — Magnets (polarized dominoes + counts). ([Chapter 33][11])
|
2021
|
-
* `signpost` — Signpost (visible dominoes + counts). ([Chapter 34][12])
|
2022
|
-
* `range` — Range (rays & totals). ([Chapter 35][13])
|
2023
|
-
* `pearl` — Pearl (pearl game). ([Chapter 36][19])
|
2024
|
-
* `undead` — UnDead (Vampires/Zombies/Ghosts). ([Chapter 37][14])
|
2025
|
-
* `unruly` — Unruly (no triples + balance). ([Chapter 38][15])
|
2026
|
-
* `tracks` — Tracks (connected components). ([Chapter 40][16])
|
2027
|
-
* `mosaic` — Mosaic (Tapa-like tiling). ([Chapter 42][17])
|
2028
|
-
* `chess_sequence` — Chess Sequence (chess moves). ([Puzzle-Chess][23])
|
2029
|
-
|
2030
|
-
---
|
2031
|
-
|
2032
2112
|
## Testing
|
2033
2113
|
|
2034
2114
|
To run the tests, simply run the following (to create a fresh conda environment and install the dev dependencies):
|
@@ -2088,4 +2168,5 @@ Issues and PRs welcome!
|
|
2088
2168
|
[15]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/unruly "puzzle_solver/src/puzzle_solver/puzzles/unruly at master · Ar-Kareem/puzzle_solver · GitHub"
|
2089
2169
|
[16]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/tracks "puzzle_solver/src/puzzle_solver/puzzles/tracks at master · Ar-Kareem/puzzle_solver · GitHub"
|
2090
2170
|
[17]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/mosaic "puzzle_solver/src/puzzle_solver/puzzles/mosaic at master · Ar-Kareem/puzzle_solver · GitHub"
|
2091
|
-
[23]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/
|
2171
|
+
[23]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/chess_range "puzzle_solver/src/puzzle_solver/puzzles/chess_range at master · Ar-Kareem/puzzle_solver · GitHub"
|
2172
|
+
[24]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/chess_range#chess-solo-puzzle-type-24 "puzzle_solver/src/puzzle_solver/puzzles/chess_range at master · Ar-Kareem/puzzle_solver · GitHub"
|
@@ -180,12 +180,18 @@ These are all the puzzles that are implemented in this repo. <br> Click on any o
|
|
180
180
|
</a>
|
181
181
|
</td>
|
182
182
|
<td align="center">
|
183
|
-
<a href="#chess-
|
184
|
-
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/
|
183
|
+
<a href="#chess-range-puzzle-type-23"><b>Chess Range</b><br><br>
|
184
|
+
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/chess_range_unsolved.png" alt="Chess range" height="120">
|
185
185
|
</a>
|
186
186
|
</td>
|
187
|
+
<td align="center">
|
188
|
+
<a href="#chess-solo-puzzle-type-24"><b>Chess Solo</b><br><br>
|
189
|
+
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/chess_solo_unsolved.png" alt="Chess solo" height="120">
|
190
|
+
</a>
|
191
|
+
</td>
|
192
|
+
<td align="center">
|
187
193
|
|
188
|
-
</td
|
194
|
+
</td>
|
189
195
|
</tr>
|
190
196
|
</table>
|
191
197
|
|
@@ -223,9 +229,10 @@ These are all the puzzles that are implemented in this repo. <br> Click on any o
|
|
223
229
|
- [Bridges (Puzzle Type #20)](#bridges-puzzle-type-20)
|
224
230
|
- [Inertia (Puzzle Type #21)](#inertia-puzzle-type-21)
|
225
231
|
- [Guess (Puzzle Type #22)](#guess-puzzle-type-22)
|
226
|
-
- [Chess
|
232
|
+
- [Chess Range (Puzzle Type #23)](#chess-range-puzzle-type-23)
|
233
|
+
- [Chess Solo (Puzzle Type #24)](#chess-solo-puzzle-type-24)
|
234
|
+
- [Chess Melee (Puzzle Type #25)](#chess-melee-puzzle-type-25)
|
227
235
|
- [Why SAT / CP-SAT?](#why-sat--cp-sat)
|
228
|
-
- [What’s Inside](#whats-inside)
|
229
236
|
- [Testing](#testing)
|
230
237
|
- [Contributing](#contributing)
|
231
238
|
- [Build and push to PyPI](#build-and-push-to-pypi)
|
@@ -1909,7 +1916,7 @@ In the case when there's only one possible choice left, the solver will inform y
|
|
1909
1916
|
|
1910
1917
|
---
|
1911
1918
|
|
1912
|
-
## Chess
|
1919
|
+
## Chess Range (Puzzle Type #23)
|
1913
1920
|
|
1914
1921
|
* [**Play online**](https://www.puzzle-chess.com/chess-ranger-11/)
|
1915
1922
|
|
@@ -1920,22 +1927,23 @@ In the case when there's only one possible choice left, the solver will inform y
|
|
1920
1927
|
|
1921
1928
|
You are given a chess board with $N$ pieces distributed on it. Your aim is to make $N-1$ sequence of moves where each move is a legal chess move and captures another piece.
|
1922
1929
|
|
1923
|
-
|
1924
|
-
|
1925
|
-
|
1930
|
+
- Pieces move as standard chess pieces.
|
1931
|
+
- You can perform only capture moves. A move that does not capture another piece is not allowed.
|
1932
|
+
- You are allowed to capture the king.
|
1933
|
+
- The goal is to end up with one single piece on the board.
|
1926
1934
|
|
1927
1935
|
</details>
|
1928
1936
|
|
1929
1937
|
**Unsolved puzzle**
|
1930
1938
|
|
1931
|
-
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/
|
1939
|
+
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/chess_range_unsolved.png" alt="Chess range unsolved" width="500">
|
1932
1940
|
|
1933
1941
|
Code to utilize this package and solve the puzzle:
|
1934
1942
|
|
1935
1943
|
(Note that this puzzle does not typically have a unique solution. Thus, we specify here that we only want the first valid solution that the solver finds.)
|
1936
1944
|
|
1937
1945
|
```python
|
1938
|
-
from puzzle_solver import
|
1946
|
+
from puzzle_solver import chess_range_solver as solver
|
1939
1947
|
# algebraic notation
|
1940
1948
|
board = ['Qe7', 'Nc6', 'Kb6', 'Pb5', 'Nf5', 'Pg4', 'Rb3', 'Bc3', 'Pd3', 'Pc2', 'Rg2']
|
1941
1949
|
binst = solver.Board(board)
|
@@ -1950,12 +1958,114 @@ Solution found
|
|
1950
1958
|
['Rg2->Pc2', 'Rc2->Bc3', 'Rc3->Pd3', 'Kb6->Pb5', 'Pg4->Nf5', 'Rd3->Rb3', 'Rb3->Kb5', 'Nc6->Qe7', 'Ne7->Pf5', 'Rb5->Nf5']
|
1951
1959
|
Solutions found: 1
|
1952
1960
|
status: FEASIBLE
|
1953
|
-
Time taken:
|
1961
|
+
Time taken: 1.16 seconds
|
1962
|
+
```
|
1963
|
+
|
1964
|
+
**Solved puzzle**
|
1965
|
+
|
1966
|
+
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/chess_range_solved.png" alt="Chess range solved" width="500">
|
1967
|
+
|
1968
|
+
---
|
1969
|
+
|
1970
|
+
## Chess Solo (Puzzle Type #24)
|
1971
|
+
|
1972
|
+
* [**Play online**](https://www.puzzle-chess.com/solo-chess-11/)
|
1973
|
+
|
1974
|
+
* [**Solver Code**][24]
|
1975
|
+
|
1976
|
+
<details>
|
1977
|
+
<summary><strong>Rules</strong></summary>
|
1978
|
+
|
1979
|
+
You are given a chess board with $N$ pieces distributed on it. Your aim is to make $N-1$ sequence of moves where each move is a legal chess move and captures another piece and end up with the king as the only piece on the board. You are not allowed to move a piece more than twice.
|
1980
|
+
|
1981
|
+
- Pieces move as standard chess pieces.
|
1982
|
+
- You can perform only capture moves. A move that does not capture another piece is not allowed.
|
1983
|
+
- You can move a piece only twice.
|
1984
|
+
- You are NOT allowed to capture the king.
|
1985
|
+
- The goal is to end up with one single piece (the king) on the board.
|
1986
|
+
|
1987
|
+
</details>
|
1988
|
+
|
1989
|
+
**Unsolved puzzle**
|
1990
|
+
|
1991
|
+
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/chess_solo_unsolved.png" alt="Chess solo unsolved" width="500">
|
1992
|
+
|
1993
|
+
Code to utilize this package and solve the puzzle:
|
1994
|
+
|
1995
|
+
(Note that this puzzle does not typically have a unique solution. Thus, we specify here that we only want the first valid solution that the solver finds.)
|
1996
|
+
|
1997
|
+
```python
|
1998
|
+
# algebraic notation
|
1999
|
+
board = ['Kc6', 'Rc5', 'Rc4', 'Pb3', 'Bd3', 'Pd2', 'Pe3', 'Nf2', 'Ng2', 'Qg3', 'Pg6']
|
2000
|
+
binst = solver.Board(board)
|
2001
|
+
solutions = binst.solve_and_print(max_solutions=1)
|
2002
|
+
```
|
2003
|
+
**Script Output**
|
2004
|
+
|
2005
|
+
The output is in the form of "pos -> pos" where "pos" is the algebraic notation of the position.
|
2006
|
+
|
2007
|
+
```python
|
2008
|
+
Solution found
|
2009
|
+
['Qg3->Pg6', 'Qg6->Bd3', 'Pd2->Pe3', 'Ng2->Pe3', 'Nf2->Qd3', 'Ne3->Rc4', 'Pb3->Nc4', 'Nd3->Rc5', 'Kc6->Nc5', 'Kc5->Pc4']
|
2010
|
+
Solutions found: 1
|
2011
|
+
status: FEASIBLE
|
2012
|
+
Time taken: 0.47 seconds
|
1954
2013
|
```
|
1955
2014
|
|
1956
2015
|
**Solved puzzle**
|
1957
2016
|
|
1958
|
-
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/
|
2017
|
+
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/chess_solo_solved.png" alt="Chess solo solved" width="500">
|
2018
|
+
|
2019
|
+
---
|
2020
|
+
|
2021
|
+
## Chess Melee (Puzzle Type #25)
|
2022
|
+
|
2023
|
+
* [**Play online**](https://www.puzzle-chess.com/chess-melee-13/)
|
2024
|
+
|
2025
|
+
* [**Solver Code**][25]
|
2026
|
+
|
2027
|
+
<details>
|
2028
|
+
<summary><strong>Rules</strong></summary>
|
2029
|
+
|
2030
|
+
You are given a chess board with $N$ pieces distributed on it (equal white and black pieces, one more black if $N$ is odd). Your aim is to make $N-1$ sequence of moves where each move is a legal chess move and captures another piece of the opposite color and end up with a single piece on the board. White starts and colors alternate as usual.
|
2031
|
+
|
2032
|
+
- Pieces move as standard chess pieces.
|
2033
|
+
- White moves first.
|
2034
|
+
- You can perform only capture moves. A move that does not capture another piece of the opposite color is not allowed.
|
2035
|
+
- The goal is to end up with one single piece on the board.
|
2036
|
+
|
2037
|
+
</details>
|
2038
|
+
|
2039
|
+
**Unsolved puzzle**
|
2040
|
+
|
2041
|
+
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/chess_melee_unsolved.png" alt="Chess melee unsolved" width="500">
|
2042
|
+
|
2043
|
+
Code to utilize this package and solve the puzzle:
|
2044
|
+
|
2045
|
+
(Note that this puzzle does not typically have a unique solution. Thus, we specify here that we only want the first valid solution that the solver finds.)
|
2046
|
+
|
2047
|
+
```python
|
2048
|
+
# algebraic notation
|
2049
|
+
board = ['Pb7', 'Nc7', 'Bc6', 'Ne6', 'Pb5', 'Rc4', 'Qb3', 'Rf7', 'Rb6', 'Pe5', 'Nc3', 'Pd3', 'Nf3']
|
2050
|
+
colors = ['B', 'B', 'B', 'B', 'B', 'B', 'B', 'W', 'W', 'W', 'W', 'W', 'W']
|
2051
|
+
binst = solver.Board(board, colors)
|
2052
|
+
solutions = binst.solve_and_print()
|
2053
|
+
```
|
2054
|
+
**Script Output**
|
2055
|
+
|
2056
|
+
The output is in the form of "pos -> pos" where "pos" is the algebraic notation of the position.
|
2057
|
+
|
2058
|
+
```python
|
2059
|
+
Solution found
|
2060
|
+
['Rf7->Nc7', 'Ne6->Rc7', 'Pd3->Rc4', 'Qb3->Nc3', 'Pc4->Pb5', 'Qc3->Pe5', 'Nf3->Qe5', 'Nc7->Pb5', 'Ne5->Bc6', 'Pb7->Nc6', 'Rb6->Nb5', 'Pc6->Rb5']
|
2061
|
+
Solutions found: 1
|
2062
|
+
status: OPTIMAL
|
2063
|
+
Time taken: 6.24 seconds
|
2064
|
+
```
|
2065
|
+
|
2066
|
+
**Solved puzzle**
|
2067
|
+
|
2068
|
+
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/chess_melee_solved.png" alt="Chess melee solved" width="500">
|
1959
2069
|
|
1960
2070
|
---
|
1961
2071
|
|
@@ -1973,36 +2083,6 @@ This repo builds those constraints in Python and uses SAT/CP-SAT (e.g., OR-Tools
|
|
1973
2083
|
|
1974
2084
|
---
|
1975
2085
|
|
1976
|
-
## What’s Inside
|
1977
|
-
|
1978
|
-
Each sub directory in `src/puzzle_solver/puzzles/` targets a different puzzle type. The following are the sub directories:
|
1979
|
-
|
1980
|
-
* `nonograms` — Picross/Griddlers (run-length constraints). ([Chapter 10][1])
|
1981
|
-
* `sudoku` — Sudoku (rows/cols/blocks all-different). ([Chapter 11][2])
|
1982
|
-
* `minesweeper` — Minesweeper (mines + counts). ([Chapter 12][3])
|
1983
|
-
* `guess` — Guess (similar to wordle, guess the colored circles). ([Chapter 15][22])
|
1984
|
-
* `dominosa` — Dominosa (dominoes + counts). ([Chapter 17][4])
|
1985
|
-
* `light_up` — *Akari* / Light Up (lighting & adjacency). ([Chapter 21][5])
|
1986
|
-
* `map` — Map (region coloring). ([Chapter 22][18])
|
1987
|
-
* `inertia` — Inertia (collect all gems without dying (with least number of moves; my addition)). ([Chapter 24][21])
|
1988
|
-
* `tents` — Tents (tree-tent matching). ([Chapter 25][6])
|
1989
|
-
* `bridges` — Bridges (island connections). ([Chapter 26][20])
|
1990
|
-
* `filling` — Filling (Fillomino-style), region sizes. ([Chapter 29][7])
|
1991
|
-
* `keen` — Keen (arithmetic operations). ([Chapter 30][8])
|
1992
|
-
* `towers` — Skyscrapers (permutation + visibility). ([Chapter 31][9])
|
1993
|
-
* `singles` — Singles (hiding numbers). ([Chapter 32][10])
|
1994
|
-
* `magnets` — Magnets (polarized dominoes + counts). ([Chapter 33][11])
|
1995
|
-
* `signpost` — Signpost (visible dominoes + counts). ([Chapter 34][12])
|
1996
|
-
* `range` — Range (rays & totals). ([Chapter 35][13])
|
1997
|
-
* `pearl` — Pearl (pearl game). ([Chapter 36][19])
|
1998
|
-
* `undead` — UnDead (Vampires/Zombies/Ghosts). ([Chapter 37][14])
|
1999
|
-
* `unruly` — Unruly (no triples + balance). ([Chapter 38][15])
|
2000
|
-
* `tracks` — Tracks (connected components). ([Chapter 40][16])
|
2001
|
-
* `mosaic` — Mosaic (Tapa-like tiling). ([Chapter 42][17])
|
2002
|
-
* `chess_sequence` — Chess Sequence (chess moves). ([Puzzle-Chess][23])
|
2003
|
-
|
2004
|
-
---
|
2005
|
-
|
2006
2086
|
## Testing
|
2007
2087
|
|
2008
2088
|
To run the tests, simply run the following (to create a fresh conda environment and install the dev dependencies):
|
@@ -2062,4 +2142,5 @@ Issues and PRs welcome!
|
|
2062
2142
|
[15]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/unruly "puzzle_solver/src/puzzle_solver/puzzles/unruly at master · Ar-Kareem/puzzle_solver · GitHub"
|
2063
2143
|
[16]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/tracks "puzzle_solver/src/puzzle_solver/puzzles/tracks at master · Ar-Kareem/puzzle_solver · GitHub"
|
2064
2144
|
[17]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/mosaic "puzzle_solver/src/puzzle_solver/puzzles/mosaic at master · Ar-Kareem/puzzle_solver · GitHub"
|
2065
|
-
[23]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/
|
2145
|
+
[23]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/chess_range "puzzle_solver/src/puzzle_solver/puzzles/chess_range at master · Ar-Kareem/puzzle_solver · GitHub"
|
2146
|
+
[24]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/chess_range#chess-solo-puzzle-type-24 "puzzle_solver/src/puzzle_solver/puzzles/chess_range at master · Ar-Kareem/puzzle_solver · GitHub"
|