Example #1
0
class GolfGame:
    def __init__(self, num_rounds_per_episode=10):
        self.deck = Deck()
        self.reset()
        self.rounds_per_episode = num_rounds_per_episode

    def reset(self):
        self.round = -1
        self.new_hand()
        return self._get_state()

    def new_hand(self):
        self.deck.shuffle()
        self.hand = self.deck.draw_n(6)
        self.top_card = self.deck.draw()
        self.mask = [0, 0, 0, 0, 0, 0]
        flip = sample(range(0, 5), 2)
        self.mask[flip[0]] = 1
        self.mask[flip[1]] = 1

        self.round += 1

    def step(self, action):
        initial_score = self._get_hand_score()

        # Make sure we dont run out of cards
        if len(self.deck.deck) == 0:
            self.deck.shuffle()

        if action == 0:  # Put card back
            self.top_card = self.deck.draw()
        else:  # Replace card
            self.hand[action - 1] = self.top_card
            self.mask[action - 1] = 1
        next_state = self._get_state()
        reward = initial_score - self._get_hand_score()
        if all(self.mask):  # Every card is flipped over, restart
            self.new_hand()

        done = (self.round >= self.rounds_per_episode)

        return next_state, reward, done

    def _get_state(self):
        state = [self.top_card.value[1]]
        for i, card in enumerate(self.hand):
            if self.mask[i]:
                state.append(card.value[1])
            else:
                state.append(-1)
        return np.array(state)

    def _get_hand_score(self):
        hand_score = 0
        if not self.hand:
            return None
        for column in range(3):
            card1 = self.hand[column]
            card2 = self.hand[3 + column]
            if card1 != card2 and card1 != Card.Joker and card2 != Card.Joker:
                hand_score += card1.value[0] + card2.value[0]
        return hand_score
Example #2
0
class Game:
    def __init__(self, players=None, num_rounds=9, verbose=True):
        if not players:
            players = [('AI1', PlayerType.Computer),
                       ('AI1', PlayerType.Computer)]
        self.verbose = verbose
        self.players = []
        for player in players:
            name, type_ = player
            self.players.append(Player(name, type_))
        self.round = 1
        self.num_rounds = num_rounds
        self.deck = Deck()
        self.top = None
        self.first_player = 0

    def run(self):
        while self.round <= self.num_rounds:
            if self.verbose:
                print('Round {}\n'.format(self.round))
            self._new_round()

            # Flip over initial cards
            for player in self.players:
                player.flip_cards()
                player.display_hand()

            # Go around the table until someone flips all of their cards over
            current_player = self.first_player
            playing = True
            while playing:
                if self.verbose:
                    print('{}\'s Turn'.format(
                        self.players[current_player].name))
                self.top = self.players[current_player].move(
                    self.deck, self.top, self.verbose)

                if self.players[current_player].is_done():
                    playing = False
                current_player = (current_player + 1) % len(self.players)

            # When round is over, add hand score to player scores and increment starting player
            for player in self.players:
                player.score += player.get_hand_score()
            self.first_player = (self.first_player + 1) % len(self.players)
            self.round += 1

        lowest_score = 10000
        winner = ''
        if self.verbose:
            print('Final Hands: ')
        for player in self.players:
            player.mask = [1, 1, 1, 1, 1, 1]
            if self.verbose:
                print('Player: {}'.format(player.name))
            player.display_hand()
        if self.verbose:
            print('Final Scores:')
        avg_score = 0
        for player in self.players:
            if self.verbose:
                print('\t {}: {}'.format(player.name, player.score))
            avg_score += player.score
            if player.score < lowest_score:
                winner = player.name
                lowest_score = player.score
            elif player.score == lowest_score:
                winner += ' and ' + player.name
        if self.verbose:
            print('The winner is... {}!'.format(winner))

        avg_score /= (len(self.players) * self.num_rounds)
        return avg_score

    def _new_round(self):
        self.deck.shuffle()
        for player in self.players:
            player.new_hand(self.deck.draw_n(6))
        self.top = self.deck.draw()