def setUp(self): m = [[0, 0, 0, 8, 8, 8, 0, 0, 0], [0, 0, 0, 8, 1, 8, 0, 0, 0], [0, 0, 0, 8, 2, 8, 0, 0, 0], [8, 8, 8, 8, 0, 8, 8, 8, 8], [8, 1, 2, 0, 4, 0, 2, 1, 8], [8, 8, 8, 8, 0, 8, 8, 8, 8], [0, 0, 0, 8, 2, 8, 0, 0, 0], [0, 0, 0, 8, 1, 8, 0, 0, 0], [0, 0, 0, 8, 8, 8, 0, 0, 0]] self.state = SokobanState(m)
def setUp(self): self.sokoban_map = [[0, 0, 0, 8, 8, 8, 0, 0, 0], [0, 0, 0, 8, 1, 8, 0, 0, 0], [0, 0, 0, 8, 2, 8, 0, 0, 0], [8, 8, 8, 8, 0, 8, 8, 8, 8], [8, 1, 2, 0, 4, 0, 2, 1, 8], [8, 8, 8, 8, 0, 8, 8, 8, 8], [0, 0, 0, 8, 2, 8, 0, 0, 0], [0, 0, 0, 8, 1, 8, 0, 0, 0], [0, 0, 0, 8, 8, 8, 0, 0, 0]] self.state = SokobanState(self.sokoban_map) self.sokoban = SokobanCore(self.sokoban_map)
def test_move_boxes(self): s = SokobanState([[0, 0, 8, 8, 8, 0, 0], [0, 0, 8, 2, 8, 0, 0], [8, 8, 8, 2, 8, 8, 8], [8, 2, 2, 4, 2, 2, 8], [8, 8, 8, 2, 8, 8, 8], [0, 0, 8, 2, 8, 0, 0], [0, 0, 8, 8, 8, 0, 0]]) with self.assertRaises(CannotMoveError): s.move(Moves.UP) with self.assertRaises(CannotMoveError): s.move(Moves.DOWN) with self.assertRaises(CannotMoveError): s.move(Moves.LEFT) with self.assertRaises(CannotMoveError): s.move(Moves.RIGHT)
def problems_in(): PROBLEMS = [] file = open('Microban100.txt') row = 0 col = 0 player = [] boxes = { } # boxes and targets are dictionaries so that the program can deal with problems that targets = { } # have restrictions on which box should go which storage. It is not used in the final test suite though. walls = [] while True: line = file.readline() if not line: break if line.count('\n') == len(line): # skip blank rows continue if '#' not in line: player = tuple(player) walls = frozenset(tuple(walls)) PROBLEMS.append( SokobanState(player, boxes, targets, walls, "start", None, 0)) row = 0 col = 0 player = [] boxes = {} targets = {} walls = [] for char in line: if char == '#': # a wall walls.append((row, col)) elif char == '@': #player player = [row, col] elif char == '$': boxes[(row, col)] = 0 elif char == '.': targets[(row, col)] = 0 elif char == '*': boxes[(row, col)] = 0 targets[(row, col)] = 0 elif char == '+': player = [row, col] targets[(row, col)] = 0 col += 1 col = 0 row += 1 return PROBLEMS
def main(map: str, setup: int): if torch.cuda.is_available(): print("Cuda found. Running DQN network on GPU.") cuda = True else: print( "Cuda not found. Running DQN network on CPU. This will be much slower." ) cuda = False state = SokobanState.load(map) heuristics = [ ("Manhattan Greedy", ManhattanHeuristic()), ("Euclidean Greedy", EuclidHeuristic()), ("Manhattan Hungarian", HungarianHeuristic("Manhattan")), ("Euclidean Hungarian", HungarianHeuristic("Euclidean")), ("Small Q-Learning", QLearningHeuristic("./qlearning_weights/convolution_network_3.torch", max_size=32, cuda=False, full_input=False)), ("Large Q-Learning", QLearningHeuristic("./qlearning_weights/convolution_network_5.torch", max_size=48, full_input=True, cuda=cuda)) ] print("=" * 80) print(f"Running Sokoban file: {map}") print("-" * 80) state.display() print("-" * 80) name, heuristic = heuristics[setup - 1] print() print("-" * 80) print(f"Using Heuristic: {name}") print("-" * 80) t0 = time() if "Large Q-Learning" in name: print("Running Batch A* Search") states, actions = BatchAstar(state, heuristic, batch_size=512, weight=10) else: print("Running A* Search") states, actions = Astar(state, heuristic) t1 = time() print(f"Runtime: {t1 - t0} seconds") print(f"Solution Length {len(actions)}")
def heur_alternate(state): # IMPLEMENT '''a better heuristic''' '''INPUT: a sokoban state''' '''OUTPUT: a numeric value that serves as an estimate of the distance of the state to the goal.''' # heur_manhattan_distance has flaws. # Write a heuristic function that improves upon heur_manhattan_distance to estimate distance between the current state and the goal. # Your function should return a numeric value for the estimate of the distance to the goal. h_val = 0 # Default value of Total Manhattan Distance for all boxes # Check Dead Lock First: if checkCornerLock(state) == True: #print("===>Corner Locked", state.index) return 99999 if checkBorderLock(state) == True: #print("===>Border Locked", state.index) return 99999 locked2x2 = check2x2Locked(state) if locked2x2 != set(): for i in locked2x2: if i not in state.storage: #print("===>2x2 Locked", state.index) # print(SokobanState.state_string(state)) return 99999 if checkSpecialCornerLock(state) == True: #print("===>Special Corner Locked", state.index) return 99999 checkProblemCase = checkProblemType(state) if checkProblemCase == 'Regular': h_val = regular_h_f(state) if checkProblemCase == 'UL': h_val = corner_consentrated_storage_h_f(state, 'UL') if checkProblemCase == 'UR': h_val = corner_consentrated_storage_h_f(state, 'UR') if checkProblemCase == 'DL': h_val = corner_consentrated_storage_h_f(state, 'DL') if checkProblemCase =='DR': h_val = corner_consentrated_storage_h_f(state, 'DR') print("====================================") print("Analyzing Case:", state.index) print(SokobanState.state_string(state)) print("box:", h_val) return h_val
class SokobanStateTestCase(unittest.TestCase): def setUp(self): m = [[0, 0, 0, 8, 8, 8, 0, 0, 0], [0, 0, 0, 8, 1, 8, 0, 0, 0], [0, 0, 0, 8, 2, 8, 0, 0, 0], [8, 8, 8, 8, 0, 8, 8, 8, 8], [8, 1, 2, 0, 4, 0, 2, 1, 8], [8, 8, 8, 8, 0, 8, 8, 8, 8], [0, 0, 0, 8, 2, 8, 0, 0, 0], [0, 0, 0, 8, 1, 8, 0, 0, 0], [0, 0, 0, 8, 8, 8, 0, 0, 0]] self.state = SokobanState(m) def test_move_up(self): s = self.state.move(Moves.UP) expected = [[0, 0, 0, 8, 8, 8, 0, 0, 0], [0, 0, 0, 8, 1, 8, 0, 0, 0], [0, 0, 0, 8, 2, 8, 0, 0, 0], [8, 8, 8, 8, 4, 8, 8, 8, 8], [8, 1, 2, 0, 0, 0, 2, 1, 8], [8, 8, 8, 8, 0, 8, 8, 8, 8], [0, 0, 0, 8, 2, 8, 0, 0, 0], [0, 0, 0, 8, 1, 8, 0, 0, 0], [0, 0, 0, 8, 8, 8, 0, 0, 0]] self.assertEqual(s.map, expected) s = s.move(Moves.UP) expected = [[0, 0, 0, 8, 8, 8, 0, 0, 0], [0, 0, 0, 8, 3, 8, 0, 0, 0], [0, 0, 0, 8, 4, 8, 0, 0, 0], [8, 8, 8, 8, 0, 8, 8, 8, 8], [8, 1, 2, 0, 0, 0, 2, 1, 8], [8, 8, 8, 8, 0, 8, 8, 8, 8], [0, 0, 0, 8, 2, 8, 0, 0, 0], [0, 0, 0, 8, 1, 8, 0, 0, 0], [0, 0, 0, 8, 8, 8, 0, 0, 0]] self.assertEqual(s.map, expected) with self.assertRaises(CannotMoveError): s.move(Moves.UP) def test_move_down(self): s = self.state.move(Moves.DOWN) expected = [[0, 0, 0, 8, 8, 8, 0, 0, 0], [0, 0, 0, 8, 1, 8, 0, 0, 0], [0, 0, 0, 8, 2, 8, 0, 0, 0], [8, 8, 8, 8, 0, 8, 8, 8, 8], [8, 1, 2, 0, 0, 0, 2, 1, 8], [8, 8, 8, 8, 4, 8, 8, 8, 8], [0, 0, 0, 8, 2, 8, 0, 0, 0], [0, 0, 0, 8, 1, 8, 0, 0, 0], [0, 0, 0, 8, 8, 8, 0, 0, 0]] self.assertEqual(s.map, expected) s = s.move(Moves.DOWN) expected = [[0, 0, 0, 8, 8, 8, 0, 0, 0], [0, 0, 0, 8, 1, 8, 0, 0, 0], [0, 0, 0, 8, 2, 8, 0, 0, 0], [8, 8, 8, 8, 0, 8, 8, 8, 8], [8, 1, 2, 0, 0, 0, 2, 1, 8], [8, 8, 8, 8, 0, 8, 8, 8, 8], [0, 0, 0, 8, 4, 8, 0, 0, 0], [0, 0, 0, 8, 3, 8, 0, 0, 0], [0, 0, 0, 8, 8, 8, 0, 0, 0]] self.assertEqual(s.map, expected) with self.assertRaises(CannotMoveError): s.move(Moves.DOWN) def test_move_left(self): s = self.state.move(Moves.LEFT) expected = [[0, 0, 0, 8, 8, 8, 0, 0, 0], [0, 0, 0, 8, 1, 8, 0, 0, 0], [0, 0, 0, 8, 2, 8, 0, 0, 0], [8, 8, 8, 8, 0, 8, 8, 8, 8], [8, 1, 2, 4, 0, 0, 2, 1, 8], [8, 8, 8, 8, 0, 8, 8, 8, 8], [0, 0, 0, 8, 2, 8, 0, 0, 0], [0, 0, 0, 8, 1, 8, 0, 0, 0], [0, 0, 0, 8, 8, 8, 0, 0, 0]] self.assertEqual(s.map, expected) s = s.move(Moves.LEFT) expected = [[0, 0, 0, 8, 8, 8, 0, 0, 0], [0, 0, 0, 8, 1, 8, 0, 0, 0], [0, 0, 0, 8, 2, 8, 0, 0, 0], [8, 8, 8, 8, 0, 8, 8, 8, 8], [8, 3, 4, 0, 0, 0, 2, 1, 8], [8, 8, 8, 8, 0, 8, 8, 8, 8], [0, 0, 0, 8, 2, 8, 0, 0, 0], [0, 0, 0, 8, 1, 8, 0, 0, 0], [0, 0, 0, 8, 8, 8, 0, 0, 0]] self.assertEqual(s.map, expected) with self.assertRaises(CannotMoveError): s.move(Moves.LEFT) def test_move_right(self): s = self.state.move(Moves.RIGHT) expected = [[0, 0, 0, 8, 8, 8, 0, 0, 0], [0, 0, 0, 8, 1, 8, 0, 0, 0], [0, 0, 0, 8, 2, 8, 0, 0, 0], [8, 8, 8, 8, 0, 8, 8, 8, 8], [8, 1, 2, 0, 0, 4, 2, 1, 8], [8, 8, 8, 8, 0, 8, 8, 8, 8], [0, 0, 0, 8, 2, 8, 0, 0, 0], [0, 0, 0, 8, 1, 8, 0, 0, 0], [0, 0, 0, 8, 8, 8, 0, 0, 0]] self.assertEqual(s.map, expected) s = s.move(Moves.RIGHT) expected = [[0, 0, 0, 8, 8, 8, 0, 0, 0], [0, 0, 0, 8, 1, 8, 0, 0, 0], [0, 0, 0, 8, 2, 8, 0, 0, 0], [8, 8, 8, 8, 0, 8, 8, 8, 8], [8, 1, 2, 0, 0, 0, 4, 3, 8], [8, 8, 8, 8, 0, 8, 8, 8, 8], [0, 0, 0, 8, 2, 8, 0, 0, 0], [0, 0, 0, 8, 1, 8, 0, 0, 0], [0, 0, 0, 8, 8, 8, 0, 0, 0]] self.assertEqual(s.map, expected) with self.assertRaises(CannotMoveError): s.move(Moves.RIGHT) def test_move_boxes(self): s = SokobanState([[0, 0, 8, 8, 8, 0, 0], [0, 0, 8, 2, 8, 0, 0], [8, 8, 8, 2, 8, 8, 8], [8, 2, 2, 4, 2, 2, 8], [8, 8, 8, 2, 8, 8, 8], [0, 0, 8, 2, 8, 0, 0], [0, 0, 8, 8, 8, 0, 0]]) with self.assertRaises(CannotMoveError): s.move(Moves.UP) with self.assertRaises(CannotMoveError): s.move(Moves.DOWN) with self.assertRaises(CannotMoveError): s.move(Moves.LEFT) with self.assertRaises(CannotMoveError): s.move(Moves.RIGHT) def test_pos(self): self.assertEqual(self.state.player_pos(), (4, 4))
class SokobanCoreTestCase(unittest.TestCase): def setUp(self): self.sokoban_map = [[0, 0, 0, 8, 8, 8, 0, 0, 0], [0, 0, 0, 8, 1, 8, 0, 0, 0], [0, 0, 0, 8, 2, 8, 0, 0, 0], [8, 8, 8, 8, 0, 8, 8, 8, 8], [8, 1, 2, 0, 4, 0, 2, 1, 8], [8, 8, 8, 8, 0, 8, 8, 8, 8], [0, 0, 0, 8, 2, 8, 0, 0, 0], [0, 0, 0, 8, 1, 8, 0, 0, 0], [0, 0, 0, 8, 8, 8, 0, 0, 0]] self.state = SokobanState(self.sokoban_map) self.sokoban = SokobanCore(self.sokoban_map) def test_basics(self): self.assertEqual(self.sokoban.map, self.state.map) self.assertEqual(self.sokoban.player_pos, self.state.player_pos()) self.assertEqual(self.sokoban.finished, self.state.check_finish()) def test_reset(self): self.sokoban.up() self.sokoban.reset() self.assertEqual(self.sokoban.state, self.state) def test_move_many(self): self.sokoban.move_many('udlr') self.assertEqual(self.sokoban.get_moves(), [Moves.UP, Moves.DOWN, Moves.LEFT, Moves.RIGHT]) def test_finish(self): self.sokoban.move_many('uuddllrrdduurr') self.assertTrue(self.sokoban.finished) def test_move_up(self): self.sokoban.up() self.assertEqual(self.sokoban.get_moves(), [Moves.UP]) self.assertEqual(self.sokoban.state, self.state.move(Moves.UP)) def test_move_down(self): self.sokoban.down() self.assertEqual(self.sokoban.get_moves(), [Moves.DOWN]) self.assertEqual(self.sokoban.state, self.state.move(Moves.DOWN)) def test_move_left(self): self.sokoban.left() self.assertEqual(self.sokoban.get_moves(), [Moves.LEFT]) self.assertEqual(self.sokoban.state, self.state.move(Moves.LEFT)) def test_move_right(self): self.sokoban.right() self.assertEqual(self.sokoban.get_moves(), [Moves.RIGHT]) self.assertEqual(self.sokoban.state, self.state.move(Moves.RIGHT)) def test_levels(self): sokoban = SokobanCore([[[0, 4]], [[4, 0]]]) self.assertEqual(sokoban.map, [[0, 4]]) sokoban.next_level() self.assertEqual(sokoban.map, [[4, 0]]) with self.assertRaises(ValueError): sokoban.next_level() sokoban.prev_level() self.assertEqual(sokoban.map, [[0, 4]]) with self.assertRaises(ValueError): sokoban.prev_level() def test_undo(self): self.sokoban.up() self.sokoban.up() self.sokoban.undo() self.assertEqual(self.sokoban.state, self.state.move(Moves.UP)) self.assertEqual(self.sokoban.get_moves(), [Moves.UP])
while currentTime < stopTime: solution = searchEngine.search(stopTime-currentTime, costBound) #Apply Search Engine to get solution if solution != False: #If solution find before time limit print("new gval is" , solution.gval) if solution.gval < costBound[0]: #Compair Current Solution g_val to so far best solution g_val bestSolutionSoFar = solution #If better, replace so far best solution costBound = (bestSolutionSoFar.gval, 99999, 99999) #replace so far best solution's gval and compair later g val with this g val for pruning elif solution == False: print("final:") return bestSolutionSoFar currentTime = os.times()[0] #Update current time for next loop return bestSolutionSoFar ######################################### ##### For Test ######### ######################################### counter = 0 for i in PROBLEMS: print("Checking Problem #",counter) print(SokobanState.state_string(i)) print(checkProblemType(i)) print("===============") counter = counter +1
# Boxxle problems are from: http://sokoban.info/?2 (any restrictions are our own) # Easiest 10 # Problem 0, Sokobanonline lesson #2-1 SokobanState( "START", 0, None, 4, 4, # dimensions (0, 3), #robot { (1, 2): 0, (1, 1): 1 }, #boxes { (2, 1): 0, (2, 2): 1 }, #storage frozenset(((0, 0), (1, 0), (3, 3))), #obstacles (frozenset(((2, 1), )), frozenset(((2, 2), ))), #restrictions, { 0: 'cyan', 1: 'magenta' }, #box colours { 0: 'cyan', 1: 'magenta' } #storage colours ), # Problem 1, Sokobanonline lesson #2-3 SokobanState( "START",
# I used to play lots of flash games on 4399.com when I was a child # These two problems are used to test the codes, and are not parts of the final testing suite TEST_PROBLEMS = [ SokobanState( # level 1 (4, 3), # player { (1, 4): 0, (2, 4): 1, (4, 2): 2, (5, 2): 3 }, # boxes { (1, 2): 0, (1, 3): 1, (5, 1): 2, (6, 1): 3 }, # targets frozenset( ((0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (1, 0), (1, 6), (2, 0), (2, 2), (2, 6), (3, 0), (3, 2), (3, 4), (3, 6), (4, 0), (4, 4), (4, 6), (5, 0), (5, 6), (6, 0), (6, 2), (6, 3), (6, 4), (6, 5), (6, 6), (7, 0), (7, 1), (7, 2))), # walls "start", # last_mov None, # predesessor 0 # gval ), SokobanState( # level 2 f1n3 (4, 6), # player { # boxes (2, 6): 0,
if solution != False: #If solution find before time limit print("new gval is" , solution.gval) if solution.gval < costBound[0]: #Compair Current Solution g_val to so far best solution g_val bestSolutionSoFar = solution #If better, replace so far best solution costBound = (bestSolutionSoFar.gval, 99999, 99999) #replace so far best solution's gval and compair later g val with this g val for pruning elif solution == False: print("final:") return bestSolutionSoFar currentTime = os.times()[0] #Update current time for next loop return bestSolutionSoFar ######################################### ##### For Test ######### ######################################### a= SokobanState("START", 0, None, 6, 6, # dimensions ( (0, 2), (0, 4)), #robots frozenset(((1, 0), (5, 3), (0, 1), (4, 3), (5, 5), (4, 0))), #boxes frozenset(((5, 0), (0, 1), (5, 2), (0, 3), (5, 4), (0, 5))), #storage frozenset() #obstacles ) print(SokobanState.state_string(a)) print("Width,x =", a.width) print("Height,y =", a.height) print(anyBoxNearRobot(a,(0,4)))
if(state.width-1,state.height-2) in state.boxes: if (((state.width-2,state.height-1) not in state.storage) or ((state.width-1,state.height-2) not in state.storage)) and ((state.width-1,state.height -1) not in state.robots): print("Special Corner Lock!") return True return caseCornerLocked ######################################### ##### For Test ######### ######################################### print(SokobanState.state_string(PROBLEMS[18])) print("Width,x =", a.width) print("Height,y =", a.height) print(checkBorderLock(a)) """ counter = 0 for a in PROBLEMS: print("Check Problem #:",counter) print(SokobanState.state_string(a)) print("Width,x =", a.width) print("Height,y =", a.height) print(checkProblemType(a)) print("=============================")