def place_stores(self, slmap: SiteLocationMap,
                     store_locations: Dict[int, List[Store]],
                     current_funds: float):
        global count
        count += 1
        store_conf = self.config['store_config']
        num_rand = 100

        sample_pos = []
        for i in range(num_rand):
            x = random.randint(0, slmap.size[0])
            y = random.randint(0, slmap.size[1])
            sample_pos.append((x, y))
        # Choose largest store type possible:
        if current_funds >= store_conf['large']['capital_cost']:
            store_type = 'large'
        elif current_funds >= store_conf['medium']['capital_cost']:
            store_type = 'medium'
        else:
            store_type = 'small'

        best_score = 0
        best_pos = []
        for pos in sample_pos:
            sample_store = Store(pos, store_type)
            temp_store_locations = copy.deepcopy(store_locations)
            temp_store_locations[self.player_id].append(sample_store)
            if count < 9:
                sample_alloc = attractiveness_allocation(slmap, temp_store_locations, store_conf)
                sample_score = (sample_alloc[self.player_id] * slmap.population_distribution).sum()
            else:
                sample_alloc = closest_store_allocation(slmap, temp_store_locations, store_conf)
                sample_score = (sample_alloc[self.player_id] * slmap.population_distribution).sum()
            if sample_score > best_score:
                best_score = sample_score
                best_pos = [pos]
            elif sample_score == best_score:
                best_pos.append(pos)

        # max_alloc_positons = np.argwhere(alloc[self.player_id] == np.amax(alloc[self.player_id]))
        # pos = random.choice(max_alloc_positons)
        pos1 = random.choice(best_pos)
        if count <= 8:
            self.stores_to_place = [Store(random.choice(best_pos), store_type)]
        else:
            temp_current_funds = current_funds - store_conf[store_type]['capital_cost']
            print(' ')
            print(temp_current_funds)
            print(' ')
            if temp_current_funds >= store_conf['large']['capital_cost']:
                store_type_2 = 'large'
            elif temp_current_funds >= store_conf['medium']['capital_cost']:
                store_type_2 = 'medium'
            else:
                store_type_2 = 'small'

            pos2 = random.choice(best_pos)
            self.stores_to_place = [Store(pos1, store_type), Store(pos2, store_type_2)]
            return
    def place_stores(
        self,
        slmap: SiteLocationMap,
        store_locations: Dict[int, List[Store]],
        current_funds: float,
    ):
        store_conf = self.config["store_config"]
        step_size = 20
        all_sample_pos = []

        x_pos = np.arange(0, slmap.size[0], step_size) + int(step_size / 2)
        y_pos = np.arange(0, slmap.size[1], step_size) + int(step_size / 2)
        for i in range(len(x_pos)):
            x = x_pos[i]
            for j in range(len(y_pos)):
                y = y_pos[j]
                all_sample_pos.append((x, y))

        # sample_pos = random.sample(all_sample_pos, 200)
        sample_pos = all_sample_pos

        # Choose largest store type possible:
        if current_funds >= store_conf["large"]["capital_cost"]:
            store_type = "large"
        elif current_funds >= store_conf["medium"]["capital_cost"]:
            store_type = "medium"
        else:
            store_type = "small"

        best_score = 0
        best_pos = []

        attractiveness_by_player = all_players_attractiveness_allocation(
            slmap, store_locations, store_conf)

        for pos in sample_pos:
            sample_store = Store(pos, store_type)
            temp_store_locations = copy.deepcopy(store_locations)
            temp_store_locations[self.player_id].append(sample_store)

            temp_attractiveness_by_player = copy.deepcopy(
                attractiveness_by_player)

            sample_player_alloc = player_attractiveness_allocation(
                temp_store_locations[self.player_id], slmap, store_conf)
            temp_attractiveness_by_player[self.player_id] = sample_player_alloc
            sample_alloc = normalized_attractiveness_allocation(
                slmap, temp_store_locations, temp_attractiveness_by_player)
            sample_score = (sample_alloc[self.player_id] *
                            slmap.population_distribution).sum()
            if sample_score > best_score:
                best_score = sample_score
                best_pos = [pos]
            elif sample_score == best_score:
                best_pos.append(pos)

        self.stores_to_place = [Store(random.choice(best_pos), store_type)]
        return
Example #3
0
    def place_stores(self, slmap: SiteLocationMap,
                     store_locations: Dict[int,
                                           List[Store]], current_funds: float):
        store_conf = self.config['store_config']
        sample_pos = []

        # Choose largest store type possible:
        if current_funds >= store_conf['large']['capital_cost']:
            store_type = 'large'
        elif current_funds >= store_conf['medium']['capital_cost']:
            store_type = 'medium'
        else:
            store_type = 'small'

        #try to delete all taken points and radius?
        # use store_locations
        # store_conf[store_type]['attractiveness']
        coords = [(x, y) for x in range(20) for y in range(20)]
        all_stores_pos = []
        for player, player_stores in store_locations.items():
            for player_store in player_stores:
                all_stores_pos.append(player_store.pos)
                # need to add radius
                r = store_conf[store_type]['attractiveness']
                radcircle = player_store.pos[0]**2 + player_store.pos[1]**2
                a = np.array(coord)
                b = np.where(radcircle < r)

        sample_pos = set(coords).symmetric_difference(all_stores_pos)
        #print ("sample pos: ",sample_pos)

        best_score = 0
        best_pos = []
        for pos in sample_pos:
            sample_store = Store(pos, store_type)
            temp_store_locations = copy.deepcopy(store_locations)
            temp_store_locations[self.player_id].append(sample_store)
            sample_alloc = attractiveness_allocation(slmap,
                                                     temp_store_locations,
                                                     store_conf)
            sample_score = (sample_alloc[self.player_id] *
                            slmap.population_distribution).sum()
            if sample_score > best_score:
                best_score = sample_score
                best_pos = [pos]
            elif sample_score == best_score:
                best_pos.append(pos)
        print("best pos: " + str(best_pos))

        # max_alloc_positons = np.argwhere(alloc[self.player_id] == np.amax(alloc[self.player_id]))
        # pos = random.choice(max_alloc_positons)
        self.stores_to_place = [Store(random.choice(best_pos), store_type)]
        return
    def place_stores(self, slmap, store_locations, current_funds):
        self.round += 1

        if self.round > self.ACTIVE_ROUND_COUNT:
            return

        store_config = self.config['store_config']

        store_types = []

        while True:
            for store_type, store in sorted(
                    store_config.items(),
                    key=lambda item: -item[1]['capital_cost']):
                if current_funds >= store['capital_cost']:
                    store_types.append(store_type)
                    current_funds -= store['capital_cost']
                    break
            else:
                break

            if len(store_types) == self.config['max_stores_per_round']:
                break

        poss = []
        attractivenesses = {}

        for _ in range(self.SAMPLE_COUNT):
            x, y = randrange(0, slmap.size[0]), randrange(0, slmap.size[1])
            poss.append((x, y))

        poss = sorted(poss,
                      key=lambda key: -slmap.population_distribution[key]
                      )[:self.FILTER_COUNT]

        for x, y in poss:
            attractivenesses[x, y] = self.get_attractiveness_allocation(
                slmap, store_locations, store_config, Store((x, y), 'small'))

        poss.sort(key=lambda key: attractivenesses[key])

        stores = []

        for store_type in store_types:
            if self.round > 1:
                pos = poss.pop()
            else:
                pos = poss.pop(int(len(poss) * self.FIRST_TARGET))

            store = Store(pos, store_type)
            stores.append(store)

        self.stores_to_place = stores
    def place_stores(self, slmap: SiteLocationMap,
                     store_locations: Dict[int, List[Store]],
                     current_funds: float):
        store_conf = self.config['store_config']
        # Configurable minimum distance away to place store
        min_dist = 50
        # Check if it can buy any store at all
        if current_funds < store_conf['small']['capital_cost']:
            self.stores_to_place = []
            return
        # Choose largest store type possible
        if current_funds >= store_conf['large']['capital_cost']:
            store_type = 'large'
        elif current_funds >= store_conf['medium']['capital_cost']:
            store_type = 'medium'
        else:
            store_type = 'small'
        # Find highest population location
        all_stores_pos = []
        for player, player_stores in store_locations.items():
            for player_store in player_stores:
                all_stores_pos.append(player_store.pos)

        sorted_indices = tuple(map(tuple, np.dstack(
            np.unravel_index(np.argsort(slmap.population_distribution.ravel()), slmap.size))[0][::-1]))
        for max_pos in sorted_indices:
            too_close = False
            for pos in all_stores_pos:
                dist = np.sqrt(np.square(max_pos[0] - pos[0]) + np.square(max_pos[1] - pos[1]))
                if dist < min_dist:
                    too_close = True
            if not too_close:
                self.stores_to_place = [Store(max_pos, store_type)]
                return
    def find_store_placement(
        self,
        store_type: str,
        step_size: int,
        slmap: SiteLocationMap,
        store_locations: Dict[int, List[Store]],
    ):
        store_conf = self.config["store_config"]

        attractiveness = player_attractiveness_allocation(
            store_locations[self.player_id], slmap, store_conf)

        potential = (1 - attractiveness / 100) * slmap.population_distribution

        grid_size = (
            self.config["map_size"][0] // step_size,
            self.config["map_size"][1] // step_size,
        )

        potential_average = np.zeros(grid_size)
        for i in range(grid_size[0]):
            for j in range(grid_size[1]):
                sub_grid = potential[i * step_size:(i + 1) * step_size,
                                     j * step_size:(j + 1) * step_size, ]
                potential_average[i][j] = sub_grid.mean()

        sorted_potential_average_indices = np.dstack(
            np.unravel_index(
                np.argsort(-potential_average.ravel()),
                potential_average.shape,
            ))[0]

        # Find the first block that we don't have a store already in
        our_stores_pos = [(store.store_type, np.array(store.pos))
                          for store in store_locations[self.player_id]]

        min_dists = {}
        store_sizes = ["small", "medium", "large"]
        for size1, size2 in itertools.product(store_sizes, store_sizes):
            min_dists[(size1,
                       size2)] = (store_conf[size1]["attractiveness"] +
                                  store_conf[size2]["attractiveness"]) / 2

        for block_position in sorted_potential_average_indices:
            # Convert block positions back to map positions (at the center of each block)
            map_position = block_position * step_size + step_size // 2
            too_close = False

            for other_store_type, other_pos in our_stores_pos:
                dist = np.linalg.norm(other_pos - map_position)
                # Allow some overlap of radaii
                if dist < min_dists[(store_type, other_store_type)] * 0.7:
                    too_close = True
                    break

            if not too_close:
                return Store((map_position[0], map_position[1]), store_type)

        return None
    def find_store_placement(
        self,
        store_type,
        sample_pos,
        current_funds,
        slmap,
        store_locations,
    ):

        store_cost = self.config["store_config"][store_type]["capital_cost"]
        store_maintenance = self.config["store_config"][store_type][
            "operating_cost"]

        if current_funds < store_cost:
            return -np.inf, None

        attractiveness_by_player = all_players_attractiveness_allocation(
            slmap, store_locations, self.config["store_config"])

        current_alloc = normalized_attractiveness_allocation(
            slmap, store_locations, attractiveness_by_player)
        current_score = (current_alloc[self.player_id] *
                         slmap.population_distribution
                         ).sum() * self.config["profit_per_customer"]

        best_score = 0.0
        best_store = None

        for pos in sample_pos:
            sample_store = Store(pos, store_type)
            temp_store_locations = copy.deepcopy(store_locations)
            temp_store_locations[self.player_id].append(sample_store)

            sample_player_alloc = player_attractiveness_allocation(
                temp_store_locations[self.player_id],
                slmap,
                self.config["store_config"],
            )
            attractiveness_by_player[self.player_id] = sample_player_alloc

            total_attractiveness = calculate_total_attractiveness(
                slmap, temp_store_locations, attractiveness_by_player)

            sample_alloc = (attractiveness_by_player[self.player_id] /
                            total_attractiveness)

            sample_score = (sample_alloc * slmap.population_distribution
                            ).sum() * self.config["profit_per_customer"]

            delta_score = sample_score - current_score
            if delta_score > store_cost * 0.33:
                if sample_score > best_score:
                    best_score = sample_score
                    best_store = sample_store

        delta_score = best_score - current_score
        print("Delta Score for {}: {:.0f}".format(store_type, delta_score))

        return best_score, best_store
    def find_store_placement(
        self,
        store_types,
        sample_pos,
        current_funds,
        slmap,
        store_locations,
        config,
        player_id,
    ):
        best_scores = []
        best_positions = []
        for i in range(len(store_types)):
            best_scores.append([])
            best_positions.append([])

        attractiveness_by_player = all_players_attractiveness_allocation(
            slmap, store_locations, config["store_config"])

        current_alloc = normalized_attractiveness_allocation(
            slmap, store_locations, attractiveness_by_player)
        current_score = (current_alloc[player_id] *
                         slmap.population_distribution
                         ).sum() * config["profit_per_customer"]

        for i in range(len(store_types)):
            store_type = store_types[i]
            store_cost = config["store_config"][store_type]["capital_cost"]
            store_maintenance = config["store_config"][store_type][
                "operating_cost"]

            if current_funds < store_cost:
                continue
            for pos in sample_pos:
                sample_store = Store(pos, store_type)
                temp_store_locations = copy.deepcopy(store_locations)
                temp_store_locations[player_id].append(sample_store)

                temp_attractiveness_by_player = copy.deepcopy(
                    attractiveness_by_player)

                sample_player_alloc = player_attractiveness_allocation(
                    temp_store_locations[player_id], slmap,
                    config["store_config"])
                temp_attractiveness_by_player[player_id] = sample_player_alloc
                sample_alloc = normalized_attractiveness_allocation(
                    slmap, temp_store_locations, temp_attractiveness_by_player)
                sample_score = (sample_alloc[player_id] *
                                slmap.population_distribution
                                ).sum() * config["profit_per_customer"]

                delta_score = sample_score - current_score
                if delta_score > store_cost * 0.33:
                    best_scores[i].append(sample_score)
                    best_positions[i].append(pos)

        return best_scores, best_positions
    def place_stores(
        self,
        slmap: SiteLocationMap,
        store_locations: Dict[int, List[Store]],
        current_funds: float,
    ):
        store_conf = self.config["store_config"]
        num_rand = 100

        sample_pos = []
        for i in range(num_rand):
            x = random.randint(0, slmap.size[0])
            y = random.randint(0, slmap.size[1])
            sample_pos.append((x, y))
        # Choose largest store type possible:
        if current_funds >= store_conf["large"]["capital_cost"]:
            store_type = "large"
        elif current_funds >= store_conf["medium"]["capital_cost"]:
            store_type = "medium"
        else:
            store_type = "small"

        best_score = 0
        best_pos = []
        for pos in sample_pos:
            sample_store = Store(pos, store_type)
            temp_store_locations = copy.deepcopy(store_locations)
            temp_store_locations[self.player_id].append(sample_store)
            sample_alloc = attractiveness_allocation(slmap,
                                                     temp_store_locations,
                                                     store_conf)
            sample_score = (sample_alloc[self.player_id] *
                            slmap.population_distribution).sum()
            if sample_score > best_score:
                best_score = sample_score
                best_pos = [pos]
            elif sample_score == best_score:
                best_pos.append(pos)

        # max_alloc_positons = np.argwhere(alloc[self.player_id] == np.amax(alloc[self.player_id]))
        # pos = random.choice(max_alloc_positons)
        self.stores_to_place = [Store(random.choice(best_pos), store_type)]
        return
Example #10
0
 def place_stores(self, slmap: SiteLocationMap,
                  store_locations: Dict[int,
                                        List[Store]], current_funds: float):
     stores = []
     for _ in range(self.config["max_stores_per_round"]):
         store_types = list(self.config["store_config"].keys())
         store = Store((random.randrange(
             0, slmap.size[0]), random.randrange(0, slmap.size[1])),
                       random.choice(store_types))
         stores.append(store)
     self.stores_to_place = stores
    def place_stores(self, slmap: SiteLocationMap,
                     store_locations: Dict[int,
                                           List[Store]], current_funds: float):
        store_conf = self.config['store_config']
        num_rand = 100

        #Array of all stores
        all_stores_pos = []
        for player, player_stores in store_locations.items():
            for player_store in player_stores:
                all_stores_pos.append(player_store.pos)

#instead of randomly choosing, choose locations with largest population
        sample_pos = []

        #count number of stores to track round and increase min_dist
        num_stores = len(store_locations[self.player_id])
        min_dist = 50
        our_stores = store_locations[self.player_id]

        #sorted population density from highest to lowest
        sorted_indices = tuple(
            map(
                tuple,
                np.dstack(
                    np.unravel_index(
                        np.argsort(slmap.population_distribution.ravel()),
                        slmap.size))[0][::-1]))

        counter = 0
        for max_pos in sorted_indices:
            if counter >= num_rand:
                break
            too_close = False
            for store in our_stores:
                dist = np.sqrt(
                    np.square(max_pos[0] - store.pos[0]) +
                    np.square(max_pos[1] - store.pos[1]))
                if store.store_type == 'small':
                    min_dist = 25
                elif store.store_type == 'medium':
                    min_dist = 50
                else:
                    min_dist = 100

                if dist < min_dist:
                    too_close = True
            if not too_close:
                counter = counter + 1
                sample_pos.append((max_pos[0], max_pos[1]))

        # Choose largest store type possible:

        if current_funds >= store_conf['large']['capital_cost']:
            remaining_funds = current_funds - 100000
            store_type = 'large'
            min_dist = 100
        elif current_funds >= store_conf['medium']['capital_cost']:
            remaining_funds = current_funds - 50000
            store_type = 'medium'
            min_dist = 50
        else:
            remaining_funds = current_funds - 10000
            store_type = 'small'
            min_dist = 25

        best_score = 0
        best_pos = []
        for pos in sample_pos:
            sample_store = Store(pos, store_type)
            temp_store_locations = copy.deepcopy(store_locations)
            temp_store_locations[self.player_id].append(sample_store)
            sample_alloc = attractiveness_allocation(slmap,
                                                     temp_store_locations,
                                                     store_conf)
            sample_score = (sample_alloc[self.player_id] *
                            slmap.population_distribution).sum()
            if sample_score > best_score:
                best_score = sample_score
                best_pos = [pos]
            elif sample_score == best_score:
                best_pos.append(pos)

        # max_alloc_positons = np.argwhere(alloc[self.player_id] == np.amax(alloc[self.player_id]))
        # pos = random.choice(max_alloc_positons)
        first_store = Store(best_pos[0], store_type)
        self.stores_to_place = [first_store]

        for next_best_pos in best_pos:
            dist = np.sqrt(
                np.square(next_best_pos[0] - first_store.pos[0]) +
                np.square(next_best_pos[1] - first_store.pos[1]))
            if dist > min_dist:
                if current_funds >= remaining_funds + 10000:
                    second_store_type = 'small'
                    second_store = Store(next_best_pos, second_store_type)
                    self.stores_to_place.append(second_store)
                    return

        for pos in sample_pos:
            dist = np.sqrt(
                np.square(pos[0] - first_store.pos[0]) +
                np.square(pos[1] - first_store.pos[1]))
            if dist > min_dist:
                if current_funds >= remaining_funds + 10000:
                    second_store_type = 'small'
                    second_store = Store(pos, second_store_type)
                    self.stores_to_place.append(second_store)
                    return

        return
Example #12
0
    def place_stores(self, slmap: SiteLocationMap,
                     store_locations: Dict[int,
                                           List[Store]], current_funds: float):

        self.stores_to_place = []

        # Check if it can buy any store at all
        if current_funds < store_conf['small']['capital_cost']:
            return

        # Find highest population location and my stores
        all_stores_pos = []
        all_my_stores = []
        for player, player_stores in store_locations.items():
            for player_store in player_stores:
                all_stores_pos.append(player_store.pos)
            if player.player_id == self.player_id:
                all_my_stores = player_stores

        sorted_indices = tuple(
            map(
                tuple,
                np.dstack(
                    np.unravel_index(
                        np.argsort(slmap.population_distribution.ravel()),
                        slmap.size))[0][::-1]))
        f = open(os.path.join(dirname, "record.txt"), "w")
        log.warning("sorted_indices: {sorted_indices}")
        f.close()
        for max_pos in sorted_indices:
            # Find the store with the max_pos
            target_store_type = ''
            for player, player_stores in store_locations.items():
                for player_store in player_stores:
                    if player_store.pos == max_pos:
                        target_store_type = player_store.store_type
                        break
                break
            log.info('target_store_type: {target_store_type}')
            # Check whether we have enough fund - Choose largest store type possible
            enough_fund = False
            if current_funds >= store_conf['large']['capital_cost']:
                store_type = 'large'
            elif current_funds >= store_conf['medium']['capital_cost']:
                store_type = 'medium'
            else:
                store_type = 'small'

            if store_type < target_store_type:
                log.info("enough fund: {enough_fund}")
                enough_fund = True
            else:
                continue

            # Check if current pos is too close to our existing stores
            too_close = False
            # Configurable minimum distance away to place store
            min_dist = store_conf[store_type]['attractiveness']
            for my_store in all_my_stores:
                min_dist += store_conf[my_store.store_type]['attractiveness']
                dist = np.sqrt(
                    np.square(max_pos[0] - pos[0]) +
                    np.square(max_pos[1] - pos[1]))
                if dist < min_dist:
                    too_close = True
                    break
            log.warn(f"too_close {too_close}")
            if too_close:
                continue

            # Check possible revenue - TODO

            if len(self.stores_to_place) < 2:
                self.stores_to_place.append(Store(max_pos, store_type))
            else:
                break

            def calculate_profit(
                self,
                slmap: SiteLocationMap,
                store_locations: Dict[int, List[Store]],
                current_funds: float,
                sample: Store,
            ):
                cost = self.config["store_config"][
                    sample.store_type]["capital_cost"] * 1.5
                sample_alloc = attractiveness_allocation(
                    slmap, temp_store_locations, store_conf)
                temp_store_locations = copy.deepcopy(store_locations)
                temp_store_locations[self.player_id].append(sample_store)
                sample_alloc = attractiveness_allocation(
                    slmap, temp_store_locations, store_conf)
                sample_score = (sample_alloc[self.player_id] *
                                slmap.population_distribution
                                ).sum() * self.config["profit_per_customer"]
                if sample_score > cost:
                    return True
                return False
    def place_stores(
        self,
        slmap: SiteLocationMap,
        store_locations: Dict[int, List[Store]],
        current_funds: float,
    ):
        store_conf = self.config["store_config"]

        # Check if any stores can be bought at all
        if current_funds < store_conf["small"]["capital_cost"]:
            self.stores_to_place = []
            return

        all_stores_pos = []
        for player, player_stores in store_locations.items():
            for player_store in player_stores:
                all_stores_pos.append(np.array(player_store.pos))

        # Sort store positions by highest population density
        if self.sorted_density_indices is None:
            self.sorted_density_indices = np.dstack(
                np.unravel_index(
                    np.argsort(slmap.population_distribution.ravel()),
                    slmap.size))[0][::-1]

        store_type = "small"
        for _store_type in ["medium", "large"]:
            if current_funds >= store_conf[_store_type]["capital_cost"]:
                store_type = _store_type
            else:
                break

        # Filter positions that are too close to other stores
        min_dist = store_conf[store_type]["attractiveness"]
        num_positions_to_consider = 100
        legal_indices = []

        if all_stores_pos:
            for pos in self.sorted_density_indices:
                too_close = False
                for nearby_pos in all_stores_pos:
                    dist = np.linalg.norm(pos - nearby_pos)
                    if dist < min_dist:
                        too_close = True
                        break
                if not too_close:
                    legal_indices.append(tuple(pos))
                    if len(legal_indices) == num_positions_to_consider:
                        break
        else:
            # Account for no stores
            legal_indices = list(
                map(tuple,
                    self.sorted_density_indices))[:num_positions_to_consider]

        attractiveness_by_player = all_players_attractiveness_allocation(
            slmap, store_locations, store_conf)

        best_score = 0.0
        self.stores_to_place = []

        for pos in legal_indices:
            sample_store = Store(pos, store_type)
            temp_store_locations = copy.deepcopy(store_locations)
            temp_store_locations[self.player_id].append(sample_store)

            temp_attractiveness_by_player = copy.deepcopy(
                attractiveness_by_player)

            sample_player_alloc = player_attractiveness_allocation(
                temp_store_locations[self.player_id], slmap, store_conf)
            temp_attractiveness_by_player[self.player_id] = sample_player_alloc
            sample_alloc = normalized_attractiveness_allocation(
                slmap, temp_store_locations, temp_attractiveness_by_player)
            sample_score = (sample_alloc[self.player_id] *
                            slmap.population_distribution).sum()

            if sample_score > best_score:
                best_score = sample_score
                self.stores_to_place = [sample_store]

        if not self.stores_to_place:
            # Place the most expensive store we can afford
            for store_type in {"small", "medium", "large"}:
                if current_funds <= store_conf[store_type]["capital_cost"]:
                    self.stores_to_place = [
                        Store(legal_indices[0], store_type)
                    ]
                else:
                    break
    def place_stores(
        self,
        slmap: SiteLocationMap,
        store_locations: Dict[int, List[Store]],
        current_funds: float,
    ):
        store_conf = self.config["store_config"]
        step_size = 20
        all_sample_pos = []

        # Partitions into grid and only takes boxes with population density over the mean + std
        half_window = int(step_size / 2)
        x_pos = np.arange(0, slmap.size[0], step_size) + half_window
        y_pos = np.arange(0, slmap.size[1], step_size) + half_window
        low_density_count = 0
        for i in range(len(x_pos)):
            x = x_pos[i]
            for j in range(len(y_pos)):
                y = y_pos[j]

                x += np.random.randint(-2, 2 + 1)
                y += np.random.randint(-2, 2 + 1)
                population_density = slmap.population_distribution[
                    x - half_window:x + half_window,
                    y - half_window:y + half_window]
                if (population_density.mean() <
                        slmap.population_distribution.mean() +
                        slmap.population_distribution.std()):
                    low_density_count += 1
                    continue

                all_sample_pos.append((x, y))

        # print("Grid Count:", len(x_pos) * len(y_pos) - low_density_count)

        # sample_pos = random.sample(all_sample_pos, 200)
        sample_pos = all_sample_pos

        self.stores_to_place = []
        temp_store_locations = copy.deepcopy(store_locations)
        for i in range(2):
            store_types = ["small", "medium", "large"]
            all_best_scores, all_best_positions = self.find_store_placement(
                store_types,
                sample_pos,
                current_funds,
                slmap,
                temp_store_locations,
                self.config,
                self.player_id,
            )

            best_scores = []
            best_positions = []
            for i in range(len(all_best_scores)):
                if len(all_best_scores[i]) > 0:
                    best_score = np.array(all_best_scores[i])

                    acceptable_scores = []
                    positions = []
                    threshold = best_score.max() * 0.90
                    for j in range(len(best_score)):
                        if best_score[j] > threshold:
                            acceptable_scores.append(best_score[j])
                            positions.append(all_best_positions[i][j])
                    index = np.random.randint(len(acceptable_scores))
                    best_scores.append(acceptable_scores[index])
                    best_positions.append(positions[index])

            try:
                # import pdb; pdb.set_trace()
                best_index = np.argmax(best_scores)
                best_pos = [best_positions[best_index]]
                store_type = store_types[best_index]
                self.stores_to_place.append(
                    Store(random.choice(best_pos), store_type))
            except:
                return

            current_funds -= store_conf[store_type]["capital_cost"]
            sample_store = Store(random.choice(best_pos), store_type)
            temp_store_locations[self.player_id].append(sample_store)

        return
    def place_stores(self, slmap: SiteLocationMap, 
                     store_locations: Dict[int, List[Store]],
                     current_funds: float):

      store_conf = self.config['store_config']
      
      #1 ------------ build q table  --------------------
      #find num stores on map
      num_stores=0
      for player, player_stores in store_locations.items():
        num_stores= num_stores + len(player_stores)
      print ("num stores",num_stores) 
      
      # read choices and top_10
      file = open(os.path.join(os.path.dirname(__file__),"data/Q_player_current_data.txt"),"r")
      lines = file.readlines()
      if (lines!= []):
        indicies=lines[0].split(" ")
        build_q_table(indicies[0], indicies[1], num_stores, current_funds) #for previous round
      file.close()
     
      #2 -----Find list of best choices randomly---
      #NEEED STORE TYPE
      # Choose largest store type possible:
      if current_funds >= store_conf['large']['capital_cost']:
          store_type = 'large'
      elif current_funds >= store_conf['medium']['capital_cost']:
          store_type = 'medium'
      else:
          store_type = 'small'

      #random 100 and find score
      sample_pos_and_scores = []
      num_rand = 100
      attractives=[]
      for i in range(num_rand):
        x = random.randint(0, slmap.size[0])
        y = random.randint(0, slmap.size[1])
        pos=(x,y)
        sample_store = Store(pos, store_type)
        temp_store_locations = copy.deepcopy(store_locations)
        temp_store_locations[self.player_id].append(sample_store)
        sample_alloc = attractiveness_allocation(slmap, temp_store_locations, store_conf)
        sample_score = (sample_alloc[self.player_id] * slmap.population_distribution).sum()
        sample_pos_and_scores.append((pos,sample_score))

      #sort and find max 10
      sorted_list=sorted(sample_pos_and_scores,key=lambda x: x[1], reverse=True)
      end=9
      top_10= sorted_list[:end]
      '''
      #throw away points that are in store_type range from each other
      indicies=[]
      for i in range(0, len(top_10)):
        for j in range(0, len(top_10)):
          if j not in indicies:
            distance=euclidean_distance(top_10[i][0], top_10[j][0])
            if (distance < store_conf[store_type]['attractiveness']/2):
              indicies.append(j)
              break #look at next pair 
 
      #remove indicies
      end=end+1
      for idx in indicies:
        top_10.pop(idx)
        top_10.append(sorted_list[end])
        end=end+1
      '''
      #print (top_10) #tuple of a tuple  
      
      #3 - randomly choose 2 stores- temporary
      choices = random.sample(top_10, 2)
      index1 = top_10.index(choices[0])
      index2 = top_10.index(choices[1])

      # write choices and top_10
      f = open(os.path.join(os.path.dirname(__file__),"data/Q_player_current_data.txt"),"w")
      f.write (str(index1) +' '+ str(index2))
      f.close()

      #4 - make selection
      # sample_score <- close to each other, not give right value, doesn't account for overlap
      if choices[0][1]+ choices[1][1] > current_funds: 
        print("only 1") 
        #make most attractive selection
        if (choices[0][1]>=choices[1][1]):
          self.stores_to_place = [Store(choices[0][0], store_type)]
        else:
          self.stores_to_place = [Store(choices[1][0], store_type)]
      else: #make both selections
          print("both")
          selection.append(Store(choices[0][0], store_type))
          selection.append(Store(choices[1][0], store_type))
          self.stores_to_place = selection
      return
    def place_stores(self, slmap: SiteLocationMap, 
                     store_locations: Dict[int, List[Store]],
                     current_funds: float):

      store_conf = self.config['store_config']

      #1-----find store type---
      #NEEED STORE TYPE
      # Choose largest store type possible:
      if current_funds >= store_conf['large']['capital_cost']:
          store_type = 'large'
      elif current_funds >= store_conf['medium']['capital_cost']:
          store_type = 'medium'
      else:
          store_type = 'small'
      
      #2-----Find the attractiveness values---
      sample_pos = []
      num_stores = 0
      for player, player_stores in store_locations.items():
        num_stores= num_stores + len(player_stores)
      if num_stores < 2:
        for i in range(400):
            x = random.randint(0, slmap.size[0])
            y = random.randint(0, slmap.size[1])
            sample_pos.append((x,y))
      else:
        for i in range(100):
            x = random.randint(0, slmap.size[0])
            y = random.randint(0, slmap.size[1])
            sample_pos.append((x,y))

      best_score = 0
      _pos = []
      best_pos = []
      score = []
      for pos in sample_pos:
        sample_store = Store(pos, store_type)
        temp_store_locations = copy.deepcopy(store_locations)
        temp_store_locations[self.player_id].append(sample_store)
        sample_alloc = attractiveness_allocation(slmap, temp_store_locations, store_conf)
        sample_score = (sample_alloc[self.player_id] * slmap.population_distribution).sum()
        if num_stores < 2:
            if sample_score > best_score:
                best_score = sample_score
                _pos = [pos]
            elif sample_score == best_score:
                _pos.append(pos)
        best_pos.append(pos)
        score.append(sample_score)
      sorted_score = sorted(score) # sorted rewards
      sorted_10 = sorted_score[-11:-1]
      # Get the state and indices
      '''
      rewardfile = "data/q_rewards.txt"
      rewards = correctingrewards(rewardfile)
      statefile = "data/q_states.txt"
      states = state_values(statefile)
      actionfile = "data/q_action.txt"
      actions = action_values(actionfile)
      q_table = q_table(states, actions, rewards)
      '''
      #file = open(os.path.join(os.path.dirname(__file__),"data/Q_player_current_data.txt"),"r")
      ansFile = open(os.path.join(os.path.dirname(__file__), "data/MLdata.txt"), 'r')
      lines = ansFile.readlines()
      # lines = data.split("\n")
      answer = {}
      for line in lines:
        num = line.split(" ")
        answer[int(num[0])]=[int(num[1]), int(num[2])]

      # Get indicies
      indices = answer[num_stores] # [2, 3]
      attract0 = sorted_10[indices[0]] #top 1 score
      attract1 = sorted_10[indices[1]] #top 2 score
      
      index0 = score.index(attract0)
      index1 = score.index(attract1)
      loc0 = best_pos[index0]
      loc1 = best_pos[index1]
      loc = best_pos[score.index(min(attract0, attract1))]
      '''
      if current_funds > (store_conf[store_type]['capital_cost'])*2:
        self.stores_to_place = [Store(loc0, store_type), Store(loc1, store_type)]
      else:
        '''
      if num_stores < 2:
        loc = _pos[0]
      self.stores_to_place = [Store(loc, store_type)]
      return
    def place_stores(self, slmap: SiteLocationMap,
                     store_locations: Dict[int, List[Store]],
                     current_funds: float):
        global count
        count += 1
        if count <= 3:
            store_conf = self.config['store_config']
            # Configurable minimum distance away to place store
            min_dist = 50
            # Check if it can buy any store at all
            if current_funds < store_conf['small']['capital_cost']:
                self.stores_to_place = []
                return
            # Choose largest store type possible
            if current_funds >= store_conf['large']['capital_cost']:
                store_type = 'large'
            elif current_funds >= store_conf['medium']['capital_cost']:
                store_type = 'medium'
            else:
                store_type = 'small'
            # Find highest population location
            all_stores_pos = []
            for player, player_stores in store_locations.items():
                for player_store in player_stores:
                    all_stores_pos.append(player_store.pos)

            sorted_indices = tuple(map(tuple, np.dstack(
                np.unravel_index(np.argsort(slmap.population_distribution.ravel()), slmap.size))[0][::-1]))
            for max_pos in sorted_indices:
                too_close = False
                for pos in all_stores_pos:
                    dist = np.sqrt(np.square(max_pos[0] - pos[0]) + np.square(max_pos[1] - pos[1]))
                    if dist < min_dist:
                        too_close = True
                if not too_close:
                    self.stores_to_place = [Store(max_pos, store_type)]
                    return
        else:
            store_conf = self.config['store_config']
            num_rand = 100

            sample_pos = []
            for i in range(num_rand):
                x = random.randint(0, slmap.size[0])
                y = random.randint(0, slmap.size[1])
                sample_pos.append((x, y))
            # Choose largest store type possible:
            if current_funds >= store_conf['large']['capital_cost']:
                store_type = 'large'
            elif current_funds >= store_conf['medium']['capital_cost']:
                store_type = 'medium'
            else:
                store_type = 'small'

            best_score = 0
            best_pos = []
            for pos in sample_pos:
                sample_store = Store(pos, store_type)
                temp_store_locations = copy.deepcopy(store_locations)
                temp_store_locations[self.player_id].append(sample_store)
                sample_alloc = attractiveness_allocation(slmap, temp_store_locations, store_conf)
                sample_score = (sample_alloc[self.player_id] * slmap.population_distribution).sum()
                if sample_score > best_score:
                    best_score = sample_score
                    best_pos = [pos]
                elif sample_score == best_score:
                    best_pos.append(pos)

            # max_alloc_positons = np.argwhere(alloc[self.player_id] == np.amax(alloc[self.player_id]))
            # pos = random.choice(max_alloc_positons)
            self.stores_to_place = [Store(random.choice(best_pos), store_type)]
            return

        '''
        store_conf = self.config['store_config']
        num_rand = 100

        sample_pos = []
        for i in range(num_rand):
            x = random.randint(0, slmap.size[0])
            y = random.randint(0, slmap.size[1])
            sample_pos.append((x, y))
        # Choose largest store type possible:
        if current_funds >= store_conf['large']['capital_cost']:
            store_type = 'large'
        elif current_funds >= store_conf['medium']['capital_cost']:
            store_type = 'medium'
        else:
            store_type = 'small'

        #all stores
        all_stores_pos = []
        for player, player_stores in store_locations.items():
            for player_store in player_stores:
                all_stores_pos.append(player_store.pos)

        #max densities
        sorted_indices = tuple(map(tuple, np.dstack(np.unravel_index(np.argsort(slmap.population_distribution.ravel()), slmap.size))[0][::-1]))

        best_score = 0
        best_pos = []

        #max density starts here
        if count < 3:
          random_value = random.randint(0,len(sorted_indices)-1)
          max_pos = sorted_indices[random_value]
          self.stores_to_place = [Store(max_pos, store_type)]
          return

        for pos in sample_pos:
            sample_store = Store(pos, store_type)
            temp_store_locations = copy.deepcopy(store_locations)
            temp_store_locations[self.player_id].append(sample_store)
            
            sample_alloc = attractiveness_allocation(slmap, temp_store_locations, store_conf)
            sample_score = (sample_alloc[self.player_id] * slmap.population_distribution).sum()
            # else:
            #     print(count)
            #     sample_alloc = closest_store_allocation(slmap, temp_store_locations)
            #     sample_score = (sample_alloc[self.player_id] * slmap.population_distribution).sum()
            if sample_score > best_score:
                best_score = sample_score
                best_pos = [pos]
            elif sample_score == best_score:
                best_pos.append(pos)

        # max_alloc_positons = np.argwhere(alloc[self.player_id] == np.amax(alloc[self.player_id]))
        # pos = random.choice(max_alloc_positons)
            self.stores_to_place = [Store(random.choice(best_pos), store_type)]
            return
        ''''