| 49 | self.state_history = [] |
| 50 | |
| 51 | def take_action(self, env): |
| 52 | # choose an action based on epsilon-greedy strategy |
| 53 | r = np.random.rand() |
| 54 | best_state = None |
| 55 | if r < self.eps: |
| 56 | # take a random action |
| 57 | if self.verbose: |
| 58 | print("Taking a random action") |
| 59 | |
| 60 | possible_moves = [] |
| 61 | for i in range(LENGTH): |
| 62 | for j in range(LENGTH): |
| 63 | if env.is_empty(i, j): |
| 64 | possible_moves.append((i, j)) |
| 65 | idx = np.random.choice(len(possible_moves)) |
| 66 | next_move = possible_moves[idx] |
| 67 | else: |
| 68 | # choose the best action based on current values of states |
| 69 | # loop through all possible moves, get their values |
| 70 | # keep track of the best value |
| 71 | pos2value = {} # for debugging |
| 72 | next_move = None |
| 73 | best_value = -1 |
| 74 | for i in range(LENGTH): |
| 75 | for j in range(LENGTH): |
| 76 | if env.is_empty(i, j): |
| 77 | # what is the state if we made this move? |
| 78 | env.board[i,j] = self.sym |
| 79 | state = env.get_state() |
| 80 | env.board[i,j] = 0 # don't forget to change it back! |
| 81 | pos2value[(i,j)] = self.V[state] |
| 82 | if self.V[state] > best_value: |
| 83 | best_value = self.V[state] |
| 84 | best_state = state |
| 85 | next_move = (i, j) |
| 86 | |
| 87 | # if verbose, draw the board w/ the values |
| 88 | if self.verbose: |
| 89 | print("Taking a greedy action") |
| 90 | for i in range(LENGTH): |
| 91 | print("------------------") |
| 92 | for j in range(LENGTH): |
| 93 | if env.is_empty(i, j): |
| 94 | # print the value |
| 95 | print(" %.2f|" % pos2value[(i,j)], end="") |
| 96 | else: |
| 97 | print(" ", end="") |
| 98 | if env.board[i,j] == env.x: |
| 99 | print("x |", end="") |
| 100 | elif env.board[i,j] == env.o: |
| 101 | print("o |", end="") |
| 102 | else: |
| 103 | print(" |", end="") |
| 104 | print("") |
| 105 | print("------------------") |
| 106 | |
| 107 | # make the move |
| 108 | env.board[next_move[0], next_move[1]] = self.sym |