def next_move(game: Game_IJK)-> None: '''board: list of list of strings -> current state of the game current_player: int -> player who will make the next move either ('+') or -'-') deterministic: bool -> either True or False, indicating whether the game is deterministic or not ''' board = game.getGame() player = game.getCurrentPlayer() deterministic = game.getDeterministic() print(player) # You'll want to put in your fancy AI code here. For right now this just # returns a random move. if player == '+': temp = 'max' else: temp = 'min' if deterministic == True: yield choice(game,temp,4)#random.choice(['U', 'D', 'L', 'R']) else: yield choice(game,temp,5)#random.choice(['U', 'D', 'L', 'R'])
def next_move(game: Game_IJK) -> None: """ game: current-state of game yield a single character as one of the following moves - 'U', 'L', 'R', 'D', 'S' """ """board: list of list of chars -> current state of the game current_player: int -> player who will make the next move either 1('+') or -1('-') """ move = ( input( "Please enter move for player %s (U, D, L, R): " % game.getCurrentPlayer() ) .strip() .upper() ) while move not in "UDLR": move = ( input( "Bad move! Please try again and enter move for player %s (U, D, L, R): " % game.getCurrentPlayer() ) .strip() .upper() ) yield move
def next_move(game: Game_IJK) -> None: '''board: list of list of strings -> current state of the game current_player: int -> player who will make the next move either ('+') or -'-') deterministic: bool -> either True or False, indicating whether the game is deterministic or not ''' global InitialPlayer InitialPlayer = game.getCurrentPlayer() board = game.getGame() player = game.getCurrentPlayer() deterministic = game.getDeterministic() # You'll want to put in your fancy AI code here. For right now this just boards = [] level = 0 max_score = -math.inf min_score = math.inf final_move = "" if player == "+": boards = succesor_boards(True, game, board) else: boards = succesor_boards(False, game, board) for board in boards: alpha = -math.inf beta = math.inf score = compute_score(False, level, 3, board[1], alpha, beta, game) if score > max_score: # print(score) # print("Final score") max_score = score final_move = board[0] yield final_move
def next_move(game: Game_IJK) -> None: '''board: list of list of strings -> current state of the game current_player: int -> player who will make the next move either ('+') or -'-') deterministic: bool -> either True or False, indicating whether the game is deterministic or not ''' board = game.getGame() player = game.getCurrentPlayer() deterministic = game.getDeterministic() # You'll want to put in your fancy AI code here. For right now this just # returns a random move. moves = ['U', 'L', 'R', 'D'] value = [] #start with minimax algorithm with current game state for i in ['U', 'L', 'R', 'D']: child = successor(copy.deepcopy(game), i) value.append(minimax(child, 3, False, float('-inf'), float('inf'))) #get index number with highest value k = np.argmax(value) # You'll want to put in your fancy AI code here. For right now this just # returns a random move. #choose a move with highest minimax utility value yield moves[k]
def next_move(game: Game_IJK) -> None: '''board: list of list of strings -> current state of the game current_player: int -> player who will make the next move either ('+') or -'-') deterministic: bool -> either True or False, indicating whether the game is deterministic or not ''' board = game.getGame() player = game.getCurrentPlayer() deterministic = game.getDeterministic() # You'll want to put in your fancy AI code here. For right now this just # returns a random move. #print('Board: ', board) if (player == '+'): current_player = 1 else: current_player = -1 #print(merge(board, current_player)) #children(board, current_player) #board = [['J', 'J', ' ', ' '], [' ', ' ', ' ', ' '], [' ', ' ', ' ', ' '], ['i', ' ', ' ', ' ']] if (deterministic == True): score, move = Decision(board, current_player, True) #print('MOVE', move, score) return move else: score, move = Decision_nondet(board, current_player, True) #print('MOVE: ', move, score) return move
def next_move(game: Game_IJK) -> None: '''board: list of list of strings -> current state of the game current_player: int -> player who will make the next move either ('+') or -'-') deterministic: bool -> either True or False, indicating whether the game is deterministic or not ''' board = game.getGame() player = game.getCurrentPlayer() deterministic = game.getDeterministic() moves = getAvailableMoves(game) maxUtility = -np.inf nextMove = -1 for move in moves: child = getChild(game, move) utility = MinimaxAB(board=child, node=player, deterministic=deterministic) if utility >= maxUtility: maxUtility = utility nextMove = move yield nextMove
def next_move(game: Game_IJK) -> None: '''board: list of list of strings -> current state of the game current_player: int -> player who will make the next move either ('+') or -'-') deterministic: bool -> either True or False, indicating whether the game is deterministic or not ''' beta = math.inf alpha = -1 * math.inf # depth future_step = 3 board = game.getGame() player = game.getCurrentPlayer() deterministic = game.getDeterministic() if player == '+': # succ = [game,'move'] succ = successor(game) best, c = max(min_value(i, future_step, alpha, beta) for i in succ) yield best[1] else: yield random.choice(['U', 'L', 'D', 'R'])
def next_move(game: Game_IJK) -> None: '''board: list of list of strings -> current state of the game current_player: int -> player who will make the next move either ('+') or -'-') deterministic: bool -> either True or False, indicating whether the game is deterministic or not ''' board = game.getGame() player = game.getCurrentPlayer() deterministic = game.getDeterministic() # You'll want to put in your fancy AI code here. For right now this just # returns a random move. depth = 0 alpha = -math.inf beta = math.inf mv = '' to_be_done = '' unchanged_board = board for m in moves: alpha, mv = max([alpha, mv], Min(m, game, depth, alpha, beta)) to_be_done = mv return to_be_done
def find_successors(board, player, deterministic): moves = ['L', 'R', 'U', 'D'] child_nodes = [] for i in moves: game1 = Game_IJK(board, player, deterministic) child_nodes.append(game1.makeMove(i).getGame()) return child_nodes
def evaluate(game: Game_IJK, player) -> (int, int): up, low = 0, 0 gamestate = game.state() if (gamestate == 'C'): up = float("inf") low = float("-inf") return float("inf") elif (gamestate == 'c'): return float("-inf") elif (gamestate == 'Tie'): return 0 adjscore = 0 board = game.getGame() for row in board: for e in row: if (e != ' '): if (e >= 'a'): low += (2**(ord(e) - ord('a') + 1) - 1) else: up += (2**(ord(e) - ord('A') + 1) - 1) for i in range(6): for j in range(6): if (j + 1 < 6 and abs(ord(board[i][j + 1]) - ord(board[i][j])) == 32): adjscore += (2**(ord(board[i][j + 1]) - ord('a') + 2) - 1) elif (i + 1 < 6 and abs(ord(board[i + 1][j]) - ord(board[i][j])) == 32): adjscore += (2**(ord(board[i + 1][j]) - ord('a') + 2) - 1) return up - low + (adjscore if game.getCurrentPlayer() == player else -adjscore)
def next_move(game: Game_IJK)-> None: board = game.getGame() player = game.getCurrentPlayer() deterministic = game.getDeterministic() print( "Player" , player ) yield moves_run( board , game , player )
def next_move(game: Game_IJK) -> None: '''board: list of list of strings -> current state of the game current_player: int -> player who will make the next move either ('+') or -'-') deterministic: bool -> either True or False, indicating whether the game is deterministic or not ''' global InitialPlayer InitialPlayer = game.getCurrentPlayer() board = game.getGame() player = game.getCurrentPlayer() deterministic = game.getDeterministic() # You'll want to put in your fancy AI code here. For right now this just boards = [] level = 0 max_score = -math.inf min_score = math.inf final_move = "" if deterministic: " Minimax - alpha/beta pruning" if player == "+": boards = succesor_boards(True, game, board) else: boards = succesor_boards(False, game, board) for board in boards: alpha = -math.inf beta = math.inf score = compute_score(False, False, level, 3, board[1], alpha, beta, game, InitialPlayer, "") if score > max_score: # print(score) # print("Final score") max_score = score final_move = board[0] else: " Expectiminimax - alpha/beta pruning" moves = ['U', 'D', 'L', 'R'] empty_tiles = get_empty_tiles(board) for move in moves: score = 0 if player == "+": boards = chance_boards(True, game, board, move, empty_tiles) else: boards = chance_boards(False, game, board, move, empty_tiles) for board1 in boards: alpha = -math.inf beta = math.inf score += compute_score(False, False, level, 3, board1[1], alpha, beta, game, InitialPlayer, "") avg_score = score / empty_tiles if avg_score > max_score: # print(score) # print("Final score") max_score = avg_score final_move = move yield final_move
def next_move(game: Game_IJK) -> None: '''board: list of list of strings -> current state of the game current_player: int -> player who will make the next move either ('+') or -'-') deterministic: bool -> either True or False, indicating whether the game is deterministic or not ''' board = game.getGame() player = game.getCurrentPlayer() deterministic = game.getDeterministic() # You'll want to put in your fancy AI code here. For right now this just # returns a random move. yield MINIMAX_Decision(game, deterministic, h=5)
def next_move(game: Game_IJK) -> None: """board: list of list of strings -> current state of the game current_player: int -> player who will make the next move either ('+') or -'-') deterministic: bool -> either True or False, indicating whether the game is deterministic or not """ board = game.getGame() player = game.getCurrentPlayer() deterministic = game.getDeterministic() if deterministic == True: move = findOptimalMoveDet(game, board, 4, player) elif deterministic == False: move = findOptimalMoveNonDet(game, board, player) yield move
def Max(move, game: Game_IJK, depth, alpha, beta): game = game.makeMove(move) depth = depth + 1 board = game.getGame() if (depth == 6): return [utility(board), move] for m in moves: alpha, move = max([alpha, move], Min(move, game, depth, alpha, beta)) if alpha > beta: return [alpha, move] return [alpha, move]
def MIN_Value(game: Game_IJK, alpha: int, beta: int, depth: int, player: str) -> int: curbeta = beta if (depth == 0): upscore = evaluate(game, player) return upscore if player == '+' else -upscore gamestate = game.state() if (gamestate == 'C'): return float("inf") if player == '+' else float("-inf") elif (gamestate == 'c'): return float("-inf") if player == '+' else float("inf") elif (gamestate == 'Tie'): return 0 w = copy.deepcopy(game) w = w.makeMove('U') s = copy.deepcopy(game) s = w.makeMove('D') a = copy.deepcopy(game) a = w.makeMove('L') d = copy.deepcopy(game) d = w.makeMove('R') for g in [w, s, a, d]: curbeta = min(curbeta, MAX_Value(g, alpha, curbeta, depth - 1, player)) if (alpha >= curbeta): return curbeta return curbeta
def next_move(game: Game_IJK)-> None: '''board: list of list of strings -> current state of the game current_player: int -> player who will make the next move either ('+') or -'-') deterministic: bool -> either True or False, indicating whether the game is deterministic or not ''' board = game.getGame() player = game.getCurrentPlayer() deterministic = game.getDeterministic() # You'll want to put in your fancy AI code here. For right now this just # returns a random move direction, child, utility = decision(game) yield direction # yield random.choice(['U', 'D', 'L', 'R'])
def next_move(game: Game_IJK) -> None: ''' game: current-state of game yield a single character as one of the following moves - 'U', 'L', 'R', 'D', 'S' ''' '''board: list of list of chars -> current state of the game current_player: int -> player who will make the next move either 1('+') or -1('-') ''' print('Please enter move for player %s (U, D, L, R): ' % game.getCurrentPlayer()) move = input().strip().upper() while (move not in "UDLR"): print( 'Bad move! Please try again and enter move for player %s (U, D, L, R): ' % game.getCurrentPlayer()) move = input().strip().upper() yield move
def max_utility(game: Game_IJK, d, alpha, beta): d = d + 1 state = game.state() board = game.getGame() if state == 'K' or state == 'k' or state == 'tie' or d == 6: return heuristics(board) moves = ['U', 'D', 'L', 'R'] best_utility = float('-inf') for move in moves: clone = game.makeMove(move) utility = min_utility(clone, d, -float('inf'), float('inf')) if utility > best_utility: best_move = move best_utility = utility alpha = max(alpha, best_utility) if beta <= alpha: break return best_utility
def next_move(game: Game_IJK) -> None: '''board: list of list of strings -> current state of the game current_player: int -> player who will make the next move either ('+') or -'-') deterministic: bool -> either True or False, indicating whether the game is deterministic or not ''' global maxdepth board = game.getGame() player = game.getCurrentPlayer() deterministic = game.getDeterministic() # You'll want to put in your fancy AI code here. For right now this just # returns a random move. if deterministic == False: if countboard(board) > 8: maxdepth = 0 elif countboard(board) > 5: maxdepth = 1 else: maxdepth = 2 if player == '+': start = time.time() best_move, _ = maximizechance(game, board) end = time.time() print(start - end) yield (best_move) if player == '-': best_move, _ = minimizechance(game, board) yield (best_move) if deterministic == True: if player == "+": maxdepth = 7 best_move, _ = Max(game, board) yield (best_move) if player == "-": maxdepth = 7 best_move, _ = Min(game, board) yield (best_move)
def next_move(game: Game_IJK) -> None: '''board: list of list of strings -> current state of the game current_player: int -> player who will make the next move either ('+') or -'-') deterministic: bool -> either True or False, indicating whether the game is deterministic or not ''' board = game.getGame() player = game.getCurrentPlayer() deterministic = game.getDeterministic() if player == '+': Ismax = True else: Ismax = False depth = 5 if (deterministic == True): score, move = Mininax_AlphaBeta(board, depth, Ismax, -math.inf, math.inf, game) #print('MOVE', move, score) return move
def next_move(game: Game_IJK) -> None: '''board: list of list of strings -> current state of the game current_player: int -> player who will make the next move either ('+') or -'-') deterministic: bool -> either True or False, indicating whether the game is deterministic or not ''' board = game.getGame() player = game.getCurrentPlayer() deterministic = game.getDeterministic() # You'll want to put in your fancy AI code here. For right now this just # returns a random move. if (deterministic): depth = 6 else: depth = 0 mins = {} w = copy.deepcopy(game) w = w.makeMove('U') s = copy.deepcopy(game) s = w.makeMove('D') a = copy.deepcopy(game) a = w.makeMove('L') d = copy.deepcopy(game) d = w.makeMove('R') mins['U'] = MIN_Value(w, float("-inf"), float("inf"), depth, player) mins['D'] = MIN_Value(s, float("-inf"), float("inf"), depth, player) mins['L'] = MIN_Value(a, float("-inf"), float("inf"), depth, player) mins['R'] = MIN_Value(d, float("-inf"), float("inf"), depth, player) move = max(mins, key=lambda k: mins[k]) for i in range(6): for j in range(6): if (j + 1 < 6 and abs(ord(board[i][j + 1]) - ord(board[i][j])) == 32): move = 'R' elif (i + 1 < 6 and abs(ord(board[i + 1][j]) - ord(board[i][j])) == 32): move = 'D' yield move
def next_move(game: Game_IJK): '''board: list of list of strings -> current state of the game current_player: int -> player who will make the next move either ('+') or -'-') deterministic: bool -> either True or False, indicating whether the game is deterministic or not ''' board = game.getGame() player = game.getCurrentPlayer() deterministic = game.getDeterministic() # You'll want to put in your fancy AI code here. For right now this just # returns a random move. moves = ['U', 'D', 'L', 'R'] best_move = moves[0] best_utility = float('-inf') for move in moves: clone = game.makeMove(move) utility = min_utility(clone, 0, -float('inf'), float('inf')) if utility > best_utility: best_utility = utility best_move = move yield best_move
def next_move(game: Game_IJK) -> None: '''board: list of list of strings -> current state of the game current_player: int -> player who will make the next move either ('+') or -'-') deterministic: bool -> either True or False, indicating whether the game is deterministic or not ''' board = game.getGame() player = game.getCurrentPlayer() deterministic = game.getDeterministic() # Create an object of the class Node node = Node(copy.deepcopy(board), player, '') start = time.time() if deterministic: # if deterministic, then call minimax with alpha beta pruning result = minimax_alpha_beta(node, 9, player, NINF, PINF, deterministic, start) else: # if non-deterministic then call normal minimax as expectation is involved result = minimax(node, 6, player, deterministic, start) print(time.time() - start) print(result) return result[0]
def succesor_boards(max_player, game, board): moves = ['U', 'D', 'L', 'R'] succs = [] for move in moves: if max_player: new_game = Game_IJK(copy.deepcopy(board), "+", game.getDeterministic()) succ = new_game.makeMove(move) succs.append((move, succ.getGame())) else: new_game = Game_IJK(board, "-", game.getDeterministic()) succ = new_game.makeMove(move) succs.append((move, succ.getGame())) return succs
def chance_boards(max_player, game, board, move, empty_tiles): succs = [] for i in range(0, empty_tiles): if max_player: new_game = Game_IJK(copy.deepcopy(board), "+", game.getDeterministic()) succ = new_game.makeMove(move) succs.append((move, succ.getGame())) else: new_game = Game_IJK(copy.deepcopy(board), "-", game.getDeterministic()) succ = new_game.makeMove(move) succs.append((move, succ.getGame())) return succs
def next_move(game: Game_IJK) -> None: '''board: list of list of strings -> current state of the game current_player: int -> player who will make the next move either ('+') or -'-') deterministic: bool -> either True or False, indicating whether the game is deterministic or not ''' board = game.getGame() player = game.getCurrentPlayer() deterministic = game.getDeterministic() global current_index if deterministic: fringe = [board] count = 1 while len(fringe) >= 0 and count <= 85: board = fringe.pop(0) fringe += find_successors(board, player, deterministic) count += 1 list_mini_max = [] for i in fringe: list_mini_max.append(heuristic(i, player)) temp, temp1 = minimax(0, 0, True, list_mini_max, -1000, 1000) temp_dict = {0: 'L', 1: 'R', 2: 'U', 3: 'D'} yield temp_dict[temp1] else: # Tuple structure : Board, max=1/min=0/chance=-1, depth, Heuristic, parent, current node index, parent node index fringe = [(board, 1, 1, 0, "root", 0, 0)] fringe1 = [(board, 1, 1, 0, "root", 0, 0)] tree_depth = 4 empty_tiles = 1 board = fringe.pop(0) succ = [] current_index = 1 succ += find_successors1(board[0], player, board[2], deterministic, tree_depth, board[5]) for i in succ: fringe1.append(i) fringe.append(i) current_index += 1 chance_flag = 0 while len(fringe) > 0: fringe_temp = [] board = fringe.pop(0) if board[2] < tree_depth: if board[1] in [1, 0]: fringe_temp = [ chance_nodes for chance_nodes in find_chance( board[0], board[1], board[2], board[5]) ] fringe += fringe_temp fringe1 += fringe_temp chance_flag = board[1] else: fringe_temp += find_successors1(board[0], chance_flag, board[2], deterministic, tree_depth, board[5]) fringe += fringe_temp fringe1 += fringe_temp else: break count = expectiminimax(fringe1) dict = {0: 'L', 1: 'R', 2: 'U', 3: 'D'} yield dict[count]
def next_move(game: Game_IJK) -> None: '''board: list of list of strings -> current state of the game current_player: int -> player who will make the next move either ('+') or -'-') deterministic: bool -> either True or False, indicating whether the game is deterministic or not ''' board = game.getGame() MAX = float('inf') MIN = float('-inf') def calculate_empty_tiles(state): bonus = 0 for i in range(6): for j in range(6): if state[i][j] == 0: bonus = bonus + 1 return bonus def weighted_tiles(state): board_score = [ 6 * 35, 6 * 34, 6 * 33, 6 * 32, 6 * 31, 6 * 30, 6 * 24, 6 * 25, 6 * 26, 6 * 27, 6 * 28, 6 * 29, 6 * 23, 6 * 22, 6 * 21, 6 * 20, 6 * 19, 6 * 18, 6 * 12, 6 * 13, 6 * 14, 6 * 15, 6 * 16, 6 * 17, 6 * 11, 6 * 10, 6 * 9, 6 * 8, 6 * 7, 6 * 6, 6 * 0, 6 * 1, 6 * 2, 6 * 3, 6 * 4, 6 * 5 ] bonus = 0 for i in range(36): current_element = ord(state[i]) bonus = bonus + int(current_element) * int(board_score[i]) return bonus def convert_to_number(state): for i in range(0, 6): for j in range(0, 6): if state[i][j] == "A" or state[i][j] == "a": state[i][j] = 1 elif state[i][j] == "B" or state[i][j] == "b": state[i][j] = 2 elif state[i][j] == "C" or state[i][j] == "c": state[i][j] = 3 elif state[i][j] == "D" or state[i][j] == "d": state[i][j] = 4 elif state[i][j] == "E" or state[i][j] == "e": state[i][j] = 5 elif state[i][j] == "F" or state[i][j] == "f": state[i][j] = 6 elif state[i][j] == "G" or state[i][j] == "g": state[i][j] = 7 elif state[i][j] == "H" or state[i][j] == "h": state[i][j] = 8 elif state[i][j] == "I" or state[i][j] == "i": state[i][j] = 9 elif state[i][j] == "J" or state[i][j] == "j": state[i][j] = 10 elif state[i][j] == "K" or state[i][j] == "k": state[i][j] = 11 else: state[i][j] = 0 return state def calculate_monotonicity(state): bonus = 0 for i in range(6): row = state[i] for j in range(6): x = row[j] # now check left and right side of the element # call function to check the position of first non-zero number in right direction if state[i][j] != 0 and j != 5: for z in range(j + 1, 6): if state[i][z] != 0: index = z break elif z == 5 and state[i][z] == 0: index = z if x <= row[index] and row[index] != 0: bonus = bonus + 10 elif x > row[index] and row[index] != 0: bonus = bonus - 15 if x <= state[index][j]: bonus = bonus + 10 elif x > state[index][j]: bonus = bonus - 15 elif state[i][j] == 0: bonus = bonus + 0 if state[i][j] != 0 and i != 5: for z in range(i + 1, 6): if state[z][j] != 0: index = z break elif z == 5 and state[z][j] == 0: index = z index = i if x <= state[index][j] and state[index][j] != 0: bonus = bonus + 10 elif x > state[index][j] and state[index][j] != 0: bonus = bonus - 15 elif state[i][j] == 0: bonus = bonus + 0 return bonus def flattened(listt): flattened_list = [] for j in listt: for i in j: flattened_list.append(i) return flattened_list def calculate_smoothness(state): bonus = 0 for i in range(6): row = state[i] for j in range(6): x = row[j] if j != 5 and (x - state[i][j + 1]) <= 1: bonus = bonus + 5 if i != 5 and (x - state[i + 1][j]) <= 1: bonus = bonus + 5 return bonus def gt_mov(array): for i in range(len(array)): array[i] = list(array[i]) if i >= 0 and i < 64: array[i][1] = 'U' elif i >= 64 and i < 128: array[i][1] = 'D' elif i >= 128 and i < 192: array[i][1] = 'L' elif i >= 192 and i < 256: array[i][1] = 'R' return array def heuristic_containing_evrything(now, state): score = 0 state = convert_to_number(state) score1 = calculate_empty_tiles(state) * 100 #score2 = weighted_tiles(now) score3 = calculate_monotonicity(state) * 100 score4 = calculate_smoothness(state) * 200 score = score1 + score3 + score4 return score def successors(game1): moves = ['U', 'D', 'L', 'R'] successor_s = [] for i in moves: successor1 = game.makeMove(i) successor1 = successor1.getGame() successor_s.append((successor1, i)) return successor_s def parse_full(game1): for_first_depth = successors(game1) for_second_depth = [] for i in for_first_depth: for_second_depth.append(successors(i[0])) for_second_depth = flattened(for_second_depth) for_third_depth = [] for i in for_second_depth: for_third_depth.append(successors(i[0])) for_third_depth = flattened(for_third_depth) for_fourth_depth = [] for i in for_third_depth: for_fourth_depth.append(successors(i[0])) for_fourth_depth = flattened(for_fourth_depth) future_successors = [] possible_moves = [] for i in for_fourth_depth: future_successors.append(i[0]) possible_moves.append(i[1]) scores = calculate_score(future_successors) final = [] for i in range(len(scores)): final.append((scores[i], possible_moves[i])) final = gt_mov(final) return final def calculate_score(arrStates): scores = [] for i in arrStates: x = flattened(i) score = heuristic_containing_evrything(x, i) scores.append(score) return scores def mini_max_algo(depth, Index_of_node, maximizing_player, values, alpha, beta): if depth == 4: return values[Index_of_node][0], values[Index_of_node][1] if maximizing_player: best = MIN final_move = " " for i in range(0, 4): value, moves = mini_max_algo(depth + 1, Index_of_node * 4 + i, False, values, alpha, beta) if value > best: best = value final_move = moves alpha = max(alpha, best) if beta <= alpha: break return (best, final_move) else: best = MAX final_move = " " for i in range(0, 4): value, moves = mini_max_algo(depth + 1, Index_of_node * 4 + i, True, values, alpha, beta) if value < best: best = value final_move = moves beta = min(beta, best) if beta <= alpha: break return (best, final_move) final_s = parse_full(board) score, move = mini_max_algo(0, 0, True, final_s, MIN, MAX) yield move