def main():

    game0 = (
             (12,99,18),
             (10,99,10),
             (10,90,10),
            )

    game1 = (
             (12,10,10,10,15),
             (10,10,99,99,99),
             (10,10,90,10,10),
             (13,10,90,10,18)
            )

    game2 = (
             (18,10,90,90,14),
             (10,99,90,99,90),
             (90,90,90,90,90),
             (90,99,90,99,90),
             (90,90,90,90,13)
            )

    game3 = (
             (12,10,10,10,10,10,10,10,10,10,15),
             (10,99,99,99,99,99,99,99,99,99,10),
             (10,99,10,90,10,10,10,10,90,90,10),
             (10,99,90,10,90,10,10,10,10,99,10),
             (10,99,10,90,10,90,10,10,10,99,10),
             (10,99,10,10,90,10,90,10,10,99,10),
             (10,99,10,10,10,90,10,90,10,99,10),
             (10,99,10,10,10,10,90,10,90,99,10),
             (10,99,10,10,10,10,10,90,10,99,10),
             (10,99,18,10,10,10,10,10,90,99,10),
             (10,99,99,99,99,99,99,99,99,99,10),
             (13,10,10,10,10,10,10,10,10,10,14),
            )


    ### Testing iterating over a matrix tuple
    # should print (1,1)
    # monsterDict = {}
    # for row in game0:
    #     for cell in row:
    #         if(cell in (12,13,14,15)):
    #             print row, cell
    #             print game0.index(row),row.index(cell)
    #             monsterDict[cell] = (game0.index(row),row.index(cell))
    #
    # print monsterDict

    # p = ex1.create_bomberman_problem
    initial = game0
    p = ex1.BombermanProblem(initial)
    print type(p)
    print p.__class__
    print "BombermanProblem in the memory: ", p
    sol = search.tree_search(p, utils.FIFOQueue())
    print sol
    print sol[0]
def main():
    
    move_one_missionary   = Action("Move One Missionary")
    move_two_missionaries = Action("Move Two Missionaries")
    move_one_cannibal     = Action("Move One Cannibal")
    move_two_cannibals    = Action("Move Two Cannibals")
    move_one_and_one      = Action("Move One Missionary + One Cannibal") 
    
    initial_state = State("Init", {'L':{'3m','3c','b'}, 'R':{'0m','0c'}})
    goal_state = State("Goal", {'L':{'0m','0c'}, 'R':{'3m','3c','b'}})
    
    # Any state where cannibals outnumber missionaries is not a valid state
    one_and_one_over = State("1m1c Over", {'L':{'2m','2c'}, 'R':{'1m','1c','b'}})
    one_and_one_over_without_boat = State("1m1c Over w/o Boat", {'L':{'2m','2c','b'}, 'R':{'1m','1c'}})

    two_cannibals_over = State("2c Over", {'L':{'3m','1c'}, 'R':{'0m','2c','b'}})
    two_cannibals_over_without_boat = State("2c Over w/o Boat", {'L':{'3m','1c', 'b'}, 'R':{'0m','2c'}})

    one_cannibal_over = State("1c Over", {'L':{'3m','2c'}, 'R':{'0m','1c','b'}})
    one_cannibal_over_without_boat = State("1c Over w/o Boat", {'L':{'3m','2c','b'}, 'R':{'0m','1c'}})
    
    two_and_two_over = State("2m2c Over", {'L':{'1m','1c'}, 'R':{'2m','2c','b'}})
    two_and_two_over_without_boat = State("2m2c Over", {'L':{'1m','1c','b'}, 'R':{'2m','2c'}})
    
    three_cannibals_over = State("3c Over", {'L':{'3m','0c'}, 'R':{'0m','3c','b'}})
    three_missionaries_over_without_boat = State("3m Over w/o Boat", {'L':{'0m','3c', 'b'}, 'R':{'3m','0c'}})
    
    three_missionaries_one_cannibal_over = State("3m3c Over", {'L':{'0m','1c'}, 'R':{'3m','1c','b'}})
    three_missionaries_one_cannibal_over_without_boat = State("3m1c Over w/o Boat", {'L':{'0m','2c', 'b'}, 'R':{'3m','1c'}})
    
    three_missionaries_two_cannibals_over = State("3m2c Over", {'L':{'0m','1c'}, 'R':{'3m','2c','b'}})
    
    
    #Example invalid states:
    #two_cannibals_over_without_boat = State("2c Over w/o Boat", {'L':{'3m','1c', 'b'}, 'R':{'0m','2c'}})
    #one_missionary_two_cannibals_over = State("1m2c Over", {'L':{'2m','1c'}, 'R':{'1m','2c','b'}})
    
    #Successor Function
    successor_fn = SuccessorFunction()
    successor_fn.addMapping(initial_state, move_two_cannibals, two_cannibals_over)
    successor_fn.addMapping(initial_state, move_one_and_one, one_and_one_over)
    successor_fn.addMapping(initial_state, move_one_cannibal, one_cannibal_over)
    
    #be careful w/mappings that result in the initial_state
    #you could descend in an infinte loop...
    
    #Beginning in (two_cannibals_over)
    successor_fn.addMapping(two_cannibals_over, move_two_cannibals, initial_state)
    successor_fn.addMapping(two_cannibals_over, move_one_cannibal, one_cannibal_over_without_boat)
    
    #Beginning in (one_and_one_over)
    successor_fn.addMapping(one_and_one_over, move_one_and_one, initial_state)
    successor_fn.addMapping(one_and_one_over, move_one_missionary, one_cannibal_over_without_boat)
    
    #Beginning in (one_cannibal_over)
    successor_fn.addMapping(one_cannibal_over, move_one_cannibal, initial_state)
    
    #Beginning in (one_cannibal_over_without_boat)
    successor_fn.addMapping(one_cannibal_over_without_boat, move_one_cannibal, two_cannibals_over)
    successor_fn.addMapping(one_cannibal_over_without_boat, move_one_missionary, one_and_one_over)
    successor_fn.addMapping(one_cannibal_over_without_boat, move_two_cannibals, three_cannibals_over)
    
    #Beginning in (three_cannibals_over)
    successor_fn.addMapping(three_cannibals_over, move_one_cannibal, two_cannibals_over_without_boat)
    successor_fn.addMapping(three_cannibals_over, move_two_cannibals, one_cannibal_over_without_boat)
    
    #Beginning in (two_cannibals_over_without_boat)
    successor_fn.addMapping(two_cannibals_over_without_boat, move_two_missionaries, two_and_two_over)
    successor_fn.addMapping(two_cannibals_over_without_boat, move_one_cannibal, three_cannibals_over)
    
    #Beginning in (two_and_two_over)
    successor_fn.addMapping(two_and_two_over, move_two_missionaries, two_cannibals_over_without_boat)
    successor_fn.addMapping(two_and_two_over, move_one_and_one, one_and_one_over_without_boat)
    
    #Beginning in (one_and_one_over_without_boat)
    successor_fn.addMapping(one_and_one_over_without_boat, move_one_and_one, two_and_two_over)
    successor_fn.addMapping(one_and_one_over_without_boat, move_two_missionaries, three_missionaries_one_cannibal_over)
    
    #Beginning in (three_missionaries_one_cannibal_over)
    successor_fn.addMapping(three_missionaries_one_cannibal_over, move_two_missionaries, one_and_one_over_without_boat)
    successor_fn.addMapping(three_missionaries_one_cannibal_over, move_one_cannibal, three_missionaries_over_without_boat)
    
    #Beginning in (three_missionaries_over_without_boat)
    successor_fn.addMapping(three_missionaries_over_without_boat, move_one_cannibal, three_missionaries_one_cannibal_over)
    successor_fn.addMapping(three_missionaries_over_without_boat, move_two_cannibals, three_missionaries_two_cannibals_over)
    
    #Beginning in (three_missionaries_two_cannibals_over)
    successor_fn.addMapping(three_missionaries_two_cannibals_over, move_two_cannibals, three_missionaries_over_without_boat)
    successor_fn.addMapping(three_missionaries_two_cannibals_over, move_one_cannibal, three_missionaries_one_cannibal_over_without_boat)
    successor_fn.addMapping(three_missionaries_two_cannibals_over, move_one_missionary, two_and_two_over_without_boat)
    
    #Beginning in (two_and_two_over_without_boat)
    successor_fn.addMapping(two_and_two_over_without_boat, move_one_missionary, three_missionaries_one_cannibal_over)
    successor_fn.addMapping(two_and_two_over_without_boat, move_one_and_one, goal_state)
    
    #Beginning in (three_missionaries_one_cannibal_over_without_boat)
    successor_fn.addMapping(three_missionaries_one_cannibal_over_without_boat, move_one_cannibal, three_missionaries_two_cannibals_over)
    successor_fn.addMapping(three_missionaries_one_cannibal_over_without_boat, move_two_cannibals, goal_state)
    
    
    #Define the Search Problem
    missionaries_and_cannibals = SearchProblem(initial_state, successor_fn, goal_state)
    plan = tree_search(missionaries_and_cannibals)
    
    print(missionaries_and_cannibals)
    print("\nSolution: \n")
    for plan_step in plan:
        if plan_step.action is None:
            print ("<start>")
        
        else:
            print ("\t"),
            print (plan_step.action)
    
    print("<end>")
    
   
    print("\nExpanded Nodes: \n")
    for plan_step in plan:
        print(plan_step)