def get_chess_move(fen_board, color): state = ai.Board_State(fen_board, color) #construct the board state, make it available globally global global_state #make top state avaliable to threads global top_max #make top max avaliable to threads global lock #make a lock avaliable to the threads global_state = state top_max = -900000 #need to assign, start at impossibly low value lock = Lock() #do some timing things start = time.time() #Start the search pool = Pool(MAX_THREADS) #spawn specified number of worker threads move_strings = get_possible_moves(state) #get all possible first moves moves = pool.map(do_search_thread, move_strings) #run the threads pool.close() #close threads after they finish pool.join() #wait for threads to terminate before continuing best_move = moves[0] all_equal = True #check if all moves are equal for move in moves[1:]: #get best move if(move.value > best_move.value): best_move = move all_equal = False print 'better_move' #pick random move instead if all moves are the same value if(all_equal): best_move = moves[randrange(len(moves))] #debug (single thread instead of multi) #best_move = alpha_beta_tree(state, MAX_DEPTH, None, None, True) #See if we've checked them (give ai a free second move, see if we capture the king) new_state = ai.Board_State() #create the new state new_state.copy_board(state) new_state.execute_move(best_move.tag,False) #execute our chosen move and take another turn check_check = alpha_beta_tree(new_state, 1, None, None, True) #check tree new_state.execute_move(check_check.tag) #execute the free move if(new_state.ai_color and not new_state.bk): print 'Check' elif(not new_state.ai_color and not new_state.wk): print 'Check' #See if we've checkmated them (iterate one round, see if they survive) new_state.copy_board(state) new_state.execute_move(best_move.tag) #execute our chosen move check_check = alpha_beta_tree(new_state, 2, None, None, False) #do thier turn new_state.execute_move(check_check.tag) check_check = alpha_beta_tree(new_state, 1, None, None, True) #do our turn new_state.execute_move(check_check.tag) if(new_state.ai_color and not new_state.bk): print 'Checkmate' elif(not new_state.ai_color and not new_state.wk): print 'Checkmate' return best_move.tag
def alpha_beta_tree(state, depth, last_max, last_min, is_max): if(depth == 0): #end of recursive function return ai.Move("", get_state_evaluation(state)) #return the value of this position move_strings = get_possible_moves(state) #get the strings corresponding to possible moves if(len(move_strings) == 0): return ai.Move("",get_state_evaluation(state)) #handle edge case new_state = ai.Board_State() new_state.copy_board(state) new_state.execute_move(move_strings[0]) if(is_max): best_move = alpha_beta_tree(new_state, depth-1, None, last_min, False) else: best_move = alpha_beta_tree(new_state, depth-1, last_max, None, True) best_move.tag = move_strings[0] for move in move_strings[1:]: #search each other move new_state.copy_board(state) #copy the board new_state.execute_move(move) #execute the move if(is_max): contender = alpha_beta_tree(new_state, depth-1, best_move.value, last_min, False) #recurse! else: contender = alpha_beta_tree(new_state, depth-1, last_max, best_move.value, True) #recurse! if((is_max and contender.value >= best_move.value) or (not is_max and contender.value <= best_move.value)): best_move = contender #contender is better best_move.tag = move #update the tag #Do alpha beta - remove any value which cannot possiby replace an existing one if(last_max != None and last_min != None): if(best_move.value >= last_min or best_move.value <= last_max): return best_move elif(last_max != None and best_move.value <= last_max): return best_move elif(last_min != None and best_move.value >= last_min): return best_move return best_move
def do_search_thread(move): global global_state # use global state global top_max # use global max global lock # use global lock # print move new_state = ai.Board_State() # create a new state new_state.copy_board(global_state) # copy the main state new_state.execute_move(move) # execute the move lock.acquire() # get the lock gmax = top_max # copy the global max lock.release() # release the lock best_move = alpha_beta_min(new_state, MAX_DEPTH-1, gmax, 900000) # throw to tree search for next iteration if(best_move.tag == ''): return ai.Move("",-900000) # catch bad results lock.acquire() # get the lock if(top_max < best_move.value): # check if we're better top_max = best_move.value # store new best value lock.release() # release the lock best_move.tag = move return best_move
def alpha_beta_min(state, depth, last_max, last_min): if(depth == 0): # end of recursive function return ai.Move("", get_state_evaluation(state)) # return the value of this position move_strings = get_possible_moves(state) # get the strings corresponding to possible moves if(len(move_strings) == 0): return ai.Move("end", get_state_evaluation(state)) # handle edge case new_state = ai.Board_State() # create empty board object best_move = ai.Move("",last_min) # preload move for move in move_strings: # search each move new_state.copy_board(state) # copy the board new_state.execute_move(move) # execute the move contender = alpha_beta_max(new_state, depth-1, last_max, last_min).value # recurse! if(contender <= last_max): return ai.Move("",last_max) # no moves if(contender < last_min): # check result last_min = contender best_move = ai.Move(move, contender) # contender is better return best_move # successfull move
def get_chess_move(fen_board, color): state = ai.Board_State(fen_board, color) # construct the board state, make it available globally global global_state # make top state avaliable to threads global top_max # make top max avaliable to threads global lock # make a lock avaliable to the threads global_state = state top_max = -900000 # need to assign, start at impossibly low value lock = Lock() # do some timing things start = time.time() # Start the search pool = Pool(MAX_THREADS) # spawn specified number of worker threads move_strings = get_possible_moves(state) # get all possible first moves random.shuffle(move_strings) # shuffle the move strings moves = pool.map(do_search_thread, move_strings) # run the threads pool.close() # close threads after they finish pool.join() # wait for threads to terminate before continuing # find the best move value best_move_val = moves[0].value for move in moves[1:]: # get best move if(move.value > best_move_val): best_move_val = move.value good_moves = [] # list of the top moves for move in moves: if(move.value == best_move_val): good_moves.append(move) # add the move # print (move.tag, move.value) # print ('good moves', len(good_moves)) # pick random move from top contender list best_move = good_moves[random.randrange(len(good_moves))] # debug (single thread instead of multi) # best_move = alpha_beta_max(state, MAX_DEPTH, -900000, 900000) check_or_mate = None # See if we've checked them (give ai a free second move, see if we capture the king) new_state = ai.Board_State() # create the new state new_state.copy_board(state) new_state.execute_move(best_move.tag,False) # execute our chosen move and take another turn check_check = alpha_beta_max(new_state, 1, -900000, 900000) # check tree new_state.execute_move(check_check.tag) # execute the free move if((new_state.ai_color and not new_state.bk) or (not new_state.ai_color and not new_state.wk)): check_or_mate = 'Check' # they're in check # See if we've checkmated them (iterate one round, see if they survive) new_state.copy_board(state) new_state.execute_move(best_move.tag) # execute our chosen move check_check = alpha_beta_min(new_state, 2, -900000, 900000) # do thier turn new_state.execute_move(check_check.tag) check_check = alpha_beta_max(new_state, 1, -900000, 900000) # do our turn new_state.execute_move(check_check.tag) if((new_state.ai_color and not new_state.bk) or (not new_state.ai_color and not new_state.wk)): check_or_mate = 'Checkmate' return {'move': best_move.tag, 'check': check_or_mate, 'value':best_move.value, 'time':time.time()-start}