chuk-puzzles-gym 0.10__py3-none-any.whl → 0.10.1__py3-none-any.whl
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.
- chuk_puzzles_gym/games/binary/game.py +2 -0
- chuk_puzzles_gym/games/bridges/game.py +2 -0
- chuk_puzzles_gym/games/cryptarithmetic/game.py +5 -0
- chuk_puzzles_gym/games/einstein/game.py +2 -0
- chuk_puzzles_gym/games/fillomino/game.py +2 -0
- chuk_puzzles_gym/games/futoshiki/game.py +2 -0
- chuk_puzzles_gym/games/graph_coloring/commands.py +20 -3
- chuk_puzzles_gym/games/graph_coloring/game.py +8 -1
- chuk_puzzles_gym/games/hidato/game.py +2 -0
- chuk_puzzles_gym/games/hitori/game.py +2 -0
- chuk_puzzles_gym/games/kakuro/game.py +2 -0
- chuk_puzzles_gym/games/kenken/game.py +2 -0
- chuk_puzzles_gym/games/killer_sudoku/game.py +2 -0
- chuk_puzzles_gym/games/knapsack/game.py +2 -0
- chuk_puzzles_gym/games/lights_out/game.py +2 -0
- chuk_puzzles_gym/games/logic_grid/game.py +2 -0
- chuk_puzzles_gym/games/mastermind/game.py +2 -0
- chuk_puzzles_gym/games/minesweeper/game.py +2 -0
- chuk_puzzles_gym/games/nonogram/game.py +2 -0
- chuk_puzzles_gym/games/nqueens/game.py +5 -0
- chuk_puzzles_gym/games/numberlink/game.py +6 -0
- chuk_puzzles_gym/games/nurikabe/game.py +2 -0
- chuk_puzzles_gym/games/rush_hour/game.py +4 -0
- chuk_puzzles_gym/games/scheduler/game.py +2 -0
- chuk_puzzles_gym/games/shikaku/game.py +2 -0
- chuk_puzzles_gym/games/skyscrapers/game.py +5 -0
- chuk_puzzles_gym/games/slitherlink/game.py +2 -0
- chuk_puzzles_gym/games/sokoban/game.py +2 -0
- chuk_puzzles_gym/games/star_battle/game.py +2 -0
- chuk_puzzles_gym/games/sudoku/game.py +2 -0
- chuk_puzzles_gym/games/tents/game.py +2 -0
- chuk_puzzles_gym/server.py +17 -69
- {chuk_puzzles_gym-0.10.dist-info → chuk_puzzles_gym-0.10.1.dist-info}/METADATA +1 -1
- {chuk_puzzles_gym-0.10.dist-info → chuk_puzzles_gym-0.10.1.dist-info}/RECORD +37 -37
- {chuk_puzzles_gym-0.10.dist-info → chuk_puzzles_gym-0.10.1.dist-info}/WHEEL +0 -0
- {chuk_puzzles_gym-0.10.dist-info → chuk_puzzles_gym-0.10.1.dist-info}/entry_points.txt +0 -0
- {chuk_puzzles_gym-0.10.dist-info → chuk_puzzles_gym-0.10.1.dist-info}/top_level.txt +0 -0
|
@@ -358,6 +358,8 @@ class BinaryPuzzleGame(PuzzleGame):
|
|
|
358
358
|
Returns:
|
|
359
359
|
Tuple of (hint_data, hint_message) or None if puzzle is complete
|
|
360
360
|
"""
|
|
361
|
+
if not self.can_use_hint():
|
|
362
|
+
return None
|
|
361
363
|
empty_cells = [(r, c) for r in range(self.size) for c in range(self.size) if self.grid[r][c] == -1]
|
|
362
364
|
if not empty_cells:
|
|
363
365
|
return None
|
|
@@ -415,6 +415,8 @@ class BridgesGame(PuzzleGame):
|
|
|
415
415
|
|
|
416
416
|
async def get_hint(self) -> tuple[Any, str] | None:
|
|
417
417
|
"""Get a hint for the next move."""
|
|
418
|
+
if not self.can_use_hint():
|
|
419
|
+
return None
|
|
418
420
|
# Find a bridge in the solution that's not yet placed correctly
|
|
419
421
|
for bridge_key, solution_count in self.solution.items():
|
|
420
422
|
current_count = self.bridges.get(bridge_key, 0)
|
|
@@ -362,6 +362,11 @@ class CryptarithmeticGame(PuzzleGame):
|
|
|
362
362
|
|
|
363
363
|
return "\n".join(lines)
|
|
364
364
|
|
|
365
|
+
def get_stats(self) -> str:
|
|
366
|
+
"""Get current game statistics."""
|
|
367
|
+
assigned = sum(1 for v in self.player_mapping.values() if v is not None)
|
|
368
|
+
return f"Moves: {self.moves_made} | Assigned: {assigned}/{len(self.letters)} | Seed: {self.seed}"
|
|
369
|
+
|
|
365
370
|
def get_rules(self) -> str:
|
|
366
371
|
return (
|
|
367
372
|
"CRYPTARITHMETIC\n"
|
|
@@ -281,6 +281,8 @@ class EinsteinGame(PuzzleGame):
|
|
|
281
281
|
Returns:
|
|
282
282
|
Tuple of (hint_data, hint_message) or None
|
|
283
283
|
"""
|
|
284
|
+
if not self.can_use_hint():
|
|
285
|
+
return None
|
|
284
286
|
# Find first unassigned attribute in solution
|
|
285
287
|
for i in range(self.num_houses):
|
|
286
288
|
for attr in ATTRIBUTES:
|
|
@@ -435,6 +435,8 @@ class FillominoGame(PuzzleGame):
|
|
|
435
435
|
Returns:
|
|
436
436
|
Tuple of (hint_data, hint_message) or None if puzzle is complete
|
|
437
437
|
"""
|
|
438
|
+
if not self.can_use_hint():
|
|
439
|
+
return None
|
|
438
440
|
# Find an empty cell
|
|
439
441
|
for r in range(self.size):
|
|
440
442
|
for c in range(self.size):
|
|
@@ -288,6 +288,8 @@ class FutoshikiGame(PuzzleGame):
|
|
|
288
288
|
Returns:
|
|
289
289
|
Tuple of (hint_data, hint_message) or None if puzzle is complete
|
|
290
290
|
"""
|
|
291
|
+
if not self.can_use_hint():
|
|
292
|
+
return None
|
|
291
293
|
empty_cells = [(r, c) for r in range(self.size) for c in range(self.size) if self.grid[r][c] == 0]
|
|
292
294
|
if not empty_cells:
|
|
293
295
|
return None
|
|
@@ -4,10 +4,14 @@ from typing import TYPE_CHECKING
|
|
|
4
4
|
|
|
5
5
|
from ...models import GameCommand, MoveResult
|
|
6
6
|
from .._base import CommandResult, GameCommandHandler
|
|
7
|
+
from .game import COLOR_NAMES
|
|
7
8
|
|
|
8
9
|
if TYPE_CHECKING:
|
|
9
10
|
from .game import GraphColoringGame
|
|
10
11
|
|
|
12
|
+
# Build a lookup from lowercase color name to color number
|
|
13
|
+
_COLOR_NAME_TO_NUM = {name.lower(): i + 1 for i, name in enumerate(COLOR_NAMES)}
|
|
14
|
+
|
|
11
15
|
|
|
12
16
|
class GraphColoringCommandHandler(GameCommandHandler):
|
|
13
17
|
"""Handles commands for Graph Coloring game."""
|
|
@@ -36,6 +40,16 @@ class GraphColoringCommandHandler(GameCommandHandler):
|
|
|
36
40
|
else:
|
|
37
41
|
return self.error_result(f"Unknown command: {cmd}")
|
|
38
42
|
|
|
43
|
+
def _parse_color(self, value: str) -> int | None:
|
|
44
|
+
"""Parse a color argument as either an integer or a color name."""
|
|
45
|
+
# Try integer first
|
|
46
|
+
try:
|
|
47
|
+
return int(value)
|
|
48
|
+
except ValueError:
|
|
49
|
+
pass
|
|
50
|
+
# Try color name lookup
|
|
51
|
+
return _COLOR_NAME_TO_NUM.get(value.lower())
|
|
52
|
+
|
|
39
53
|
async def _handle_place(self, args: list[str]) -> CommandResult:
|
|
40
54
|
"""Handle the PLACE command: place <node> <color>."""
|
|
41
55
|
if len(args) != 2:
|
|
@@ -45,10 +59,13 @@ class GraphColoringCommandHandler(GameCommandHandler):
|
|
|
45
59
|
)
|
|
46
60
|
|
|
47
61
|
node = self.parse_int(args[0], "node")
|
|
48
|
-
color = self.
|
|
62
|
+
color = self._parse_color(args[1])
|
|
49
63
|
|
|
50
|
-
if node is None
|
|
51
|
-
return self.error_result("Node
|
|
64
|
+
if node is None:
|
|
65
|
+
return self.error_result("Node must be an integer.")
|
|
66
|
+
if color is None:
|
|
67
|
+
valid = ", ".join(f"{i + 1}={COLOR_NAMES[i]}" for i in range(self.game.num_colors))
|
|
68
|
+
return self.error_result(f"Invalid color. Use a number or name: {valid}")
|
|
52
69
|
|
|
53
70
|
result = await self.game.validate_move(node, color)
|
|
54
71
|
|
|
@@ -289,6 +289,11 @@ class GraphColoringGame(PuzzleGame):
|
|
|
289
289
|
|
|
290
290
|
return "\n".join(lines)
|
|
291
291
|
|
|
292
|
+
def get_stats(self) -> str:
|
|
293
|
+
"""Get current game statistics."""
|
|
294
|
+
colored = sum(1 for n in range(1, self.num_nodes + 1) if self.coloring.get(n, 0) > 0)
|
|
295
|
+
return f"Moves: {self.moves_made} | Colored: {colored}/{self.num_nodes} | Edges: {len(self.edges)} | Seed: {self.seed}"
|
|
296
|
+
|
|
292
297
|
def get_rules(self) -> str:
|
|
293
298
|
return (
|
|
294
299
|
f"GRAPH COLORING ({self.num_nodes} nodes, {self.num_colors} colors)\n"
|
|
@@ -298,9 +303,11 @@ class GraphColoringGame(PuzzleGame):
|
|
|
298
303
|
)
|
|
299
304
|
|
|
300
305
|
def get_commands(self) -> str:
|
|
306
|
+
color_map = ", ".join(f"{i + 1}={COLOR_NAMES[i]}" for i in range(self.num_colors))
|
|
301
307
|
return (
|
|
302
308
|
"Commands:\n"
|
|
303
|
-
f" place <node> <color> - Color a node (
|
|
309
|
+
f" place <node> <color> - Color a node (number or name)\n"
|
|
310
|
+
f" Colors: {color_map}\n"
|
|
304
311
|
" clear <node> - Remove color from a node\n"
|
|
305
312
|
" hint - Get a hint\n"
|
|
306
313
|
" check - Check if solved\n"
|
|
@@ -302,6 +302,8 @@ class HidatoGame(PuzzleGame):
|
|
|
302
302
|
Returns:
|
|
303
303
|
Tuple of (hint_data, hint_message) or None if puzzle is complete
|
|
304
304
|
"""
|
|
305
|
+
if not self.can_use_hint():
|
|
306
|
+
return None
|
|
305
307
|
# Find an empty cell
|
|
306
308
|
empty_cells = [(r, c) for r in range(self.size) for c in range(self.size) if self.grid[r][c] == 0]
|
|
307
309
|
if not empty_cells:
|
|
@@ -395,6 +395,8 @@ class HitoriGame(PuzzleGame):
|
|
|
395
395
|
|
|
396
396
|
async def get_hint(self) -> tuple[Any, str] | None:
|
|
397
397
|
"""Get a hint for the next move."""
|
|
398
|
+
if not self.can_use_hint():
|
|
399
|
+
return None
|
|
398
400
|
# Find a cell that should be shaded but isn't, or vice versa
|
|
399
401
|
for r in range(self.size):
|
|
400
402
|
for c in range(self.size):
|
|
@@ -366,6 +366,8 @@ class KenKenGame(PuzzleGame):
|
|
|
366
366
|
Returns:
|
|
367
367
|
Tuple of (hint_data, hint_message) or None if puzzle is complete
|
|
368
368
|
"""
|
|
369
|
+
if not self.can_use_hint():
|
|
370
|
+
return None
|
|
369
371
|
empty_cells = [(r, c) for r in range(self.size) for c in range(self.size) if self.grid[r][c] == 0]
|
|
370
372
|
if not empty_cells:
|
|
371
373
|
return None
|
|
@@ -395,6 +395,8 @@ class KillerSudokuGame(PuzzleGame):
|
|
|
395
395
|
Returns:
|
|
396
396
|
Tuple of (hint_data, hint_message) or None if puzzle is complete
|
|
397
397
|
"""
|
|
398
|
+
if not self.can_use_hint():
|
|
399
|
+
return None
|
|
398
400
|
empty_cells = [(r, c) for r in range(9) for c in range(9) if self.grid[r][c] == 0]
|
|
399
401
|
if not empty_cells:
|
|
400
402
|
return None
|
|
@@ -255,6 +255,8 @@ class KnapsackGame(PuzzleGame):
|
|
|
255
255
|
Returns:
|
|
256
256
|
Tuple of (hint_data, hint_message) or None
|
|
257
257
|
"""
|
|
258
|
+
if not self.can_use_hint():
|
|
259
|
+
return None
|
|
258
260
|
# Suggest selecting an item that's in the optimal solution but not selected
|
|
259
261
|
for i in range(len(self.items)):
|
|
260
262
|
if self.optimal_selection[i] and not self.selection[i]:
|
|
@@ -173,6 +173,8 @@ class LightsOutGame(PuzzleGame):
|
|
|
173
173
|
Returns:
|
|
174
174
|
Tuple of (hint_data, hint_message) or None if puzzle is complete
|
|
175
175
|
"""
|
|
176
|
+
if not self.can_use_hint():
|
|
177
|
+
return None
|
|
176
178
|
# Find a cell in the solution that should be pressed
|
|
177
179
|
for row in range(self.size):
|
|
178
180
|
for col in range(self.size):
|
|
@@ -235,6 +235,8 @@ class LogicGridGame(PuzzleGame):
|
|
|
235
235
|
Returns:
|
|
236
236
|
Tuple of (hint_data, hint_message) or None if puzzle is complete
|
|
237
237
|
"""
|
|
238
|
+
if not self.can_use_hint():
|
|
239
|
+
return None
|
|
238
240
|
# Find a connection that hasn't been marked
|
|
239
241
|
for person in self.categories.person:
|
|
240
242
|
attrs = self.solution[person]
|
|
@@ -192,6 +192,8 @@ class NonogramGame(PuzzleGame):
|
|
|
192
192
|
Returns:
|
|
193
193
|
Tuple of (hint_data, hint_message) or None if puzzle is complete
|
|
194
194
|
"""
|
|
195
|
+
if not self.can_use_hint():
|
|
196
|
+
return None
|
|
195
197
|
unknown_cells = [(r, c) for r in range(self.size) for c in range(self.size) if self.grid[r][c] == -1]
|
|
196
198
|
if not unknown_cells:
|
|
197
199
|
return None
|
|
@@ -296,6 +296,11 @@ class NQueensGame(PuzzleGame):
|
|
|
296
296
|
|
|
297
297
|
return "\n".join(lines)
|
|
298
298
|
|
|
299
|
+
def get_stats(self) -> str:
|
|
300
|
+
"""Get current game statistics."""
|
|
301
|
+
placed = sum(1 for r in range(self.size) for c in range(self.size) if self.grid[r][c] == 1)
|
|
302
|
+
return f"Moves: {self.moves_made} | Queens: {placed}/{self.size} | Board: {self.size}x{self.size} | Seed: {self.seed}"
|
|
303
|
+
|
|
299
304
|
def get_rules(self) -> str:
|
|
300
305
|
return (
|
|
301
306
|
f"N-QUEENS ({self.size}x{self.size})\n"
|
|
@@ -317,6 +317,12 @@ class NumberlinkGame(PuzzleGame):
|
|
|
317
317
|
|
|
318
318
|
return "\n".join(lines)
|
|
319
319
|
|
|
320
|
+
def get_stats(self) -> str:
|
|
321
|
+
"""Get current game statistics."""
|
|
322
|
+
filled = sum(1 for r in range(self.size) for c in range(self.size) if self.grid[r][c] != 0)
|
|
323
|
+
total = self.size * self.size
|
|
324
|
+
return f"Moves: {self.moves_made} | Filled: {filled}/{total} | Pairs: {self.num_pairs} | Seed: {self.seed}"
|
|
325
|
+
|
|
320
326
|
def get_rules(self) -> str:
|
|
321
327
|
return (
|
|
322
328
|
f"NUMBERLINK ({self.size}x{self.size}, {self.num_pairs} pairs)\n"
|
|
@@ -479,6 +479,8 @@ class NurikabeGame(PuzzleGame):
|
|
|
479
479
|
Returns:
|
|
480
480
|
Tuple of (hint_data, hint_message) or None
|
|
481
481
|
"""
|
|
482
|
+
if not self.can_use_hint():
|
|
483
|
+
return None
|
|
482
484
|
# Find a cell that differs from solution
|
|
483
485
|
for row in range(self.size):
|
|
484
486
|
for col in range(self.size):
|
|
@@ -454,6 +454,10 @@ class RushHourGame(PuzzleGame):
|
|
|
454
454
|
|
|
455
455
|
return "\n".join(lines)
|
|
456
456
|
|
|
457
|
+
def get_stats(self) -> str:
|
|
458
|
+
"""Get current game statistics."""
|
|
459
|
+
return f"Moves: {self.moves_made} | Vehicles: {len(self.vehicles)} | Grid: {self.size}x{self.size} | Seed: {self.seed}"
|
|
460
|
+
|
|
457
461
|
def get_rules(self) -> str:
|
|
458
462
|
return (
|
|
459
463
|
f"RUSH HOUR ({self.size}x{self.size})\n"
|
|
@@ -316,6 +316,8 @@ class SchedulerGame(PuzzleGame):
|
|
|
316
316
|
Returns:
|
|
317
317
|
Tuple of (hint_data, hint_message) or None
|
|
318
318
|
"""
|
|
319
|
+
if not self.can_use_hint():
|
|
320
|
+
return None
|
|
319
321
|
# Find an unscheduled task that's in the optimal solution
|
|
320
322
|
for task_id in range(self.num_tasks):
|
|
321
323
|
if task_id not in self.schedule and task_id in self.optimal_schedule:
|
|
@@ -327,6 +327,8 @@ class ShikakuGame(PuzzleGame):
|
|
|
327
327
|
|
|
328
328
|
async def get_hint(self) -> tuple[Any, str] | None:
|
|
329
329
|
"""Get a hint for the next move."""
|
|
330
|
+
if not self.can_use_hint():
|
|
331
|
+
return None
|
|
330
332
|
# Find a rectangle from the solution that hasn't been placed yet
|
|
331
333
|
solution_rects: dict[int, list[tuple[int, int]]] = {}
|
|
332
334
|
for r in range(self.size):
|
|
@@ -255,6 +255,11 @@ class SkyscrapersGame(PuzzleGame):
|
|
|
255
255
|
|
|
256
256
|
return "\n".join(lines)
|
|
257
257
|
|
|
258
|
+
def get_stats(self) -> str:
|
|
259
|
+
"""Get current game statistics."""
|
|
260
|
+
empty = sum(1 for r in range(self.size) for c in range(self.size) if self.grid[r][c] == 0)
|
|
261
|
+
return f"Moves: {self.moves_made} | Empty cells: {empty} | Grid: {self.size}x{self.size} | Seed: {self.seed}"
|
|
262
|
+
|
|
258
263
|
def get_rules(self) -> str:
|
|
259
264
|
return (
|
|
260
265
|
f"SKYSCRAPERS ({self.size}x{self.size})\n"
|
|
@@ -272,6 +272,8 @@ class SlitherlinkGame(PuzzleGame):
|
|
|
272
272
|
Returns:
|
|
273
273
|
Tuple of (hint_data, hint_message) or None
|
|
274
274
|
"""
|
|
275
|
+
if not self.can_use_hint():
|
|
276
|
+
return None
|
|
275
277
|
# Find an edge that's in the solution but not set by player
|
|
276
278
|
for row in range(self.size + 1):
|
|
277
279
|
for col in range(self.size):
|
|
@@ -301,6 +301,8 @@ class StarBattleGame(PuzzleGame):
|
|
|
301
301
|
Returns:
|
|
302
302
|
Tuple of (hint_data, hint_message) or None if puzzle is complete
|
|
303
303
|
"""
|
|
304
|
+
if not self.can_use_hint():
|
|
305
|
+
return None
|
|
304
306
|
# Find a star location from solution that hasn't been placed
|
|
305
307
|
for r in range(self.size):
|
|
306
308
|
for c in range(self.size):
|
|
@@ -249,6 +249,8 @@ class SudokuGame(PuzzleGame):
|
|
|
249
249
|
Returns:
|
|
250
250
|
Tuple of (hint_data, hint_message) or None if puzzle is complete
|
|
251
251
|
"""
|
|
252
|
+
if not self.can_use_hint():
|
|
253
|
+
return None
|
|
252
254
|
empty_cells = [(r, c) for r in range(9) for c in range(9) if self.grid[r][c] == 0]
|
|
253
255
|
if not empty_cells:
|
|
254
256
|
return None
|
|
@@ -326,6 +326,8 @@ class TentsGame(PuzzleGame):
|
|
|
326
326
|
Returns:
|
|
327
327
|
Tuple of (hint_data, hint_message) or None if puzzle is complete
|
|
328
328
|
"""
|
|
329
|
+
if not self.can_use_hint():
|
|
330
|
+
return None
|
|
329
331
|
# Find a tent location from solution that hasn't been placed
|
|
330
332
|
for r in range(self.size):
|
|
331
333
|
for c in range(self.size):
|
chuk_puzzles_gym/server.py
CHANGED
|
@@ -599,10 +599,6 @@ class ArcadeHandler(TelnetHandler):
|
|
|
599
599
|
if self.game_handler and cmd_enum in self.game_handler.supported_commands:
|
|
600
600
|
result = await self.game_handler.handle_command(cmd_enum, parts[1:])
|
|
601
601
|
|
|
602
|
-
# Track invalid moves
|
|
603
|
-
if not result.result.success:
|
|
604
|
-
self.current_game.invalid_moves += 1
|
|
605
|
-
|
|
606
602
|
# Send result based on output mode
|
|
607
603
|
code = "OK" if result.result.success else "INVALID"
|
|
608
604
|
await self.send_result(result.result.success, result.result.message, code)
|
|
@@ -626,9 +622,7 @@ class ArcadeHandler(TelnetHandler):
|
|
|
626
622
|
num = int(parts[3])
|
|
627
623
|
|
|
628
624
|
result = await self.current_game.validate_move(row, col, num)
|
|
629
|
-
|
|
630
|
-
if not result.success:
|
|
631
|
-
self.current_game.invalid_moves += 1
|
|
625
|
+
self.current_game.record_move((row, col), result.success)
|
|
632
626
|
|
|
633
627
|
await self.send_result(result.success, result.message, "PLACED" if result.success else "INVALID_MOVE")
|
|
634
628
|
|
|
@@ -639,7 +633,6 @@ class ArcadeHandler(TelnetHandler):
|
|
|
639
633
|
await self.send_game_complete()
|
|
640
634
|
|
|
641
635
|
except ValueError:
|
|
642
|
-
self.current_game.invalid_moves += 1
|
|
643
636
|
await self.send_result(False, "Invalid input. Use numbers only.", "PARSE_ERROR")
|
|
644
637
|
return
|
|
645
638
|
|
|
@@ -653,9 +646,7 @@ class ArcadeHandler(TelnetHandler):
|
|
|
653
646
|
col = int(parts[2])
|
|
654
647
|
|
|
655
648
|
result = await self.current_game.validate_move(row, col, 0)
|
|
656
|
-
|
|
657
|
-
if not result.success:
|
|
658
|
-
self.current_game.invalid_moves += 1
|
|
649
|
+
self.current_game.record_move((row, col), result.success)
|
|
659
650
|
|
|
660
651
|
await self.send_result(result.success, result.message, "CLEARED" if result.success else "INVALID_CLEAR")
|
|
661
652
|
|
|
@@ -663,7 +654,6 @@ class ArcadeHandler(TelnetHandler):
|
|
|
663
654
|
await self.display_puzzle()
|
|
664
655
|
|
|
665
656
|
except ValueError:
|
|
666
|
-
self.current_game.invalid_moves += 1
|
|
667
657
|
await self.send_result(False, "Invalid input. Use numbers only.", "PARSE_ERROR")
|
|
668
658
|
return
|
|
669
659
|
|
|
@@ -693,9 +683,7 @@ class ArcadeHandler(TelnetHandler):
|
|
|
693
683
|
col = int(parts[2])
|
|
694
684
|
|
|
695
685
|
result = await self.current_game.validate_move(row, col)
|
|
696
|
-
|
|
697
|
-
if not result.success:
|
|
698
|
-
self.current_game.invalid_moves += 1
|
|
686
|
+
self.current_game.record_move((row, col), result.success)
|
|
699
687
|
|
|
700
688
|
await self.send_result(result.success, result.message, "PRESSED" if result.success else "INVALID_PRESS")
|
|
701
689
|
|
|
@@ -706,7 +694,6 @@ class ArcadeHandler(TelnetHandler):
|
|
|
706
694
|
await self.send_game_complete()
|
|
707
695
|
|
|
708
696
|
except ValueError:
|
|
709
|
-
self.current_game.invalid_moves += 1
|
|
710
697
|
await self.send_result(False, "Invalid input. Use numbers only.", "PARSE_ERROR")
|
|
711
698
|
return
|
|
712
699
|
|
|
@@ -718,9 +705,7 @@ class ArcadeHandler(TelnetHandler):
|
|
|
718
705
|
|
|
719
706
|
cat1, val1, cat2, val2 = parts[1], parts[2], parts[3], parts[4]
|
|
720
707
|
result = await self.current_game.validate_move(cat1, val1, cat2, val2, True)
|
|
721
|
-
|
|
722
|
-
if not result.success:
|
|
723
|
-
self.current_game.invalid_moves += 1
|
|
708
|
+
self.current_game.record_move((cat1, val1, cat2, val2), result.success)
|
|
724
709
|
|
|
725
710
|
await self.send_result(result.success, result.message, "CONNECTED" if result.success else "INVALID_CONNECT")
|
|
726
711
|
if result.success:
|
|
@@ -736,9 +721,7 @@ class ArcadeHandler(TelnetHandler):
|
|
|
736
721
|
|
|
737
722
|
cat1, val1, cat2, val2 = parts[1], parts[2], parts[3], parts[4]
|
|
738
723
|
result = await self.current_game.validate_move(cat1, val1, cat2, val2, False)
|
|
739
|
-
|
|
740
|
-
if not result.success:
|
|
741
|
-
self.current_game.invalid_moves += 1
|
|
724
|
+
self.current_game.record_move((cat1, val1, cat2, val2), result.success)
|
|
742
725
|
|
|
743
726
|
await self.send_result(result.success, result.message, "EXCLUDED" if result.success else "INVALID_EXCLUDE")
|
|
744
727
|
if result.success:
|
|
@@ -758,9 +741,7 @@ class ArcadeHandler(TelnetHandler):
|
|
|
758
741
|
col = int(parts[2])
|
|
759
742
|
|
|
760
743
|
result = await self.current_game.validate_move("reveal", row, col)
|
|
761
|
-
|
|
762
|
-
if not result.success:
|
|
763
|
-
self.current_game.invalid_moves += 1
|
|
744
|
+
self.current_game.record_move((row, col), result.success)
|
|
764
745
|
|
|
765
746
|
await self.send_result(
|
|
766
747
|
result.success, result.message, "REVEALED" if result.success else "INVALID_REVEAL"
|
|
@@ -783,7 +764,6 @@ class ArcadeHandler(TelnetHandler):
|
|
|
783
764
|
await self.send_line("=" * 50 + "\n")
|
|
784
765
|
|
|
785
766
|
except ValueError:
|
|
786
|
-
self.current_game.invalid_moves += 1
|
|
787
767
|
await self.send_result(False, "Invalid input. Use numbers only.", "PARSE_ERROR")
|
|
788
768
|
return
|
|
789
769
|
|
|
@@ -797,9 +777,7 @@ class ArcadeHandler(TelnetHandler):
|
|
|
797
777
|
col = int(parts[2])
|
|
798
778
|
|
|
799
779
|
result = await self.current_game.validate_move("flag", row, col)
|
|
800
|
-
|
|
801
|
-
if not result.success:
|
|
802
|
-
self.current_game.invalid_moves += 1
|
|
780
|
+
self.current_game.record_move((row, col), result.success)
|
|
803
781
|
|
|
804
782
|
await self.send_result(result.success, result.message, "FLAGGED" if result.success else "INVALID_FLAG")
|
|
805
783
|
|
|
@@ -807,7 +785,6 @@ class ArcadeHandler(TelnetHandler):
|
|
|
807
785
|
await self.display_puzzle()
|
|
808
786
|
|
|
809
787
|
except ValueError:
|
|
810
|
-
self.current_game.invalid_moves += 1
|
|
811
788
|
await self.send_result(False, "Invalid input. Use numbers only.", "PARSE_ERROR")
|
|
812
789
|
return
|
|
813
790
|
|
|
@@ -824,9 +801,7 @@ class ArcadeHandler(TelnetHandler):
|
|
|
824
801
|
state = int(parts[4])
|
|
825
802
|
|
|
826
803
|
result = await self.current_game.validate_move(edge_type, row, col, state)
|
|
827
|
-
|
|
828
|
-
if not result.success:
|
|
829
|
-
self.current_game.invalid_moves += 1
|
|
804
|
+
self.current_game.record_move((edge_type, row, col), result.success)
|
|
830
805
|
|
|
831
806
|
await self.send_result(result.success, result.message, "SET" if result.success else "INVALID_SET")
|
|
832
807
|
|
|
@@ -837,7 +812,6 @@ class ArcadeHandler(TelnetHandler):
|
|
|
837
812
|
await self.send_game_complete()
|
|
838
813
|
|
|
839
814
|
except ValueError:
|
|
840
|
-
self.current_game.invalid_moves += 1
|
|
841
815
|
await self.send_result(False, "Invalid input. Use numbers only for row, col, state.", "PARSE_ERROR")
|
|
842
816
|
return
|
|
843
817
|
|
|
@@ -851,9 +825,7 @@ class ArcadeHandler(TelnetHandler):
|
|
|
851
825
|
guess = [int(p) for p in parts[1:]]
|
|
852
826
|
|
|
853
827
|
result = await self.current_game.validate_move(*guess)
|
|
854
|
-
|
|
855
|
-
if not result.success:
|
|
856
|
-
self.current_game.invalid_moves += 1
|
|
828
|
+
self.current_game.record_move(tuple(guess), result.success)
|
|
857
829
|
|
|
858
830
|
await self.send_result(result.success, result.message, "GUESSED" if result.success else "INVALID_GUESS")
|
|
859
831
|
|
|
@@ -874,7 +846,6 @@ class ArcadeHandler(TelnetHandler):
|
|
|
874
846
|
await self.send_line("=" * 50 + "\n")
|
|
875
847
|
|
|
876
848
|
except ValueError:
|
|
877
|
-
self.current_game.invalid_moves += 1
|
|
878
849
|
await self.send_result(False, "Invalid input. Use numbers only.", "PARSE_ERROR")
|
|
879
850
|
return
|
|
880
851
|
|
|
@@ -888,9 +859,7 @@ class ArcadeHandler(TelnetHandler):
|
|
|
888
859
|
item_index = int(parts[1])
|
|
889
860
|
|
|
890
861
|
result = await self.current_game.validate_move("select", item_index)
|
|
891
|
-
|
|
892
|
-
if not result.success:
|
|
893
|
-
self.current_game.invalid_moves += 1
|
|
862
|
+
self.current_game.record_move((item_index,), result.success)
|
|
894
863
|
|
|
895
864
|
await self.send_result(
|
|
896
865
|
result.success, result.message, "SELECTED" if result.success else "INVALID_SELECT"
|
|
@@ -900,7 +869,6 @@ class ArcadeHandler(TelnetHandler):
|
|
|
900
869
|
await self.display_puzzle()
|
|
901
870
|
|
|
902
871
|
except ValueError:
|
|
903
|
-
self.current_game.invalid_moves += 1
|
|
904
872
|
await self.send_result(False, "Invalid input. Use numbers only.", "PARSE_ERROR")
|
|
905
873
|
return
|
|
906
874
|
|
|
@@ -913,9 +881,7 @@ class ArcadeHandler(TelnetHandler):
|
|
|
913
881
|
item_index = int(parts[1])
|
|
914
882
|
|
|
915
883
|
result = await self.current_game.validate_move("deselect", item_index)
|
|
916
|
-
|
|
917
|
-
if not result.success:
|
|
918
|
-
self.current_game.invalid_moves += 1
|
|
884
|
+
self.current_game.record_move((item_index,), result.success)
|
|
919
885
|
|
|
920
886
|
await self.send_result(
|
|
921
887
|
result.success, result.message, "DESELECTED" if result.success else "INVALID_DESELECT"
|
|
@@ -925,7 +891,6 @@ class ArcadeHandler(TelnetHandler):
|
|
|
925
891
|
await self.display_puzzle()
|
|
926
892
|
|
|
927
893
|
except ValueError:
|
|
928
|
-
self.current_game.invalid_moves += 1
|
|
929
894
|
await self.send_result(False, "Invalid input. Use numbers only.", "PARSE_ERROR")
|
|
930
895
|
return
|
|
931
896
|
|
|
@@ -941,9 +906,7 @@ class ArcadeHandler(TelnetHandler):
|
|
|
941
906
|
color = parts[3].lower()
|
|
942
907
|
|
|
943
908
|
result = await self.current_game.validate_move(row, col, color)
|
|
944
|
-
|
|
945
|
-
if not result.success:
|
|
946
|
-
self.current_game.invalid_moves += 1
|
|
909
|
+
self.current_game.record_move((row, col), result.success)
|
|
947
910
|
|
|
948
911
|
await self.send_result(result.success, result.message, "MARKED" if result.success else "INVALID_MARK")
|
|
949
912
|
|
|
@@ -954,7 +917,6 @@ class ArcadeHandler(TelnetHandler):
|
|
|
954
917
|
await self.send_game_complete()
|
|
955
918
|
|
|
956
919
|
except ValueError:
|
|
957
|
-
self.current_game.invalid_moves += 1
|
|
958
920
|
await self.send_result(False, "Invalid input. Row and col must be numbers.", "PARSE_ERROR")
|
|
959
921
|
return
|
|
960
922
|
|
|
@@ -969,9 +931,7 @@ class ArcadeHandler(TelnetHandler):
|
|
|
969
931
|
col = int(parts[2])
|
|
970
932
|
|
|
971
933
|
result = await self.current_game.validate_move(row, col, "shade")
|
|
972
|
-
|
|
973
|
-
if not result.success:
|
|
974
|
-
self.current_game.invalid_moves += 1
|
|
934
|
+
self.current_game.record_move((row, col), result.success)
|
|
975
935
|
|
|
976
936
|
await self.send_result(result.success, result.message, "SHADED" if result.success else "INVALID_SHADE")
|
|
977
937
|
|
|
@@ -982,7 +942,6 @@ class ArcadeHandler(TelnetHandler):
|
|
|
982
942
|
await self.send_game_complete()
|
|
983
943
|
|
|
984
944
|
except ValueError:
|
|
985
|
-
self.current_game.invalid_moves += 1
|
|
986
945
|
await self.send_result(False, "Invalid input. Use numbers only.", "PARSE_ERROR")
|
|
987
946
|
return
|
|
988
947
|
|
|
@@ -1000,9 +959,7 @@ class ArcadeHandler(TelnetHandler):
|
|
|
1000
959
|
count = int(parts[5])
|
|
1001
960
|
|
|
1002
961
|
result = await self.current_game.validate_move(r1, c1, r2, c2, count)
|
|
1003
|
-
|
|
1004
|
-
if not result.success:
|
|
1005
|
-
self.current_game.invalid_moves += 1
|
|
962
|
+
self.current_game.record_move((r1, c1, r2, c2), result.success)
|
|
1006
963
|
|
|
1007
964
|
await self.send_result(
|
|
1008
965
|
result.success, result.message, "BRIDGED" if result.success else "INVALID_BRIDGE"
|
|
@@ -1015,7 +972,6 @@ class ArcadeHandler(TelnetHandler):
|
|
|
1015
972
|
await self.send_game_complete()
|
|
1016
973
|
|
|
1017
974
|
except ValueError:
|
|
1018
|
-
self.current_game.invalid_moves += 1
|
|
1019
975
|
await self.send_result(False, "Invalid input. Use numbers only.", "PARSE_ERROR")
|
|
1020
976
|
return
|
|
1021
977
|
|
|
@@ -1028,9 +984,7 @@ class ArcadeHandler(TelnetHandler):
|
|
|
1028
984
|
direction = parts[1].lower()
|
|
1029
985
|
|
|
1030
986
|
result = await self.current_game.validate_move(direction)
|
|
1031
|
-
|
|
1032
|
-
if not result.success:
|
|
1033
|
-
self.current_game.invalid_moves += 1
|
|
987
|
+
self.current_game.record_move((direction,), result.success)
|
|
1034
988
|
|
|
1035
989
|
await self.send_result(result.success, result.message, "MOVED" if result.success else "INVALID_MOVE")
|
|
1036
990
|
|
|
@@ -1054,9 +1008,7 @@ class ArcadeHandler(TelnetHandler):
|
|
|
1054
1008
|
start_time = int(parts[3])
|
|
1055
1009
|
|
|
1056
1010
|
result = await self.current_game.validate_move(task_id, worker_id, start_time)
|
|
1057
|
-
|
|
1058
|
-
if not result.success:
|
|
1059
|
-
self.current_game.invalid_moves += 1
|
|
1011
|
+
self.current_game.record_move((task_id,), result.success)
|
|
1060
1012
|
|
|
1061
1013
|
await self.send_result(
|
|
1062
1014
|
result.success, result.message, "ASSIGNED" if result.success else "INVALID_ASSIGN"
|
|
@@ -1068,7 +1020,6 @@ class ArcadeHandler(TelnetHandler):
|
|
|
1068
1020
|
await self.send_game_complete()
|
|
1069
1021
|
|
|
1070
1022
|
except ValueError:
|
|
1071
|
-
self.current_game.invalid_moves += 1
|
|
1072
1023
|
await self.send_result(False, "Invalid input. Use numbers only.", "PARSE_ERROR")
|
|
1073
1024
|
return
|
|
1074
1025
|
|
|
@@ -1081,9 +1032,7 @@ class ArcadeHandler(TelnetHandler):
|
|
|
1081
1032
|
task_id = int(parts[1])
|
|
1082
1033
|
|
|
1083
1034
|
result = await self.current_game.validate_move(task_id, 0, -1)
|
|
1084
|
-
|
|
1085
|
-
if not result.success:
|
|
1086
|
-
self.current_game.invalid_moves += 1
|
|
1035
|
+
self.current_game.record_move((task_id,), result.success)
|
|
1087
1036
|
|
|
1088
1037
|
await self.send_result(
|
|
1089
1038
|
result.success, result.message, "UNASSIGNED" if result.success else "INVALID_UNASSIGN"
|
|
@@ -1093,7 +1042,6 @@ class ArcadeHandler(TelnetHandler):
|
|
|
1093
1042
|
await self.display_puzzle()
|
|
1094
1043
|
|
|
1095
1044
|
except ValueError:
|
|
1096
|
-
self.current_game.invalid_moves += 1
|
|
1097
1045
|
await self.send_result(False, "Invalid input. Use numbers only.", "PARSE_ERROR")
|
|
1098
1046
|
return
|
|
1099
1047
|
|
|
@@ -2,7 +2,7 @@ chuk_puzzles_gym/__init__.py,sha256=zh2sc6QFKrtAmMLee7vlHgXuOBoB5CjSldlKFjZTVVE,
|
|
|
2
2
|
chuk_puzzles_gym/constants.py,sha256=58pKdvwoaB4PF1AK4b7mLNf_Y_YFyFassd1hYH1IUNE,280
|
|
3
3
|
chuk_puzzles_gym/eval.py,sha256=jWjfQ4OaBNY2vDwcRxw1-MC27VorLNUMfRW-lQpK3Rs,26415
|
|
4
4
|
chuk_puzzles_gym/gym_env.py,sha256=qoQZFz2Dnbl3QjTsDNHAxAx1qomU8paXVlH-SDcwlZI,17288
|
|
5
|
-
chuk_puzzles_gym/server.py,sha256=
|
|
5
|
+
chuk_puzzles_gym/server.py,sha256=QnG48mXd8AKDVFUULIwLWidqDvcsCkayxbvo7h_EKBg,45947
|
|
6
6
|
chuk_puzzles_gym/export/__init__.py,sha256=TTXBRR5CBBCL04r1iXMzxib9oOIDTC4npxy2_L1xc2A,366
|
|
7
7
|
chuk_puzzles_gym/export/dataset.py,sha256=dZMz9m4JwpZZSigvaJjIpGKIoxUWB01gXoyNCZ4o17o,10998
|
|
8
8
|
chuk_puzzles_gym/games/__init__.py,sha256=zByuxje5uVWQ4wBoGHUooHkAg5cgCljrCCXkyOLxLzo,3403
|
|
@@ -11,113 +11,113 @@ chuk_puzzles_gym/games/_base/commands.py,sha256=tY0kxk08D8nPr_C_awo8qDUhkL6EHA59
|
|
|
11
11
|
chuk_puzzles_gym/games/_base/game.py,sha256=-YPJOgWsb4YVz8tS3cXJYd-y-1Tyx7eh8vs3tZEXcEA,11240
|
|
12
12
|
chuk_puzzles_gym/games/binary/__init__.py,sha256=Pphgj0kcvHUgkM0Mq89GsWPt-Bg6DobDLi7cqliOywk,156
|
|
13
13
|
chuk_puzzles_gym/games/binary/config.py,sha256=Iw8Wax1856aqaz1KvDC69Qou6z8gxIWr5rSAI0MGnWg,812
|
|
14
|
-
chuk_puzzles_gym/games/binary/game.py,sha256=
|
|
14
|
+
chuk_puzzles_gym/games/binary/game.py,sha256=lRBweQIdzyRZm_jMPItZ1VAzAcsEEbxvGqjGwAlTTy0,16359
|
|
15
15
|
chuk_puzzles_gym/games/bridges/__init__.py,sha256=ItdexP5RYfyTdxcvGY41fwQEi6tMCuMNdQpf8IDA70k,143
|
|
16
16
|
chuk_puzzles_gym/games/bridges/config.py,sha256=JWhK6AmQzfFDs7uWiKqUayw4UQEcxPE6a5CdJ2HUm5A,910
|
|
17
|
-
chuk_puzzles_gym/games/bridges/game.py,sha256=
|
|
17
|
+
chuk_puzzles_gym/games/bridges/game.py,sha256=qEI8LFYKRASyTu0zomxvogWWdyPrEU989LlZ4TWascQ,18957
|
|
18
18
|
chuk_puzzles_gym/games/cryptarithmetic/__init__.py,sha256=vnM5L1jvSEPlMrB_FoxDTLqi7HA6uFb2_leyLdjCVmY,261
|
|
19
19
|
chuk_puzzles_gym/games/cryptarithmetic/commands.py,sha256=0feQk24ezYk_RubLv0I1URy_d2SPkswmecozYGx84p0,2514
|
|
20
20
|
chuk_puzzles_gym/games/cryptarithmetic/config.py,sha256=IBCqJCVfb9UZTRDaDGGGr8qOpVyci9WsRiLmHyeFowU,960
|
|
21
|
-
chuk_puzzles_gym/games/cryptarithmetic/game.py,sha256=
|
|
21
|
+
chuk_puzzles_gym/games/cryptarithmetic/game.py,sha256=aQvA2u-X5lmuxqMhH3IJkeOPJGkUOX6ZwLzrlhb1uYo,15202
|
|
22
22
|
chuk_puzzles_gym/games/einstein/__init__.py,sha256=ETFLNXXeR7fE8cQZb0cIdeupSdtReV5zr5cwS0Fs108,148
|
|
23
23
|
chuk_puzzles_gym/games/einstein/config.py,sha256=JCnFSXWz3Vjd3k53-ZdS_x6UpvGKOYaoVMNtX-3ZcBc,829
|
|
24
24
|
chuk_puzzles_gym/games/einstein/constants.py,sha256=8IXKJwaGupSqxAYlTFdc7og6xiqJC7xqYa5-CdwxeQQ,607
|
|
25
|
-
chuk_puzzles_gym/games/einstein/game.py,sha256=
|
|
25
|
+
chuk_puzzles_gym/games/einstein/game.py,sha256=ifMC9IOigbPOX0Z_s1NetPaunOxPcfqeAWjOWyJF4lY,13962
|
|
26
26
|
chuk_puzzles_gym/games/einstein/models.py,sha256=DtHJW65mlBgTynUJS0kPnynNJBbgAqPFWNC7jttQoxE,1076
|
|
27
27
|
chuk_puzzles_gym/games/fillomino/__init__.py,sha256=A_aXhoY8ASfh3C_JGBASMJ6oWo8beN-YWc8gfPl1L9g,153
|
|
28
28
|
chuk_puzzles_gym/games/fillomino/config.py,sha256=H7-CzBL3b4hYRe0QiOC1_hTXVojbbg-7vvZf5Q7idrQ,927
|
|
29
|
-
chuk_puzzles_gym/games/fillomino/game.py,sha256=
|
|
29
|
+
chuk_puzzles_gym/games/fillomino/game.py,sha256=CPZnzWkm29beSxt4kmRPKImBQDqEDlDsVslYCf3Apys,19379
|
|
30
30
|
chuk_puzzles_gym/games/futoshiki/__init__.py,sha256=kwgCnU2VGVEUX6oNBUb-k2PJ12EER3Do6az0JJAQVkQ,153
|
|
31
31
|
chuk_puzzles_gym/games/futoshiki/config.py,sha256=zycoGtrGtXMhcbJkPf5-4WSgAYmCB6xFg5PNe7xjzTM,794
|
|
32
|
-
chuk_puzzles_gym/games/futoshiki/game.py,sha256=
|
|
32
|
+
chuk_puzzles_gym/games/futoshiki/game.py,sha256=yFSKXGsk8xfsLyzfmnz5UMbIUKqxJcuPJ7dyYWL-6lg,14136
|
|
33
33
|
chuk_puzzles_gym/games/graph_coloring/__init__.py,sha256=iEh_AL8NngVPRGzOwgMAumpp1qU9SWNR7WWjsTGxsnE,248
|
|
34
|
-
chuk_puzzles_gym/games/graph_coloring/commands.py,sha256=
|
|
34
|
+
chuk_puzzles_gym/games/graph_coloring/commands.py,sha256=2PeTAgZ_3eQ2WTmoYgsDy42JnkZpg6U-wdAvTTjfBDY,3279
|
|
35
35
|
chuk_puzzles_gym/games/graph_coloring/config.py,sha256=i0fGexuy2fT0FN4CZdj6AEZwpXCBjB1OmAOMAqEAtFY,1085
|
|
36
|
-
chuk_puzzles_gym/games/graph_coloring/game.py,sha256=
|
|
36
|
+
chuk_puzzles_gym/games/graph_coloring/game.py,sha256=OqE5VyjGqkEjcmJMP9SqrnjAEW0eBar6DFYKo43NP7k,12845
|
|
37
37
|
chuk_puzzles_gym/games/hidato/__init__.py,sha256=nx9hhBuYUW6k5insmoY8T8ZYCQTNH-74yNmkvuN1Fv8,138
|
|
38
38
|
chuk_puzzles_gym/games/hidato/config.py,sha256=tk8fwAVQvkVIfrBdschdGcdpvVr8r58zUI3P0UJ0-FA,913
|
|
39
|
-
chuk_puzzles_gym/games/hidato/game.py,sha256=
|
|
39
|
+
chuk_puzzles_gym/games/hidato/game.py,sha256=4-oUnC5nOry5UJgsWqj-QTscgTndnm0ZQvokKJqNp_4,15097
|
|
40
40
|
chuk_puzzles_gym/games/hitori/__init__.py,sha256=mSit-2ejHlBpFDNM7YAduZADBZgP7DTgLwvGUFT0VHs,138
|
|
41
41
|
chuk_puzzles_gym/games/hitori/config.py,sha256=kcCBBhZr398hRwWU2FINarq2lJ1T2HZ4S-wlcm1X0UE,782
|
|
42
|
-
chuk_puzzles_gym/games/hitori/game.py,sha256=
|
|
42
|
+
chuk_puzzles_gym/games/hitori/game.py,sha256=z3OeEpiJufaZOIzCvKv6uYgSlpCusbhk5f8CEn9tlWM,17325
|
|
43
43
|
chuk_puzzles_gym/games/kakuro/__init__.py,sha256=rYiQIzs1bSlRGk5DOcXgI_xud3gz_LO7CKekiC39ivM,138
|
|
44
44
|
chuk_puzzles_gym/games/kakuro/config.py,sha256=QTbt6TOSgFpGfyDulZiTm13u9lzuOwJw_ZTKT5XO_Dw,910
|
|
45
|
-
chuk_puzzles_gym/games/kakuro/game.py,sha256=
|
|
45
|
+
chuk_puzzles_gym/games/kakuro/game.py,sha256=tu4rRx4u4icVXt-FtyJCXY7XTl5SkEYghpslVboNT_A,14525
|
|
46
46
|
chuk_puzzles_gym/games/kenken/__init__.py,sha256=4V9h7RS2nBr6ZoXD3xselQVcR8NxslzLFYguzJ4JPxw,138
|
|
47
47
|
chuk_puzzles_gym/games/kenken/config.py,sha256=mcyku9kPnqdXJBR1pW_kLd_0ejeebg44PXGHQb7bsOw,896
|
|
48
48
|
chuk_puzzles_gym/games/kenken/enums.py,sha256=8LUwUGTZR2MovoLMBrLcVwq3Mx8TVpojyJ9teSp2muk,247
|
|
49
|
-
chuk_puzzles_gym/games/kenken/game.py,sha256=
|
|
49
|
+
chuk_puzzles_gym/games/kenken/game.py,sha256=g11gYbCSBHV-RmXFlLh1FwxsEekG2PEuMdXNRWCRvng,18673
|
|
50
50
|
chuk_puzzles_gym/games/kenken/models.py,sha256=PsZx9FCWr7B0sgEgiTYMmNSeRp6qriU7ES6i8rjBH5s,526
|
|
51
51
|
chuk_puzzles_gym/games/killer_sudoku/__init__.py,sha256=t5wYyc4kyPPTlw3EzMVtu4MNF8HtJwt1OmaJqNqTI1w,168
|
|
52
52
|
chuk_puzzles_gym/games/killer_sudoku/config.py,sha256=PU9vABsdODFnswrlEILykOLUMcvsy4T9JSKd0JxpJJc,833
|
|
53
|
-
chuk_puzzles_gym/games/killer_sudoku/game.py,sha256=
|
|
53
|
+
chuk_puzzles_gym/games/killer_sudoku/game.py,sha256=uOB7l0Mmt88Q7aBkVaZekNRNJFGi_SDVDYByYoAnl5E,18897
|
|
54
54
|
chuk_puzzles_gym/games/killer_sudoku/models.py,sha256=HjTdW80adBpl5r_3uaNijrNR9YSwWlBdDrxLihtJJO4,434
|
|
55
55
|
chuk_puzzles_gym/games/knapsack/__init__.py,sha256=JqpjOUl5w7S_9tNfzP28Qgo5sIqk6JDBFfSUnDi1sew,148
|
|
56
56
|
chuk_puzzles_gym/games/knapsack/config.py,sha256=yxDnIgkOWuiDjaK__O4N2WHd5BNC8Jh-HFLI6jV7ckE,941
|
|
57
57
|
chuk_puzzles_gym/games/knapsack/enums.py,sha256=_ByA1xdURmEIp6wlXDn-l2d7ffqYmMMBJdfsFM3vQ6I,171
|
|
58
|
-
chuk_puzzles_gym/games/knapsack/game.py,sha256=
|
|
58
|
+
chuk_puzzles_gym/games/knapsack/game.py,sha256=tT1oY5bAjrk3003XApplGTLb7XIKpcOJHULP8wAVuRI,12569
|
|
59
59
|
chuk_puzzles_gym/games/knapsack/models.py,sha256=OdtmDHsm-62Ej7HMVLqVfAh_ylsIIQl7Vv0DxmpRUqc,397
|
|
60
60
|
chuk_puzzles_gym/games/lights_out/__init__.py,sha256=H3Uf6F_nyaJt1h0A6EWDRRWZERTZlqJ8URZAo8wFRXA,153
|
|
61
61
|
chuk_puzzles_gym/games/lights_out/config.py,sha256=PujrybVGgmuKeY3bgpO7owUGbbHE6KbPqsqweMjiknk,944
|
|
62
|
-
chuk_puzzles_gym/games/lights_out/game.py,sha256=
|
|
62
|
+
chuk_puzzles_gym/games/lights_out/game.py,sha256=KcvNdB54uDDk2Fq6fal-NExIKN3K9w-9yFFwZfxZXvE,8883
|
|
63
63
|
chuk_puzzles_gym/games/logic_grid/__init__.py,sha256=ayL8uFmc7s8PCd1qjsQcMX9Y7yVvSBatQTwRjJVAriI,153
|
|
64
64
|
chuk_puzzles_gym/games/logic_grid/config.py,sha256=OmffFq7Kmpnfi_ltITi-5lsbYz5LTbMWZL0k4VtEIUQ,977
|
|
65
65
|
chuk_puzzles_gym/games/logic_grid/constants.py,sha256=20C07GHBY2swGDfJBFo3sXQt3Ag8GkH5McqyfniutFU,480
|
|
66
|
-
chuk_puzzles_gym/games/logic_grid/game.py,sha256=
|
|
66
|
+
chuk_puzzles_gym/games/logic_grid/game.py,sha256=d1j-R1RS_-uX_oJpD3SC_E-U5joFvuretOEBDtcGx_I,12043
|
|
67
67
|
chuk_puzzles_gym/games/logic_grid/models.py,sha256=lmE7jsP_-7oPzI081NGqm02DCZCQCwRy7T5_ecFHv1k,475
|
|
68
68
|
chuk_puzzles_gym/games/mastermind/__init__.py,sha256=FIqOTKheJf5yexmMYJ0gU6prflJBqDrPasTAbdvYn9w,158
|
|
69
69
|
chuk_puzzles_gym/games/mastermind/config.py,sha256=3QDlAbomhHhZAGnkkxknVXPSf1aVJ0b-mm3FycXcuBM,1117
|
|
70
|
-
chuk_puzzles_gym/games/mastermind/game.py,sha256
|
|
70
|
+
chuk_puzzles_gym/games/mastermind/game.py,sha256=FHs5yIWx6TvAoWpJ6sirwEkhx2rLM7wnRXfjRtLoBzc,10915
|
|
71
71
|
chuk_puzzles_gym/games/minesweeper/__init__.py,sha256=mDSuSivp2m34GOn9XnchaKtIR_fhOExGhweGQUjhEkk,163
|
|
72
72
|
chuk_puzzles_gym/games/minesweeper/config.py,sha256=W-K9RkxwlHZf1UUIS5275qaVzsTuRH2SDv3XG7G_HBw,902
|
|
73
73
|
chuk_puzzles_gym/games/minesweeper/enums.py,sha256=VK6S4PGHXahHGl-ekRmdrhMr_D9L4FfuU-SJFoni-q8,196
|
|
74
|
-
chuk_puzzles_gym/games/minesweeper/game.py,sha256=
|
|
74
|
+
chuk_puzzles_gym/games/minesweeper/game.py,sha256=PbWTWpq8eQN8ubPniqB-ciENDo-krzUwQ2awVr7d1RA,16496
|
|
75
75
|
chuk_puzzles_gym/games/nonogram/__init__.py,sha256=rjtRm0IumZfjTT02mmWWE0mNZ5LvJt7TpPA7drIvJUI,148
|
|
76
76
|
chuk_puzzles_gym/games/nonogram/config.py,sha256=J0hPA3DqiPZjFg84YM-iqzHBWZDA1DuEqThJHTyoQVE,792
|
|
77
|
-
chuk_puzzles_gym/games/nonogram/game.py,sha256=
|
|
77
|
+
chuk_puzzles_gym/games/nonogram/game.py,sha256=TRIBT8ajRL2cuOXgi_3nrO29qsi90YkIb05LceQsinY,10965
|
|
78
78
|
chuk_puzzles_gym/games/nqueens/__init__.py,sha256=BEWSaLz2x4Tj_0iXMPM-lgRPQLoaZOi-UKgRmzBO8KA,137
|
|
79
79
|
chuk_puzzles_gym/games/nqueens/config.py,sha256=qb9XeyrswjaJ9Mmfxq1j3IdWOODJGrF0Uz6W5BTM75o,871
|
|
80
|
-
chuk_puzzles_gym/games/nqueens/game.py,sha256=
|
|
80
|
+
chuk_puzzles_gym/games/nqueens/game.py,sha256=mnwWKRWxiMRKqcpIDtvZRo_fun7RGXhLJuDycfCOaxI,11613
|
|
81
81
|
chuk_puzzles_gym/games/numberlink/__init__.py,sha256=5mm2g8QD2PN8HUIUsJ5-tTBNdLlfQaagjYEjKLGo0UI,158
|
|
82
82
|
chuk_puzzles_gym/games/numberlink/config.py,sha256=E6UsRkUkpR6bMWnQBkt7tYxEb77wBdeutEPSRa6lynw,871
|
|
83
|
-
chuk_puzzles_gym/games/numberlink/game.py,sha256=
|
|
83
|
+
chuk_puzzles_gym/games/numberlink/game.py,sha256=x8x1PLjJvXsj5kfNhychi2OYCZ7Nquu0BC8vzWk-Pgc,12852
|
|
84
84
|
chuk_puzzles_gym/games/nurikabe/__init__.py,sha256=maIZE3xItadevCnH_FMJiQr5VHMQrqiaOdnbBs87ndo,148
|
|
85
85
|
chuk_puzzles_gym/games/nurikabe/config.py,sha256=UpET5L8UGFUuggDqrF6OaxVpGJt5iieVS8N5iBVT62U,914
|
|
86
86
|
chuk_puzzles_gym/games/nurikabe/enums.py,sha256=NU5WyLK6t0df72zn5RL9T7_XGn8cDh4mHApuVE-V39c,218
|
|
87
|
-
chuk_puzzles_gym/games/nurikabe/game.py,sha256=
|
|
87
|
+
chuk_puzzles_gym/games/nurikabe/game.py,sha256=AVNNKJslJrUwdQ3niI4-16bIYoCABbNi4mLXkBlwa8Y,22801
|
|
88
88
|
chuk_puzzles_gym/games/rush_hour/__init__.py,sha256=8JifY9z86sy-BktQlDQKBZQhLCw1ZwrZrpokX2cUTYs,252
|
|
89
89
|
chuk_puzzles_gym/games/rush_hour/commands.py,sha256=_c91Lefd0R4HQskAWfaRe8HfrG5wfExTzPHbdxnspq4,1784
|
|
90
90
|
chuk_puzzles_gym/games/rush_hour/config.py,sha256=HPNebhFSS82l0AYPe-HBtUy0FidpyizbfdTKV68RMGQ,1158
|
|
91
|
-
chuk_puzzles_gym/games/rush_hour/game.py,sha256
|
|
91
|
+
chuk_puzzles_gym/games/rush_hour/game.py,sha256=me42wLbB_oM6HEFQXDijHvhdIYz3Ib2bWD08Tuyjaik,20046
|
|
92
92
|
chuk_puzzles_gym/games/rush_hour/models.py,sha256=N9-So3PGFSy947LUy_Zf6UUYDsWN8KVYGS8qGJaCjDY,586
|
|
93
93
|
chuk_puzzles_gym/games/scheduler/__init__.py,sha256=2dsZ3a1QcaGobAOHOtEwGMWGscnYrOtZpod8C_mg2XQ,153
|
|
94
94
|
chuk_puzzles_gym/games/scheduler/config.py,sha256=mjznF2sKQRqcC8fO3KHbkdi48NMUV_GALmL0XzQ4rCY,1115
|
|
95
95
|
chuk_puzzles_gym/games/scheduler/constants.py,sha256=KiySqF61dh2mcjiCfsXO5DX8IHmEU9w1xYsO7N5bJiw,242
|
|
96
96
|
chuk_puzzles_gym/games/scheduler/enums.py,sha256=Npnop_EkNkfB4Q0s5LeF1oIMmIWFp8rBvMzsz31IfW4,174
|
|
97
|
-
chuk_puzzles_gym/games/scheduler/game.py,sha256=
|
|
97
|
+
chuk_puzzles_gym/games/scheduler/game.py,sha256=ykU3uepLUvNXMDarNcgzIwIIlGGk6UeZDacRyjn9jiA,17391
|
|
98
98
|
chuk_puzzles_gym/games/scheduler/models.py,sha256=qh3IoOuuOoEVTcTP8CWpAdDlyL2HYYAfe-jj7WMqkxQ,520
|
|
99
99
|
chuk_puzzles_gym/games/shikaku/__init__.py,sha256=-uBxf00nGMRvrF_m3Uk-Izzj24uOO9PaoVa6bInqmGo,143
|
|
100
100
|
chuk_puzzles_gym/games/shikaku/config.py,sha256=orYfuE5y5iw8vPzgZaR9lofxMsMhLV6skr8nOhY9FSM,907
|
|
101
|
-
chuk_puzzles_gym/games/shikaku/game.py,sha256=
|
|
101
|
+
chuk_puzzles_gym/games/shikaku/game.py,sha256=JrpGHRkPMNympVRZhGInVnHGwFkv6bVb6k2uE6rnLeg,15601
|
|
102
102
|
chuk_puzzles_gym/games/skyscrapers/__init__.py,sha256=Y8XEu920EO97WgnRa9mtq_wtc8BFeG6jCBLowO5F2xY,156
|
|
103
103
|
chuk_puzzles_gym/games/skyscrapers/config.py,sha256=K7LnI4Akz9QrfISIksOpbdMph0YAsbZO41AAG78ddoE,746
|
|
104
|
-
chuk_puzzles_gym/games/skyscrapers/game.py,sha256=
|
|
104
|
+
chuk_puzzles_gym/games/skyscrapers/game.py,sha256=kkW_q9N9CMnClvkzxxbtyBbSKEHmXq3sD-OqwfQYNNU,10510
|
|
105
105
|
chuk_puzzles_gym/games/slitherlink/__init__.py,sha256=9KZSUINa7tJ6P1DF_Jb3qvGkYqZARPWYnZ3bZVGUVhE,163
|
|
106
106
|
chuk_puzzles_gym/games/slitherlink/config.py,sha256=BunuL_XA5yOPI5AqMmOCF3iFcCgY8rLtokrye6wCNiA,804
|
|
107
|
-
chuk_puzzles_gym/games/slitherlink/game.py,sha256=
|
|
107
|
+
chuk_puzzles_gym/games/slitherlink/game.py,sha256=woj_mC3niE70SfEaVpb8784jW_kFuSjqfKaD5Ibu2Cs,14640
|
|
108
108
|
chuk_puzzles_gym/games/sokoban/__init__.py,sha256=F3gxLt0QeDqN3oku6Kg-FDAck5HjKlFXCgf_ZkuFsTc,143
|
|
109
109
|
chuk_puzzles_gym/games/sokoban/config.py,sha256=An9LxYnPyx1r3orP3Cas-PFZYthbMnCvYJPNz4DEFXE,914
|
|
110
|
-
chuk_puzzles_gym/games/sokoban/game.py,sha256=
|
|
110
|
+
chuk_puzzles_gym/games/sokoban/game.py,sha256=W58VxnJC_jy1jPmUCB5VLsT5Gj5xc70DK9_AjO5pnwo,25627
|
|
111
111
|
chuk_puzzles_gym/games/star_battle/__init__.py,sha256=qsE4q6Awa9Ywj3oyDrruA5E-NOLEblKZEgrnrMB9Das,158
|
|
112
112
|
chuk_puzzles_gym/games/star_battle/config.py,sha256=MUwFsoeIT9S7FwDGUSZ--3QePpoXSWRpDaLb7X0zcgs,958
|
|
113
|
-
chuk_puzzles_gym/games/star_battle/game.py,sha256=
|
|
113
|
+
chuk_puzzles_gym/games/star_battle/game.py,sha256=f0c9gtvakhA7T0XPnoQS3TztI3DLOo0epoG83N2B-uM,14552
|
|
114
114
|
chuk_puzzles_gym/games/sudoku/__init__.py,sha256=Q14HabjmkQc3QzqtA66WrAcHSoqLyv6A36_-KG8j-J4,205
|
|
115
115
|
chuk_puzzles_gym/games/sudoku/commands.py,sha256=PbU0-7pkelP0sulyh8zudU47jVhpWhiUP0d0TOOmC0o,3004
|
|
116
116
|
chuk_puzzles_gym/games/sudoku/config.py,sha256=pgr82NHcxvUAVZnAlsxeA7Iq3HrkhR1xAe_OGBOwAp8,779
|
|
117
|
-
chuk_puzzles_gym/games/sudoku/game.py,sha256=
|
|
117
|
+
chuk_puzzles_gym/games/sudoku/game.py,sha256=35vB5x-KIs5z2b-CDV-dq5kifmVkoEkbLOx01xiCgKw,11717
|
|
118
118
|
chuk_puzzles_gym/games/tents/__init__.py,sha256=iVxsZg7Juz3iHXTK8mfJZniFcMNnmAd2h2RjxR2TH40,133
|
|
119
119
|
chuk_puzzles_gym/games/tents/config.py,sha256=gSi5epG5va8-a4ZQv5ekcFDkWQSYOSheX2j4FIs_I8Q,914
|
|
120
|
-
chuk_puzzles_gym/games/tents/game.py,sha256=
|
|
120
|
+
chuk_puzzles_gym/games/tents/game.py,sha256=JGPLYvIosCwjJYhi0FCtA3YUFsgQsD9L_BEArHSOPFM,15802
|
|
121
121
|
chuk_puzzles_gym/models/__init__.py,sha256=dZzLWsyKE993o8HFfFkxTR7XjDwYK56rB-5clwW4zPg,930
|
|
122
122
|
chuk_puzzles_gym/models/base.py,sha256=L7Zug9jUXJCOhD3wKJp0ppJZNTgroDQwdYMjvAaVVqc,1156
|
|
123
123
|
chuk_puzzles_gym/models/config.py,sha256=12UkPlEEFzN1k9ZfJClpVqkp7E11MWriZVAH2RkfEM4,301
|
|
@@ -127,8 +127,8 @@ chuk_puzzles_gym/models/games.py,sha256=rnEW_Sl9xuZtvlBXBZfab34HrIhtUEiBdUSs_nvh
|
|
|
127
127
|
chuk_puzzles_gym/trace/__init__.py,sha256=8JHaHxbTDhT9kv4e2e5Px4dCWuXY49OXmvzkMS4nKfw,273
|
|
128
128
|
chuk_puzzles_gym/trace/generator.py,sha256=4pks0d_asoDE15QjM2VuzgFWTV1fZke_gHH2lVF8KVQ,34058
|
|
129
129
|
chuk_puzzles_gym/utils/__init__.py,sha256=1AKPfRjT9YlBxxcA7qdKcvKBXdHJzfGtUWansrb_2VE,149
|
|
130
|
-
chuk_puzzles_gym-0.10.dist-info/METADATA,sha256=
|
|
131
|
-
chuk_puzzles_gym-0.10.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
132
|
-
chuk_puzzles_gym-0.10.dist-info/entry_points.txt,sha256=tJGHiH8wjkBev2SPNuXOLFkaXE76sW9ZFIMQw4pUj5E,181
|
|
133
|
-
chuk_puzzles_gym-0.10.dist-info/top_level.txt,sha256=H3z9wKGl7CV1BPlO6t5lEtok6WW9rwGr5C1Dr3Kqx28,17
|
|
134
|
-
chuk_puzzles_gym-0.10.dist-info/RECORD,,
|
|
130
|
+
chuk_puzzles_gym-0.10.1.dist-info/METADATA,sha256=HD-oYiDi5OTNMOjtvxQkB9aBuOBUARAy1RcXcjf4T2I,49935
|
|
131
|
+
chuk_puzzles_gym-0.10.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
132
|
+
chuk_puzzles_gym-0.10.1.dist-info/entry_points.txt,sha256=tJGHiH8wjkBev2SPNuXOLFkaXE76sW9ZFIMQw4pUj5E,181
|
|
133
|
+
chuk_puzzles_gym-0.10.1.dist-info/top_level.txt,sha256=H3z9wKGl7CV1BPlO6t5lEtok6WW9rwGr5C1Dr3Kqx28,17
|
|
134
|
+
chuk_puzzles_gym-0.10.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|