def look_opponent_turn(board, bag, level, self_rack, opp_rack, accu, alpha, beta): #needs to take randomly from Bag global M, O, R, N #the value of a move is its score + future values needed_letters = 7 - len(opp_rack) min_future_score = float('inf') #the value of a move is its score + future values if len(bag) >= needed_letters: random_rack = opp_rack + bag[:needed_letters] bag = bag[needed_letters:] else: random_rack = opp_rack + bag next_moves = brie_search(board, random_rack, O) for move in next_moves: clean_board = copy.deepcopy(board) score = move["score"] move_score = accu - score word = move["word"] if word != "N/A": if move["direction"] == "horizontal": for i in range(len(word)): clean_board[move["Y"]][move["X"] + i] = word[i] else: for i in range(len(word)): clean_board[move["Y"] + i][move["X"]] = word[i] if level > 1: eval = look_self_turn(clean_board, bag, level - 1, self_rack, move["rack"], move_score, alpha, beta) else: eval = move_score if eval < min_future_score: min_future_score = eval # beta = min(beta, move_score) # # if beta <= alpha: # break return min_future_score
def find_best_moves(board, rack, other_rack, bag, player): global turn_counter, score_list turn_counter += 1 rack = rack.rack other_rack = other_rack.rack bag = bag.bag board = board.board if player.name == "Bot1": #best_move = BruteForce(board, rack) #best_move = look_ahead(board, rack, other_rack, bag) best_move = brie_search(board, rack, 1)[0] elif player.name == "Bot2": #best_move = BruteForce(board, rack) #best_move = look_ahead(board, rack, other_rack, bag) best_move = brie_search(board, rack, 1)[0] #best_move = end_game_search(board, rack, other_rack, bag) return best_move
def look_ahead(board, rack, other_rack, bag): global M, O, R, N #number of moves considered for player M = 5 #number of moves for opponent O = 1 #number of racks guessed R = 10 #number of turns in N = 1 unknown_tiles = other_rack + bag best_move = {"score": 0, "word": "N/A", "heuristic": -9999999999} next_moves = brie_search(board, rack, M) randomness = max(len(unknown_tiles) - 7, 1) for move in next_moves: #get future value for each move if move["word"] != "N/A": future_score = 0 for iterations in range(R): random.shuffle(unknown_tiles) alpha = float('inf') beta = float('-inf') future_score += move["score"] + ( look_opponent_turn(board, unknown_tiles, N, move["rack"], [], 0, alpha, beta) / randomness) if (future_score / R) > best_move["heuristic"]: best_move = { "score": move["score"], "word": move["word"], "X": move["X"], "Y": move["Y"], "direction": move["direction"], "heuristic": future_score / R } return best_move
def look_self_turn(board, bag, self_rack, opp_rack, accu, alpha, beta): #needs to take randomly from Bag global M, O, R, N needed_letters = 7 - len(self_rack) max_future_score = float('-inf') #the value of a move is its score + future values if len(bag) >= needed_letters: random_racks = list(combinations(bag, needed_letters)) else: random_racks = [tuple(bag)] average_accu = 0 for rack in random_racks: random_rack = self_rack + list(rack) remaining_letters = copy.deepcopy(bag) for letter in list(rack): remaining_letters.remove(letter) next_moves = brie_search(board, random_rack, M) for move in next_moves: word = move["word"] if word != "N/A": clean_board = copy.deepcopy(board) score = move["score"] move_score = accu + score if move["direction"] == "horizontal": for i in range(len(word)): clean_board[move["Y"]][move["X"] + i] = word[i] else: for i in range(len(word)): clean_board[move["Y"] + i][move["X"]] = word[i] eval = look_opponent_turn(clean_board, remaining_letters, move["rack"], opp_rack, move_score, alpha, beta) else: eval = accu if eval > max_future_score: max_future_score = eval average_accu += max_future_score # alpha = max(alpha, move_score) # # if beta <= alpha: # break return average_accu / len(random_racks)
def end_game_search(board, rack, other_rack, bag): global M, O, R, N #number of moves considered for player M = 10 #number of moves for opponent O = 10 unknown_tiles = other_rack + bag best_move = {"score": 0, "word": "N/A", "heuristic": float('-inf')} next_moves = brie_search(board, rack, M) leftover_tiles = len(unknown_tiles) if leftover_tiles > 8: return next_moves[-1] else: opp_racks = list(combinations(unknown_tiles, min(7, leftover_tiles))) for move in next_moves: clean_board = copy.deepcopy(board) word = move["word"] if move["word"] != "N/A": if move["direction"] == "horizontal": for i in range(len(word)): clean_board[move["Y"]][move["X"] + i] = word[i] else: for i in range(len(word)): clean_board[move["Y"] + i][move["X"]] = word[i] future_score = 0 i = 0 for opp_rack in opp_racks: i += 1 #try different combos of opponent racks remaining_letters = copy.deepcopy(unknown_tiles) for letter in list(opp_rack): remaining_letters.remove(letter) #get future value for each move if move["word"] != "N/A": alpha = float('inf') beta = float('-inf') future_score += move["score"] + look_opponent_turn( clean_board, remaining_letters, move["rack"], list(opp_rack), 0, alpha, beta) if move["word"] != "N/A": if future_score > best_move["heuristic"]: best_move = { "score": move["score"], "word": move["word"], "X": move["X"], "Y": move["Y"], "direction": move["direction"], "heuristic": future_score } return best_move