4 class AgentBishop(AgentRandom): # Inherits from AgentRandom (in qchess)
5 def __init__(self, name, colour,value={"pawn" : 1, "bishop" : 3, "knight" : 3, "rook" : 5, "queen" : 9, "king" : 100, "unknown" : 2}):
6 InternalAgent.__init__(self, name, colour)
8 self.aggression = 2.0 # Multiplier for scoring due to aggressive actions
9 self.defence = 1.0 # Multiplier for scoring due to defensive actions
11 self.depth = 0 # Current depth
12 self.max_depth = 2 # Recurse this many times (for some reason, makes more mistakes when this is increased???)
13 self.recurse_for = -1 # Recurse for the best few moves each times (less than 0 = all moves)
15 for p in self.board.pieces["white"] + self.board.pieces["black"]:
17 p.selected_moves = None
21 def get_value(self, piece):
24 return float(self.value[piece.types[0]] + self.value[piece.types[1]]) / 2.0
26 # Score possible moves for the piece
28 def prioritise_moves(self, piece):
30 #sys.stderr.write(sys.argv[0] + " : " + str(self) + " prioritise called for " + str(piece) + "\n")
34 grid = self.board.probability_grid(piece)
35 #sys.stderr.write("\t Probability grid " + str(grid) + "\n")
39 if grid[x][y] < 0.3: # Throw out moves with < 30% probability
40 #sys.stderr.write("\tReject " + str(x) + "," + str(y) + " (" + str(grid[x][y]) + ")\n")
43 target = self.board.grid[x][y]
48 # Get total probability that the move is protected
49 self.board.push_move(piece, x, y)
53 defenders = self.board.coverage(x, y, piece.colour, reject_allied = False)
55 for d in defenders.keys():
56 d_prob += defenders[d]
57 if len(defenders.keys()) > 0:
58 d_prob /= float(len(defenders.keys()))
63 # Get total probability that the move is threatened
64 attackers = self.board.coverage(x, y, opponent(piece.colour), reject_allied = False)
66 for a in attackers.keys():
67 a_prob += attackers[a]
68 if len(attackers.keys()) > 0:
69 a_prob /= float(len(attackers.keys()))
79 value = self.aggression * (1.0 + d_prob) * self.get_value(target) - self.defence * (1.0 - d_prob) * a_prob * self.get_value(piece)
81 # Adjust score based on movement of piece out of danger
82 attackers = self.board.coverage(piece.x, piece.y, opponent(piece.colour))
84 for a in attackers.keys():
85 s_prob += attackers[a]
86 if len(attackers.keys()) > 0:
87 s_prob /= float(len(attackers.keys()))
91 value += self.defence * s_prob * self.get_value(piece)
93 # Adjust score based on probability that the move is actually possible
94 moves.append([[x, y], grid[x][y] * value])
96 moves.sort(key = lambda e : e[1], reverse = True)
97 #sys.stderr.write(sys.argv[0] + ": Moves for " + str(piece) + " are " + str(moves) + "\n")
99 piece.last_moves = moves
100 piece.selected_moves = None
107 def select_best(self, colour):
111 for p in self.board.pieces[colour]:
112 self.choice = p # Temporarily pick that piece
113 m = self.prioritise_moves(p)
115 all_moves.update({p : m[0]})
117 if len(all_moves.items()) <= 0:
121 opts = all_moves.items()
122 opts.sort(key = lambda e : e[1][1], reverse = True)
124 if self.depth >= self.max_depth:
128 if self.recurse_for >= 0:
129 opts = opts[0:self.recurse_for]
130 #sys.stderr.write(sys.argv[0] + " : Before recurse, options are " + str(opts) + "\n")
132 # Take the best few moves, and recurse
133 for choice in opts[0:self.recurse_for]:
134 [xx,yy] = [choice[0].x, choice[0].y] # Remember position
135 [nx,ny] = choice[1][0] # Target
136 [choice[0].x, choice[0].y] = [nx, ny] # Set position
137 target = self.board.grid[nx][ny] # Remember piece in spot
138 self.board.grid[xx][yy] = None # Remove piece
139 self.board.grid[nx][ny] = choice[0] # Replace with moving piece
142 best_enemy_move = self.select_best(opponent(choice[0].colour))
143 choice[1][1] -= best_enemy_move[1][1] / float(self.depth + 1.0)
145 [choice[0].x, choice[0].y] = [xx, yy] # Restore position
146 self.board.grid[nx][ny] = target # Restore taken piece
147 self.board.grid[xx][yy] = choice[0] # Restore moved piece
151 opts.sort(key = lambda e : e[1][1], reverse = True)
152 #sys.stderr.write(sys.argv[0] + " : After recurse, options are " + str(opts) + "\n")
159 # Returns [x,y] of selected piece
161 #sys.stderr.write("Getting choice...")
162 self.choice = self.select_best(self.colour)[0]
164 #sys.stderr.write(" Done " + str(self.choice)+"\n")
165 return [self.choice.x, self.choice.y]
167 # Returns [x,y] of square to move selected piece into
169 #sys.stderr.write("Choice is " + str(self.choice) + "\n")
170 self.choice.selected_moves = self.choice.last_moves
171 moves = self.prioritise_moves(self.choice)
175 return AgentRandom.get_move(self)