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])
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
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]
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
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
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))
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
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
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))
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
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
def _check_more_than_one_valid_card(self, rnd: PlayerRound) -> bool: return rnd.get_valid_cards().sum() > 1
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))
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
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