| 145 | |
| 146 | |
| 147 | class WindyGrid: |
| 148 | def __init__(self, rows, cols, start): |
| 149 | self.rows = rows |
| 150 | self.cols = cols |
| 151 | self.i = start[0] |
| 152 | self.j = start[1] |
| 153 | |
| 154 | def set(self, rewards, actions, probs): |
| 155 | # rewards should be a dict of: (i, j): r (row, col): reward |
| 156 | # actions should be a dict of: (i, j): A (row, col): list of possible actions |
| 157 | self.rewards = rewards |
| 158 | self.actions = actions |
| 159 | self.probs = probs |
| 160 | |
| 161 | def set_state(self, s): |
| 162 | self.i = s[0] |
| 163 | self.j = s[1] |
| 164 | |
| 165 | def current_state(self): |
| 166 | return (self.i, self.j) |
| 167 | |
| 168 | def is_terminal(self, s): |
| 169 | return s not in self.actions |
| 170 | |
| 171 | def move(self, action): |
| 172 | s = (self.i, self.j) |
| 173 | a = action |
| 174 | |
| 175 | next_state_probs = self.probs[(s, a)] |
| 176 | next_states = list(next_state_probs.keys()) |
| 177 | next_probs = list(next_state_probs.values()) |
| 178 | next_state_idx = np.random.choice(len(next_states), p=next_probs) |
| 179 | s2 = next_states[next_state_idx] |
| 180 | |
| 181 | # update the current state |
| 182 | self.i, self.j = s2 |
| 183 | |
| 184 | # return a reward (if any) |
| 185 | return self.rewards.get(s2, 0) |
| 186 | |
| 187 | def game_over(self): |
| 188 | # returns true if game is over, else false |
| 189 | # true if we are in a state where no actions are possible |
| 190 | return (self.i, self.j) not in self.actions |
| 191 | |
| 192 | def all_states(self): |
| 193 | # possibly buggy but simple way to get all states |
| 194 | # either a position that has possible next actions |
| 195 | # or a position that yields a reward |
| 196 | return set(self.actions.keys()) | set(self.rewards.keys()) |
| 197 | |
| 198 | |
| 199 | def windy_grid(): |
no outgoing calls
no test coverage detected