|
| 1 | +import numpy as np |
| 2 | + |
| 3 | +ACTIONS = {'U': (-1, 0), 'D': (1, 0), 'L': (0, -1), 'R': (0, 1)} |
| 4 | + |
| 5 | +class Maze(object): |
| 6 | + def __init__(self): |
| 7 | + self.maze = np.zeros((6, 6)) |
| 8 | + self.maze[0, 0] = 2 |
| 9 | + self.maze[5, :5] = 1 |
| 10 | + self.maze[:4, 5] = 1 |
| 11 | + self.maze[2, 2:] = 1 |
| 12 | + self.maze[3, 2] = 1 |
| 13 | + self.robot_position = (0, 0) |
| 14 | + self.steps = 0 |
| 15 | + self.construct_allowed_states() |
| 16 | + |
| 17 | + def print_maze(self): |
| 18 | + print('---------------------------------') |
| 19 | + for row in self.maze: |
| 20 | + for col in row: |
| 21 | + if col == 0: |
| 22 | + print('', end="\t") # empty space |
| 23 | + elif col == 1: |
| 24 | + print('X', end="\t") # walls |
| 25 | + elif col == 2: |
| 26 | + print('R', end="\t") # robot position |
| 27 | + print("\n") |
| 28 | + print('---------------------------------') |
| 29 | + |
| 30 | + def is_allowed_move(self, state, action): |
| 31 | + # check allowed move from a given state |
| 32 | + y, x = state |
| 33 | + y += ACTIONS[action][0] |
| 34 | + x += ACTIONS[action][1] |
| 35 | + if y < 0 or x < 0 or y > 5 or x > 5: |
| 36 | + # if robot will move off the board |
| 37 | + return False |
| 38 | + |
| 39 | + if self.maze[y, x] == 0 or self.maze[y, x] == 2: |
| 40 | + # if robot moves into empty space or its original start position |
| 41 | + return True |
| 42 | + else: |
| 43 | + return False |
| 44 | + |
| 45 | + def construct_allowed_states(self): |
| 46 | + # create a dictionary of allowed states from any position |
| 47 | + # using the isAllowedMove() function |
| 48 | + # this is so that you don't have to call the function every time |
| 49 | + allowed_states = {} |
| 50 | + for y, row in enumerate(self.maze): |
| 51 | + for x, col in enumerate(row): |
| 52 | + # iterate through all spaces |
| 53 | + if self.maze[(y,x)] != 1: |
| 54 | + # if the space is not a wall, add it to the allowed states dictionary |
| 55 | + allowed_states[(y,x)] = [] |
| 56 | + for action in ACTIONS: |
| 57 | + if self.is_allowed_move((y,x), action) & (action != 0): |
| 58 | + allowed_states[(y,x)].append(action) |
| 59 | + self.allowed_states = allowed_states |
| 60 | + |
| 61 | + def update_maze(self, action): |
| 62 | + y, x = self.robot_position # get current position |
| 63 | + self.maze[y, x] = 0 # set the current position to 0 |
| 64 | + y += ACTIONS[action][0] # get new position |
| 65 | + x += ACTIONS[action][1] # get new position |
| 66 | + self.robot_position = (y, x) # set new position |
| 67 | + self.maze[y, x] = 2 # set new position |
| 68 | + self.steps += 1 # add steps |
| 69 | + |
| 70 | + def is_game_over(self): |
| 71 | + # check if robot in the final position |
| 72 | + if self.robot_position == (5, 5): |
| 73 | + return True |
| 74 | + else: |
| 75 | + return False |
| 76 | + |
| 77 | + def get_state_and_reward(self): |
| 78 | + return self.robot_position, self.give_reward() |
| 79 | + |
| 80 | + def give_reward(self): |
| 81 | + # if at end give 0 reward |
| 82 | + # if not at end give -1 reward |
| 83 | + if self.robot_position == (5, 5): |
| 84 | + return 0 |
| 85 | + else: |
| 86 | + return -1 |
| 87 | + |
| 88 | + def get_robot_position(self): |
| 89 | + return self.robot_position |
0 commit comments