Compare commits

..

No commits in common. "e7f3dac12fe2b13ad7f61a0f13696d2dac9aa443" and "e5dc8f5c5c299e3994887fddda56f4071d0cb9f1" have entirely different histories.

8 changed files with 145 additions and 141 deletions

54
blackjack.py Normal file
View file

@ -0,0 +1,54 @@
from src.deck import Deck
from src.io import CLI
from src.gamemaster import GameMaster
def main():
global kill
global ui
global num_decks
global deck
game = GameMaster()
for player in game.players:
for _ in range(2):
player.hand.append(deck.draw())
dealer = game.dealer
player = game.player
while game.active:
ui.update(game)
if game.active:
match ui.player_move(deck).lower():
case 'y':
game.active = False
case 'q':
game.active = False
kill = True
case 'n':
game.active = False
case 'h':
player.hand.append(deck.draw())
if player.bust(game):
game.active = False
case 's':
game.active = False
while dealer.score(game) < 17:
dealer.hand.append(deck.draw())
ui.update(game)
kill = False
ui = CLI()
ui.intro()
num_decks = ui.get_decks()
if num_decks == 'q':
kill = True
deck = Deck(num_decks)
while not kill:
main()
if not ui.play_again():
kill = True

25
main.py
View file

@ -1,25 +0,0 @@
from src.deck import Deck
from src.io import CLI
from src.blackjack import Blackjack
from src.controller import PlayerController
def main():
player = PlayerController()
screen = CLI()
print(screen.intro)
deck = Deck(player.get_decks())
while player.seated:
game = Blackjack(deck)
game.deal()
game.check_player_blackjack()
print(screen.update(game))
while game.active:
game.update(player.get_input(deck.count()))
print(screen.update(game))
player.ask_deal_again()
main()

View file

@ -1,4 +1,3 @@
Need Python >= 3.10
``` ```
.oPYo. 8 8 o 8 .oPYo. 8 8 o 8
8 `8 8 8 8 8 8 `8 8 8 8 8

View file

@ -1,64 +0,0 @@
from src.player import Player
class Blackjack:
def __init__(self, deck):
self.deck = deck
self.active = True
self.players = [Player('Dealer'), Player('Player')] # 5-9 seats
self.dealer = self.players[0] # Mickey
self.player = self.players[1] # Mouse
def score(self):
status = 'Error'
if self.dealer.score(self) == self.player.score(self):
self.active = False
status = 'Push.'
elif self.dealer.score(self) > self.player.score(self):
self.active = False
status = 'House wins.'
elif self.dealer.score(self) < self.player.score(self):
self.active = False
status = 'You win!'
for player in self.players:
if player.score(self) > 21:
self.active = False
status = player.name + ' Bust!'
for player in self.players:
if player.blackjack(self):
self.active = False
status = player.name + ' has Blackjack!'
return status
def deal(self):
for player in self.players:
for _ in range(2):
player.hand.append(self.deck.draw())
def check_player_blackjack(self):
for player in self.players:
if player.blackjack(self):
self.active = False
return True
return False
def hit(self):
self.player.hand.append(self.deck.draw())
if self.player.bust(self):
self.active = False
def stand(self):
self.active = False
while self.dealer.score(self) < 17:
self.dealer.hand.append(self.deck.draw())
def update(self, input):
if not input:
pass
elif input in 'yqn':
self.active = False
elif input == 'h':
self.hit()
elif input == 's':
self.stand()

View file

@ -1,22 +0,0 @@
class PlayerController():
def __init__(self):
self.seated = True
def get_decks(self):
user_input = input('How many decks? (1-8): ')
if not user_input:
return '1'
if user_input in 'qx':
self.seated = False
return (int(user_input) if user_input in '12345678' else 1)
def get_input(self, count):
return input(f'{count} cards left in deck.\n[H]it or [S]tand? ')
def ask_deal_again(self):
user_input = input('Play again? [Y/n] ').lower()
if not user_input:
return
elif user_input in 'qnx':
self.seated = False

View file

@ -3,21 +3,24 @@ import random
class Deck: class Deck:
def __init__(self, n_decks): def __init__(self, n_decks):
self.cards = [] self.cards = []
self.n_decks = int(n_decks) self.n_decks = n_decks
def count(self): def count(self):
return len(self.cards) return len(self.cards)
def shuffle(self): def shuffle(self, n_decks):
self.cards = []
n_decks = 1 if not n_decks or n_decks not in '12345678' else int(n_decks)
suits = '♠♥♦♣' suits = '♠♥♦♣'
cards = 'A234567890JQK' cards = 'A234567890JQK'
for _ in range(self.n_decks): while n_decks > 0:
self.cards += [card + suit for card in cards for suit in suits] self.cards += [card + suit for card in cards for suit in suits]
n_decks -= 1
def check(self): def check(self):
if self.count() < 1: if self.count() < 1:
self.shuffle() self.shuffle(self.n_decks)
def draw(self): def draw(self):
self.check() self.check()

31
src/gamemaster.py Normal file
View file

@ -0,0 +1,31 @@
from src.player import Player
class GameMaster:
def __init__(self):
self.active = True
self.players = [Player('Dealer'), Player('Player')] # 5-9 seats
self.dealer = self.players[0]
self.player = self.players[1]
def score(self):
status = 'Error'
if self.dealer.score(self) == self.player.score(self):
self.active = False
status = 'Push.'
elif self.dealer.score(self) > self.player.score(self):
self.active = False
status = 'House wins.'
elif self.dealer.score(self) < self.player.score(self):
self.active = False
status = 'You win!'
for player in self.players:
if player.score(self) > 21:
self.active = False
status = player.name + ' Bust!'
elif player.blackjack(self):
self.active = False
status = player.name + ' has Blackjack!'
return status

View file

@ -12,9 +12,6 @@ o8YooP' 8 .oPYo. .oPYo. 8 .o 8 .oPYo. .oPYo. 8 .o
:::::::::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::''' ::::::::::::::::::::::::::::::::::::::::::::::::::::::::'''
self.clear = '\033c'
self.intro = self.clear + self.title
self.deck = '''\ self.deck = '''\
@ -51,14 +48,15 @@ o8YooP' 8 .oPYo. .oPYo. 8 .o 8 .oPYo. .oPYo. 8 .o
''' '''
def draw_card_part(self, vs): def make_card(self, vs, style):
value = '10' if vs[0] == '0' else vs[0] + ' ' value = vs[0]
value = '10' if value == '0' else value + ' '
suit = vs[1] + ' ' suit = vs[1] + ' '
# request text (not emoji) render of preceeding glyph but can break some fonts # request text (not emoji) render of preceeding glyph but can break some fonts
# suit += '\uFE0E' # suit += '\uFE0E'
return f'''\ card_part = f'''\
{value} {value}
{suit} {suit}
@ -67,32 +65,62 @@ o8YooP' 8 .oPYo. .oPYo. 8 .o 8 .oPYo. .oPYo. 8 .o
''' '''
def draw_player_hand(self, player, game): match style:
card_stack = [self.draw_card_part(card) for card in player.hand] case 'deck':
card_stack.append(self.card_rest) return self.deck
case 'card_rest':
return self.card_rest
case 'hidden_part':
return self.hidden_part
case 'hidden_rest':
return self.hidden_rest
case 'card_part':
return card_part
def print_hand(self, player, game):
player_cards = [self.make_card(card,'card_part') for card in player.hand]
if player.name == 'Dealer' and game.active: if player.name == 'Dealer' and game.active:
card_stack[0] = self.hidden_part player_cards[0] = self.make_card('na','hidden_part')
card_slices = [card.splitlines() for card in card_stack] player_cards.append(self.make_card('na','card_rest'))
card_height = len(card_slices[0]) card_slices = [str(card).splitlines() for card in player_cards]
buffer = '' for i in range(7):
for i in range(card_height): clist = [card_slice[i] for card_slice in card_slices]
buffer += ''.join([card_slice[i] for card_slice in card_slices])+'\n' carriage = ''
for chunk in clist:
carriage += chunk
print(carriage)
return buffer[:-1] def clear(self):
print('\033c')
def show_players(self, game): def intro(self):
buffer = '' self.clear()
for player in game.players: print(self.title)
buffer += f"\n {player.name}{37*' '}Score: {player.score(game)}\n{self.draw_player_hand(player, game)}"
return buffer
def update(self, game): def update(self, game):
buffer = f'{self.clear}{self.title}{self.show_players(game)}' self.clear()
print(self.title)
for player in game.players:
print(' '+player.name,'''\
Score:''', player.score(game))
self.print_hand(player, game)
if not game.active: if not game.active:
buffer += '\n' + game.score() print(game.score())
return buffer def get_decks(self):
return input('How many decks? (1-8): ')
def play_again(self):
match input('Play again? [Y/n] ').lower():
case 'n':
return False
case 'q':
return False
case _:
return True
def player_move(self, deck):
return input(str(deck.count()) + ' cards left in deck.\n[H]it or [S]tand? ')