solve.py 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. from graphviz import Digraph
  2. from chess_state import ChessState
  3. proof = Digraph(format='svg', node_attr={'shape': 'record'}, comment='Proof that chess domino is not possible')
  4. def state_id(index):
  5. return f'state{index}'
  6. class Solver:
  7. def __init__(self, board_size=8):
  8. self.board_size = board_size
  9. self.steps = 1
  10. self.starting_state = ChessState(board_size=board_size)
  11. self.states = [self.starting_state]
  12. def solvable(self, state):
  13. current_id = len(self.states) - 1
  14. x, y = state.next_move()
  15. if x is None:
  16. return True # end of board
  17. for direction in ['right', 'down']:
  18. if state.possible(x, y, direction):
  19. next_state = state.put(x, y, direction)
  20. self.steps += 1
  21. found_symmetry = -1
  22. # look for symmetry
  23. for i, b in enumerate(self.states):
  24. if next_state.symmetric_to(b):
  25. print(f'found symmetry between states {current_id} and {i}')
  26. found_symmetry = i
  27. break
  28. # symmetry found
  29. if found_symmetry != -1:
  30. proof.edge(state_id(current_id),
  31. state_id(found_symmetry),
  32. label=f'put next brick facing {direction} at {(x,y)}')
  33. continue
  34. # pace next brick
  35. self.states.append(next_state)
  36. next_id = len(self.states) - 1
  37. proof.edge(state_id(current_id),
  38. state_id(next_id),
  39. label=f'put next brick facing {direction} at {(x,y)}')
  40. proof.node(name=state_id(next_id), label=next_state.board_label())
  41. # try to solve the remaining board
  42. if self.solvable(next_state):
  43. return True
  44. return False
  45. if __name__ == '__main__':
  46. s = Solver()
  47. proof.node(name=state_id(0), label=s.starting_state.board_label())
  48. result = s.solvable(s.starting_state)
  49. print('solvable:', result)
  50. print('steps:', s.steps)
  51. print('states:', len(s.states))
  52. # proof.render(f'img/proof.gv', view=False)