def determineNextMove(playerLocation, opponentLocation, coins): global route, old_coins, playerScore, enemyScore u.update_dists_from_each(dists_matrix, route_matrix, playerLocation, mazeMap, coins) u.update_dists_from_each(dists_matrix, route_matrix, opponentLocation, mazeMap, coins + [playerLocation]) # Calculate our score and en score : if playerLocation in old_coins and playerLocation not in coins: playerScore += 1 if opponentLocation in old_coins and opponentLocation not in coins: enemyScore += 1 if len(route) == 0 or route[-1] not in coins or 1==1: winning_value, en_best_path, pl_best_path = minmax(coins, playerScore, 0, playerLocation, enemyScore, 0, opponentLocation) interface.debug("------------") interface.debug(pl_best_path) interface.debug(en_best_path) interface.debug("score of : " + str(winning_value)) route = route_matrix[playerLocation][pl_best_path[0]] # coins_which_are_close = coins_close(playerLocation, coins, dists_matrix, limit=2) # closest_coin = None # for coin in coins_which_are_close: # # If we don't already go there, and the enemy is not going there # if dists_matrix[playerLocation][coin] < dists_matrix[opponentLocation][coin]: # TODO : magic number, same : with the enemy # if closest_coin is None or dists_matrix[playerLocation][coin] < dists_matrix[playerLocation][closest_coin]: # closest_coin = coin # if closest_coin is not None: # pass # # route = route_matrix[playerLocation][closest_coin] # # interface.debug("NEAR : " + str(closest_coin)) old_coins = coins next_pos = route.pop(0) return u.direction(playerLocation, next_pos)
def minmax(coins_left, score_p1, len_path_p1, loc_p1, score_p2, len_path_p2, loc_p2): """Recursive search of the winning tree""" # At the end of the tree, return the value of the leaf if len(coins_left) == 0 or score_p2 > 5 or score_p1 > 5: return score_p1, [], [] # maximizing for p1 pl_last_coin = [] en_last_coin = [] best_pl_path = [] best_en_path = [] # Update the map data u.update_dists_from_each(dists_matrix, route_matrix, loc_p1, mazeMap, coins) u.update_dists_from_each(dists_matrix, route_matrix, loc_p2, mazeMap, coins + [loc_p1]) # Todo : this is not very dynamic, if the enemy goes to the coin I want ? if len_path_p1 <= len_path_p2: # MAXIMIZING player1 turn best_value = float('-inf') best_coin = get_closest_coin(loc_p1, coins_left, dists_matrix)[0] best_pl_path = [] en_closest_coin, en_closest_coin_dist = get_closest_coin(loc_p2, coins_left, dists_matrix) for coin in coins_left: new_len_path_p1 = len_path_p1 + dists_matrix[loc_p1][coin] loc_p1 = coin new_score_p1 = score_p1 + 1 new_coins_left = coins_left[:] new_coins_left.remove(coin) node_value, en_path, pl_path = minmax(new_coins_left, new_score_p1, new_len_path_p1, loc_p1, score_p2, len_path_p2, loc_p2) if node_value > best_value and (coin != en_closest_coin or dists_matrix[loc_p1][coin] <= en_closest_coin_dist): best_value = node_value best_coin = coin best_pl_path = pl_path best_en_path = en_path pl_last_coin = [best_coin] else: # MINIMIZING, player 2 is going to the closest coin closest_coin, closest_coin_dist = get_closest_coin(loc_p2, coins_left, dists_matrix) new_len_path_p2 = len_path_p2 + closest_coin_dist loc_p2 = closest_coin new_score_p2 = score_p2 + 1 new_coins_left = coins_left[:] new_coins_left.remove(closest_coin) node_value, en_path, pl_path = minmax(new_coins_left, score_p1, len_path_p1, loc_p1, new_score_p2, new_len_path_p2, loc_p2) best_value = node_value best_coin = closest_coin best_pl_path = pl_path best_en_path = en_path en_last_coin = [best_coin] en_path = en_last_coin + best_en_path pl_path = pl_last_coin + best_pl_path return best_value, en_path, pl_path
def determineNextMove(playerLocation, opponentLocation, coins): """Function called at each turn, must return the next move of the player""" global packages, dists, route_table, best_path, best_weight, current_package if playerLocation in current_package: current_package.remove(playerLocation) i1, i2, j1, j2 = find_players(packages, opponentLocation, playerLocation) if i1 >= 0: packages[i1].remove(packages[i1][i2]) if len(packages[i1]) == 0: packages.remove(packages[i1]) if j1 >= 0: api.debug(packages[j1]) packages[j1].remove(packages[j1][j2]) if len(packages[j1]) == 0: packages.remove(packages[j1]) if opponentLocation in current_package: dists, route_table = u.update_dists_from_each(dists, route_table, playerLocation, mazeMap, coins) if len(current_package) > 1: current_package.remove(opponentLocation) else: current_package = packages.pop(0) best_weight = float("inf") best_path = [] exhaustive(current_package, playerLocation, [], 0, (route_table, dists)) if len(best_path) == 0: packages = list( reversed( sorted( packages, key=lambda x: (len(x) + 3) / min([dists[playerLocation][c] for c in x])))) best_weight = float("inf") best_path = [] current_package = packages.pop(0) if len(current_package) == 1 and packages != []: current_package = current_package + packages.pop(0) exhaustive(current_package, playerLocation, [], 0, (route_table, dists)) return u.direction(playerLocation, best_path.pop(0))
def determineNextMove(playerLocation, opponentLocation, coins): """Function called at each turn, must return the next move of the player""" global packages, dists, route_table, best_path, best_weight, current_package if playerLocation in current_package: current_package.remove(playerLocation) i1,i2,j1,j2 = find_players(packages, opponentLocation, playerLocation) if i1 >= 0: packages[i1].remove(packages[i1][i2]) if len(packages[i1]) == 0: packages.remove(packages[i1]) if j1 >= 0: api.debug(packages[j1]) packages[j1].remove(packages[j1][j2]) if len(packages[j1]) == 0: packages.remove(packages[j1]) if opponentLocation in current_package: dists, route_table = u.update_dists_from_each(dists, route_table, playerLocation, mazeMap, coins) if len(current_package) > 1: current_package.remove(opponentLocation) else: current_package = packages.pop(0) best_weight = float("inf") best_path = [] exhaustive(current_package, playerLocation, [], 0, (route_table, dists)) if len(best_path) == 0: packages = list(reversed(sorted(packages, key=lambda x: (len(x)+3)/min([dists[playerLocation][c] for c in x])))) best_weight = float("inf") best_path = [] current_package = packages.pop(0) if len(current_package) == 1 and packages != []: current_package = current_package + packages.pop(0) exhaustive(current_package, playerLocation, [], 0, (route_table, dists)) return u.direction(playerLocation, best_path.pop(0))