def simulate_with_heuristic(state, max_states=50_000): visited = set() moveseq = [] i = 0 while True: v = len(visited) if i >= max_states: return EndState(solved=False, visited=v, msg="exceeded max states") if state in visited: return EndState(solved=False, msg="revisited state", visited=v) visited.add(state) # Yan et al. Section 4 "Machine Play" # 1. identify set of legal moves # 2. select and execute a legal move actions = yan_et_al_prioritized_actions(state) if len(actions) == 0: return EndState(solved=False, visited=v, msg="run out of actions") action = actions[0] moveseq.append(action) state = play_move(state, action) # 3. If all cards are on suit stacks, declare victory and terminate. if state_is_win(state): return EndState(solved=True, moveseq=moveseq, visited=v) # 4. If new card configuration repeats a previous one, declare loss and terminate. # 5. Repeat procedure. i += 1
def endgame(fname, k): """ fname: path to a shootme solution fixture k: number of moves *remaining* until shootme solution :returns: {KlonState} """ state, moveseq = state_with_moveseq(fname) while len(moveseq) > k: state = play_move(state, moveseq.pop(0)) return state
def yan_et_al_rollout_1(state): moves = get_legal_moves(state) for move in moves: new_state = play_move(state, move) result = simulate_with_heuristic(new_state) if result.solved: return EndState( solved=True, msg="solved in rollout", visited=result.visited, moveseq=(move,) + tuple(result.moveseq), ) # no optimal move: use the strategy as before actions = yan_et_al_prioritized_actions(state) if len(actions) == 0: return None return actions[0]
def make_move(state, move): new_state = play_move(state, move) return KlondikeNode(*new_state, parent=state)
def validate_move_seq(state, move_seq): state = copy(state) for move in move_seq: state = play_move(state, move) return state_is_win(state)
def play_move(self, move): child = play_move(self, move) return KlonNode(*child, parent=self, action=move)