def ab_neg_test(): ''' Test that alpha-beta and negamax arrive at the same move ''' test_posn1 = Posn('W') test_posn2 = Posn('W') test_moves1 = move_gen.find_moves(test_posn1) test_moves2 = move_gen.find_moves(test_posn2) test_move1 = test_posn1.negamax_move(3, test_moves1) test_move2 = test_posn2.alpha_beta_move(3, test_moves2) print('negamax move: ' + test_move1.to_str() + ' alpha-beta move: ' + test_move2.to_str()) assert test_move1.to_str() == test_move2.to_str()
def __alpha_beta(self, depth, alpha, beta): ''' XXX ''' if self.check_end() or depth <= 0: return self.compute_score() # Generate moves and score them moves = move_gen.find_moves(self) # Extract the first move arbitrarily move = moves.pop() # Make the move and do negamax search undo = Undo(self.board, move) self.make_move(move) max_score = -(self.__alpha_beta(depth - 1, -beta, -alpha)) # Undo the move self.do_undo(undo) if max_score >= beta: return max_score alpha = max(alpha, max_score) for move in moves: undo = Undo(self.board, move) self.make_move(move) val = -(self.__alpha_beta(depth - 1, -beta, -alpha)) self.do_undo(undo) if val >= beta: return val max_score = max(max_score, val) alpha = max(alpha, val) return max_score
def make_move(self): ''' Run negamax algorithm to choose move. ''' moves = move_gen.find_moves(self.posn) move = self.posn.negamax_move(self.depth, moves) self.posn.make_move(move) return move.to_str(), move.win
def make_move(self): ''' Choose move randomly and execute it. ''' moves = move_gen.find_moves(self.posn) move = moves[r.randint(0, len(moves)) - 1] self.posn.make_move(move) return move.to_str(), move.win
def make_move(self): ''' Run alpha-beta algorithm to choose move. ''' moves = move_gen.find_moves(self.posn) move = self.posn.alpha_beta_move(self.depth, moves) self.posn.make_move(move) return move.to_str(), move.win
def make_move(self): ''' Choose move using iteratively deepened alpha-beta. ''' moves = move_gen.find_moves(self.posn) if self.use_adjustment is True: self.limit = self.determine_time() move = self.posn.iterative_deepening(self.limit, moves) self.posn.make_move(move) return move.to_str(), move.win
def do_test_moves(): ''' Test piece movement. ''' # Check pawn forward movement board = Posn('W') moves = move_gen.find_moves(board) # Do Bart's move checking ins = glob.glob('move-tests/*.in') for filename in ins: with open(filename) as i: lines = i.readlines() color = lines[0].split()[1] board = [] for i in range(1, len(lines)): line = lines[i].strip() row = [] for char in line: row.append(char) board.append(row) posn = Posn('W') posn.on_move = color posn.set_board(board) moves = move_gen.find_moves(posn) move_strs = [] for move in moves: move_strs.append(move.to_str()) with open(filename[0:-2] + 'out') as out: lines = out.readlines() output = [] for line in lines: output.append(line.strip()) if collections.Counter(move_strs) != collections.Counter(output): print(filename) print(posn.on_move) print(move_strs) print(output) print(set(move_strs) - set(output)) print(posn)
def make_move(self): ''' Generate all moves and choose highest-scoring. ''' moves = move_gen.find_moves(self.posn) scored_moves = [] for move in moves: undo = representation.Undo(self.posn, move) self.posn.make_move(move) scored_moves.append(self.posn.compute_score()) self.posn.do_undo(undo) # Find all moves that have an equal score and choose one randomly. best_score = max(scored_moves) indices = [i for i, j in enumerate(scored_moves) if j == best_score] move = moves[indices[r.randint(0, len(indices)) - 1]] self.posn.make_move(move) return move.to_str(), move.win
def __negamax(self, depth): ''' XXX ''' if self.check_end() or depth <= 0: return self.compute_score() # Generate moves and score them moves = move_gen.find_moves(self) max_score = MIN_SCORE # For the rest of the moves, make the move, compare it to the # score found so far, and save the best of them. for move in moves: undo = Undo(self.board, move) self.make_move(move) val = -(self.__negamax(depth - 1)) max_score = max(max_score, val) self.do_undo(undo) return max_score