예제 #1
0
파일: gui.py 프로젝트: hans101/OFC
 def create_deck(self):
     self.deck = Deck(randint(1, 500))
     # creating back card image
     back_card_image = ImageTk.PhotoImage(Image.open("Cards/green_back.png"))
     self.board.create_image(130, 370, image=back_card_image, tags=('card_back', 'this'), state=HIDDEN)
     self.all_hand_cards = [self.deck.get_card() for _ in range(1, 18)]
     self.all_hand_cards.insert(0, back_card_image)
예제 #2
0
 def __init__(self):
     self.state = self.States.INIT
     self.current_player_index = 0
     self.players = []
     self.deck = Deck()
     self.rules = Rules()
     self.stack = Stack()
     self.cheat_card = ""
예제 #3
0
def index():
    title = 'random'

    deck = Deck()

    deck.shuffle()

    card = deck.drawCard()

    return render_template('index.html', title=title, card=card)
예제 #4
0
    def _reset_play(self) -> None:
        self._community_cards = []
        self._current_bet = 0
        self._current_raise = 0
        self._is_round_active = True
        self._raise_cnt = 0
        self._deck = Deck()

        for player in self._players:
            player.reset()
예제 #5
0
 def draw_card(self):
     """
     Draws a card from the deck.  If the deck is exhausted, a new deck is shuffled and
     used.
     """
     card = self.deck.draw()
     if card is None:
         self.deck = Deck()
         card = self.deck.draw()
     return card
예제 #6
0
파일: test_deck.py 프로젝트: pisskidney/mdp
 def test_shuffle(self):
     d1 = Deck()
     old = []
     for i in xrange(20):
         old.append(d1.cards[i].rank)
     d1.shuffle()
     same = True
     for i in xrange(20):
         if old[i] != d1.cards[i].rank:
             same = False
             break
     self.assertEqual(same, False)
            def test_other_player_health_gets_to_zero__game_won(self):
                attacker = Player('attacker', Deck())
                victim = Player('victim', Deck())
                game = Game(attacker, victim)

                victim.health = 2
                kill_card = Card(4)
                attacker.mana_slots = 8
                attacker.mana = 4
                attacker.hand = [Card(2), kill_card, Card(8)]
                game.attacker = attacker

                assert game.status['finished'] is False
                game.play_card(kill_card)
                assert game.status['finished'] is True
                assert game.status['winner'] == 'attacker'
예제 #8
0
 def test_can_do_split(self):
     hand = Hand(60)
     deck = Deck.create(1)
     while (len(hand.cards) < 2 and not deck.is_empty()):
         card = deck.get_card()
         if card.value > 9:
             hand.add_card(card)
     assert hand.can_do_split()
예제 #9
0
 def test_hit(self):
     hand = Hand(60)
     player = Player("Foo", 100)
     game = SingleDeck([player])
     deck = Deck.create(1)
     game.get_card = Mock(return_value=deck.get_card())
     hand.hit(game)
     assert len(hand.cards) == 1
예제 #10
0
파일: test_deck.py 프로젝트: pisskidney/mdp
 def test_pop_hand(self):
     d1 = Deck()
     c1 = d1.pop_card()
     c2 = d1.pop_card()
     c3 = d1.pop_card()
     c4 = d1.pop_card()
     c5 = d1.pop_card()
     self.assertEqual(c1.rank, ranks[-1])
     self.assertEqual(c1.suit, suits[-1])
     self.assertEqual(c2.rank, ranks[-1])
     self.assertEqual(c2.suit, suits[-2])
     self.assertEqual(c3.rank, ranks[-1])
     self.assertEqual(c3.suit, suits[-3])
     self.assertEqual(c4.rank, ranks[-1])
     self.assertEqual(c4.suit, suits[-4])
     self.assertEqual(c5.rank, ranks[-2])
     self.assertEqual(c5.suit, suits[-1])
예제 #11
0
 def __init__(self, players_classes: List[Type[BasicPlayer]]) -> None:
     self._init_chips = self.INIT_CHIPS
     self._deck = Deck()
     self._players = self._create_players(players_classes)
     self._total_players = self._players.count()
     self._pot = 0
     self._pot_leftover = 0
     self._community_cards = []
     self._current_bet = 0
     self._small_bet = self.SMALL_BET
     self._big_bet = self.BIG_BET
     self._current_raise = self._small_bet
     self._raise_cnt = 0
     self._is_round_active = True
     self._is_game_active = True
     self._observers = Observers()
     self._players_who_lost = []
     self._current_phase = None
예제 #12
0
 def test_is_empty(self):
     deck = Deck.create(1)
     cards = list(deck.deck)
     assert not deck.is_empty()
     try:
         while True:
             deck.get_card()
     except:
         assert deck.is_empty()
예제 #13
0
    def test_get_score(self):
        hand = Hand(60)
        deck = Deck.create(1)
        card1 = deck.get_card()
        card2 = deck.get_card()
        hand.add_card(card1)
        hand.add_card(card2)

        assert hand.get_score() == card1.value + card2.value
예제 #14
0
 def test_cards(self):
     hand = Hand()
     deck = Deck.create(1)
     card = deck.get_card()
     card.hidden = True
     hand.add_card(card)
     hand.add_card(deck.get_card())
     assert any([card.hidden for card in hand.cards])
     hand.reveal()
     assert all([not card.hidden for card in hand.cards])
예제 #15
0
    def _create_community_combinations(self, opp_hand: Tuple[Card, Card],
                                       state: State) -> List[List[Card]]:
        deck = Deck().get_cards()
        indexes = []
        popped_cards = 0
        community_combos = []
        nbr_of_comm_cards = len(state.community_cards)

        if nbr_of_comm_cards >= 5:
            community_combos.append(state.community_cards)

        else:

            for i, c in enumerate(deck):
                if c in self.get_hand(
                ) or c in state.community_cards or c in opp_hand:
                    indexes.append(i)

            for i in indexes:
                deck.pop(i - popped_cards)
                popped_cards += 1

            if nbr_of_comm_cards < 3:
                for i1, c1 in enumerate(deck):
                    for i2, c2 in enumerate(deck[i1 + 1:]):
                        for i3, c3 in enumerate(deck[i2 + 1:]):
                            for i4, c4 in enumerate(deck[i3 + 1:]):
                                for c5 in deck[i4 + 1:]:
                                    community_combos.append(
                                        [c1, c2, c3, c4, c5])

            elif nbr_of_comm_cards < 4:
                for i, c1 in enumerate(deck):
                    for c2 in deck[i + 1:]:
                        community_combos.append(
                            list(state.community_cards) + [c1, c2])

            elif nbr_of_comm_cards < 5:
                for c in deck:
                    community_combos.append(list(state.community_cards) + [c])

        return community_combos
예제 #16
0
    def _create_opponent_hand_combinations(
            self, state: State) -> List[Tuple[Card, Card]]:
        deck = Deck().get_cards()
        indexes = []
        popped_cards = 0
        opponent_hand_combinations = []

        for i, c in enumerate(deck):
            if c in self.get_hand() or c in state.community_cards:
                indexes.append(i)

        for i in indexes:
            deck.pop(i - popped_cards)
            popped_cards += 1

        for i, c1 in enumerate(deck):
            for c2 in deck[i + 1:]:
                opponent_hand_combinations.append((c1, c2))

        return opponent_hand_combinations
예제 #17
0
    def __init__(self):
        """
        Initializing game variables and the variables that are applied to the layout.
        """

        # Initially shuffled deck
        self.deck = Deck()

        # Player's chips, hand and a text representing the cards
        self.player_holdings_var = tk.IntVar(value=200)
        self.player_hand = None
        self.player_cards_var = tk.StringVar(value="")

        # Dealer's house bank, hand and a text representing the cards
        self.dealer_holdings_var = tk.IntVar(value=5000)
        self.dealer_hand = None
        self.dealer_cards_var = tk.StringVar(value="")

        # Holders for player's bet, the pot and a description of the winning hand
        self.bet_var = tk.IntVar(value=0)
        self.pot_var = tk.IntVar(value=0)
        self.winner_var = tk.StringVar(value="")
    def test_draw_all_cards(self, _random_module):
        deck = Deck()  # Not using fixture because of 'hypothesis'

        for _ in range(0, 20):
            deck.draw_card()

        with pytest.raises(RuntimeError, match=r'.*empty.*'):
            deck.draw_card()
예제 #19
0
 def test_split(self):
     hand = Hand(60)
     assert hand.bet == 60
     deck = Deck.create(1)
     card1 = deck.get_card()
     card2 = deck.get_card()
     hand.add_card(card1)
     hand.add_card(card2)
     player = Player("Foo", 100)
     game = Game([player])
     new_hand = hand.split(game)
     assert len(hand.cards) == 1
     assert hand.cards[0] == card1
     assert hand.bet == 30
     assert len(new_hand.cards) == 1
     assert new_hand.cards[0] == card2
     assert new_hand.bet == 30
예제 #20
0
class TestBlackjack(unittest.TestCase):
    deck = Deck(BuildDeck().create_deck())
    blackjack = Blackjack(deck)

    def test_data(self):
        self.assertEqual(self.blackjack.deck, self.deck)
        self.assertEqual(self.blackjack.draw_count, 0)
        self.assertEqual(self.blackjack.bet, 0)

    def test_restart(self):
        self.blackjack.draw_count = 5
        self.blackjack.bet = 10
        self.assertEqual(self.blackjack.draw_count, 5)
        self.assertEqual(self.blackjack.bet, 10)

        self.blackjack.restart()

        self.assertIsNone(self.blackjack.deck)
        self.assertEqual(self.blackjack.draw_count, 0)
        self.assertEqual(self.blackjack.bet, 0)
예제 #21
0
class GameEngine:
    class States(Enum):
        INIT = 1
        PLAYING = 2
        FINISHED = 3

    def __init__(self):
        self.state = self.States.INIT
        self.current_player_index = 0
        self.players = []
        self.deck = Deck()
        self.rules = Rules()
        self.stack = Stack()
        self.cheat_card = ""

    def initialize_game(self):
        self.deck.build()
        self.deck.shuffle()
        self.rules.read_rules()

    def create_players(self):
        number_players = int(input("Enter the number of players? "))
        for player_number in range(1, number_players + 1):
            player_question = f"Enter the name of player{player_number}? "
            name = input(player_question)
            self.players.append(Player(name))

    def current_player(self):
        return self.players[self.current_player_index]

    def deal_cards(self):
        player_index = 0
        for card in self.deck.cards:
            self.players[player_index].hand.append(card)
            player_index += 1
            if player_index >= len(self.players):
                player_index = 0

    def next_player(self):
        if self.current_player().no_more_cards():
            print(f"{self.current_player().name} won the game!!!!!")
            self.state = self.States.FINISHED

        self.current_player_index += 1
        if self.current_player_index >= len(self.players):
            self.current_player_index = 0

    def previous_player(self):
        if self.current_player_index > 0:
            return self.players[self.current_player_index - 1]
        else:
            return self.players[len(self.players) - 1]

    def print_rules(self):
        print(self.rules)

    def game_loop(self):
        while self.state != self.States.FINISHED:
            if self.state == self.States.INIT:
                self.create_players()
                self.deal_cards()
                self.state = self.States.PLAYING

            print(f"{self.current_player().name} it is your turn")
            print(self.stack)
            print(self.current_player())

            command = input((f"What do you want to do?"
                             " (help, playcard, cheater) "))

            if command == "help":
                self.print_rules()
            elif command == "playcard":
                call_card = input("Which card do you want to play? ")
                if self.current_player().has_card(call_card):
                    card = self.current_player().get_card(call_card)
                    self.stack.add_card(card)
                    self.cheat_card = input(("What card do you "
                                             "want to say you "
                                             "played? "))
                    self.next_player()
                else:
                    print("You don't have that card")
            elif command == "cheater":
                lastcard = self.stack.get_last_card()
                print(f"Last card was: {lastcard}")
                if self.cheat_card == str(lastcard):
                    print((f"No, {self.previous_player().name} did not cheat, "
                           "you will get all the played cards"))
                    played_cards = self.stack.get_cards()
                    self.current_player().add(played_cards)
                    self.stack.clear()
                else:
                    print((f"Yes, you are right {self.previous_player().name} "
                           f"cheated. {self.previous_player().name} will get "
                           "all played cards"))
                    played_cards = self.stack.get_cards()
                    self.previous_player().add(played_cards)
                    self.stack.clear()

    def start_game(self):
        self.initialize_game()
        self.game_loop()
예제 #22
0
파일: gui.py 프로젝트: hans101/OFC
class Game:

    def __init__(self, root):
        self.root = root
        self.deck = None
        self.first_player_frame = None
        self.board = None
        self.set_button = None
        self.button_reset = None
        self.switch = None
        self.all_hand_cards = None
        self.hand_history = {}
        self.hand_id = None

        self.board_prepare()
        self.new_hand()

    def create_deck(self):
        self.deck = Deck(randint(1, 500))
        # creating back card image
        back_card_image = ImageTk.PhotoImage(Image.open("Cards/green_back.png"))
        self.board.create_image(130, 370, image=back_card_image, tags=('card_back', 'this'), state=HIDDEN)
        self.all_hand_cards = [self.deck.get_card() for _ in range(1, 18)]
        self.all_hand_cards.insert(0, back_card_image)

    def board_prepare(self):
        # root config
        self.root.geometry('1000x500')
        self.root.title('OFC v 0.1')
        self.root.configure(background='#222B12')

        # first player frame config
        self.first_player_frame = Frame(root, width=800, height=450)
        self.first_player_frame.configure(background='#3E4D21')
        self.first_player_frame.pack()
        first_player_label = Label(self.first_player_frame, text='PLAYER 1')
        first_player_label.place(x=375, y=0)

        # place Canvas board
        self.board = Canvas(self.first_player_frame, bg='black', width=700, height=420)
        self.board.place(x=50, y=25)

        # creating grid
        self.board.create_line(0, 105, 700, 105, width=3, fill='grey')
        self.board.create_line(0, 210, 700, 210, width=3, fill='grey')
        self.board.create_line(0, 315, 700, 315, width=3, fill='grey')

        self.board.create_line(165, 105, 165, 420, width=3, fill='grey')
        self.board.create_line(235, 0, 235, 420, width=3, fill='grey')
        self.board.create_line(305, 0, 305, 420, width=3, fill='grey')
        self.board.create_line(375, 0, 375, 420, width=3, fill='grey')
        self.board.create_line(445, 0, 445, 420, width=3, fill='grey')
        self.board.create_line(515, 105, 515, 420, width=3, fill='grey')

        # switch to show/hide burned cards
        self.switch = 0

        # create set and reset button
        self.set_button = Button(self.board, text='SET', state=DISABLED)
        self.set_button.place(x=600, y=50)
        self.button_reset = Button(self.board, text='RESET', state=DISABLED)
        self.button_reset.place(x=590, y=15)

    # function to create image on board
    def create_new_card_image(self, card, x_position, y_position):
        self.board.create_image(x_position, y_position, image=card.representation(),
                                tags=('draw', 'bottom_row', 'reset', 'this', 'card' + str(card)))

    # first draw(5 cards)
    def first_draw(self):
        [self.create_new_card_image(self.all_hand_cards[i], (130 + (i * 70)), 370) for i in range(1, 6)]

    # function returning card object of specified card image
    def returning_card_of_image_object(self, image_object):
        image_name = self.board.itemcget(image_object, 'tags')
        result = re.search(r'\d+[A-Z]', image_name)
        card_index = self.all_hand_cards.index(result.group())
        card = self.all_hand_cards[card_index]
        return card

    # setting in order objects in a chosen row
    def row_reload(self, row, x_position, y_position):
        for i in range(0, len(row)):
            self.board.coords(row[i], (x_position + (i * 70)), y_position)

    # setting all cards in all rows in order
    def all_rows_reload(self, bottom_row, row1, row2, row3):
        if len(bottom_row) > 4:
            self.row_reload(bottom_row, 200, 370)
        else:
            self.row_reload(bottom_row, 270, 370)
            self.row_reload(row1, 200, 265)
            self.row_reload(row2, 200, 160)
            self.row_reload(row3, 270, 55)

    # handle reset button
    def reset(self):
        round_cards = self.board.find_withtag('reset')
        for card in round_cards:
            self.board.dtag(card, 'row1')
            self.board.dtag(card, 'row2')
            self.board.dtag(card, 'row3')
            card_tags = self.board.itemcget(card, 'tags') + ' bottom_row'
            self.board.itemconfig(card, tags=card_tags)
        row1 = self.board.find_withtag('row1')
        row2 = self.board.find_withtag('row2')
        row3 = self.board.find_withtag('row3')
        bottom_row = self.board.find_withtag('bottom_row')
        self.all_rows_reload(bottom_row, row1, row2, row3)
        self.button_reset.config(state=DISABLED)

    # creating set button
    def set_position(self):

        row1 = self.board.find_withtag('row1')
        row2 = self.board.find_withtag('row2')
        row3 = self.board.find_withtag('row3')
        bottom_row = self.board.find_withtag('bottom_row')

        # adding burned card to HH
        burned_card = ''
        if bottom_row:
            burned_card = (self.returning_card_of_image_object(bottom_row[0]).__str__(),)

        # adding all drew hands to HH
        this_round_cards = self.board.find_withtag('reset')
        this_round_cards_str = [self.returning_card_of_image_object(card).__str__() for card in this_round_cards]

        # cards added only in this round
        cards_append_to_row1 = [self.returning_card_of_image_object(card).__str__()
                                for card in row1 if card in this_round_cards]
        cards_append_to_row2 = [self.returning_card_of_image_object(card).__str__()
                                for card in row2 if card in this_round_cards]
        cards_append_to_row3 = [self.returning_card_of_image_object(card).__str__()
                                for card in row3 if card in this_round_cards]
        row_1_before_append = [self.returning_card_of_image_object(card).__str__()
                               for card in row1 if card not in this_round_cards]
        row_2_before_append = [self.returning_card_of_image_object(card).__str__()
                               for card in row2 if card not in this_round_cards]
        row_3_before_append = [self.returning_card_of_image_object(card).__str__()
                               for card in row3 if card not in this_round_cards]
        this_round_cards_added = (
            this_round_cards_str, (row_1_before_append, cards_append_to_row1),
            (row_2_before_append, cards_append_to_row2), (row_3_before_append, cards_append_to_row3), burned_card)

        if bottom_row:
            self.board.addtag_withtag('burn', 'bottom_row')
            burned_cards = self.board.find_withtag('burn')
            for i in range(0, len(burned_cards)):
                self.board.itemconfig(burned_cards[i], tag='burn')
                self.board.itemconfig(burned_cards[i], state=HIDDEN)
                self.board.coords(burned_cards[i], (130 - i * 30), 370)

        card_number = len(row1) + len(row2) + len(row3)
        possible_cards_quantity = [5, 7, 9, 11, 13]

        card_back = self.board.find_withtag('card_back')

        self.board.dtag('reset')

        if card_number in possible_cards_quantity:
            # placing cards on board
            round_description = ''
            if card_number == 5:
                self.board.dtag('draw')
                round_description = 'DRAW 1'
                # second draw(3 cards)
                [self.create_new_card_image(self.all_hand_cards[i], (-150 + (i * 70)), 370) for i in range(6, 9)]
            elif card_number == 7:
                round_description = 'DRAW 2'
                self.board.dtag('draw')
                self.board.itemconfig(card_back, state=NORMAL)
                # third draw(3 cards)
                [self.create_new_card_image(self.all_hand_cards[i], (-360 + (i * 70)), 370) for i in range(9, 12)]
            elif card_number == 9:
                round_description = 'DRAW 3'
                self.board.dtag('draw')
                # fourth draw(3 cards)
                [self.create_new_card_image(self.all_hand_cards[i], (-570 + (i * 70)), 370) for i in range(12, 15)]
            elif card_number == 11:
                round_description = 'DRAW 4'
                self.board.dtag('draw')
                # fifth_draw(5 cards)
                [self.create_new_card_image(self.all_hand_cards[i], (-780 + (i * 70)), 370) for i in range(15, 18)]
            elif card_number == 13:
                round_description = 'DRAW 5'
                self.board.dtag('draw')

                # adding data to HH
                self.hand_history[round_description] = this_round_cards_added

                top = [self.returning_card_of_image_object(card) for card in row3]
                mid = [self.returning_card_of_image_object(card) for card in row2]
                bottom = [self.returning_card_of_image_object(card) for card in row1]
                new_hand = OfcHand(top=top, bot=bottom, mid=mid)

                self.hand_history['FINAL HAND'] = (
                    [card.__str__() for card in bottom],
                    [card.__str__() for card in mid],
                    [card.__str__() for card in top])

                points_bottom_row = FrontMidBotHand(5, 3, bottom)
                points_middle_row = FrontMidBotHand(5, 2, mid)
                points_top_row = FrontMidBotHand(3, 1, top)
                hand_points = points_bottom_row.evaluate() + points_middle_row.evaluate() + points_top_row.evaluate()

                self.hand_history['EVALUATION'] = (
                    points_bottom_row.evaluate(), points_middle_row.evaluate(), points_top_row.evaluate(), hand_points)
                print(new_hand)
                print(self.hand_history)

                self.hand_history_handler()

                self.delete_all_cards()
                self.hand_reset()
                self.new_hand()

            # adding data to HH
            self.hand_history[round_description] = this_round_cards_added

            self.set_button.config(state=DISABLED)
        else:
            pass

    def hand_history_handler(self):

        self.hand_id = 0
        for _ in os.listdir('HH'):
            self.hand_id += 1

        str_hand_id = str(self.hand_id)

        while len(str_hand_id) < 5:
            str_hand_id = '0' + str_hand_id

        date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

        file = open("HH/hand#{}.txt".format(str_hand_id), "w+")
        file.write(f'Hand #{str_hand_id}, played {date}\n\n')

        for key in self.hand_history:
            file.write('\n{}\n\n'.format(key))
            if key == 'EVALUATION':
                file.write('\n\n$$$\nHAND POINTS: {}\nBottom row: {}\nMiddle row: {}\nTop row: {}\n$$$'.format(
                    self.hand_history[key][3], self.hand_history[key][0], self.hand_history[key][1],
                    self.hand_history[key][2]))

            elif key == 'FINAL HAND':
                file.write(
                    '***BOTTOM ROW ***\n[> {} {} {} {} {} <]\n'.format(self.hand_history[key][0][0],
                                                                       self.hand_history[key][0][1],
                                                                       self.hand_history[key][0][2],
                                                                       self.hand_history[key][0][3],
                                                                       self.hand_history[key][0][4]))
                file.write(
                    '***MIDDLE ROW ***\n[> {} {} {} {} {} <]\n'.format(self.hand_history[key][1][0],
                                                                       self.hand_history[key][1][1],
                                                                       self.hand_history[key][1][2],
                                                                       self.hand_history[key][1][3],
                                                                       self.hand_history[key][1][4]))
                file.write(
                    '***TOP ROW ***\n[> {} {} {} <]'.format(self.hand_history[key][2][0],
                                                            self.hand_history[key][2][1],
                                                            self.hand_history[key][2][2]))
            else:
                for j in range(0, len(self.hand_history[key])):
                    text2 = ''
                    if j == 0:
                        text2 = '*** CARDS DEALT ***\n'
                    elif j == 1:
                        text2 = '\n*** BOTTOM ROW ***\n'
                    elif j == 2:
                        text2 = '\n*** MIDDLE ROW ***\n'
                    elif j == 3:
                        text2 = '\n*** TOP ROW ***\n'
                    elif j == 4:
                        text2 = '\n*** BURNED CARD ***\n'

                    file.write(text2)
                    if j in (0, 4):
                        for card in self.hand_history[key][j]:
                            file.write('[{}]'.format(card))
                    if j in (1, 2, 3):
                        for s in range(0, len(self.hand_history[key][j])):
                            # cards already in a row
                            if s == 0:
                                file.write('[> ')
                                for card in self.hand_history[key][j][s]:
                                    file.write('{} '.format(card))
                                file.write('<]')
                            # new cards
                            if s == 1:
                                for card in self.hand_history[key][j][s]:
                                    file.write('[{}]'.format(card))
                file.write('\n')

        file.close()

    def card_move(self, event):
        x = self.board.canvasx(event.x)
        y = self.board.canvasy(event.y)
        this_round_cards = self.board.find_withtag('draw')
        selected_card = self.board.find_closest(x, y)[0]
        blocked_cards = self.board.find_withtag('blocked')
        if selected_card in this_round_cards:
            if selected_card not in blocked_cards:
                self.board.addtag_all('blocked')
                self.board.dtag(selected_card, 'blocked')
                self.board.coords(selected_card, x, y)

    def tag_add(self, event):
        self.board.dtag('blocked')
        x = self.board.canvasx(event.x)
        y = self.board.canvasy(event.y)
        this_round_cards = self.board.find_withtag('draw')
        selected_card = self.board.find_closest(x, y)[0]
        if selected_card in this_round_cards:
            self.board.dtag(selected_card, 'row1')
            self.board.dtag(selected_card, 'row2')
            self.board.dtag(selected_card, 'row3')
            self.board.dtag(selected_card, 'bottom_row')
            self.board.addtag_enclosed('bottom_row', 165, 275, 515, 485)
            self.board.addtag_enclosed('row1', 165, 165, 515, 345)
            self.board.addtag_enclosed('row2', 165, 55, 515, 255)
            self.board.addtag_enclosed('row3', 165, -53, 515, 150)
            row1 = self.board.find_withtag('row1')
            row2 = self.board.find_withtag('row2')
            row3 = self.board.find_withtag('row3')
            bottom_row = self.board.find_withtag('bottom_row')
            if selected_card in row1:
                self.board.coords(selected_card, (130 + len(row1) * 70), 265)
                if len(row1) == 6:
                    self.board.dtag(selected_card, 'row1')
                    selected_card_tags = self.board.itemcget(selected_card, 'tags') + ' bottom_row'
                    self.board.itemconfig(selected_card, tags=selected_card_tags)
                self.row_reload(row1, 200, 265)
            elif selected_card in row2:
                self.board.coords(selected_card, (130 + len(row2) * 70), 160)
                if len(row2) == 6:
                    self.board.dtag(selected_card, 'row2')
                    selected_card_tags = self.board.itemcget(selected_card, 'tags') + ' bottom_row'
                    self.board.itemconfig(selected_card, tags=selected_card_tags)
                self.row_reload(row1, 200, 160)
            elif selected_card in row3:
                self.board.coords(selected_card, (200 + len(row3) * 70), 55)
                if len(row3) == 4:
                    self.board.dtag(selected_card, 'row3')
                    selected_card_tags = self.board.itemcget(selected_card, 'tags') + ' bottom_row'
                    self.board.itemconfig(selected_card, tags=selected_card_tags)
                self.row_reload(row3, 270, 55)
            else:
                self.board.dtag(selected_card, 'row1')
                self.board.dtag(selected_card, 'row2')
                self.board.dtag(selected_card, 'row3')
                selected_card_tags = self.board.itemcget(selected_card, 'tags') + ' bottom_row'
                self.board.itemconfig(selected_card, tags=selected_card_tags)
                self.board.coords(selected_card, (130 + len(bottom_row) * 70), 370)
                self.row_reload(bottom_row, 200, 370)

            self.returning_card_of_image_object(selected_card)

            row1 = self.board.find_withtag('row1')
            row2 = self.board.find_withtag('row2')
            row3 = self.board.find_withtag('row3')
            bottom_row = self.board.find_withtag('bottom_row')

            if (len(row1) + len(row2) + len(row3)) in [5, 7, 9, 11, 13] and len(bottom_row) in [0, 1]:
                self.set_button.config(state=NORMAL)
            else:
                self.set_button.config(state=DISABLED)

            self.all_rows_reload(bottom_row, row1, row2, row3)

            this_round_cards = self.board.find_withtag('reset')

            for card in this_round_cards:
                if card in row1 or card in row2 or card in row3:
                    self.button_reset.config(state=NORMAL)

    def display_burned_cards(self, event):
        self.switch += 1
        # show/hide burned cards:
        burned_cards = self.board.find_withtag('burn')
        if self.switch % 2 == 1:
            if burned_cards:
                for card in burned_cards:
                    self.board.itemconfig(card, state=NORMAL)
        else:
            if burned_cards:
                for card in burned_cards:
                    self.board.itemconfig(card, state=HIDDEN)

    def hand_reset(self):
        previous_round_cards = self.board.find_withtag('this')
        for card in previous_round_cards:
            self.board.dtag('row1')
            self.board.dtag('row2')
            self.board.dtag('row3')
            self.board.dtag('bottom_row')
            self.board.dtag('burn')
            self.board.delete(card)
        self.deck = None
        self.all_hand_cards = None

    def delete_all_cards(self):
        for card in self.all_hand_cards:
            self.board.delete(card)

    def new_hand(self):
        self.hand_reset()
        self.create_deck()

        self.hand_id = randint(10000, 99999)

        self.set_button.config(command=self.set_position)
        self.button_reset.config(command=self.reset)

        self.first_draw()

        self.board.bind("<B1-Motion>", self.card_move)
        self.board.bind('<ButtonRelease-1>', self.tag_add)
        self.board.bind('<3>', self.display_burned_cards)
예제 #23
0
class Controller:
    """
    Serves as game controller.  Attempting to separate game logic from GUI.
    """

    def __init__(self):
        """
        Initializing game variables and the variables that are applied to the layout.
        """

        # Initially shuffled deck
        self.deck = Deck()

        # Player's chips, hand and a text representing the cards
        self.player_holdings_var = tk.IntVar(value=200)
        self.player_hand = None
        self.player_cards_var = tk.StringVar(value="")

        # Dealer's house bank, hand and a text representing the cards
        self.dealer_holdings_var = tk.IntVar(value=5000)
        self.dealer_hand = None
        self.dealer_cards_var = tk.StringVar(value="")

        # Holders for player's bet, the pot and a description of the winning hand
        self.bet_var = tk.IntVar(value=0)
        self.pot_var = tk.IntVar(value=0)
        self.winner_var = tk.StringVar(value="")

    def place_bet(self):
        """
        Player makes a bet.  The amount of the bet is subtracted from both the player's holdings and the
        dealer's holdings and added to the pot.  The cards are dealt.
        """
        bet = self.bet_var.get()
        player_holdings = self.player_holdings_var.get()
        dealer_holdings = self.dealer_holdings_var.get()

        if bet and 0 < bet <= player_holdings and dealer_holdings >= bet:
            player_holdings -= bet
            self.player_holdings_var.set(player_holdings)
            dealer_holdings -= bet
            self.dealer_holdings_var.set(dealer_holdings)
            self.pot_var.set(2*bet)
            self.bet_var.set(0)
            return self.deal()
        else:
            print("Bet must be a positive integer but less than both the player's holdings "
                  "and the dealer's holdings.")
            return None

    def deal(self):
        """
        Two cards are dealt to each player.  All but the dealer's hole card are shown.  The player is
        declared a winner if his/her 2 cards amount to 21.  Otherwise, the game continues.
        """
        self.player_hand = Hand([self.draw_card(), self.draw_card()])
        self.player_cards_var.set(self.player_hand.display())
        self.dealer_hand = Hand([self.draw_card(), self.draw_card()])
        self.dealer_cards_var.set(self.dealer_hand.display(hole_card=True))
        if self.player_hand.is_blackjack():
            self.player_wins("Blackjack")
            return True
        return False

    def player_wins(self, reason):
        """
        The contents of the pot are emptied and added to the player's holdings.  The victor and the nature of
        the win are set in the winner variable for display.
        """
        pot = self.pot_var.get()
        player_holdings = self.player_holdings_var.get()
        player_holdings += pot
        self.player_holdings_var.set(player_holdings)
        self.pot_var.set(0)
        self.winner_var.set(f"Player - {reason}")

    def dealer_wins(self, reason):
        """
        The contents of the pot are emptied and added to the deaker's holdings.  The victor and the nature of
        the win are set in the winner variable for display.
        """
        pot = self.pot_var.get()
        dealer_holdings = self.dealer_holdings_var.get()
        dealer_holdings += pot
        self.dealer_holdings_var.set(dealer_holdings)
        self.pot_var.set(0)
        self.winner_var.set(f"Dealer - {reason}")

    def hit(self):
        """
        Player chooses to hit.  The new card is displayed and the hand is re-evaluated to determine
        whether the player won or lost or whether the game should continue.
        """
        self.player_hand.hit(self.draw_card())
        self.player_cards_var.set(self.player_hand.display())
        if self.player_hand.is_bust():
            self.dealer_wins("Player goes Bust")
            return True
        if self.player_hand.is_blackjack():
            self.player_wins("Blackjack")
            return True
        return False

    def stand(self):
        """
        Player choose to stand.  The dealer reveals the hole card and hits the hand until the hand evaluates
        to at least 17 points.  At the conclusion of this method either the player or the dealer will have
        won the game.
        """
        self.dealer_cards_var.set(self.dealer_hand.display())
        while self.dealer_hand.total_points["soft"] < 17:
            self.dealer_hand.hit(self.draw_card())
            self.dealer_cards_var.set(self.dealer_hand.display())
        if self.dealer_hand.is_blackjack():
            self.dealer_wins("Blackjack")
        elif self.dealer_hand.is_bust():
            self.player_wins("Dealer goes Bust")
        elif self.dealer_hand.beats(self.player_hand):
            self.dealer_wins("Dealer's Hand Beats Player's Hand")
        else:
            self.player_wins("Player's Hand Beats Dealer's Hand")
        return True

    def continue_play(self):
        """
        If the user indicates that he/she wants to play again, the prior hands and their displayed cards are
        erased.
        """
        self.player_hand = None
        self.player_cards_var.set("")
        self.dealer_hand = None
        self.dealer_cards_var.set("")

    def draw_card(self):
        """
        Draws a card from the deck.  If the deck is exhausted, a new deck is shuffled and
        used.
        """
        card = self.deck.draw()
        if card is None:
            self.deck = Deck()
            card = self.deck.draw()
        return card
예제 #24
0
from flask import render_template, request, url_for, redirect, send_file
from app import app
from game import Deck, Card
import random
deck = Deck()


@app.route('/', methods=['GET', 'POST'])
@app.route('/index', methods=['GET', 'POST'])
def index():
    title = 'random'

    deck = Deck()

    deck.shuffle()

    card = deck.drawCard()

    return render_template('index.html', title=title, card=card)


@app.route('/card', methods=['GET', 'POST'])
def card():
    title = 'random'
    card = deck.drawCard()

    return render_template('index.html', title=title, card=card)
 def p0(self):
     return Player('First', Deck())
 def test_drawn_card_is_not_in_deck_anymore(self, _random_module):
     deck = Deck()  # Not using fixture because of 'hypothesis'
     card = deck.draw_card()
     cards_in_deck_after_draw = deck.cards.copy()
     assert card not in cards_in_deck_after_draw
 def other_player(self):
     return Player('Opponent', Deck())
 def test_initial_values(self):
     player = Player('Frank', Deck())
     assert player.name == 'Frank'
     assert player.health == 30
     assert player.mana_slots == 0
     assert player.mana == 0
예제 #29
0
class Table:
    INIT_CHIPS = 100
    SMALL_BET = 2
    BIG_BET = 4

    def __init__(self, players_classes: List[Type[BasicPlayer]]) -> None:
        self._init_chips = self.INIT_CHIPS
        self._deck = Deck()
        self._players = self._create_players(players_classes)
        self._total_players = self._players.count()
        self._pot = 0
        self._pot_leftover = 0
        self._community_cards = []
        self._current_bet = 0
        self._small_bet = self.SMALL_BET
        self._big_bet = self.BIG_BET
        self._current_raise = self._small_bet
        self._raise_cnt = 0
        self._is_round_active = True
        self._is_game_active = True
        self._observers = Observers()
        self._players_who_lost = []
        self._current_phase = None

    def run_tournament(self) -> None:
        while self._is_game_active:
            self._init_pre_flop_phase()
            self._init_flop_phase()
            self._init_turn_phase()
            self._init_river_phase()
            self._init_showdown_phase()
            self._init_pot_collection_phase()
            self._prepare_next_round()

    def reset_tournament(self) -> None:
        self._reset_players()
        self._reset_player_chips()
        self._reset_play()
        self._is_game_active = True

    def get_winner_name(self) -> str:
        if self._is_winner_present():
            return self._players.name
        return str(None)

    @property
    def player_names(self) -> List[str]:
        names = []
        for player in self._players:
            names.append(player.name)

        return names

    def attach_observer(self, observer: BaseObserver) -> None:
        self._observers.attach(observer)

    def detach_observer(self, observer: BaseObserver) -> None:
        self._observers.detach(observer)

    def _create_players(self, players_classes: List[Type[BasicPlayer]]) -> TablePlayers:
        if len(players_classes) < 2 or len(players_classes) > 10:
            raise ValueError('Only between 2 and 10 players allowed...')

        dealer = None
        previous_table_player = None

        for player_cnt in range(len(players_classes)):
            player_name = f'Player_{str(player_cnt + 1)} ({players_classes[player_cnt].__name__})'
            basic_player = players_classes[player_cnt](self._init_chips, player_name)

            if not isinstance(basic_player, BasicPlayer):
                raise ValueError('Class has to be extended from game.Player base class')

            table_player = TablePlayers(basic_player)

            if previous_table_player is not None:
                previous_table_player.next = table_player
            else:
                dealer = table_player

            previous_table_player = table_player

        previous_table_player.next = dealer

        return dealer

    def _init_pre_flop_phase(self) -> None:
        self._current_phase = Phases.PRE_FLOP

        self._deck.shuffle()
        self._deal_cards()
        self._collect_blinds()
        self._current_raise = self._current_bet = self._small_bet

        self._init_betting_round(self._players.get_by_position(3))

        self._update_round_active_state()

        self._notify_observers()

    def _init_flop_phase(self) -> None:
        self._current_phase = Phases.FLOP

        self._deal_community_cards(3)

        if self._is_round_active:
            self._init_common_phase(self._small_bet)

        self._notify_observers()

    def _init_turn_phase(self) -> None:
        self._current_phase = Phases.TURN

        self._deal_community_cards()

        if self._is_round_active:
            self._init_common_phase(self._big_bet)

        self._notify_observers()

    def _init_river_phase(self) -> None:
        self._current_phase = Phases.RIVER

        self._deal_community_cards()

        if self._is_round_active:
            self._init_common_phase(self._big_bet)

        self._notify_observers()

    def _init_showdown_phase(self) -> None:
        self._current_phase = Phases.SHOWDOWN

        self._find_players_final_hand()

        self._notify_observers()

    def _init_pot_collection_phase(self) -> None:
        self._current_phase = Phases.POT_COLLECTION

        sorted_players = self._sort_players_by_score()
        individual_pot_collection = self._split_pot_among_players(sorted_players)
        pot_leftover_collections = 0

        for player in self._players:
            if player in individual_pot_collection:
                collecting_chips = self._take_from_pot(individual_pot_collection[player])
                same_win_amount = list(individual_pot_collection.values()).count(individual_pot_collection[player])
                total_pot_leftover = self._pot_leftover * (pot_leftover_collections + 1)
                if self._pot_leftover > 0 and total_pot_leftover % same_win_amount == 0:
                    collecting_chips += self._take_from_pot_leftover(int(total_pot_leftover / same_win_amount))
                    pot_leftover_collections += 1

                player.receive_chips(collecting_chips)
            else:
                player.receive_chips(0)

        self._pot_leftover += self._take_from_pot(self._pot)

        self._notify_observers(individual_pot_collection)

    def _prepare_next_round(self) -> None:
        self._define_next_dealer()
        self._kick_out_players_who_lost()
        self._update_game_active_state()

        if self._is_game_active:
            self._reset_play()

    def _init_common_phase(self, bet_size: int) -> None:
        self._prepare_common_phase(bet_size)

        self._init_betting_round(self._players.next)

        self._update_round_active_state()

    def _prepare_common_phase(self, bet_amount: int) -> None:
        self._current_raise = bet_amount
        self._raise_cnt = 0
        self._current_bet = 0

        for player in self._players:
            player.current_bet = 0
            if player.current_move is not Moves.FOLD and player.current_move is not Moves.ALL_IN:
                player.current_move = None

    def _init_betting_round(self, stopping_player: TablePlayers) -> None:
        player = stopping_player

        while True:
            self._update_round_active_state()
            if not self._is_round_active:
                break

            moves = self._generate_player_moves(player)

            if moves is None:
                player = player.next
                if player is stopping_player:
                    break
                continue

            move = player.make_move(moves, self.generate_game_state(tuple(moves)))

            raise_cnt_before_move_execution = self._raise_cnt

            self._execute_player_move(player, move)

            if player.current_move is Moves.RAISE or (
                    player.current_move is Moves.ALL_IN and raise_cnt_before_move_execution != self._raise_cnt):
                stopping_player = player

            player = player.next

            if player is stopping_player:
                break

        for player in self._players:
            if player.current_move is Moves.ALL_IN and player.is_active:
                player.is_active = False

    def _deal_cards(self) -> None:
        for _ in range(2):
            self._deal_one_round()

    def _deal_community_cards(self, amount: int = 1):
        self._deck.burn()
        self._community_cards += self._deck.deal(amount)

    def _deal_one_round(self) -> None:
        for player in self._players:
            player.receive_cards(self._deck.deal())

    def _collect_blinds(self) -> None:
        player = self._players.next
        self._collect_blind(player, int(self._small_bet / 2))

        player = player.next
        self._collect_blind(player, self._small_bet)

        self._current_bet = self._small_bet

    def _collect_blind(self, player: TablePlayers, blind: int) -> None:
        if player.get_amount_of_chips() > blind:
            self._collect_bet(player, blind)
        else:
            amount = player.get_amount_of_chips()
            self._collect_bet(player, amount)
            player.current_move = Moves.ALL_IN

    def _collect_bet(self, player: TablePlayers, amount: int) -> None:
        self._pot += player.spend_chips(amount)
        player.current_bet += amount
        player.total_bet += amount

    def _generate_player_moves(self, player: TablePlayers) -> Optional[List[Moves]]:
        moves = list()

        if player.current_move is Moves.FOLD or player.get_amount_of_chips() == 0:
            return None

        if player.current_bet < self._current_bet < player.get_amount_of_chips() + player.current_bet:
            moves.append(Moves.CALL)

        if player.get_amount_of_chips() + player.current_bet <= self._current_bet \
                or (player.get_amount_of_chips() + player.current_bet <= (self._current_bet + self._current_raise)
                    and not self._is_raising_capped()):
            moves.append(Moves.ALL_IN)

        if self._current_bet == player.current_bet:
            moves.append(Moves.CHECK)

        if not self._is_raising_capped() \
                and player.get_amount_of_chips() + player.current_bet > (self._current_bet + self._current_raise) \
                and self._players.count() - (
                len(self._players.find_by_move(Moves.FOLD)) + len(self._players.find_by_move(Moves.ALL_IN))) > 1:
            moves.append(Moves.RAISE)

        moves.append(Moves.FOLD)

        return moves

    def _is_raising_capped(self) -> bool:
        return not self._raise_cnt < 4

    def generate_game_state(self, allowed_moves: Tuple[Moves]) -> State:
        return State(
            community_cards=tuple(Card(c.rank, c.suit, c.value) for c in self._community_cards),
            total_players=self._total_players,
            total_chips=self._total_players * self._init_chips,
            nbr_of_active_players=self._players.count() - len(self._players.find_by_move(Moves.FOLD)),
            current_phase=self._current_phase,
            is_raising_capped=self._is_raising_capped(),
            allowed_moves=allowed_moves,
            pot=self._pot,
            current_bet=self._current_bet
        )

    def _execute_player_move(self, player: TablePlayers, move: Moves) -> None:

        if move is Moves.CALL:
            amount = self._calculate_amount_to_call(player)
            self._collect_bet(player, amount)

        elif move is Moves.RAISE:
            amount = self._calculate_amount_to_raise(player)
            self._collect_bet(player, amount)
            self._current_bet = player.current_bet
            self._raise_cnt += 1

        elif move is Moves.ALL_IN:
            amount = player.get_amount_of_chips()
            self._collect_bet(player, amount)
            if self._current_bet < player.current_bet:
                self._raise_cnt += 1
                self._current_bet = player.current_bet
            else:
                player.is_active = False

        elif move is Moves.FOLD:
            player.is_active = False

        player.current_move = move

    def _calculate_amount_to_call(self, player: TablePlayers) -> int:
        return self._current_bet - player.current_bet

    def _calculate_amount_to_raise(self, player: TablePlayers) -> int:
        return self._calculate_amount_to_call(player) + self._current_raise

    def _update_round_active_state(self) -> None:
        total_players = self._players.count()
        folded_players = len(self._players.find_by_move(Moves.FOLD))
        not_folded_players = total_players - folded_players
        none_move_players = len(self._players.find_by_move(None))

        self._is_round_active = (self._players.count_active()) > 1 or (not_folded_players > 1 and none_move_players > 0)

    def _find_players_final_hand(self) -> None:

        for player in self._players:
            if player.current_move is not Moves.FOLD:
                final_hand = StrongestFinalHandFinder.find(self._community_cards + player.get_hand())

                player.final_hand = final_hand.hand
                player.final_hand_type = final_hand.type
                player.score = final_hand.score

    def _sort_players_by_score(self) -> List[List[TablePlayers]]:
        sorted_players = list()

        for player in self._players:
            sorted_players = self._insert_player_in_sorted_list(player, sorted_players)

        return sorted_players

    def _insert_player_in_sorted_list(self, player: TablePlayers, sorted_players: List[List[TablePlayers]]) \
            -> List[List[TablePlayers]]:
        has_player_been_inserted = False

        for i in range(len(sorted_players)):
            if player.score > self._players.find(sorted_players[i][0]).score:
                sorted_players.insert(i, [player])
                has_player_been_inserted = True

            elif player.score == self._players.find(sorted_players[i][0]).score:
                comparing_player = sorted_players[i][0]
                stronger_player = self._find_stronger_player_on_draw(player, comparing_player)

                if stronger_player is None:
                    sorted_players[i].append(player)
                    has_player_been_inserted = True

                elif player is stronger_player:
                    sorted_players.insert(i, [player])
                    has_player_been_inserted = True

            if has_player_been_inserted:
                break

        if not has_player_been_inserted:
            sorted_players.append([player])

        return sorted_players

    @staticmethod
    def _find_stronger_player_on_draw(player_1: TablePlayers, player_2: TablePlayers) -> Optional[TablePlayers]:
        if player_1.final_hand is None:
            return None

        for i, player_1_card in enumerate(player_1.final_hand):
            if player_1_card.value > player_2.final_hand[i].value:
                return player_1

            if player_2.final_hand[i].value > player_1_card.value:
                return player_2

        return None

    def _split_pot_among_players(self, players_grouped_by_strength: List[List[TablePlayers]]) \
            -> Dict[TablePlayers, int]:
        players_pot_collections = {player: 0 for player in self._players}
        is_pot_collection = True

        while is_pot_collection:
            collecting_players = players_grouped_by_strength.pop(0)
            sub_pot = self._calculate_sub_pot(collecting_players, players_grouped_by_strength)

            if sub_pot is None:
                pot = 0

                for player in self._players:
                    pot += player.total_bet

                pot_division = pot / len(collecting_players)

                for player in collecting_players:
                    players_pot_collections[player] = int(pot_division)

                is_pot_collection = False

            else:
                individual_pot_collection = self._split_sub_pot_among_players(collecting_players)
                is_pot_collection = self._should_pot_collection_continue(collecting_players,
                                                                         players_grouped_by_strength)

                for player in collecting_players:
                    players_pot_collections[player] = int(individual_pot_collection[player])

                if is_pot_collection:
                    self._update_players_total_bet(collecting_players, players_grouped_by_strength)

        return players_pot_collections

    def _calculate_sub_pot(self, collecting_players: List[TablePlayers],
                           players_grouped_by_strength: List[List[TablePlayers]]) -> Optional[int]:
        is_any_player_all_in = False
        sub_pot = 0

        for player in collecting_players:
            player_bet = player.total_bet
            sub_pot += player_bet

            if player.current_move is Moves.ALL_IN:
                is_any_player_all_in = True

        if not is_any_player_all_in:
            return None
        else:
            highest_bet = self._find_highest_player_bet(collecting_players)
            for player_group in players_grouped_by_strength:
                sub_pot += self._calculate_sub_pot_portion(player_group, highest_bet)

            return sub_pot

    @staticmethod
    def _calculate_sub_pot_portion(players: List[TablePlayers], amount: int) -> int:
        sub_pot_portion = 0

        for player in players:
            if player.total_bet < amount:
                sub_pot_portion += player.total_bet
            else:
                sub_pot_portion += amount

        return sub_pot_portion

    def _split_sub_pot_among_players(self, collecting_players: List[TablePlayers]) -> Dict[TablePlayers, int]:
        individual_pot_collection = {p: 0 for p in collecting_players}
        highest_bet = self._find_highest_player_bet(collecting_players)
        players_bets_asc = [{
            'bet': highest_bet,
            'total_players': 0,
            'collecting_players': 0
        }]

        for player in self._players:
            index = None
            for i, player_bet in enumerate(players_bets_asc):
                if player.total_bet < player_bet['bet']:
                    index = i
                    break

            if index is not None:
                players_bets_asc.insert(index, {
                    'bet': player.total_bet,
                    'total_players': 0,
                    'collecting_players': 0
                })

        for player in self._players:
            for player_bet in players_bets_asc:
                if player.total_bet == player_bet['bet']:
                    player_bet['total_players'] += 1
                    if player in collecting_players:
                        player_bet['collecting_players'] += 1
                    break

                if player.total_bet > player_bet['bet']:
                    player_bet['total_players'] += 1
                    if player in collecting_players:
                        player_bet['collecting_players'] += 1

        for player in collecting_players:
            sub = 0
            for player_bet in players_bets_asc:
                if player.total_bet >= player_bet['bet']:
                    individual_pot_collection[player] += \
                        ((player_bet['bet'] - sub) * player_bet['total_players']) / player_bet['collecting_players']
                sub = player_bet['bet']

        return individual_pot_collection

    @staticmethod
    def _find_lowest_bet(players: List[TablePlayers]) -> int:
        comparing_player = players[0]
        lowest_bet = comparing_player.total_bet

        for i in range(1, len(players)):
            if players[i].total_bet < lowest_bet:
                lowest_bet = players[i].total_bet

        return lowest_bet

    def _should_pot_collection_continue(self, collecting_players: List[TablePlayers],
                                        players_grouped_by_strength: List[List[TablePlayers]]) -> bool:
        should_collection_continue = False
        highest_collecting_player_bet = 0

        for player in collecting_players:
            if player.total_bet > highest_collecting_player_bet:
                highest_collecting_player_bet = player.total_bet

        for player_group in players_grouped_by_strength:
            highest_not_collecting_player_bet = self._find_highest_player_bet(player_group)

            if highest_not_collecting_player_bet > highest_collecting_player_bet:
                should_collection_continue = True
                break

        return should_collection_continue

    @staticmethod
    def _find_highest_player_bet(players: List[TablePlayers]) -> int:
        comparing_player = players[0]
        highest_bet = comparing_player.total_bet

        for i in range(1, len(players)):
            if players[i].total_bet > highest_bet:
                highest_bet = players[i].total_bet

        return highest_bet

    def _update_players_total_bet(self, collecting_players: List[TablePlayers],
                                  players_grouped_by_strength: List[List[TablePlayers]]) -> None:
        highest_bet = self._find_highest_player_bet(collecting_players)

        for player in collecting_players:
            player.total_bet = 0

        for player_group in players_grouped_by_strength:
            self._reduce_players_total_bet(player_group, highest_bet)

    @staticmethod
    def _reduce_players_total_bet(players: List[TablePlayers], amount: int) -> None:
        for player in players:
            if player.total_bet < amount:
                player.total_bet = 0
            else:
                player.total_bet -= amount

    def _take_from_pot(self, amount: int) -> int:
        self._pot -= amount
        return amount

    def _take_from_pot_leftover(self, amount: int) -> int:
        self._pot_leftover -= amount
        return amount

    def _define_next_dealer(self) -> None:
        for player in self._players:
            if player.next.get_amount_of_chips() > 0:
                self._players = player.next
                break

    def _kick_out_players_who_lost(self) -> None:
        players_who_lost = []

        for player in self._players:
            if player.get_amount_of_chips() == 0:
                players_who_lost.append(player)

        for player in players_who_lost:
            self._players.remove_player(player)
            self._players_who_lost.append(player)

    def _reset_play(self) -> None:
        self._community_cards = []
        self._current_bet = 0
        self._current_raise = 0
        self._is_round_active = True
        self._raise_cnt = 0
        self._deck = Deck()

        for player in self._players:
            player.reset()

    def _update_game_active_state(self) -> None:
        self._is_game_active = not self._is_winner_present()

    def _is_winner_present(self) -> bool:
        return self._players.count() == 1

    def _reset_players(self) -> None:
        players = []

        for p in self._players_who_lost:
            players.append(p)

        for p in self._players:
            players.append(p)

        np = None
        for p in players:
            if np is not None:
                np.next = p
            np = p
        np.next = players[0]
        self._players = np.next
        self._players_who_lost = []

    def _reset_player_chips(self) -> None:
        for p in self._players:
            a = p.get_amount_of_chips()
            p.spend_chips(a)
            p.receive_chips(self._init_chips)

    def _notify_observers(self, individual_pot_collection: Optional[Dict[TablePlayers, int]] = None) -> None:
        state = ObserverState(
            players=self._players,
            community_cards=deepcopy(self._community_cards),
            pot=self._pot,
            phase=self._current_phase,
            individual_pot_collection=individual_pot_collection
        )
        self._observers.notify(state)

    def print_player_info(self):
        print('--- PLAYER INFO ---')
        for player in self._players:
            hand = player.get_hand()
            print('NAME:\t\t' + str(player.name))
            print('HAND:\t\t' + (str(hand[0].rank) + ' ' + str(hand[0].suit) + ', '
                                 + str(hand[1].rank) + ' ' + str(hand[1].suit) if len(hand) > 0 else str(
                hand)))
            print('CURRENT_BET:\t' + str(player.current_bet))
            print('CURRENT_MOVE:\t' + str(player.current_move))
            print('CURRENT_CHIPS:\t' + str(player.get_amount_of_chips()))
            print('SCORE:\t\t' + str(player.score))
            print('FINAL_HAND:\t' + str(player.final_hand_type))
            print()

    def print_state_info(self):
        cards = ''
        for card in self._community_cards:
            cards += '[' + str(card.rank) + ' ' + str(card.suit + '] ')

        print('--- STATE INFO ---')
        print('IS_ACTIVE:\t' + str(self._is_round_active))
        print('SMALL_BET:\t' + str(self._small_bet))
        print('BIG_BET:\t' + str(self._big_bet))
        print('POT:\t\t' + str(self._pot))
        print('DEALER:\t\t' + str(self._players.name))
        print('CURRENT_BET:\t' + str(self._current_bet))
        print('CURRENT_RAISE:\t' + str(self._current_raise))
        print('RAISE_CNT:\t' + str(self._raise_cnt))
        print('COMMUNITY_CARDS:' + cards)
        print()
예제 #30
0
from pprint import pprint

from game import Game, Player, Deck

if __name__ == '__main__':
    p1_name = input('Player 1:')
    p2_name = input('Player 2:')

    p1 = Player(p1_name, Deck())
    p2 = Player(p2_name, Deck())
    game = Game(p1, p2)

    while not game.status['finished']:
        pprint(game.status)
        print('')
        print(f"It's {game.status['current_player']}'s turn")
        card_index = int(input('Which card? (index (<0 to pass))'))
        if card_index < 0:
            game.finish_turn()
        else:
            card = game.status['players'][
                game.status['current_player']]['hand'][card_index]
            game.play_card(card)
            print(f"You planed {card}")
        print('')
        print('')

    print("Game Finished!! :D :D")
    pprint(game.status)
 def test_draws_3_cards(self, draw_card_mock):
     _player = Player('Frank', Deck())
     assert draw_card_mock.call_count == 3
 def p1(self):
     return Player('Second', Deck())
 def test_cards_left(self, _random_module):
     deck = Deck()
     deck.cards = [Card(0), Card(0), Card(8)]
     assert deck.cards_left() == 3
     deck.draw_card()
     assert deck.cards_left() == 2
from __future__ import division

import numpy as np
#import xrange

from game import CardGame, Deck, Player
from mc import MonteCarloLearning

CARDS_IN_DECK = {0.25: 16, 0.50: 28, 0.75: 16}
NUM_PLAYERS = 2
HAND_SIZE = 5
ACTIONS = ['small_spoil', 'median', 'large_max']

NUM_GAMES_TO_PLAY = 2000000

deck = Deck(CARDS_IN_DECK)
card_game = CardGame(deck, NUM_PLAYERS, ACTIONS, HAND_SIZE)


def play_action(card_showing, player):
    if card_showing == 0:  # player goes first
        if player.next_action == ACTIONS.index('small_spoil'):
            card_value = player.play_card(0)
        elif player.next_action == ACTIONS.index('large_max'):
            card_value = player.play_card(-1)
        else:
            card_value = player.play_card(card_game.hand_size // 2)
    else:  # opponent went first, player's turn
        if player.next_action == ACTIONS.index('small_spoil'):
            for c, card in enumerate(player.hand):
                if card + card_showing > 1.0:  # can spoil, play this card
예제 #35
0
파일: test_deck.py 프로젝트: pisskidney/mdp
 def test_pop_card(self):
     d1 = Deck()
     c1 = d1.pop_card()
     self.assertEqual(c1.rank, ranks[-1])
     self.assertEqual(c1.suit, suits[-1])
예제 #36
0
 def test_shuffle(self):
     deck = Deck.create(1)
     cards = list(deck.deck)
     deck.shuffle()
     assert cards[0] != deck.deck[0]
 def deck(self):
     return Deck()
 def test_draw_card_draws_random_card_from_deck(self, _random_module):
     deck = Deck()  # Not using fixture because of 'hypothesis'
     cards_in_deck_before_draw = deck.cards.copy()
     card = deck.draw_card()
     assert card in cards_in_deck_before_draw