Refactoring

This commit is contained in:
Lukas Wölfer
2019-04-21 01:36:37 +02:00
parent 87cfcbf7c0
commit 7f055eb302
4 changed files with 48 additions and 44 deletions

View File

@@ -1,7 +1,6 @@
"""Contains actions that can be used on the board""" """Contains actions that can be used on the board"""
from typing import List, Tuple, Union from typing import List, Tuple
from dataclasses import dataclass from dataclasses import dataclass
import itertools
from . import board from . import board

View File

@@ -1,8 +1,9 @@
"""Contains solver for solitaire""" """Contains solver for solitaire"""
from typing import List, Tuple, Iterator, Set, Optional from typing import List, Iterator, Optional
from .board import Board from .board import Board
from . import board_actions from . import board_actions
from .board_possibilities import possible_actions from .board_possibilities import possible_actions
from .board_actions import MoveAction
class ActionStack: class ActionStack:
@@ -41,49 +42,51 @@ class ActionStack:
return len(self.index_stack) return len(self.index_stack)
class SolitaireSolver: def solve(board: Board) -> Iterator[List[board_actions.Action]]:
"""Solver for Shenzhen Solitaire""" """Solve a solitaire puzzle"""
state_set = {board.state_identifier}
stack = ActionStack()
stack.push(board)
search_board: Board while stack:
stack: ActionStack if len(stack) == -1:
state_set: Set[int] stack.pop()
stack.action_stack[-1].undo(board)
assert (board.state_identifier
in state_set)
def __init__(self, board: Board) -> None: assert (board.state_identifier ==
self.search_board = board stack.state_stack[-1])
self.state_set = {board.state_identifier} action = stack.get()
self.stack = ActionStack()
self.stack.push(self.search_board)
def solve(self) -> Iterator[List[board_actions.Action]]:
while self.stack:
if len(self.stack) == -1:
self.stack.pop()
self.stack.action_stack[-1].undo(self.search_board)
assert (self.search_board.state_identifier
in self.state_set)
assert (self.search_board.state_identifier ==
self.stack.state_stack[-1])
action = self.stack.get()
if not action: if not action:
self.stack.pop() stack.pop()
self.stack.action_stack[-1].undo(self.search_board) stack.action_stack[-1].undo(board)
assert (self.search_board.state_identifier assert (board.state_identifier
in self.state_set) in state_set)
continue continue
action.apply(self.search_board) if isinstance(action, MoveAction):
drop = False
if self.search_board.solved(): for prev_action in stack.action_stack[-2:-21:-1]:
yield self.stack.action_stack if isinstance(prev_action, MoveAction):
if prev_action.cards == action.cards:
if self.search_board.state_identifier in self.state_set: print("Dropping")
action.undo(self.search_board) print(action)
assert self.search_board.state_identifier in self.state_set print(prev_action)
drop = True
if drop:
continue continue
self.state_set.add(self.search_board.state_identifier) action.apply(board)
self.stack.push(self.search_board)
return self.stack.action_stack if board.solved():
yield stack.action_stack
if board.state_identifier in state_set:
action.undo(board)
assert board.state_identifier in state_set
continue
state_set.add(board.state_identifier)
stack.push(board)

View File

@@ -3,11 +3,13 @@ from shenzhen_solitaire import solver
from .boards import my_board from .boards import my_board
def main() -> None: def main() -> None:
A = solver.SolitaireSolver(my_board) A = solver.solve(my_board)
for _, B in zip(range(100), A.solve()): for _, B in zip(range(1), A):
#print(*B, sep='\n') print(*B, sep='\n')
print(len(B)) print(len(B))
if __name__ == "__main__": if __name__ == "__main__":
main() main()