def expand(self): if self.state.curr_cards.size() == 0 or self.state.next_cards.size( ) == 0: return False valid_hands = get_complete_hand(str( self.state.curr_cards)) if self.state.prev_hand.size( ) == 0 else get_beat_hand(str(self.state.prev_hand), str(self.state.curr_cards)) valid_hands = [ CardSet.parse_from("") if valid_hand == "x" else CardSet.parse_from(valid_hand) for valid_hand in valid_hands.split(" ") ] next_states = [ MCTSState(1 - self.state.player, self.state.next_cards, CardSet.diff(self.state.curr_cards, valid_hand), valid_hand, False if valid_hand.nonempty() else True) for valid_hand in valid_hands ] self.children = [ MCTSNode(self, next_state) for next_state in next_states ] pn_scores = self._get_pn_scores() vn_scores = self._get_vn_scores() for child, pn_score, vn_score in zip(self.children, pn_scores, vn_scores): child.P = pn_score child.V = vn_score return True
def give_hand(self, cards): """ Give a hand of cards to this player, by passing a list of cards. cards: a list of 13 Card objects. """ self.hand = CardSet(cards) print("You have received the following hand:") print(self.hand) print()
def valid_actions(self): actions = get_complete_hand(str( self.curr_cards)) if self.prev_hand.size() == 0 else get_beat_hand( str(self.prev_hand), str(self.curr_cards)) actions = actions.split(" ") actions = [ CardSet.parse_from("") if action == "x" else CardSet.parse_from(action) for action in actions ] return actions
def give_hand(self, cards): """ Give a hand of cards to this player, by passing a list of cards. cards: a list of 13 Card objects. """ # Make sure to reset the trick counter self.trick_count = {i: 0 for i in range(4)} self.hand = CardSet(cards) print("You have received the following hand:") print(self.hand) print()
def select_action_by_rule(state): valid_hands = get_complete_hand(str( state.curr_cards)) if state.prev_hand.size() == 0 else get_beat_hand( str(state.prev_hand), str(state.curr_cards)) valid_hands = valid_hands.split(" ") valid_hands = [ CardSet.parse_from("") if valid_hand == "x" else CardSet.parse_from(valid_hand) for valid_hand in valid_hands ] # sorted by split card length left_cards = [ CardSet.diff(state.curr_cards, valid_hand) for valid_hand in valid_hands ] split_lens = [ 0 if left_card.size() == 0 else len( get_simple_hand(str(left_card)).split(" ")) for left_card in left_cards ] hands_with_lens = list(zip(valid_hands, split_lens)) min_split_len = min(hands_with_lens, key=lambda tpl: tpl[1]) min_split_len_hands = [ hand_with_len[0] for hand_with_len in hands_with_lens if hand_with_len[1] == min_split_len[1] ] if len(min_split_len_hands) == 1: return min_split_len_hands[0] # sorted by left card length left_len = [(hand, 0 if CardSet.diff(state.curr_cards, hand).size() == 0 else len(str(CardSet.diff(state.curr_cards, hand)))) for hand in min_split_len_hands] min_left_len = min(left_len, key=lambda tpl: tpl[1]) min_left_len_hands = [ hand for hand, length in left_len if length == min_left_len[1] ] if len(min_left_len_hands) == 1: return min_left_len_hands[0] # sorted by hand rank card_hands = [ CardHand.parse_from('' if str(hand) == 'x' else str(hand)) for hand in min_left_len_hands ] sorted_by_rank = sorted(card_hands, key=cmp_to_key(card_hand_compare)) return sorted_by_rank[0].card_set
def rollout(state): # valid_hand = select_action_by_rule(state) valid_hand = select_action_by_policy(state) # print "%s: %s" % ("dz" if state.player == 1 else "nm", str(valid_hand)) left_cards = CardSet.diff(state.curr_cards, valid_hand) if left_cards.size() == 0: # print "%s win" % ("dz" if state.player == 1 else "nm") return 1.0 if state.player == 1 else -1.0 next_state = MCTSState(1 - state.player, state.next_cards, left_cards, valid_hand, False if state.prev_hand.nonempty() else True) return MCTSNode.rollout(next_state)
class HumanPlayer(IPlayer): def __init__(self): IPlayer.__init__(self) self.player_id = 0 self.teammate_id = 2 self.team_id = 0 self.score = None self.bids = None self.trick_count = {i: 0 for i in range(4)} def give_hand(self, cards): """ Give a hand of cards to this player, by passing a list of cards. cards: a list of 13 Card objects. """ # Make sure to reset the trick counter self.trick_count = {i: 0 for i in range(4)} self.hand = CardSet(cards) print("You have received the following hand:") print(self.hand) print() def print_bids(self, final=False): assert not final or len(self.bids) == 4 for i in range(4): if i not in self.bids: self.bids.add_bid('?', i) team0_sum = "" team1_sum = "" if final: print("The bids for this round:") team0_sum = " = " + "+".join( [str(bid) for bid in self.bids.get_team_bid(0)]) team1_sum = " = " + "+".join( [str(bid) for bid in self.bids.get_team_bid(1)]) else: print("Bids so far:") print("\tteam 0: " + str(self.bids[0]) + " + " + str(self.bids[2]) + team0_sum) print("\tteam 1: " + str(self.bids[1]) + " + " + str(self.bids[3]) + team1_sum) def make_bid(self, bids): """" Ask this player to make a bid at the start of a round. bids: a dict containing all bids so far, with keys 0-3 (player_id) and values 0-13 or "B" for Blind Nill. return value: An integer between 0 (a Nill bid) and 13 minus the teammate's bid (inclusive). """ teammate_bid = 0 if 2 in bids: pass if self.teammate_id in bids: teammate_bid = bids[self.teammate_id] max_bid = 13 - teammate_bid self.bids = bids print("Please make a bid for this round") self.print_bids() print(bids) answer = -1 while not (0 <= answer <= max_bid): try: answer = int( input("Please enter a number between 0 and " + str(13 - teammate_bid) + "\n")) except ValueError: answer = -1 print() return answer def play_card(self, trick, valid_cards): """ Ask this player to play a card, given the trick so far. trick: a Trick object with the cards played so far. valid_cards: a list of Card objects present in your hand that are valid to play for this trick. Intended purely to assist in choosing a card. return value: a Card object present in your hand. """ print("It's your turn to play a card!") print("The trick so far:", str(trick)) print("Your hand:") print(self.hand.to_string(True)) valid_ids = [int(card) for card in valid_cards] chosen_card_nr = "" while chosen_card_nr not in valid_ids: if not isinstance(chosen_card_nr, int): try: chosen_card_nr = int( input( "Please enter the value of the card you wish to play (shown in parenthesis)\n" )) except ValueError: chosen_card_nr = -1 if chosen_card_nr not in valid_ids: try: chosen_card_nr = int( input( "That card is not valid for this trick, please choose another\n" )) except ValueError: chosen_card_nr = "" chosen_card = None for card in valid_cards: if int(card) == chosen_card_nr: chosen_card = card break self.hand.remove(chosen_card) print("You have played " + str(chosen_card)) print() return chosen_card def offer_blind_nill(self, bids): """" Ask this player if they want to bid a Blind Nill. bids: a dict containing all bids so far, with keys 0-3 (player_id) and values 0-13 return value: True or False """ print("You are allowed to bid a Blind Nill this round.") print("Bids so far are: " + str(bids)) answer = input("Bid Blind Nill? (y/n)\n") while answer not in ["y", "Y", "n", "N"]: answer = input("Please answer y or n\n") return answer in ["y", "Y"] def receive_blind_nill_cards(self, cards): """" Receive 2 cards from your teammate in case of a Blind Nill. cards: a list of 2 Card objects. """ for card in cards: self.hand.append(card) print("Your teammate has given you the following cards:", cards[0], cards[1]) print() def request_blind_nill_cards(self): """" Donate 2 cards to your teammate in case of a Blind Nill. return value: a list of 2 Card objects present in your hand. """ print("Please select 2 cards to give to your teammate") print("Your hand:") print(self.hand.to_string(True)) hand_card_ids = [int(card) for card in self.hand] chosen_card_numbers = [] chosen_card_nr = "" ordinals = ["first", "second"] while chosen_card_nr not in hand_card_ids and len( chosen_card_numbers) < 2: if not isinstance(chosen_card_nr, int): try: chosen_card_nr = int( input( "Please enter the value of the {} card you wish to give (shown in parenthesis)\n" .format(ordinals[len(chosen_card_numbers)]))) except ValueError: print( "Invalid card value given. Card values must be integers" ) chosen_card_nr = "" continue if chosen_card_nr not in hand_card_ids: try: if len(chosen_card_numbers ) == 1 and chosen_card_nr == chosen_card_numbers[0]: chosen_card_nr = int( input( "You have already picked that card, please choose another\n" )) else: chosen_card_nr = int( input( "That card is not in your hand, please choose another\n" )) except ValueError: print( "Invalid card value given. Card values must be integers" ) chosen_card_nr = "" continue else: chosen_card_numbers.append(chosen_card_nr) hand_card_ids.remove(chosen_card_nr) chosen_card_nr = "" chosen_cards = [] for chosen_card_nr in chosen_card_numbers: for card in self.hand: if int(card) == chosen_card_nr: chosen_cards.append(card) self.hand.remove(card) break print("You have given your teammate", str(chosen_cards[0]), "and", str(chosen_cards[1])) print() return chosen_cards def announce_bids(self, bids): """" Tell the player about the bids that have been made. bids: a dict containing all bids, with keys 0-3 (player_id) and values 0-13 or "B" for Blind Nill. """ self.bids = bids self.print_bids(final=True) print() def announce_trick(self, trick): """" Tell the player about a completed trick. trick: a Trick object with the cards played. """ self.trick_count[trick.get_winner()] += 1 print("Result:", str(trick)) winner = trick.get_winner() if winner == self.player_id: print("Congratulations! The trick is yours!") elif winner == self.teammate_id: print("Well done, the trick goes to your teammate") else: print("Alas, the trick has gone to your opponent") progress_strings = [] for team_id in range(2): res = "Team " + str(team_id) + ": " if self.bids.team_has_nill(team_id): res += str(self.trick_count[0 + team_id]) + "/" + str( self.bids[0 + team_id]) res += " + " res += str(self.trick_count[2 + team_id]) + "/" + str( self.bids[2 + team_id]) else: trick_sum = self.trick_count[0 + team_id] + self.trick_count[ 2 + team_id] res += str(trick_sum) + "/" + str( self.bids.get_team_bid(team_id)[0]) progress_strings.append(res) print("Current trick count:", self.trick_count, "Progress:", ", ".join(progress_strings)) print() def announce_score(self, score): """" Tell the player about the new scores for each team. score: a dict containing the scores of each team (keys 0 and 1). """ if self.score is None: self.announce_start() self.score = score else: self.score = score print("The new scores are " + str(score)) print() def announce_start(self): print("Welcome, player " + str(self.player_id) + "!") print("You are on team " + str(self.team_id) + " together with player " + str(self.teammate_id)) print()