Пример #1
0
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
Пример #2
0
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
Пример #3
0
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
Пример #4
0
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
Пример #5
0
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}