def test_shuffle(self, shuffle_mock): number = 1 deck = Deck(number) deck.shuffle() shuffle_mock.assert_called_with(deck.cards)
def test_shuffle_changes_cards_order(self): d = Deck() for _ in range(0, 4): deck_before = d.deck.copy() self.assertEqual(None, d.shuffle()) self.assertNotEqual(d.deck, deck_before)
class DeckTest(unittest.TestCase): def setUp(self): self.deck = Deck() def test_deck_reshuffle(self): self.assertIsNotNone(self.deck.cards) self.assertListEqual(self.deck.dealt, []) def test_generate_deck(self): new_deck = self.deck._generate() self.assertIsInstance(new_deck, list) self.assertEqual(len(set(new_deck)), 52) self.assertEqual(len(new_deck[0]), 2) def test_shuffle(self): old_deck = list(self.deck.cards) self.deck.shuffle() new_deck = list(self.deck.cards) self.assertEqual(len(old_deck), len(new_deck)) self.assertNotEqual(old_deck, new_deck) self.assertEqual(sum([1 for card in self.deck.cards if card in old_deck]), len(old_deck)) def test_deal(self): for n in [0, 1, 2, 52]: with self.subTest(n=n): old_deck = list(self.deck.cards) if n <=0: with self.assertRaises(AssertionError): self.deck.deal(n_cards=n) elif n > len(old_deck): with self.assertRaises(DeckException): self.deck.deal(n_cards=n) else: dealt = self.deck.deal(n_cards=n) dealt.reverse() self.assertEqual(len(self.deck.cards), len(old_deck) - n) self.assertEqual(len(dealt), n) self.assertListEqual(old_deck[-n:], dealt) self.assertNotIn(dealt[0], self.deck.cards)
def play_blackjack(chips=Account('Chris', 500)): """ Play BlackJack :param chips: object :return: """ # request a name be entered if one isn't present while not len(chips.name): try: named = input('What\'s your name? ') if named.isalpha(): chips.name = named break else: print( f"{named} is not a valid name, please enter a valid name") continue except: print( 'Sorry something went wrong, please try and input your name again' ) continue # Add fund to account if none is present if not chips.has_funds(): chips.add_funds() # Add bet if none has been placed while not chips.has_bet(): chips.make_bet() # Build deck and shuffle deck = Deck() deck.shuffle() deal_count = 1 player = Hand() dealer = Hand() player.cards = [] dealer.cards = [] # Start first phase of the dealing while deal_count <= 4: deal_count += 1 if deal_count % 2 == 0: if deal_count == 4: the_fourth_card = deck.deal() the_fourth_card.hide_card() dealer.add_card(the_fourth_card) else: dealer.add_card(deck.deal()) else: player.add_card(deck.deal()) # Second phase of the dealing while True: # display cards clear() print(chips.name + ': ') print(player) print('Dealers: ') print(dealer) if player.bust(): break if player.next_move(): player.add_card(deck.deal()) continue else: break # change view permissions for card in dealer.cards: card.show_card() # Once player finishes turn continue to deal dealers hand while True: # display cards clear() print(chips.name + ': ') print(player) print('Dealers: ') print(dealer) if dealer.bust(): break if player.bust(): break if dealer.total() > player.total(): break else: dealer.add_card(deck.deal()) continue # display results and finalise transaction if player.bust(): clear() chips.subtract() print( f"{chips.name} you lost this one\n\nYour new Balance {chips.balance()}\n" f"{chips.name}: {player}" f"Dealers: {dealer}" f"\nYour Score {player.total()}\nDealers Score {dealer.total()}") elif player.total() < dealer.total() and not dealer.bust(): clear() chips.subtract() print( f"{chips.name} the dealer beat your score\n\nYour new Balance {chips.balance()}\n" f"{chips.name}: {player}" f"Dealers: {dealer}" f"\nYour Score {player.total()}\nDealers Score {dealer.total()}") else: clear() chips.add() print(f"{chips.name} you won!\n\nYour new Balance {chips.balance()}\n" f"{chips.name}: {player}" f"Dealers: {dealer}" f"\nYour Score {player.total()}\nDealers Score {dealer.total()}") # Do they want to replay while True: try: replay = input('Do you want to play again? ').upper() if replay == 'YES': play_blackjack() break elif replay == 'NO': print( f'{chips.name} thank you for playing and we look forward to seeing you again' ) break else: print( 'We didn\'t understand your request, a YES or NO is desired' ) continue except ValueError: print( 'Invalid Input: We didn\'t recognise your request please try again YES or No' ) continue
class Game: deck: Deck def __init__(self, players, dealer): self.players = players self.dealer = dealer def clean_cards(self): for player in self.players: player.cards = [] self.dealer.cards = [] def game_loop(self): while True: self.single_game() print('\nGame finished') for player in self.players: if player.budget < 2: print(f'Out of budget, {player.name}. Bye!') self.players.remove(player) if not self.players: break print('\nContinue?') if get_answer() == 'n': break def single_game(self): print_header('Make your bets') self.make_bets() print_header('Preparing the deck') self.prepare_deck(1) print_header('Dealing cards') self.clean_cards() self.deal_start_cards() self.print_participants_cards() print_header('Make your moves') self.each_player_makes_move() self.print_participants_cards() print_header('Dealer exposes cards') self.dealer.expose_cards() self.print_participants_cards() self.dealer_makes_move() print_header('Game end state:') self.print_participants_cards() print_header('Winners') self.determine_winner() def prepare_deck(self, count): self.deck = Deck(count) self.deck.shuffle() def make_bets(self): for player in self.players: player.make_bet() def deal_start_cards(self): for player in self.players: player.cards.extend(self.deck.get(exposed=2)) self.dealer.cards.extend(self.deck.get(exposed=1, hidden=1)) def print_participants_cards(self): for number, player in enumerate(self.players + [self.dealer]): player.print_summary() print('\n') def each_player_makes_move(self): for player in self.players: while player.determine_points() <= 21: action = player.make_move() if action == 'stand': break player.cards.extend(self.deck.get(exposed=1)) player.print_summary() def dealer_makes_move(self): while True: action = self.dealer.make_move() if action == 'stand': break self.dealer.cards.extend(self.deck.get(exposed=1)) self.dealer.print_summary() def _win(self, player, multiplier=1): amount = player.current_bet * multiplier player.budget += amount self.dealer.budget -= amount print(f'\n{player.name} wins this time! (${amount})\n') def _lose(self, player): amount = player.current_bet player.budget -= amount self.dealer.budget += amount print(f'\n{player.name} loses this time. (${amount})\n') def determine_winner(self): dealer_points = self.dealer.determine_points() for player in self.players: player_points = player.determine_points() if player_points == 21 and dealer_points != 21: self._win(player, 2) elif dealer_points > 21 and player_points <= 21: self._win(player) elif player_points > 21: self._lose(player) elif player_points > dealer_points: self._win(player) elif player_points < dealer_points: self._lose(player) else: print(f'Push! No loses for {player.name}')
class Blackjack: shuffle_counter = 0 max_deals = 50 def __init__(self, players): self.deck = Deck() self.deck.shuffle() self.dealer = Dealer() self.players = players self.player_records = {player: PlayerRecord( player) for player in players} def start_round(self): logger.info('[START]') logger.info('[CARDS] {0}'.format( list(card.value for card in self.deck.cards))) self.deal_starting_hands() self.pay_out_naturals() self.run_main_loop() results = self.generate_round_results() self.reset_records() return results def deal_starting_hands(self): for player in self.players: self.player_records[player].bet = player.get_bet() self.deal_card(player) self.deal_card(self.dealer) for player in self.players + [self.dealer]: self.deal_card(player) def pay_out_naturals(self): dealer = self.dealer players = self.players players_with_naturals = [ player for player in players if player.has_natural()] if dealer.has_natural(): for player in players: if player not in players_with_naturals: self.end_player_turn(player, 'L') else: self.end_player_turn(player, 'D') else: for player in players_with_naturals: self.end_player_turn(player, 'W', True) def run_main_loop(self): active_players = self.get_active_players() dealer = self.dealer while len(active_players) > 0: for player in active_players: if player.will_hit(): self.deal_card(player) if player.hand.get_score() > 21: self.end_player_turn(player, 'L') else: self.stand(player) active_players = self.get_active_players() logger.info('[ROUND] {0} active players left'.format( len(active_players))) while dealer.will_hit(): self.deal_card(dealer) dealer_score = dealer.hand.get_score() for player in self.get_standing_players(): player_score = player.hand.get_score() if dealer_score > 21: result = 'W' else: if player_score == dealer_score: result = 'D' elif player_score > dealer_score: result = 'W' else: result = 'L' self.end_player_turn(player, result) def generate_round_results(self): results = [] for player in self.players: record = self.player_records[player] player_score = player.hand.get_score() dealer_score = self.dealer.hand.get_score() bet = record.bet balance = player.balance result = record.result results.append(Result( player, player_score, dealer_score, bet, balance, result)) return results def reset_records(self): for player in self.players: self.player_records[player].reset() self.dealer.reset() def get_active_players(self): return [player for player in self.players if self.player_records[player].is_player_active()] def get_standing_players(self): return [player for player in self.players if self.player_records[player].is_standing] def set_player_finished(self, player, result): record = self.player_records[player] record.in_game = False record.result = result def end_player_turn(self, player, result, natural=False): """ End turn with provided result and split bets accordingly. Arguments: player -- Currently playing result -- ['W', 'L', 'D'] for win, loss or draw natural -- Indicates if the player has a natural 21 """ logger.info('[RESULT] {0}: {1}'.format(player, result)) bet = self.player_records[player].bet if result == 'W': if natural: bet = bet * 1.5 self.dealer.pay(player, bet) elif result == 'L': player.pay(self.dealer, bet) self.set_player_finished(player, result) def notify_players(self, card, is_dealer): for player in self.players: player.on_card_dealt(card, is_dealer) def notify_players_shuffle(self): for player in self.players: player.on_shuffle() def deal_card(self, player, face_up=True): card = self.deck.deal() logger.info('[HIT] ({0}) {1}'.format(player, card)) player.hand.add_card(card) if face_up: self.notify_players(card, player == self.dealer) if self.shuffle_counter > self.max_deals: self.notify_players_shuffle() self.deck.shuffle() self.shuffle_counter = 0 self.shuffle_counter += 1 def stand(self, player): self.player_records[player].is_standing = True logger.info('[STAND] ({0})'.format(player))
class Game: def __init__(self, players_file): """ A new game - registered players are taken from input file - dealer gets 1000 - a new fresh deck - deck is shuffled """ self.players = Players(players_file) self.dealer = Dealer(1000) self.deck = Deck() self.deck.log() self.deck.shuffle() self.deck.log() self.rounds_played = 0 self.total_bets = 0 self.__outcome = game_outcome(self) def run(self): """ Game main """ # set the bets self.__set_bets() # deal cards self.__deal_first_hand() # log current game state self.log() # ask each player - (h)it or (s)tand? self.__players() # dealer's turn self.__dealer() # game's outcome self.__outcome.get() # see who's broke self.__check_players_for_money() # show the round's results self.__show_outcome() # reset for a new game self.__reset() def __deal_first_hand(self): """ Deals the first hand: - player 1, 2, 3, 4 first card - dealer only card - player 1, 2, 3, 4 second card """ log_and_print('') log_and_print(" > Dealing cards", end='') # players first card for player in self.players.players: delay() player.draw_card(self.deck.draw_card()) # dealer delay() self.dealer.draw_card(self.deck.draw_card()) # players second card for player in self.players.players: delay() player.draw_card(self.deck.draw_card()) log_and_print('') def __set_bets(self): """ Ask all the players to place their bets """ log.debug('Setting bets...') for player in self.players.players: self.total_bets += player.bet() def hit(self, player): card = self.deck.draw_card() player.draw_card(card) log_and_print('\t\t>> %s drew a card - [%s]' % (player.nume, str(card))) if (player.get_cards_sum() == 21): log_and_print('\t\t>> %s ' % (player.display_name())) if (player.get_cards_sum() > 21): player.lost = True log_and_print('\t\t>> %s is done' % (player.display_name())) return -1 return 0 def stand(self, player): log_and_print('\t\t>> %s stands [sum=%d]' % (player.display_name(), player.get_cards_sum())) log_and_print('-' * 80) def players_in_game(self): return len(self.players.get()) def new_round(self): answer = ' ' while answer != 'y' and answer != 'n': if self.rounds_played > 0: msg = "\nFancy another round? (Y)es or (N)o: " else: msg = "\nShall we begin a game? (Y)es or (N)o: " answer = input(msg).lower() if answer == 'y': self.rounds_played += 1 # check if we need a new deck self.__new_deck() return answer == 'y' def log(self): """ Log current game state """ # header log_and_print('') log.debug('-' * 80) log.debug('-- GAME STATE') log.debug('') # deck self.deck.log() log.debug('') fmt = ' %12s[%4d$] : %24s' # dealer log_and_print(fmt % (self.dealer.nume, self.dealer.jetoane, self.dealer.get_cards_str())) # players for player in self.players.players: log_and_print( fmt % (player.nume, player.jetoane, player.get_cards_str())) # footer log.debug('-' * 80) log_and_print('') def __everyone_lost(self): """ Return True if everyone lost :( """ return (self.dealer.lost and len(self.players.get_losers()) == len(self.players.get())) def __all_players_lost(self): """ Return True if all players lost lost :( """ return (len(self.players.get_losers()) == len(self.players.get())) def __show_outcome(self): """ Log current round's status """ # header log_and_print('') log.debug('-' * 80) log.debug('-- ROUND RESULT') log.debug('') # deck self.deck.log() log.debug('') # print format # ' name[money] : cards list | cards sum - [WON/LOST] bet_value fmt = ' %12s[%4s$] : %24s | %2s | %5s %4s$' fmt_l = ' %12s[%4d$] LOST' fmt_b = ' %12s[%4d$]' # print header log_and_print(fmt % ('Name', 'Amt', 'Card list', 'S', 'Stats', '')) log_and_print('-' * 66) # all lost if self.__everyone_lost(): # dealer log_and_print(fmt_l % (self.dealer.nume, self.dealer.jetoane)) # players for player in self.players.players: log_and_print(fmt_l % (player.nume, player.jetoane)) else: # dealer log_and_print( fmt % (self.dealer.nume, self.dealer.jetoane, self.dealer.get_cards_str(), self.dealer.get_cards_sum(), "+" if self.dealer.balance >= 0 else "-", str(abs(self.dealer.balance)))) # players for player in self.players.players: log_and_print( fmt % (player.nume, player.jetoane, player.get_cards_str(), player.get_cards_sum(), "-" if player.lost else "+", str(player.bet_value))) # bankrupts if len(self.players.broke_players) > 0: log_and_print('') log_and_print('Went bankrupt: ') for player in self.players.broke_players: log_and_print(fmt_b % (player.nume, player.jetoane)) def __new_deck(self): """ Use a fresh shuffled pack of cards if there aren't enough cards left `Enough cards` are defined randomly when each player plus the dealer can get 5 cards 5*(np + 1) """ if len(self.deck.card_deck) < (len(self.players.players) + 1) * 5: self.deck.__init__() self.deck.shuffle() self.deck.log() def __dealer(self): """ The dealer's turn at the game """ # stop if already won if self.__all_players_lost(): log.debug("Dealer already won! [stands... and drops the mic]") self.stand(self.dealer) return while True: time.sleep(0.1) s = self.dealer.get_cards_sum() # stop only if more than 17 if s > 17: self.stand(self.dealer) break # hit the dealer self.hit(self.dealer) def __players(self): """ Ask each player if they want another card or not """ for player in self.players.players: log.debug(' player %s turn' % player.nume) while True: answer = ' ' while answer != 'h' and answer != 's': answer = input('%s : (h)it or (s)tand? ' % player.display_name()).lower() # hit if answer == 'h': if self.hit(player) == -1: break continue # stand if answer == 's': self.stand(player) break def __check_players_for_money(self): """ Remove from the game players with no money left """ for player in self.players.get(): if player.jetoane == 0: self.players.broke(player) self.players.remove_broke_players_from_game() def __reset(self): """ Reset internal objects state for a new round """ self.players.reset_for_new_game() self.dealer.reset_for_new_game()
from blackjack.dealer import Dealer from blackjack.player import Player from blackjack.util import hand_total dealer = Dealer() player = Player() while True: print('*** Starting a new game...') playing = True player.hand = [] dealer.hand = [] dealer.show_hand = False deck = Deck() deck.shuffle() player.place_bet() player.get_card(deck.deal()) dealer.get_card(deck.deal()) player.get_card(deck.deal()) dealer.get_card(deck.deal()) print(dealer) print(player) while playing: hs = input('Hit or stand? (h/s) ') if hs == 'h':
from blackjack.card import Card #dont know if needed (deck.py is importhing card and comenting in isn't causing an error) from blackjack.player import Player from blackjack.thegame import TheGame #==================================================== #▒█▀█▀█░▐█░▐█░▐█▀▀ ░▐█▀▀▀──░▄█▀▄─▒▐██▄▒▄██▌░▐█▀▀ #░░▒█░░░▐████░▐█▀▀ ░▐█░▀█▌░▐█▄▄▐█░▒█░▒█░▒█░░▐█▀▀ #░▒▄█▄░░▐█░▐█░▐█▄▄ ░▐██▄█▌░▐█─░▐█▒▐█░░░░▒█▌░▐█▄▄ #==================================================== game = TheGame() player1 = Player('Player1') #player 1 is human player2 = Player('Computer') #player 2 is a computer #Before we start, we need to create deck mydeck = Deck() mydeck.shuffle() #THis will be repeated until player decide to stop playing while True: if player1.balance <= 0: print('Player have not money anymore. Game is finished!') break #in case it is not first round we have to discard all cards from hand player1.discard_hand() player2.discard_hand() #Before game each player pick their cards, Human players have to make a bet player1_bet = player1.bet() #Then, each player have to pick 2 cards player1.pick_cards(mydeck)
def play(): print("Welcome to blackjack!\n=====================") try: num_decks = int(input("Number of decks?: "), 10) except ValueError: print("You need to give me an integer value!") return try: cash = int(input("Starting cash?: "), 10) except ValueError: print("You need to give me an integer value!") return deck = Deck(num_decks) deck.shuffle(20) times_won = 0 times_drawn = 0 times_lost = 0 print("Let's Play!") while cash > 0 and len(deck.cards) > num_decks * 16: print(f"Your cash: ${cash}") try: bet = int(input("Place your bet!: "), 10) except ValueError: print("You need to give me an integer value!") break player_hand = Hand() dealer_hand = Hand() player_hand.add(deck.draw()) dealer_hand.add(deck.draw()) player_hand.add(deck.draw()) player_bust = False player_blackjack = False player_split = False while True: print() print(f"Dealer shows: {dealer_hand.list()}") print(f"Your hand: {player_hand.list()}") print(f"Your current value: {player_hand.value()}") print() if player_hand.is_blackjack(): player_blackjack = True print("B L A C K J A C K !") break if player_hand.value() > 21: player_bust = True print("You bust!") break print("Options") print("=======") print("- (h)it") print("- (s)tay") if cash >= bet * 2 and player_hand.can_be_split(): print("- s(p)lit") if cash >= bet * 2 and player_hand.can_double(): print(" - (d)ouble") action = input("Pick an action: ") if action == "h": player_hand.add(deck.draw()) elif action == "p" and player_hand.can_be_split( ) and cash >= bet * 2: second_hand = Hand() second_hand.add(player_hand.pop()) player_split = True first_bet = bet second_bet = bet break elif action == "d" and player_hand.can_double( ) and cash >= bet * 2: bet = bet * 2 player_hand.add(deck.draw()) if player_hand.value() > 21: player_bust = True break elif action == "s": break if player_split: first_bust = False second_bust = False # First hand player_hand.add(deck.draw()) while True: print("Playing first hand...\n") print(f"Dealer shows: {dealer_hand.list()}") print(f"Your hand: {player_hand.list()}") print(f"Your current value: {player_hand.value()}") if player_hand.value() > 21: first_bust = True print("Bust!") break print("Options") print("=======") print("- (h)it") print("- (s)tay") if cash >= (first_bet * 2) + second_bet and player_hand.can_double(): print(" - (d)ouble") action = input("Pick an action: ") if action == "h": player_hand.add(deck.draw()) elif action == "d" and player_hand.can_double( ) and cash >= (first_bet * 2) + second_bet: first_bet = first_bet * 2 player_hand.add(deck.draw()) if player_hand.value() > 21: first_bust = True break elif action == "s": break # Second hand second_hand.add(deck.draw()) while True: print("Playing second hand...\n") print(f"Dealer shows: {dealer_hand.list()}") print(f"Your hand: {second_hand.list()}") print(f"Your current value: {second_hand.value()}") if second_hand.value() > 21: second_bust = True print("Bust!") break print("Options") print("=======") print("- (h)it") print("- (s)tay") if cash >= (second_bet * 2) + first_bet and second_hand.can_double(): print("- (d)ouble") action = input("Pick an action: ") if action == "h": second_hand.add(deck.draw()) elif action == "d" and second_hand.can_double( ) and cash >= (second_bet * 2) + first_bet: second_bet = second_bet * 2 second_hand.add(deck.draw()) if second_hand.value() > 21: second_bust = True break elif action == "s": break if player_blackjack: cash += bet print("You win!") times_won += 1 continue if player_bust: print("Dealer wins!") cash -= bet times_lost += 1 continue dealer_bust = False while True: print(f"Dealer: {dealer_hand.list()} Value: {dealer_hand.value()}") if dealer_hand.value() < 17: print("Dealer hits!") dealer_hand.add(deck.draw()) elif dealer_hand.value() > 21: print("Dealer busts!") dealer_bust = True break elif dealer_hand.value() == 17 and dealer_hand.has_ace(): print("Dealer hits!") dealer_hand.add(deck.draw()) else: break if player_split: print() print( f"Dealer hand: {dealer_hand.list()}, Value: {dealer_hand.value()}" ) print(f"Your first hand: {player_hand.list()}") print(f"Your second hand: {second_hand.list()}") if first_bust: print("First hand busted...") cash -= first_bet times_lost += 1 elif dealer_bust or player_hand.value() > dealer_hand.value(): print("First hand wins!") cash += first_bet times_won += 1 elif player_hand.value() < dealer_hand.value(): print("First hand loses...") cash -= first_bet times_lost += 1 else: print("First hand PUSH!") times_drawn += 1 if second_bust: print("Second hand busted...") cash -= second_bet times_lost += 1 elif dealer_bust or second_hand.value() > second_hand.value(): print("Second hand wins!") cash += second_bet times_won += 1 elif second_hand.value() < dealer_hand.value(): print("Second hand loses...") cash -= second_bet times_lost += 1 else: print("Second hand PUSH!") times_drawn += 1 else: print() print("Result:") print( f"Dealer hand: {dealer_hand.list()}, Value: {dealer_hand.value()}" ) print( f"Your hand: {player_hand.list()}, Value: {player_hand.value()}" ) if dealer_bust or player_hand.value() > dealer_hand.value(): print(f"You win ${bet}!") times_won += 1 cash += bet elif player_hand.value() < dealer_hand.value(): print("You lose!") times_lost += 1 cash -= bet else: print("PUSH!") times_drawn += 1 print("Thanks for playing!") print(f"You won {times_won} hands.") print(f"You lost {times_lost} hands.") print(f"You pushed {times_drawn} hands.")
class Game(): def __init__(self, stake, players): self.stake = stake self.bank = 0 self.players = players self.winner = None self.busted_players = [] self.deck = None def start(self, deck=None): if self.winner != None: raise RuntimeError("Game is over") enough_money = True for p in self.players: enough_money = p.has_enough_money(self.stake) if not enough_money: raise RuntimeError("One of the players does not have enought money to make a stake!") for p in self.players: p.make_stake(self.stake) p.give_cards(Hand()) self.bank += self.stake if deck == None: self.deck = Deck() self.deck.shuffle() else: self.deck = deck for _ in range(0, 2): for p in self.players: p.hand.add(self.deck.pop()) def next_turn(self): if self.winner != None: raise RuntimeError("Game is over") current_player = self.players[0] if current_player.take_turn() == STAY: self.__next_player() else: current_player.hand.add(self.deck.pop()) self.__update_game_state() def finish(self): if self.winner == None: raise RuntimeError("Game has not finished yet") self.winner.game_over() self.winner.give_money(self.bank) self.bank = 0 for p in self.players + self.busted_players: p.game_over() def __next_player(self): self.players.append(self.players.pop(0)) def __update_game_state(self): active_players = [] for p in self.players: hand_value = p.hand.best_value() if hand_value == 21: self.winner = p active_players.append(p) elif hand_value < 21: active_players.append(p) else: self.busted_players.append(p) self.players = active_players if len(self.players) == 1: self.winner = self.players.pop(0) def __str__(self): res = f'Game for ${self.bank}\n' if self.deck == None: return f'{res} Has not started yet.' if self.winner: res += f' {self.winner}\n' for p in (self.players + self.busted_players): res += f' {p}\n' return res