def play_card(self, rnd: PlayerRound) -> int:
        """
        Player returns a card to play based on the given round information.

        Args:
            rnd: current round

        Returns:
            card to play, int encoded
        """

        # get the valid cards to play
        valid_cards = rnd.get_valid_cards()

        # select a random card
        player = self._one_hot(rnd.player, 4)
        trump = self._one_hot(rnd.trump, 6)
        current_trick = self._get_current_trick(rnd.tricks)
        arr = np.array([np.append(valid_cards, current_trick)])
        arr = np.array([np.append(arr, player)])
        arr = np.array([np.append(arr, trump)])
        card_to_play = int(np.argmax(self.playCardModel.predict(arr)))

        if valid_cards[card_to_play] == 1: #valid card
            return card_to_play
        else:
            return int(np.nonzero(valid_cards == 1)[0][0])
Exemple #2
0
    def play_card(self, rnd: PlayerRound) -> int:
        others_indices = extract_others_card_indices(rnd)

        valid_cards = rnd.get_valid_cards()
        our_trick_index = np.where(rnd.current_trick == -1)[0][0]
        valid_card_indices = np.where(valid_cards == 1)[0]
        if valid_card_indices.size == 1:
            return valid_card_indices[0]

        best_result = np.iinfo(np.int32).min
        best_card = -1
        for card_index in valid_card_indices:
            simulated_trick = rnd.current_trick

            # put our card
            simulated_trick[our_trick_index] = card_index

            # simulate others cards
            cards_missing = MAX_PLAYER - our_trick_index
            choice_sets = self.build_choice_sets(others_indices, cards_missing)

            for others_choices in choice_sets:
                np.put(simulated_trick,
                       range(our_trick_index + 1, MAX_PLAYER + 1),
                       others_choices)
                round_result = calculate_round_outcome(rnd, simulated_trick)
                if round_result > best_result:
                    best_result = round_result
                    best_card = card_index

        return best_card
Exemple #3
0
    def _play_lowest_card_with_highest_score(self, rnd: PlayerRound) -> int:
        max_score = -10000 #start with high score
        color_to_play = -1
        color_index = 0

        for s in self.score_per_color:
            if (self.lowest_card_per_color[color_index] == -1 or
                rnd.get_valid_cards()[self.lowest_card_per_color[color_index]] != 1):

                color_index = color_index + 1
                print("No card of Color or not valid at the moment: {}".format(color_index))
                continue #no card in this color or color not valid...continue...

            #check the score and set color to play
            if max_score < s:
                max_score = s
                color_to_play = color_index

            color_index = color_index + 1

        if(color_to_play < 0 or color_to_play > 3 or
            self.lowest_card_per_color[color_to_play] == -1):
            raise ValueError("Color to Play has to be within 0 and 3 and Card != -1!")

        print("Playing lowest card of Best Color! Color: {}, Card: {}, Scores: {}".format(color_to_play, self.lowest_card_per_color[color_to_play], self.score_per_color))
        return self.lowest_card_per_color[color_to_play]
Exemple #4
0
    def _play_last_valid_card(self, rnd: PlayerRound) -> int:
        for card in self.highest_card_per_color:
            if card != -1 and rnd.get_valid_cards()[card] == 1:
                return card

        raise ValueError("No valid card anymore!")
        return -1
Exemple #5
0
    def _play_trump(self, rnd: PlayerRound) -> int:
        #TODO check if highest or lowest trump
        trump = self.highest_card_per_color[rnd.trump]
        if trump == -1 or rnd.get_valid_cards()[self.highest_card_per_color[rnd.trump]] != 1:
            raise ValueError("Invalid Trump: Check first if trump is available!")

        print("Playing Trump! Trump: {}".format(trump))
        return trump
Exemple #6
0
def main():
    parser = argparse.ArgumentParser(description='Read and convert log files')
    parser.add_argument('--output_dir',
                        type=str,
                        required=True,
                        help='Directory for output files')
    parser.add_argument('files', type=str, nargs='+', help='The log files')
    arg = parser.parse_args()

    total_number_of_rounds = 0

    # create output directory
    if not os.path.exists(arg.output_dir):
        print('Creating directory {}'.format(arg.output_dir))
        os.makedirs(arg.output_dir)

    # keep count of the number of output actions generated
    actions = 0

    # parse all files
    for f in arg.files:
        parser = LogParser(f)
        # returns an array of dict with 'players' and 'rounds' as entries
        rounds_players = parser.parse_rounds_and_players()
        total_number_of_rounds += len(rounds_players)

        # open a file for each input file and write it to the output directory
        basename = os.path.basename(f)
        basename, _ = os.path.splitext(basename)
        filename = basename + '.csv'
        filename = os.path.join(arg.output_dir, filename)

        with open(filename, mode='w', newline='') as file:
            print('Processing file: {}'.format(f))
            csv_writer = csv.writer(file)
            for rnd_players in rounds_players:
                # get the player view for making trump
                rnd = rnd_players['round']
                players = rnd_players['players']

                # get a player_rnd for each card played
                player_rnds = PlayerRound.all_from_complete_round(rnd)
                for card_nr, player_rnd in enumerate(player_rnds):
                    features = calculate_features(player_rnd)

                    nr_trick, move_in_trick = divmod(card_nr, 4)
                    # card played (one hot)
                    label = rnd.tricks[nr_trick, move_in_trick]
                    entry = features.tolist()
                    entry.append(label)

                    csv_writer.writerow(entry)
                    actions += 1
                    _print_progress(actions)

    print('Processed {} rounds'.format(total_number_of_rounds))
    print('Processed {} card actions'.format(actions))
Exemple #7
0
    def play_card(self, rnd: PlayerRound) -> int:
        """
        Player returns a card to play based on the given round information.

        Args:
            rnd: current round

        Returns:
            card to play, int encoded
        """

        hand = rnd.hand.astype(np.int)
        # 36 elements

        # unordered cards of the current trick
        cards_of_current_trick = np.zeros(36, np.int)
        if rnd.nr_cards_in_trick > 0:
            cards_of_current_trick[rnd.current_trick[0]] = 1
        if rnd.nr_cards_in_trick > 1:
            cards_of_current_trick[rnd.current_trick[1]] = 1
        if rnd.nr_cards_in_trick > 2:
            cards_of_current_trick[rnd.current_trick[2]] = 1
        # 36 elements

        # player to play
        player = self.one_hot(rnd.player, 4)
        # 4 elements

        # trump
        trump = self.one_hot(rnd.trump, 6)
        # 6 elements

        # total 82 elements
        total = np.array([np.concatenate([hand, cards_of_current_trick, player, trump], axis=0)])

        with self.graph.as_default():
            set_session(self.sess)
            cards = self.card_model.predict(total)

        choice = int(np.argmax(cards))

        valid_cards = rnd.get_valid_cards()

        while valid_cards[choice] != 1:
                cards = np.delete(cards, np.argmax(cards))
                if len(cards) == 0:
                    choice = np.argmax(valid_cards)
                else:
                    new_choice = int(np.argmax(cards))
                    choice = new_choice

        return choice
Exemple #8
0
    def _play_perfect_win(self, rnd: PlayerRound) -> int:
        for color in range(0, 4):
            if(self.highest_card_per_color[color] == -1 or
                self.best_next_card_per_color[color] == -1):
                continue

            if self.highest_card_per_color[color] == self.best_next_card_per_color[color]:
                if rnd.get_valid_cards()[self.highest_card_per_color[color]] != 1:
                    print("Perfect win is not a valid card at the moment :(")
                    continue

                print("Playing perfect card: {}, playingTrump: {}, stillTrumps: {}".format(self.highest_card_per_color[color], (color == rnd.trump), self._check_round_has_still_trumps(rnd)))
                return self.highest_card_per_color[color]

        raise ValueError("Should never reach this line :/. Check for perfect win before calling!")
        return -1
Exemple #9
0
    def play_card(self, rnd: PlayerRound) -> int:
        """
        Player returns a card to play based on the given round information.

        Args:
            rnd: current round

        Returns:
            card to play, int encoded
        """
        # play random

        # get the valid cards to play
        valid_cards = rnd.get_valid_cards()

        # select a random card
        return np.random.choice(np.flatnonzero(valid_cards))
Exemple #10
0
def calculate_lowest_card_per_color(rnd: PlayerRound) -> np.array:
    lowest_card_per_color = np.array([-1, -1, -1, -1])

    for c in range(0, 4):
        cards = rnd.get_valid_cards()[c * 9:(c * 9) + 9]

        if c == rnd.trump:
            #check lowest trump
            lowest_card_per_color[c] = get_lowest_trump(c, cards)
        elif rnd.trump == 5:
            #check lowest unde
            lowest_card_per_color[c] = get_lowest_unde(c, cards)
        else:
            #check lowest obe
            lowest_card_per_color[c] = get_lowest_obe(c, cards)

    return lowest_card_per_color
Exemple #11
0
    def play_card(self, rnd: PlayerRound) -> int:
        """
        Implement the action to play hearts.
        Args:
            rnd: The round for which to play
        Returns:
            the card to play, must be a valid card
        """
        # we can check if we are playing the correct game
        assert rnd.jass_type == JASS_HEARTS

        # get the valid cards to play
        valid_cards = rnd.get_valid_cards()

        # lets divide our cards into heart and other cards
        my_heart_cards = valid_cards * color_masks[HEARTS, :]
        my_other_cards = valid_cards - my_heart_cards

        if rnd.nr_cards_in_trick == 0:
            # we are the first player, so we can select what to play
            # lets select some random non-heart card if we have any (not that this is necessarily
            # a good strategy :-)
            if my_other_cards.sum() > 0:
                card = np.random.choice(np.flatnonzero(my_other_cards))
            else:
                # just play a random valid card
                card = np.random.choice(np.flatnonzero(valid_cards))
        else:
            # if we have to give a card, lets try to give a heart card
            if my_heart_cards.sum() > 0:
                card = np.random.choice(np.flatnonzero(my_heart_cards))
            else:
                # just play a random valid card
                card = np.random.choice(np.flatnonzero(valid_cards))

        self._logger.debug('Played card: {}'.format(card_strings[card]))
        return card
Exemple #12
0
 def _check_more_than_one_valid_card(self, rnd: PlayerRound) -> bool:
     return rnd.get_valid_cards().sum() > 1
Exemple #13
0
def main():
    parser = argparse.ArgumentParser(description='Read and convert log files')
    parser.add_argument('--output_dir',
                        type=str,
                        required=True,
                        help='Directory for output files')
    parser.add_argument('files', type=str, nargs='+', help='The log files')
    arg = parser.parse_args()

    total_number_of_rounds = 0

    if not os.path.exists(arg.output_dir):
        print('Creating directory {}'.format(arg.output_dir))
        os.makedirs(arg.output_dir)

    actions = 0
    for f in arg.files:
        parser = LogParser(f)
        rounds = parser.parse_rounds()
        total_number_of_rounds += len(rounds)

        # open a file for each input file and write it to the output directory
        basename = os.path.basename(f)
        basename, _ = os.path.splitext(basename)
        filename = basename + '.csv'
        filename = os.path.join(arg.output_dir, filename)

        with open(filename, mode='w', newline='') as file:
            print('Processing file: {}'.format(f))
            csv_writer = csv.writer(file)
            for rnd in rounds:
                # get the player view for making trump
                if not rnd.forehand:
                    # was not declared forehand, so add a entry for push
                    player_rnd = PlayerRound.trump_from_complete_round(
                        rnd, forehand=True)
                    entry = player_rnd.hand.tolist()
                    # add a boolean (1) for forehand
                    entry.append(1)
                    entry.append(PUSH)
                    csv_writer.writerow(entry)
                    actions += 1
                    _print_progress(actions)

                    # and then the entry for backhand
                    player_rnd = PlayerRound.trump_from_complete_round(
                        rnd, forehand=False)
                    entry = player_rnd.hand.tolist()
                    # add a boolean (0) for rearhand
                    entry.append(0)
                    entry.append(rnd.trump)
                    csv_writer.writerow(entry)
                    actions += 1
                    _print_progress(actions)
                else:
                    # add only one entry for forehand
                    player_rnd = PlayerRound.trump_from_complete_round(
                        rnd, forehand=True)
                    entry = player_rnd.hand.tolist()
                    # add a boolean (0) for rearhand
                    entry.append(1)
                    entry.append(rnd.trump)
                    csv_writer.writerow(entry)
                    actions += 1
                    _print_progress(actions)

    print('Processed {} rounds'.format(total_number_of_rounds))
    print('Processed {} trump actions'.format(actions))
Exemple #14
0
 def play_card(self, rnd: PlayerRound) -> int:
     valid_cards = rnd.get_valid_cards()
     card = np.random.choice(np.flatnonzero(valid_cards))
     self._logger.debug('Played card: {}'.format(card_strings[card]))
     return card
Exemple #15
0
def calculate_score(rnd: PlayerRound, trumpToCheck=None) -> np.array:
    """trump can be given to check specific trump on a round otherwise the rnd trump is taken
        return an array with four elemnts which each containing the score of one color """
    trump = None
    if trumpToCheck is not None:
        trump = trumpToCheck
    else:
        trump = rnd.trump

    score_per_color = np.array([0, 0, 0, 0])

    if trump == 0:
        #it's a D: Schellen trump
        score_per_color[0] = get_score_per_color_and_trump(
            0, rnd.get_valid_cards(), trump, 0)
        score_per_color[1] = get_score_per_color_and_trump(
            1, rnd.get_valid_cards(), trump, 1)
        score_per_color[2] = get_score_per_color_and_trump(
            2, rnd.get_valid_cards(), trump, 1)
        score_per_color[3] = get_score_per_color_and_trump(
            3, rnd.get_valid_cards(), trump, 1)

    elif trump == 1:
        #it's a H: Rosen trump
        score_per_color[0] = get_score_per_color_and_trump(
            0, rnd.get_valid_cards(), trump, 1)
        score_per_color[1] = get_score_per_color_and_trump(
            1, rnd.get_valid_cards(), trump, 0)
        score_per_color[2] = get_score_per_color_and_trump(
            2, rnd.get_valid_cards(), trump, 1)
        score_per_color[3] = get_score_per_color_and_trump(
            3, rnd.get_valid_cards(), trump, 1)

    elif trump == 2:
        #it's a S: Schilten trump
        score_per_color[0] = get_score_per_color_and_trump(
            0, rnd.get_valid_cards(), trump, 1)
        score_per_color[1] = get_score_per_color_and_trump(
            1, rnd.get_valid_cards(), trump, 1)
        score_per_color[2] = get_score_per_color_and_trump(
            2, rnd.get_valid_cards(), trump, 0)
        score_per_color[3] = get_score_per_color_and_trump(
            3, rnd.get_valid_cards(), trump, 1)

    elif trump == 3:
        #it's a C: Eichel trump
        score_per_color[0] = get_score_per_color_and_trump(
            0, rnd.get_valid_cards(), trump, 1)
        score_per_color[1] = get_score_per_color_and_trump(
            1, rnd.get_valid_cards(), trump, 1)
        score_per_color[2] = get_score_per_color_and_trump(
            2, rnd.get_valid_cards(), trump, 1)
        score_per_color[3] = get_score_per_color_and_trump(
            3, rnd.get_valid_cards(), trump, 0)

    elif trump == 4:
        #it's O: Obe
        #score_per_color[0] = get_score_per_color_and_trump(0, rnd.get_valid_cards(), trump, 1)
        #score_per_color[1] = get_score_per_color_and_trump(1, rnd.get_valid_cards(), trump, 1)
        #score_per_color[2] = get_score_per_color_and_trump(2, rnd.get_valid_cards(), trump, 1)
        #score_per_color[3] = get_score_per_color_and_trump(3, rnd.get_valid_cards(), trump, 1)
        pass

    elif trump == 5:
        #it's U: Une-Ufe
        #score_per_color[0] = get_score_per_color_and_trump(0, rnd.get_valid_cards(), trump, 2)
        #score_per_color[1] = get_score_per_color_and_trump(1, rnd.get_valid_cards(), trump, 2)
        #score_per_color[2] = get_score_per_color_and_trump(2, rnd.get_valid_cards(), trump, 2)
        #score_per_color[3] = get_score_per_color_and_trump(3, rnd.get_valid_cards(), trump, 2)
        pass

    else:
        raise ValueError(
            "Wrong trump number! only works for 0 to 5 (D, H, S, C, Obe, Unde)"
        )

    print("Calculate Score - Trump: {}, ScorePerColor: {}".format(
        trump_strings_german_long[trump], score_per_color))
    return score_per_color