Exemple #1
0
    def possible_turns(self):
        """Find possible turns with hold higher hold probability than treshold

        This method returns list of all moves with probability of holding the area
        higher than the treshold or areas with 8 dice. In addition, it includes 
        the preference of these moves. The list is sorted in descending order with
        respect to preference * hold probability
        """
        turns = []
        for area in self.board.areas.values():
            if area.get_owner_name(
            ) == self.player_name and area.get_dice() > 1:
                for adj in area.get_adjacent_areas():
                    adjacent_area = self.board.get_area(adj)
                    if adjacent_area.get_owner_name() != self.player_name:
                        area_name = area.get_name()
                        if area_name not in self.possible_attackers:
                            self.possible_attackers.append(area_name)

                        atk_power = area.get_dice()
                        atk_prob = probability_of_successful_attack(
                            self.board, area_name, adj)
                        hold_prob = atk_prob * probability_of_holding_area(
                            self.board, adj, atk_power - 1, self.player_name)
                        if hold_prob >= self.treshold or atk_power is 8:
                            preference = hold_prob
                            if area_name in self.largest_region:
                                preference *= self.score_weight
                            turns.append(
                                [area.get_name(), adj, preference, hold_prob])

        return sorted(turns, key=lambda turn: turn[2], reverse=True)
Exemple #2
0
    def possible_turns(self):
        """Get a list of preferred moves

        This list is sorted with respect to hold probability in descending order.
        It includes all moves that either have hold probability higher or equal to 20 %
        or have strength of eight dice.
        """
        turns = []
        for area in self.board.areas.values():
            if area.get_owner_name(
            ) == self.player_name and area.get_dice() > 1:
                for adj in area.get_adjacent_areas():
                    adjacent_area = self.board.get_area(adj)
                    if adjacent_area.get_owner_name() != self.player_name:
                        area_name = area.get_name()
                        atk_power = area.get_dice()
                        atk_prob = probability_of_successful_attack(
                            self.board, area_name, adj)
                        hold_prob = atk_prob * probability_of_holding_area(
                            self.board, adj, atk_power - 1, self.player_name)
                        if hold_prob >= 0.2 or atk_power is 8:
                            turns.append([area_name, adj, hold_prob])

        return sorted(turns, key=lambda turn: turn[2], reverse=True)
Exemple #3
0
    def possible_turns(self):
        """Get list of possible turns with the associated improvement
        in estimated win probability. The list is sorted in descending order
        with respect to the improvement.
        """
        turns = []
        name = self.player_name

        features = []
        for p in self.players_order:
            dice = numpy.log(self.game.board.get_player_dice(p))
            if numpy.isinf(dice):
                dice = 0
            features.append(dice)

        wp_start = numpy.log(
            sigmoid(numpy.dot(numpy.array(features), self.weights)))

        end_features = [d for d in features]
        end_features[0] = numpy.log(
            self.game.board.get_player_dice(name) +
            self.get_score_by_player(name))
        if numpy.isinf(end_features[0]):
            end_features[0] = 0
        wp_end = numpy.log(
            sigmoid(numpy.dot(numpy.array(end_features), self.weights)))
        improvement = wp_end - wp_start

        turns.append(['end', 0, improvement])

        for area in self.board.areas.values():
            # area belongs to the player and has strength to attack
            if area.get_owner_name() == name and area.get_dice() > 1:
                area_name = area.get_name()
                atk_power = area.get_dice()

                for adj in area.get_adjacent_areas():
                    adjacent_area = self.board.get_area(adj)

                    # adjacent area belongs to an opponent
                    opponent_name = adjacent_area.get_owner_name()
                    if opponent_name != name:
                        def_power = adjacent_area.get_dice()
                        # check whether the attack would expand the largest region
                        increase_score = False
                        if area_name in self.largest_region:
                            increase_score = True
                        else:
                            for n in adjacent_area.get_adjacent_areas():
                                if n in self.largest_region:
                                    increase_score = True
                                    break

                        a_dice = self.game.board.get_player_dice(name)
                        a_score = self.get_score_by_player(name)
                        if increase_score:
                            a_score += 1

                        atk_dice = {
                            "current": a_dice,
                            "win": a_dice + a_score,
                            "loss": a_dice + a_score - atk_power + 1,
                        }

                        d_dice = self.game.board.get_player_dice(opponent_name)
                        d_score = self.get_score_by_player(opponent_name)
                        def_dice = {
                            "loss": d_dice,
                            "win": d_dice - def_power,
                        }

                        atk_prob = probability_of_successful_attack(
                            self.board, area_name, adj)
                        opponent_idx = self.players_order.index(opponent_name)
                        win_features = [d for d in features]
                        win_features[0] = numpy.log(atk_dice["win"])
                        if numpy.isinf(win_features[0]):
                            win_features[0] = 0
                        win_features[opponent_idx] = numpy.log(def_dice["win"])
                        if numpy.isinf(win_features[opponent_idx]):
                            win_features[opponent_idx] = 0

                        loss_features = [d for d in features]
                        loss_features[0] = numpy.log(atk_dice["loss"])
                        if numpy.isinf(loss_features[0]):
                            loss_features[0] = 0
                        loss_features[opponent_idx] = numpy.log(
                            def_dice["loss"])
                        if numpy.isinf(loss_features[opponent_idx]):
                            loss_features[opponent_idx] = 0

                        wp_win = sigmoid(
                            numpy.dot(numpy.array(win_features), self.weights))
                        wp_loss = sigmoid(
                            numpy.dot(numpy.array(loss_features),
                                      self.weights))

                        wp_win = sigmoid(
                            numpy.dot(numpy.array(win_features), self.weights))
                        wp_loss = sigmoid(
                            numpy.dot(numpy.array(loss_features),
                                      self.weights))
                        total_prob = (wp_win * atk_prob) + (wp_loss *
                                                            (1.0 - atk_prob))
                        wp_atk = numpy.log(total_prob)

                        improvement = wp_atk - wp_start
                        turns.append([area_name, adj, improvement])

        return sorted(turns, key=lambda turn: turn[2], reverse=True)
Exemple #4
0
    def possible_turns(self):
        """Get list of possible turns with the associated improvement
        in estimated win probability
        """
        turns = []

        features = []
        for p in self.players_order:
            features.append(self.get_score_by_player(p))
        win_prob = numpy.log(
            sigmoid(numpy.dot(numpy.array(features), self.weights)))

        self.get_largest_region()

        for area in self.board.areas.values():
            # area belongs to the player and has strength to attack
            if area.get_owner_name(
            ) == self.player_name and area.get_dice() > 1:
                area_name = area.get_name()
                atk_power = area.get_dice()

                for adj in area.get_adjacent_areas():
                    adjacent_area = self.board.get_area(adj)

                    # adjacent area belongs to an opponent
                    opponent_name = adjacent_area.get_owner_name()
                    if opponent_name != self.player_name:
                        # check whether the attack would expand the largest region
                        increase_score = False
                        if area_name in self.largest_region:
                            increase_score = True
                        else:
                            for n in adjacent_area.get_adjacent_areas():
                                if n in self.largest_region:
                                    increase_score = True
                                    break

                        if increase_score or atk_power is 8:
                            atk_prob = numpy.log(
                                probability_of_successful_attack(
                                    self.board, area_name, adj))
                            new_features = []
                            for p in self.players_order:
                                idx = self.players_order.index(p)
                                if p == self.player_name:
                                    new_features.append(
                                        features[idx] +
                                        1 if increase_score else features[idx])
                                elif p == opponent_name:
                                    new_features.append(
                                        self.get_score_by_player(
                                            p, skip_area=adj))
                                else:
                                    new_features.append(features[idx])
                            new_win_prob = numpy.log(
                                sigmoid(
                                    numpy.dot(numpy.array(new_features),
                                              self.weights)))
                            total_prob = new_win_prob + atk_prob
                            improvement = total_prob - win_prob
                            if improvement >= -1:
                                turns.append([area_name, adj, improvement])

        return sorted(turns, key=lambda turn: turn[2], reverse=True)