Exemplo n.º 1
0
    def _create_players(self):
        self.dealer = Dealer()

        name = input("Ingrese su nombre: ")
        money = typed_input(int, "Ingrese la cantidad de dinero que tiene: ",
                            f"{Fore.RED}Error: Ingrese una cantidad válida")
        self.player = Player(name, money)
Exemplo n.º 2
0
 def create_players(self, number_of_players):
     self.players = []
     if self.human_mode:
         number_of_players = int(
             input('How many players are in the game? '))
         for i in range(number_of_players):
             name = input("Enter player number %d name: " % (i + 1))
             money = int(input("Enter player number %d budget: " % (i + 1)))
             player = RegularPlayer(name, money)
             player.print_money()
             self.players.append(player)
     else:
         if number_of_players == 1:
             name = "Player"
             money = 100
             player = RegularPlayer(name, money)
             player.print_money()
             self.players.append(player)
         else:
             for i in range(number_of_players):
                 name = "Player" + str(i + 1)
                 money = random.randint(100, 500)
                 player = RegularPlayer(name, money)
                 player.print_money()
                 self.players.append(player)
     self.dealer = Dealer()
Exemplo n.º 3
0
    def __init__(self, num_decks=4, num_players=1, initial_amount=50):
        self.num_decks = num_decks
        self.deck = Deck(num_decks)

        self.player = Player(initial_amount)

        self.dealer = Dealer()

        self.wins = self.losses = self.draws = 0

        self._play()
Exemplo n.º 4
0
    def __init__(self,
                 print_func=print,
                 input_func=input,
                 dealer=None,
                 user=None):
        """
    This is where most of the basic game set up should take place. Namely the creation of the deck as well as the dealer. For now we can also add the player.
    In: None
    Exceptions: None
    Out: None
    """
        # Variables to control both the users starting bank as well as their goal
        self.starting_bank = 100
        self.score_goal = 250

        # Override functions so you can create a wrapper around the program
        self._print = print_func
        self._input = input_func

        # Create a new deck of cards
        self.deck = Deck(deck_count=2)

        # Add the players that the game cares about
        self.dealer = dealer or Dealer()
        self.user = user or User(starting_bank=self.starting_bank)
        self.round = 0
Exemplo n.º 5
0
 def setup(self):
     self.deck = Deck()
     self.player = Player()
     self.dealer = Dealer()
     for _ in range(2):
         self.player.hit(self.deck.next_card())
         self.dealer.hit(self.deck.next_card())
Exemplo n.º 6
0
    def __init__(self, shoe):
        self.shoe = shoe
        self.player_one = Player()
        self.dealer = Dealer()

        # used for game stats
        self.player_won = False
        self.winning_hand_value = None
Exemplo n.º 7
0
def dealer():
    return Dealer()
Exemplo n.º 8
0
 def __init__(self, max_hand=5, phases=2):
   self._max_hand = max_hand
   self._phase = 0
   self._phases = phases
   self._player = Player()
   self._dealer = Dealer()
Exemplo n.º 9
0
class Table:
  # initialize
  def __init__(self, max_hand=5, phases=2):
    self._max_hand = max_hand
    self._phase = 0
    self._phases = phases
    self._player = Player()
    self._dealer = Dealer()

  # play function
  def play(self):
    if self._phase == 0: self._deal_phase()
    elif self._phase == 1: self.display_player()
    else:
      self.winner_phase()
      self._reset()
    self._phase = (self._phase + 1) % self._phases

  # Get phase function
  def get_phase(self):
    return self._phase

  # Deal phase function
  def _deal_phase(self):
    self._deal_players()
    self._display_player()

  # Winner phase
  def _winner_phase(self):
    self._display_player()
    self._display_dealer()
    self._winner()

  # Deal calds to each player
  def _deal_players(self):
    for _ in range(self._max_hand):
       self._player.receive(self._dealer.deal(1))
       self._dealer.receive(self._dealer.deal(1))

  # Reset table
  def _reset(self):
    self._dealer.retrieve_cards(self._player.put_back_hand())
    self._dealer.retrieve_cards(self._dealer.put_back_hand())

  # Displays player
  def _display_player(self):
    print(self._player)

  # Displays dealer
  def _display_dealer(self):
    print(self._dealer)

  # Determines who has the winning hand
  def _winner(self):
    player_rank = self._player.get_rank()
    dealer_rank = self._dealer.get_rank()
    if player_rank > dealer_rank:
      print("Player wins")
    elif player_rank < dealer_rank:
      print("Dealer wins")
    else:
      self.__tie_breaker()

  # Breaks the tie between player and dealer
  def __tie_breaker(self):
    player_hand = self._player.best_hand()
    dealer_hand = self._dealer.best_hand()
    player_hand = list(dict.fromkeys(player_hand))
    dealer_hand = list(dict.fromkeys(dealer_hand))
    for p,d in zip(player_hand, dealer_hand):
      if p > d:
        print("Player wins")
        return
      elif p < d:
        print("Dealer wins")
        return
    print("It's a Tie")
Exemplo n.º 10
0
 def __init__(self):
     player1 = Player("")
     dealer = Dealer("mr.dealer")
     deck = Deck()
Exemplo n.º 11
0
class Game:
    """
  This is the main controller for Black Jack. It handles the creation of the Deck, Dealer, and User.
  As well as managing the main parts of the game flow.
  """
    def __init__(self, print_func=print, input_func=input):
        """
    This is where most of the basic game set up should take place. Namely the creation of the deck as well as the dealer. For now we can also add the player.
    In: None
    Exceptions: None
    Out: None
    """
        # Variables to control both the users starting bank as well as their goal
        self.starting_bank = 100
        self.score_goal = 250
        self.endless = False

        # Override functions so you can create a wrapper around the program
        self._print = print_func
        self._input = input_func

        # Create a new deck of cards
        self.deck = Deck(deck_count=2)

        # Add the players that the game cares about
        self.dealer = Dealer()
        self.user = User(starting_bank=self.starting_bank)
        self.round = 0

    def difficulty_level(self):
        valid_easy_responses = {'e', 'easy'}
        valid_hard_responses = {'h', 'hard'}
        while True:
            level_response = self._input(
                'Which difficulty? \nEasy: start with 100 chips, and goal is 250 chips \nHard: start with 50 chips, and goal is 500 chips \nPress (e) or (h): '
            )

            if level_response.lower() in valid_easy_responses:
                self.user = User(starting_bank=100)
                self.score_goal = 250
                break

            if level_response.lower() in valid_hard_responses:
                self.user = User(starting_bank=50)
                self.score_goal = 500
                break

            self._print('Difficulty must be Easy or Hard')

    def iterate_round(self):
        """
    Increment the round number
    In: None
    Out: None
    """
        self.round += 1

    def shuffle_deck(self):
        """
    Shuffles decks of cards
    In: None
    Out: None
    """
        if self.deck.deck_size() / 4 > self.deck.cards_remaining():
            self.deck.shuffle()

    def place_user_bet(self, value):
        """
    Shows current bank, requests bet, handles edge cases
    In: None
    Out: None
    """
        current_bank = self.user.get_bank()

        if value >= 1 and value <= current_bank:
            self.user.place_bet(value)

    def deal(self):
        """
    Deals 2 cards to the user and dealer
    In: None
    Out: None
    """
        for _ in range(0, 2):
            self.user.hit(self.deck.deal())
            self.dealer.hit(self.deck.deal())
        self.save_game()

    def user_hand(self):
        return self.user.hand

    def dealer_hand(self):
        return self.dealer.hand

    def user_hit(self):
        """
    Handles the users decision to either hit and gain a card, or to stay and keep the cards they have.
    In: None
    Out: None
    """
        self.user.hit(self.deck.deal())
        self.save_game()

    def dealer_turn(self):
        """
    Controls the dealers logic if they need to hit again or keep the cards that they already have
    In: None
    Out: None
    """
        while not self.dealer.bust():
            if self.dealer.get_score() < 17:
                self.dealer.hit(self.deck.deal())
            else:
                break

    def calculate_winner(self):
        """
    ** WIP **
    Used to decide if the player or the dealer is the one to win the round
    In: None
    Out: Changes the value in the Player's bank
    """

        if self.user.bust():
            self.user.beat_dealer(False)
            return False

        else:
            if self.user.blackjack() and not self.dealer.blackjack():
                self.user.beat_dealer(True)
                return True

            if not self.user.blackjack() and self.dealer.blackjack():
                self.user.beat_dealer(False)
                return False

            if self.user.get_score() == self.dealer.get_score(
            ) and not self.dealer.bust():

                return None

            result = self.user.get_score() > self.dealer.get_score(
            ) or self.dealer.bust()
            self.user.beat_dealer(result)

            return result

    def reset_hands(self):
        """
    Resets hands of all players to contain no cards
    In: None
    Out: None
    """
        self.user.reset_hand()
        self.dealer.reset_hand()

    def save_game(self):
        """
    Calls on the player and the deck to save their respective cards to the csv files for the notebook.
    In: None
    Exceptions: No Data To Save
    Out: .csv files
    """
        self.user.to_csv()
        self.deck.to_csv()
Exemplo n.º 12
0
 def __init__(self, startingAmount):
     self.deck = Deck()
     self.player = Player(startingAmount)
     self.dealer = Dealer()
     self.id = uuid.uuid4()
Exemplo n.º 13
0
class Blackjack:

    ace_values = {1, 11}

    def __init__(self, num_decks=4, num_players=1, initial_amount=50):
        self.num_decks = num_decks
        self.deck = Deck(num_decks)

        self.player = Player(initial_amount)

        self.dealer = Dealer()

        self.wins = self.losses = self.draws = 0

        self._play()

    def _shuffle(self):
        # add cut here possibly

        self.deck.shuffle()

    def _deal(self):

        for i in range(2):
            card = self.deck.remove_card()
            self.player.add_card(card)
            print(f"You are dealt {str(card)}")

            card = self.deck.remove_card(False if i == 1 else True)

            self.dealer.add_card(card)
            if i == 0:
                print(f"Dealer drew {str(card)}")

        print()

    def _get_stand_or_hit(self):

        valid_choices = {'s', 'h', 'stand', 'hit'}

        while True:

            choice = input("Stand or Hit? ").lower()

            if choice not in valid_choices:
                print("Please type one of 's','h','stand',or 'hit'")
                continue

            return choice[0]

    def _players_turn(self, bet):

        choice = self._get_stand_or_hit()

        while choice != 's':
            card = self.deck.remove_card()
            self.player.add_card(card)
            print(f"You are dealt {str(card)}")
            self._display_cards()
            if self.player.bust:
                self.player.money -= bet
                self.dealer.money += bet
                self.losses += 1
                print(
                    f"You busted with a total of {self.player.bust_total}:( Dealer wins\n"
                )
                return True

            choice = self._get_stand_or_hit()

        print()
        return False

    def _check_for_naturals(self):

        player_has_natural = self.player.has_natural

        dealer_has_natural = self.dealer.has_natural

        if player_has_natural and not dealer_has_natural:
            print("You have a natural blackjack! You win!")
            self.player.money += bet
            self.dealer.money -= bet
            self.wins += 1
        elif dealer_has_natural and not player_has_natural:
            print("Dealer has natural blackjack!. You lose :(")
            self.losses += 1
        elif player_has_natural and dealer_has_natural:
            self.player.money -= bet
            self.dealer.money += bet
            print("Both you and the dealer have a natural blackjack. Tie game")
            self.draws += 1

        return player_has_natural or dealer_has_natural

    def _dealers_turn(self, bet):

        self.dealer.flip_face_down_card()
        print("Dealer flips second card over")
        print(f"Dealers Cards: {self.dealer}")
        while not self.dealer.bust and self.dealer.total < 16:
            card = self.deck.remove_card()
            self.dealer.add_card(card)
            print(f"Dealer drew {str(card)}")
            print(f"Dealers Cards: {self.dealer}")

        if self.dealer.bust:
            self.wins += 1
            self.player.money += bet
            self.dealer.money -= bet
            print(
                f"Dealer busted with a total of  {self.dealer.bust_total}! You win"
            )
        else:
            dealer_total = self.dealer.total
            player_total = self.player.total

            if player_total == dealer_total:
                print(f"Tie game with totals of {dealer_total}")
                self.draws += 1
            elif player_total > dealer_total:
                self.player.money += bet
                self.dealer.money -= bet
                self.wins += 1
                print(
                    f"You win with a total of {player_total} versus {dealer_total}"
                )
            else:
                self.player.money -= bet
                self.dealer.money += bet
                self.losses += 1
                print(
                    f"Dealer wins with a total of {dealer_total} versus {player_total}"
                )

    def _get_yes_or_no(self):

        valid_choices = ('y', 'yes', 'no', 'n')
        choice = None
        while choice not in valid_choices:

            choice = input("Play Again? ")

            if choice not in valid_choices:
                print("Please type one of 'yes','y','no', or 'n'")
                continue

        return choice[0] == 'y'

    def _get_bet(self):

        while True:

            bet = input("How much money do you want to bet? ")

            try:
                bet = float(bet)
            except:
                print("Please type a NUMBER")
                continue

            if bet <= 0 or bet > self.player.money:
                print(
                    "Please enter a valid bet(nonnegative and less than or equal to the money you have"
                )
                continue

            return float(bet)

    def _display_cards(self):

        print()
        print(f"Your Cards: {self.player}")
        print(f"Dealers Cards: {self.dealer}")
        print()

    def _play(self):

        play_again = True
        while play_again:

            print(
                f"Your Money: {self.player.money}\nDealer's Money: {self.dealer.money}\n"
            )
            bet = self._get_bet()
            self._deal()

            self._display_cards()

            game_over = self._check_for_naturals()

            if not game_over:

                lose = self._players_turn(bet)

                if not lose:
                    self._dealers_turn(bet)

            if self.player.money <= 0:
                print("You have no money left :( GAME OVER")
                break

            play_again = self._get_yes_or_no()
            if play_again:
                self.dealer.reset()
                self.player.reset()
                print(
                    f"Wins: {self.wins}\nLosses: {self.losses}\nDraws: {self.draws}"
                )

        print(f"Wins: {self.wins}\nLosses: {self.losses}\nDraws: {self.draws}")
        print(
            f"Your Money: {self.player.money}\nDealer's Money: {self.dealer.money}\n"
        )
        print("Thank you for playing!")
Exemplo n.º 14
0
class Blackjack(object):
    def __init__(self, human=True, number_of_players=1):
        self.deck = Deck()
        self.deck.shuffle()
        self.human_mode = human
        self.create_players(number_of_players)

    def create_players(self, number_of_players):
        self.players = []
        if self.human_mode:
            number_of_players = int(
                input('How many players are in the game? '))
            for i in range(number_of_players):
                name = input("Enter player number %d name: " % (i + 1))
                money = int(input("Enter player number %d budget: " % (i + 1)))
                player = RegularPlayer(name, money)
                player.print_money()
                self.players.append(player)
        else:
            if number_of_players == 1:
                name = "Player"
                money = 100
                player = RegularPlayer(name, money)
                player.print_money()
                self.players.append(player)
            else:
                for i in range(number_of_players):
                    name = "Player" + str(i + 1)
                    money = random.randint(100, 500)
                    player = RegularPlayer(name, money)
                    player.print_money()
                    self.players.append(player)
        self.dealer = Dealer()

    def play_game(self):
        while self.players:
            print("----------------------------------------------------------")
            self.play_round()
            for player in self.players.copy():
                player.reset()
                if self.bankrupt(player) or self.quit(player):
                    self.players.remove(player)
            self.dealer.reset()

    def play_round(self):
        print("Start playing...")
        # Player plays
        for player in self.players:
            self.deal(player)
            self.deal(player)
            print(player)

        self.deal(self.dealer)
        print(self.dealer)
        self.deal(self.dealer)

        for player in self.players:
            print("%s plays..." % player.name)
            self.get_bet(player)
            while self.hit_or_stay(player):
                self.deal(player)

        print("Dealer plays...")
        print(self.dealer)
        # Dealer plays
        while calc_cards_sum(self.dealer.hand) <= 16:
            self.deal(self.dealer)

        print("All hands:")
        for player in self.players:
            print(player)
        print(self.dealer)

        for player in self.players:
            if calc_cards_sum(player.hand) > 21:
                player.lostRound()

            elif calc_cards_sum(self.dealer.hand) > 21:
                player.wonRound()

            elif calc_cards_sum(player.hand) > calc_cards_sum(
                    self.dealer.hand):
                player.wonRound()

            elif calc_cards_sum(player.hand) < calc_cards_sum(
                    self.dealer.hand):
                player.lostRound()
            else:
                print("No one won (Push)!")

    def deal(self, player):
        player.hand.append(self.deck.draw_card())

    def get_bet(self, player):
        amount = 0
        if not self.human_mode:
            amount = random.randint(1, int(player.money))
            print("%s bets $%d" % (player.name, amount))
            player.bet(amount)
        else:
            while not (amount > 0 and amount <= player.money):
                amount = int(input("Enter your bet amount in $ : "))
            player.bet(amount)

    def hit_or_stay(self, player):
        print(player)
        if self.human_mode:
            hit_or_stay = input("Hit or Stay? [H/S] ").lower()
            if hit_or_stay == 'h':
                return True
            elif hit_or_stay == 's':
                return False
            else:
                raise Exception("Wrong input!")
            return
        else:
            return random.randint(0, 1)

    def quit(self, player):
        if self.human_mode:
            continue_game = input("%s would you like to continue? [Y/N] " %
                                  player.name).lower()
            if continue_game == 'y':
                return False
            elif continue_game == 'n':
                return True
            else:
                raise Exception("Wrong input!")
        else:
            return random.randint(0, 1)

    def bankrupt(self, player):
        if player.money <= 0:
            print("%s is bankrupt!" % (player.name))
            return True

        return False
Exemplo n.º 15
0
	def __init__(self, deck):
		self.deck = deck
		self.user = User(deck)
		self.dealer = Dealer(deck)
		self.mxscore = 21
		self.deck.shuffle()
Exemplo n.º 16
0
class Game(object):

    def setup(self):
        self.deck = Deck()
        self.player = Player()
        self.dealer = Dealer()
        for _ in range(2):
            self.player.hit(self.deck.next_card())
            self.dealer.hit(self.deck.next_card())

    def player_turn(self):
        player_choice = input("[H]it, [S]tay, or [Q]uit?").lower()
        os.system('clear')

        if player_choice == 'h':
            self.player.hit(self.deck.next_card())
            self.display_info()
            if self.player.hand_value() > 21:
                pass
            else:
                self.player_turn()
        elif player_choice == 's':
            pass
        elif player_choice == 'q':
            sys.exit()
        else:
            self.player_turn

    def dealer_turn(self):
        while self.dealer.hand_value() <= 16:
            self.display_info(True)
            time.sleep(2)
            self.dealer.hit(self.deck.next_card())
    

    def check_for_outcome(self):
        if self.dealer.hand_value() > 21:
            print("Dealer bust! You Win!")
            self.play_again()
        elif self.player.hand_value() > self.dealer.hand_value():
            print("You win!")
        elif self.player.hand_value() < self.dealer.hand_value():
            print("You lose!")
        elif self.player.hand_value() == self.dealer.hand_value():
            print("Push!")

    def check_for_bust(self):
        if self.player.hand_value() > 21:
            print("You bust! You lose!")
            self.play_again()

    def display_info(self,show = False):
        os.system('clear')
        print("Blackjack")
        print("="*20)
        if show:
            print(self.dealer)
        else:
            print(self.dealer.hidden())
        print(self.player)
        print("="*20)
    
    def play_again(self):
        play_again = input("Do you want to play again? [Y]/[N]?").lower()
        if play_again == 'y':
            Game()
        else:
            sys.exit()

    def __init__(self):
        self.setup()
        
        self.display_info()
        self.player_turn()
        self.check_for_bust()
        self.display_info(True)
        self.dealer_turn()
        self.display_info(True)
        self.check_for_outcome()

        self.play_again()
Exemplo n.º 17
0
	def __init__(self, players = [], shoe_size = 1):
		self.dealer = Dealer("Dealer")
		self.shoe_size = shoe_size
		self.deck = self.new_deck()
		self.players = players
Exemplo n.º 18
0
from player import Player, Dealer
from utils import (
    get_hands_result,
    declare_winner,
    print_hand,
    construct_optimal_bet,
    expand_chipset,
    compress_chipset,
    decision_generator,
)

pot = {"ones": 0, "fives": 0, "tens": 0, "twentys": 0, "fiftys": 0}

dealer = Dealer()
player1 = Player()

# Start of the Game
while True:
    playing = True
    num_mapping = {
        "ones": 1,
        "fives": 5,
        "tens": 10,
        "twentys": 20,
        "fiftys": 50
    }
    bust = []
    dealer.deal_hands([player1])
    dealer_card = dealer.hand[0]
    # print(f"Dealer hand: {[str(dealer_card.name) + ' of ' + dealer_card.suit]}")
    print_hand(dealer)
Exemplo n.º 19
0
def test_dealer_instance():
  assert Dealer()
Exemplo n.º 20
0
 def __init__(self, player_name):
     self.player = Player(player_name, 1000)
     self.dealer = Dealer("Dealer")
     self.game_on = True
     self.player_cards = []
     self.dealer_cards = []
Exemplo n.º 21
0
class Round:
	"""start a round of blackjack
	Arguments
	----------
	deck : shared deck of cards between classes
	Parameters
	----------
	user : player class controlled by input
	dealer : player class controlled by hit rules
	mxscore : maximum score without busting
	"""
	def __init__(self, deck):
		self.deck = deck
		self.user = User(deck)
		self.dealer = Dealer(deck)
		self.mxscore = 21
		self.deck.shuffle()

	def play(self):
		def deal(self):
			self.user.get_card()
			self.user.get_card()
			self.dealer.get_card()
			print("\nDealer has {0} ??? for a visible total of {1} points".format(str(self.dealer), self.dealer.first_ace()))
			self.dealer.get_card() # Dealer gets 2nd card after first print to keep 2nd card hidden
			print("You have {0} for a total of {1} points".format(str(self.user), self.user.score()))
			print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
			check_blackjack(self)

		def check_blackjack(self):
			if self.dealer.score() == 21:
				print("Dealer has {0} for a total of {1} points".format(str(self.dealer), self.dealer.score()))
				print("Dealer got a Blackjack! You Lose!")
			elif self.user.score() == 21:
				print("You got a Blackjack! You Win!")
			else:
				user_hit(self)

		def user_hit(self):
			while self.user.score() <= 21 and self.user.hit():
				if self.user.score() > 21:
					print("You have {0} for a total of {1} points. \nYOU BUSTED!".format(str(self.user), self.user.score()))
				if self.user.score() <= 21:
					print("You have {0} for a total of {1} points.".format(str(self.user), self.user.score()))
			if self.user.score() <= 21:
				print("You stay with {0} for a total of {1} points.".format(str(self.user), self.user.score()))
				print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
				dealer_hit(self)
				
		def dealer_hit(self):
			print("Dealer has {0} for a total of {1} points.".format(str(self.dealer), self.dealer.score()))
			if self.dealer.score() >= 17:
				print("Dealer stays at {0}".format(self.dealer.score()))
				print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
				compare_score(self)
			while self.dealer.score() < 17:
				print("Dealer Hits")
				self.dealer.hit()
				print("Dealer has {0} for a total of {1} points.".format(str(self.dealer), self.dealer.score()))
				if 17 <= self.dealer.score() <= 21:
					print("Dealer stays at {0}".format(self.dealer.score()))
					print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
					compare_score(self)
				elif self.dealer.score() > 21:
					print("DEALER BUSTED!".format(str(self.dealer), self.dealer.score()))

		def compare_score(self):
			if self.user.score <= self.dealer.score:
				print("The Dealer's {0} beats your {1}. \nYOU LOSE!").format(self.dealer.score(), self.user.score())
			if self.user.score > self.dealer.score:
				print("Your {0} beats the Dealer's {1}. \nYOU WIN!").format(self.user.score(), self.dealer.score())
				
		deal(self)		
Exemplo n.º 22
0
class Game:
    def __init__(self):
        self.init()

        self._create_players()

    def _create_players(self):
        self.dealer = Dealer()

        name = input("Ingrese su nombre: ")
        money = typed_input(int, "Ingrese la cantidad de dinero que tiene: ",
                            f"{Fore.RED}Error: Ingrese una cantidad válida")
        self.player = Player(name, money)

    def bet(self):
        print(f"Tienes {self.player.money} dinero")
        bet_value = safe_input(lambda x: x > 0 and x <= self.player.money,
                               "Ingrese la cantidad a apostar: ",
                               f"{Fore.RED}Error: Ingrese una cantidad válida",
                               type_=int)
        self.player.hands.append(Hand([], bet_value))
        self.player.money -= bet_value

    def init(self):
        self.deck = Deck()
        self.round = 0
        self.ended = False

    def run(self):
        self.init()
        self.bet()
        keep = "1"
        while keep == "1":
            self.play_game()
            keep = input("Ingrese 1 para jugar de nuevo:")
            if keep != "1":
                break
            self.player = Player(self.player.name, self.player.money)
            self.init()

    def play_game(self):
        while not self.player.has_ended() and not self.round > 3:
            if self.dealer.get_max_points() < 17:
                self.dealer.add(self.deck.pop())
            for i in range(self.player.get_num_hands()):
                self.player.current = i
                self.turn_hand()
            self.player.has_ended()
            self.round += 1
        self.show_wins()

    def turn_hand(self):
        self.print_hands(self.player.current)
        if self.player.is_current_complete():
            return
        if self.player.can_split_current():
            self.split()
        if self.dealer.can_buy_insurance():
            self.buy_insurance()
        opt = self.get_opt()
        if opt == 1:
            self.player.double_current_bet()
        if opt == 2:
            self.player.add_card_current(self.deck.pop())
        if opt == 3:
            self.player.complete_current()
        clear_screen()

    def get_opt(self):
        print("1) Doblar apuesta")
        print("2) Pedir otra carta")
        print("3) Plantarse")
        return safe_input(lambda x: x >= 1 and x <= 3,
                          "Ingrese el número de la opción",
                          f"{Fore.RED}Error: Ingrese una opción válida",
                          type_=int)

    def buy_insurance(self):
        v = input("Ingrese 1 si desea comprar un seguro: ")
        if v != 1:
            return
        self.player.buy_insurance()

    def split(self):
        v = input("Ingrese 1 si desea hacer un split: ")
        if v != "1":
            return
        self.player.split()

    def print_hands(self, current, all_=False):
        self._print_dealer(all_)
        self.player.current = current
        self._print_player_hand()

    def _print_dealer(self, all_):
        print(f"{self.dealer.name}: ")
        if all_:
            self.dealer.print_all()
        else:
            self.dealer.print_hand()

    def _print_player_hand(self):

        print(f"{self.player.name}, mano {self.player.current+1}:")
        self.player.print_current_hand()
        print(f"Puntos: {self.player.get_max_current_points()}")
        print(f"Dinero: {self.player.money}")
        print(f"Dinero apostado en mano: {self.player.get_current_bet()}")

    def show_wins(self):
        for i in range(self.player.get_num_hands()):
            self.player.current = i

            dealer_points = self.dealer.hand.get_max_points()
            player_points = self.player.get_max_current_points()
            hand = self.player.hands[self.player.current]

            if self.player.has_current_insurance():
                self._show_insurance_win()
            if self.player.is_current_surrended():
                self._show_surrender_win()
            elif dealer_points == player_points:
                self._show_tie()
            elif player_points > 21 or dealer_points > player_points:
                self._show_p()
            elif player_points == 21 and len(hand) == 2:
                self._show_blackjack_win()
            else:
                self._print_win()
        input("Ingrese algo para continuar")
        clear_screen()

    def _print_win(self):
        print("Ganaste, recibes 1 a 1")
        self.player.money += self.player.get_current_bet() * 2
        print(f"Dinero: {self.player.money}")

    def _show_blackjack_win(self):
        print("Ganaste por blackjack, recibes 3 a 2")
        self.player.money += self.player.get_current_bet() / 2 * 5
        print(f"Dinero: {self.player.money}")

    def _show_p(self):
        print("Perdiste:")
        print(f"Dinero: {self.player.money}")

    def _show_tie(self):
        print("Empate:")
        self.player.money += self.player.get_current_bet()
        print(f"Dinero: {self.player.money}")

    def _show_surrender_win(self):
        print("Perdiste la mitad del dinero de la apuesta")
        self.player.money += self.player.get_current_bet() / 2
        print(f"Dinero: {self.player.money}")

    def _show_insurance_win(self):
        dealer_21 = self.dealer.hand.get_max_points() == 1
        dealer_blackjack = len(self.dealer.hand.cards) == 2 and dealer_21

        if dealer_blackjack:
            print("Ganaste el dinero del seguro")
            self.player.money += (self.player.get_current_bet() / 2) * 3
            print(f"Dinero: {self.player.money}")
        else:
            print("Perdiste el dinero del seguro")