sparc-visualization 0.1.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.
Files changed (23) hide show
  1. sparc_visualization-0.1.0/LICENCE.txt +7 -0
  2. sparc_visualization-0.1.0/PKG-INFO +229 -0
  3. sparc_visualization-0.1.0/README.md +210 -0
  4. sparc_visualization-0.1.0/pyproject.toml +27 -0
  5. sparc_visualization-0.1.0/sparc_visualization/__init__.py +0 -0
  6. sparc_visualization-0.1.0/sparc_visualization/objects/board.py +50 -0
  7. sparc_visualization-0.1.0/sparc_visualization/objects/tile.py +35 -0
  8. sparc_visualization-0.1.0/sparc_visualization/plot.py +63 -0
  9. sparc_visualization-0.1.0/sparc_visualization/plots/black_frame_plot.py +59 -0
  10. sparc_visualization-0.1.0/sparc_visualization/plots/coordinate_grid_plot.py +97 -0
  11. sparc_visualization-0.1.0/sparc_visualization/plots/low_contrast_plot.py +85 -0
  12. sparc_visualization-0.1.0/sparc_visualization/plots/low_resolution_plot.py +69 -0
  13. sparc_visualization-0.1.0/sparc_visualization/plots/original_plot.py +334 -0
  14. sparc_visualization-0.1.0/sparc_visualization/plots/path_cell_annotation_plot.py +66 -0
  15. sparc_visualization-0.1.0/sparc_visualization/plots/plot.py +166 -0
  16. sparc_visualization-0.1.0/sparc_visualization/plots/rotated_plot.py +91 -0
  17. sparc_visualization-0.1.0/sparc_visualization/plots/start_end_marked_plot.py +58 -0
  18. sparc_visualization-0.1.0/sparc_visualization/plots/text_plot.py +229 -0
  19. sparc_visualization-0.1.0/sparc_visualization/prompt.py +18 -0
  20. sparc_visualization-0.1.0/sparc_visualization/prompts/default.py +38 -0
  21. sparc_visualization-0.1.0/sparc_visualization/prompts/prompt_engineering.py +55 -0
  22. sparc_visualization-0.1.0/sparc_visualization/prompts/prompts.py +31 -0
  23. sparc_visualization-0.1.0/sparc_visualization/util.py +15 -0
@@ -0,0 +1,7 @@
1
+ Copyright (c) 2025 Florian Valentin Wunderlich
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,229 @@
1
+ Metadata-Version: 2.4
2
+ Name: sparc-visualization
3
+ Version: 0.1.0
4
+ Summary:
5
+ License-Expression: MIT
6
+ License-File: LICENCE.txt
7
+ Author: Florian Valentin Wunderlich
8
+ Author-email: florian.valentin.wunderlich@gmail.com
9
+ Requires-Python: >=3.10
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Programming Language :: Python :: 3.14
16
+ Requires-Dist: Pillow (>=12)
17
+ Description-Content-Type: text/markdown
18
+
19
+ ## Overview
20
+
21
+ SPaRC (sparc-puzzle) provides a comprehensive framework for evaluating language models on spatial reasoning tasks inspired by "The Witness" puzzle game.
22
+ This package (sparc-visualization) includes various visual puzzle representations and an improved visual reasoning prompt to complement the functionality of the sparc-puzzle package.
23
+
24
+ ## Installation
25
+
26
+ Install the package from PyPI:
27
+
28
+ ```bash
29
+ pip install sparc-visualization
30
+ ```
31
+
32
+ Or install from source:
33
+
34
+ ```bash
35
+ git clone https://github.com/flowun/sparc-visualization.git
36
+ cd sparc-visualization
37
+ pip install -e .
38
+ ```
39
+
40
+
41
+
42
+ ### Example Usage
43
+
44
+
45
+ ```python
46
+ from sparc_visualization.plot import get_puzzle_image
47
+ from sparc_visualization.prompt import generate_prompt
48
+ from sparc.validation import extract_solution_path, validate_solution, analyze_path
49
+ from datasets import load_dataset
50
+
51
+ # Load the dataset
52
+ dataset = load_dataset("lkaesberg/SPaRC", "all", split="test")
53
+ puzzle = dataset[0]
54
+
55
+ puzzle_image = get_puzzle_image(puzzle, plot_type="path_cell_annotated")
56
+
57
+ # Generate prompt and image, e.g.
58
+ plot_type = "path_cell_annotated"
59
+ prompt_type = "prompt_engineering"
60
+
61
+ b64_image = get_puzzle_image(puzzle, plot_type=plot_type, base_64_image=True)
62
+ text_prompt = generate_prompt(puzzle, plot_type, prompt_type)
63
+
64
+ # create message array and payload for an LLM
65
+ puzzle_prompt = [
66
+ {
67
+ "role": "user",
68
+ "content": [
69
+ {
70
+ "type": "image_url",
71
+ "image_url": {
72
+ "url": f"data:image/png;base64,{b64_image}"
73
+ }
74
+ },
75
+ {
76
+ "type": "text",
77
+ "text": text_prompt
78
+ }
79
+ ]
80
+ }
81
+ ]
82
+
83
+ payload = {
84
+ "model": your_model_name,
85
+ "messages": puzzle_prompt,
86
+ "temperature": temperature,
87
+ "max_tokens": max_tokens,
88
+ }
89
+
90
+ # Your model generates a response
91
+ model_response = "... model response with path coordinates ..."
92
+
93
+ # Analysis using sparc-puzzle package
94
+
95
+ # Extract the path from model response
96
+ extracted_path = extract_solution_path(model_response, puzzle)
97
+ # Returns: [{"x": 0, "y": 2}, {"x": 0, "y": 1}, ...]
98
+
99
+ # Validate against ground truth
100
+ is_correct = validate_solution(extracted_path, puzzle)
101
+ # Returns: True/False
102
+
103
+ # Get detailed analysis
104
+ analysis = analyze_path(extracted_path, puzzle)
105
+ # Returns: {
106
+ # "starts_at_start_ends_at_exit": True,
107
+ # "connected_line": True,
108
+ # "non_intersecting_line": True,
109
+ # "no_rule_crossing": True,
110
+ # "fully_valid_path": True
111
+ # }
112
+ ```
113
+
114
+ ### Core Functions
115
+
116
+ `get_puzzle_image(puzzle: Dict, plot_type: str = "original", base_64_image: bool = False, show_plot: bool = False, save_to_disk: bool = False, save_dir: str = ".", save_filename: str = "puzzle_image.png") -> PIL.Image.Image | str`
117
+ Renders a SPaRC puzzle into one of the supported visual representations (`plot_type` values). To get a base64-encoded string of the image suitable for LLM input, set `base_64_image=True`.
118
+ Besides returning the image object or base64 string, the function has options to display the image (`show_plot=True`) or save it to disk (`save_to_disk=True`).
119
+
120
+ `generate_prompt(puzzle: Dict, plot_type: str = "original", prompt_type: str = "prompt_engineering") -> str`
121
+ Generates the text prompt (based on `prompt_type` values) that should be paired with the rendered image for an LLM call.
122
+ Available `prompt_type` values are:
123
+ - "default_tr": visual prompt from the SPaRC paper (with textual coordinates)
124
+ - "default_no_tr": visual prompt from the SPaRC paper (however with textual coordinates removed)
125
+ - "prompt_engineering": improved vision-only prompt with prompt engineering (no textual coordinates)
126
+ `puzzle` and `plot_type` should be provided the same as in `get_puzzle_image` to allow small prompt adjustments.
127
+
128
+ ### Available Puzzle Representations (`plot_type`)
129
+
130
+ <table>
131
+ <tr>
132
+ <td align="center">
133
+ <code>original</code><br/>
134
+ <img src="docs/images/original.png" alt="original" width="200" />
135
+ </td>
136
+ <td align="center">
137
+ <code>start_end_marked</code><br/>
138
+ <img src="docs/images/start_end_marked.png" alt="start_end_marked" width="200" />
139
+ </td>
140
+ <td align="center">
141
+ <code>coordinate_grid</code><br/>
142
+ <img src="docs/images/coordinate_grid.png" alt="coordinate_grid" width="200" />
143
+ </td>
144
+ </tr>
145
+ <tr>
146
+ <td align="center">
147
+ <code>coordinate_grid_and_start_end_marked</code><br/>
148
+ <img src="docs/images/coordinate_grid_and_start_end_marked.png" alt="coordinate_grid_and_start_end_marked" width="200" />
149
+ </td>
150
+ <td align="center">
151
+ <code>path_cell_annotated</code><br/>
152
+ <img src="docs/images/path_cell_annotated.png" alt="path_cell_annotated" width="200" />
153
+ </td>
154
+ <td align="center">
155
+ <code>text</code><br/>
156
+ <img src="docs/images/text.png" alt="text" width="200" />
157
+ </td>
158
+ </tr>
159
+ <tr>
160
+ <td align="center">
161
+ <code>low_contrast</code><br/>
162
+ <img src="docs/images/low_contrast.png" alt="low_contrast" width="200" />
163
+ </td>
164
+ <td align="center">
165
+ <code>low_contrast_and_path_cell_annotated</code><br/>
166
+ <img src="docs/images/low_contrast_and_path_cell_annotated.png" alt="low_contrast_and_path_cell_annotated" width="200" />
167
+ </td>
168
+ <td align="center">
169
+ <code>low_resolution</code><br/>
170
+ <img src="docs/images/low_resolution.png" alt="low_resolution" width="200" />
171
+ </td>
172
+ </tr>
173
+ <tr>
174
+ <td align="center">
175
+ <code>low_resolution_and_path_cell_annotated</code><br/>
176
+ <img src="docs/images/low_resolution_and_path_cell_annotated.png" alt="low_resolution_and_path_cell_annotated" width="200" />
177
+ </td>
178
+ <td align="center">
179
+ <code>rotated</code><br/>
180
+ <img src="docs/images/rotated.png" alt="rotated" width="200" />
181
+ </td>
182
+ <td align="center">
183
+ <code>rotated_and_path_cell_annotated</code><br/>
184
+ <img src="docs/images/rotated_and_path_cell_annotated.png" alt="rotated_and_path_cell_annotated" width="200" />
185
+ </td>
186
+ </tr>
187
+ <tr>
188
+ <td align="center">
189
+ <code>black_frame</code><br/>
190
+ <img src="docs/images/black_frame.png" alt="black_frame" width="200" />
191
+ </td>
192
+ <td align="center">
193
+ <code>black_frame_and_path_cell_annotated</code><br/>
194
+ <img src="docs/images/black_frame_and_path_cell_annotated.png" alt="black_frame_and_path_cell_annotated" width="200" />
195
+ </td>
196
+ <td></td>
197
+ </tr>
198
+ </table>
199
+
200
+
201
+ ## Contributing
202
+
203
+ Contributions are welcome! Please feel free to submit pull requests or open issues.
204
+
205
+ ## Citation
206
+
207
+ If you use SPaRC in your research, please cite:
208
+
209
+ ```bibtex
210
+ @article{kaesberg2025sparc,
211
+ title = {SPaRC: A Spatial Pathfinding Reasoning Challenge},
212
+ author = {Kaesberg, Lars Benedikt and Wahle, Jan Philip and Ruas, Terry and Gipp, Bela},
213
+ year = {2025},
214
+ url = {https://arxiv.org/abs/2505.16686}
215
+ }
216
+ ```
217
+
218
+ ## License
219
+
220
+ This project is licensed under the MIT License - see the LICENSE file for details.
221
+
222
+ ## Links
223
+
224
+ - 🌐 **Website**: [sparc.gipplab.org](https://sparc.gipplab.org/)
225
+ - 📚 **Dataset**: [Hugging Face](https://huggingface.co/datasets/lkaesberg/SPaRC)
226
+ - 🐛 **Issues**: [GitHub Issues](https://github.com/flowun/sparc-visualization/issues)
227
+ - 📖 **Documentation**: [GitHub Repository](https://github.com/flowun/sparc-visualization)
228
+
229
+
@@ -0,0 +1,210 @@
1
+ ## Overview
2
+
3
+ SPaRC (sparc-puzzle) provides a comprehensive framework for evaluating language models on spatial reasoning tasks inspired by "The Witness" puzzle game.
4
+ This package (sparc-visualization) includes various visual puzzle representations and an improved visual reasoning prompt to complement the functionality of the sparc-puzzle package.
5
+
6
+ ## Installation
7
+
8
+ Install the package from PyPI:
9
+
10
+ ```bash
11
+ pip install sparc-visualization
12
+ ```
13
+
14
+ Or install from source:
15
+
16
+ ```bash
17
+ git clone https://github.com/flowun/sparc-visualization.git
18
+ cd sparc-visualization
19
+ pip install -e .
20
+ ```
21
+
22
+
23
+
24
+ ### Example Usage
25
+
26
+
27
+ ```python
28
+ from sparc_visualization.plot import get_puzzle_image
29
+ from sparc_visualization.prompt import generate_prompt
30
+ from sparc.validation import extract_solution_path, validate_solution, analyze_path
31
+ from datasets import load_dataset
32
+
33
+ # Load the dataset
34
+ dataset = load_dataset("lkaesberg/SPaRC", "all", split="test")
35
+ puzzle = dataset[0]
36
+
37
+ puzzle_image = get_puzzle_image(puzzle, plot_type="path_cell_annotated")
38
+
39
+ # Generate prompt and image, e.g.
40
+ plot_type = "path_cell_annotated"
41
+ prompt_type = "prompt_engineering"
42
+
43
+ b64_image = get_puzzle_image(puzzle, plot_type=plot_type, base_64_image=True)
44
+ text_prompt = generate_prompt(puzzle, plot_type, prompt_type)
45
+
46
+ # create message array and payload for an LLM
47
+ puzzle_prompt = [
48
+ {
49
+ "role": "user",
50
+ "content": [
51
+ {
52
+ "type": "image_url",
53
+ "image_url": {
54
+ "url": f"data:image/png;base64,{b64_image}"
55
+ }
56
+ },
57
+ {
58
+ "type": "text",
59
+ "text": text_prompt
60
+ }
61
+ ]
62
+ }
63
+ ]
64
+
65
+ payload = {
66
+ "model": your_model_name,
67
+ "messages": puzzle_prompt,
68
+ "temperature": temperature,
69
+ "max_tokens": max_tokens,
70
+ }
71
+
72
+ # Your model generates a response
73
+ model_response = "... model response with path coordinates ..."
74
+
75
+ # Analysis using sparc-puzzle package
76
+
77
+ # Extract the path from model response
78
+ extracted_path = extract_solution_path(model_response, puzzle)
79
+ # Returns: [{"x": 0, "y": 2}, {"x": 0, "y": 1}, ...]
80
+
81
+ # Validate against ground truth
82
+ is_correct = validate_solution(extracted_path, puzzle)
83
+ # Returns: True/False
84
+
85
+ # Get detailed analysis
86
+ analysis = analyze_path(extracted_path, puzzle)
87
+ # Returns: {
88
+ # "starts_at_start_ends_at_exit": True,
89
+ # "connected_line": True,
90
+ # "non_intersecting_line": True,
91
+ # "no_rule_crossing": True,
92
+ # "fully_valid_path": True
93
+ # }
94
+ ```
95
+
96
+ ### Core Functions
97
+
98
+ `get_puzzle_image(puzzle: Dict, plot_type: str = "original", base_64_image: bool = False, show_plot: bool = False, save_to_disk: bool = False, save_dir: str = ".", save_filename: str = "puzzle_image.png") -> PIL.Image.Image | str`
99
+ Renders a SPaRC puzzle into one of the supported visual representations (`plot_type` values). To get a base64-encoded string of the image suitable for LLM input, set `base_64_image=True`.
100
+ Besides returning the image object or base64 string, the function has options to display the image (`show_plot=True`) or save it to disk (`save_to_disk=True`).
101
+
102
+ `generate_prompt(puzzle: Dict, plot_type: str = "original", prompt_type: str = "prompt_engineering") -> str`
103
+ Generates the text prompt (based on `prompt_type` values) that should be paired with the rendered image for an LLM call.
104
+ Available `prompt_type` values are:
105
+ - "default_tr": visual prompt from the SPaRC paper (with textual coordinates)
106
+ - "default_no_tr": visual prompt from the SPaRC paper (however with textual coordinates removed)
107
+ - "prompt_engineering": improved vision-only prompt with prompt engineering (no textual coordinates)
108
+ `puzzle` and `plot_type` should be provided the same as in `get_puzzle_image` to allow small prompt adjustments.
109
+
110
+ ### Available Puzzle Representations (`plot_type`)
111
+
112
+ <table>
113
+ <tr>
114
+ <td align="center">
115
+ <code>original</code><br/>
116
+ <img src="docs/images/original.png" alt="original" width="200" />
117
+ </td>
118
+ <td align="center">
119
+ <code>start_end_marked</code><br/>
120
+ <img src="docs/images/start_end_marked.png" alt="start_end_marked" width="200" />
121
+ </td>
122
+ <td align="center">
123
+ <code>coordinate_grid</code><br/>
124
+ <img src="docs/images/coordinate_grid.png" alt="coordinate_grid" width="200" />
125
+ </td>
126
+ </tr>
127
+ <tr>
128
+ <td align="center">
129
+ <code>coordinate_grid_and_start_end_marked</code><br/>
130
+ <img src="docs/images/coordinate_grid_and_start_end_marked.png" alt="coordinate_grid_and_start_end_marked" width="200" />
131
+ </td>
132
+ <td align="center">
133
+ <code>path_cell_annotated</code><br/>
134
+ <img src="docs/images/path_cell_annotated.png" alt="path_cell_annotated" width="200" />
135
+ </td>
136
+ <td align="center">
137
+ <code>text</code><br/>
138
+ <img src="docs/images/text.png" alt="text" width="200" />
139
+ </td>
140
+ </tr>
141
+ <tr>
142
+ <td align="center">
143
+ <code>low_contrast</code><br/>
144
+ <img src="docs/images/low_contrast.png" alt="low_contrast" width="200" />
145
+ </td>
146
+ <td align="center">
147
+ <code>low_contrast_and_path_cell_annotated</code><br/>
148
+ <img src="docs/images/low_contrast_and_path_cell_annotated.png" alt="low_contrast_and_path_cell_annotated" width="200" />
149
+ </td>
150
+ <td align="center">
151
+ <code>low_resolution</code><br/>
152
+ <img src="docs/images/low_resolution.png" alt="low_resolution" width="200" />
153
+ </td>
154
+ </tr>
155
+ <tr>
156
+ <td align="center">
157
+ <code>low_resolution_and_path_cell_annotated</code><br/>
158
+ <img src="docs/images/low_resolution_and_path_cell_annotated.png" alt="low_resolution_and_path_cell_annotated" width="200" />
159
+ </td>
160
+ <td align="center">
161
+ <code>rotated</code><br/>
162
+ <img src="docs/images/rotated.png" alt="rotated" width="200" />
163
+ </td>
164
+ <td align="center">
165
+ <code>rotated_and_path_cell_annotated</code><br/>
166
+ <img src="docs/images/rotated_and_path_cell_annotated.png" alt="rotated_and_path_cell_annotated" width="200" />
167
+ </td>
168
+ </tr>
169
+ <tr>
170
+ <td align="center">
171
+ <code>black_frame</code><br/>
172
+ <img src="docs/images/black_frame.png" alt="black_frame" width="200" />
173
+ </td>
174
+ <td align="center">
175
+ <code>black_frame_and_path_cell_annotated</code><br/>
176
+ <img src="docs/images/black_frame_and_path_cell_annotated.png" alt="black_frame_and_path_cell_annotated" width="200" />
177
+ </td>
178
+ <td></td>
179
+ </tr>
180
+ </table>
181
+
182
+
183
+ ## Contributing
184
+
185
+ Contributions are welcome! Please feel free to submit pull requests or open issues.
186
+
187
+ ## Citation
188
+
189
+ If you use SPaRC in your research, please cite:
190
+
191
+ ```bibtex
192
+ @article{kaesberg2025sparc,
193
+ title = {SPaRC: A Spatial Pathfinding Reasoning Challenge},
194
+ author = {Kaesberg, Lars Benedikt and Wahle, Jan Philip and Ruas, Terry and Gipp, Bela},
195
+ year = {2025},
196
+ url = {https://arxiv.org/abs/2505.16686}
197
+ }
198
+ ```
199
+
200
+ ## License
201
+
202
+ This project is licensed under the MIT License - see the LICENSE file for details.
203
+
204
+ ## Links
205
+
206
+ - 🌐 **Website**: [sparc.gipplab.org](https://sparc.gipplab.org/)
207
+ - 📚 **Dataset**: [Hugging Face](https://huggingface.co/datasets/lkaesberg/SPaRC)
208
+ - 🐛 **Issues**: [GitHub Issues](https://github.com/flowun/sparc-visualization/issues)
209
+ - 📖 **Documentation**: [GitHub Repository](https://github.com/flowun/sparc-visualization)
210
+
@@ -0,0 +1,27 @@
1
+ [project]
2
+ name = "sparc-visualization"
3
+ version = "0.1.0"
4
+ description = ""
5
+ authors = [
6
+ {name = "Florian Valentin Wunderlich",email = "florian.valentin.wunderlich@gmail.com"}
7
+ ]
8
+ license = "MIT"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ dependencies = [
12
+ "Pillow>=12",
13
+ ]
14
+
15
+ [tool.poetry]
16
+ name = "sparc-visualization"
17
+ description = ""
18
+ authors = ["Florian Valentin Wunderlich <florian.valentin.wunderlich@gmail.com>"]
19
+ readme = "README.md"
20
+
21
+ [tool.poetry.dependencies]
22
+ python = "^3.10"
23
+ Pillow = ">=12"
24
+
25
+ [build-system]
26
+ requires = ["poetry-core>=2.0.0,<3.0.0"]
27
+ build-backend = "poetry.core.masonry.api"
@@ -0,0 +1,50 @@
1
+ import json
2
+
3
+ from sparc_visualization.objects.tile import Tile
4
+
5
+ def get_board_from_data(data):
6
+ return Board(
7
+ height=data['grid_size']['height'],
8
+ width=data['grid_size']['width'],
9
+ difficulty_level=data['difficulty_level'],
10
+ difficulty_score=data['difficulty_score'],
11
+ id=data['id'],
12
+ polyshapes=data['polyshapes'],
13
+ puzzle_array=data['puzzle_array'],
14
+ solution_count=data['solution_count'],
15
+ solutions=data['solutions']
16
+ )
17
+
18
+
19
+ class Board:
20
+ def __init__(self, height, width, difficulty_level, difficulty_score, id, polyshapes, puzzle_array, solution_count, solutions):
21
+ self.height = height * 2 + 1
22
+ self.width = width * 2 + 1
23
+ self.difficulty_level = difficulty_level
24
+ self.difficulty_score = difficulty_score
25
+ self.id = id
26
+ self.polyshapes = json.loads(polyshapes)
27
+ self.puzzle_array = puzzle_array
28
+ self.solution_count = solution_count
29
+ self.solutions = solutions
30
+ self.grid = [[None for _ in range(self.width)] for _ in range(self.height)]
31
+ self.place_all_objects()
32
+
33
+ def place_object(self, x, y, obj):
34
+ if 0 <= x < self.width and 0 <= y < self.height:
35
+ self.grid[y][x] = obj
36
+ else:
37
+ raise ValueError("Coordinates out of bounds")
38
+
39
+ def place_all_objects(self):
40
+ for y in range(self.height):
41
+ for x in range(self.width):
42
+ obj_abbr = self.puzzle_array[y][x]
43
+ obj = Tile(obj_abbr)
44
+ self.place_object(x, y, obj)
45
+
46
+ def get_object(self, x, y):
47
+ if 0 <= x < self.width and 0 <= y < self.height:
48
+ return self.grid[y][x]
49
+ else:
50
+ raise ValueError("Coordinates out of bounds")
@@ -0,0 +1,35 @@
1
+ def get_type_from_abbreviation(abbreviation):
2
+ translation_dict = {
3
+ 'S': 'Start',
4
+ 'E': 'End',
5
+ '+': 'Walkable',
6
+ 'N': 'Empty Rule',
7
+ 'G': 'Gap',
8
+ '.': 'Dot',
9
+ 'o': 'Stone',
10
+ '*': 'Star',
11
+ 'A': 'Triangle',
12
+ 'B': 'Triangle',
13
+ 'C': 'Triangle',
14
+ 'D': 'Triangle',
15
+ 'P': 'Positive Polyshape',
16
+ 'Y': 'Negative Polyshape'
17
+ }
18
+ return translation_dict[abbreviation]
19
+
20
+ class Tile:
21
+ def __init__(self, abbreviation):
22
+ self.abbreviation = abbreviation
23
+ self.is_walkable = abbreviation in ['S', 'E', '+', '.']
24
+ self.is_rule_cell = abbreviation.startswith(('N', 'o', '*', 'A', 'B', 'C', 'D', 'P', 'Y'))
25
+ self.type = get_type_from_abbreviation(abbreviation[0])
26
+ self.color = None
27
+ self.shape_id = None
28
+ if '-' in abbreviation:
29
+ self.color = abbreviation.split('-')[1]
30
+ if self.abbreviation.startswith(('P', 'Y')):
31
+ parts = abbreviation.split('-')
32
+ self.shape_id = parts[2]
33
+ if self.abbreviation.startswith(('A', 'B', 'C', 'D')):
34
+ self.triangle_count = {'A': 1, 'B': 2, 'C': 3, 'D': 4}[abbreviation[0]]
35
+ # print(f"Created Tile: {self.name}, Walkable: {self.is_walkable}")
@@ -0,0 +1,63 @@
1
+ from sparc_visualization.plots.plot import get_plot_class
2
+ from sparc_visualization.objects.board import get_board_from_data
3
+ from sparc_visualization.util import encode_image_to_base64
4
+
5
+
6
+ def get_puzzle_image(
7
+ puzzle,
8
+ plot_type="original",
9
+ base_64_image=False,
10
+ show_plot=False,
11
+ save_to_disk=False,
12
+ save_dir=".",
13
+ save_filename="puzzle_image.png",
14
+ ):
15
+ """Render a SPaRC puzzle and return it as a PIL image (or base64).
16
+
17
+ Parameters
18
+ ----------
19
+ puzzle:
20
+ The puzzle data of a single SPaRC puzzle.
21
+ plot_type:
22
+ - "original" (default)
23
+ - "start_end_marked"
24
+ - "coordinate_grid"
25
+ - "coordinate_grid_and_start_end_marked"
26
+ - "path_cell_annotated"
27
+ - "text"
28
+ - "low_contrast"
29
+ - "low_contrast_and_path_cell_annotated"
30
+ - "low_resolution"
31
+ - "low_resolution_and_path_cell_annotated"
32
+ - "rotated"
33
+ - "rotated_and_path_cell_annotated"
34
+ - "black_frame"
35
+ - "black_frame_and_path_cell_annotated"
36
+ base_64_image:
37
+ If True, returns a base64-encoded string instead of a PIL Image.
38
+ show_plot:
39
+ If True, shows the plot in a GUI window.
40
+ save_to_disk:
41
+ If True, saves the plot to disk.
42
+ save_dir:
43
+ Directory to save the plot if ``save_to_disk=True``.
44
+ save_filename:
45
+ Filename to save the plot if ``save_to_disk=True``.
46
+
47
+ Returns
48
+ -------
49
+ PIL.Image.Image | str
50
+ Either a PIL Image (default) or a base64-encoded string if ``base_64_image=True``.
51
+ """
52
+ board = get_board_from_data(puzzle)
53
+ plot = get_plot_class(plot_type, board, size=(board.width, board.height))
54
+ plot.render()
55
+ if save_to_disk:
56
+ plot.save(dir=save_dir, filename=save_filename)
57
+ if show_plot:
58
+ plot.show()
59
+ if base_64_image:
60
+ return encode_image_to_base64(plot._img)
61
+ else:
62
+ return plot._img
63
+