#!/usr/bin/env python3 class State: left_cats = 0 left_dogs = 0 right_cats = 0 right_dogs = 0 boat_side = "left" actions = [] def __init__(self, lc, ld, side): self.left_cats = lc self.left_dogs = ld self.right_cats = 3 - lc self.right_dogs = 3 - ld self.boat_side = side def row(self, direction, cats, dogs): for act in self.actions: if (act.direction == direction and act.required_cats == cats and act.required_dogs == dogs): return act.result_state def add_action(self, act): self.actions.append(act) class Action: required_cats = 0 required_dogs = 0 direction = "left" result_state = None def __init__(self, source, dest): self.required_cats = abs(source.left_cats - dest.left_cats) self.required_dogs = abs(source.left_dogs - dest.left_dogs) self.boat_side = "left" if source.boat_side == "left": self.boat_side = "right" self.result_state = dest source.add_action(self) start = State(3, 3, "left") # Starting point g31 = State(3, 1, "right") g22 = State(2, 2, "right") g31 = State(3, 2, "right") Action(start, g31) Action(start, g22) Action(start, g31) b32 = State(3, 2, "left") g30 = State(3, 0, "right") b31 = State(3, 1, "left") g11 = State(1, 1, "right") Action(g31, b32) Action(g22, b32) Action(b32, g30) Action(g30, b31) Action(b31, g11) g01 = State(0, 1, "right") b03 = State(0, 3, "left") g02 = State(0, 2, "right") b22 = State(2, 2, "left") Action(g11, b22) Action(b22, g02) Action(g02, b03) Action(b03, g01) b02 = State(0, 2, "left") b11 = State(1, 1, "left") b01 = State(0, 1, "left") Action(g01, b02) Action(g01, b11) end = State(0, 0, "right") Action(b02, end) Action(b11, end) Action(b01, end) def is_goal(state): return state.right_cats == 3 and state.right_dogs == 3 def depth_limited_search(node, depth): if depth == 0: if is_goal(node): return (node, True) return (None, True) elif depth > 0: any_remaining = False for act in node.actions: child = act.result_state found, remaining = depth_limited_search(child, depth - 1) if found is not None: return (found, True) if remaining: any_remaining = True return (None, any_remaining) def iterative_deepening_dfs(root): for depth in range(0, 999): found, remaining = depth_limited_search(root, depth) if found is not None: return found elif not remaining: return None print("Overflow in iterative deepening depth-first search") finish = iterative_deepening_dfs(start) if finish: print("Finished DFS of path")