Compare commits
10 commits
e5dc8f5c5c
...
e7f3dac12f
Author | SHA1 | Date | |
---|---|---|---|
|
e7f3dac12f | ||
|
6c486f4145 | ||
|
b8bb4a338b | ||
|
2875f08ed7 | ||
|
a31c7f985c | ||
|
7572833e60 | ||
|
b666aa803b | ||
|
8af654353b | ||
|
fb2e4040db | ||
|
b316210184 |
8 changed files with 141 additions and 145 deletions
54
blackjack.py
54
blackjack.py
|
@ -1,54 +0,0 @@
|
||||||
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
Normal file
25
main.py
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
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()
|
|
@ -1,3 +1,4 @@
|
||||||
|
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
|
||||||
|
|
64
src/blackjack.py
Normal file
64
src/blackjack.py
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
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()
|
22
src/controller.py
Normal file
22
src/controller.py
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
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
|
||||||
|
|
11
src/deck.py
11
src/deck.py
|
@ -3,24 +3,21 @@ import random
|
||||||
class Deck:
|
class Deck:
|
||||||
def __init__(self, n_decks):
|
def __init__(self, n_decks):
|
||||||
self.cards = []
|
self.cards = []
|
||||||
self.n_decks = n_decks
|
self.n_decks = int(n_decks)
|
||||||
|
|
||||||
def count(self):
|
def count(self):
|
||||||
return len(self.cards)
|
return len(self.cards)
|
||||||
|
|
||||||
def shuffle(self, n_decks):
|
def shuffle(self):
|
||||||
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'
|
||||||
|
|
||||||
while n_decks > 0:
|
for _ in range(self.n_decks):
|
||||||
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.n_decks)
|
self.shuffle()
|
||||||
|
|
||||||
def draw(self):
|
def draw(self):
|
||||||
self.check()
|
self.check()
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
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
|
|
78
src/io.py
78
src/io.py
|
@ -12,6 +12,9 @@ o8YooP' 8 .oPYo. .oPYo. 8 .o 8 .oPYo. .oPYo. 8 .o
|
||||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::'''
|
::::::::::::::::::::::::::::::::::::::::::::::::::::::::'''
|
||||||
|
|
||||||
|
self.clear = '\033c'
|
||||||
|
self.intro = self.clear + self.title
|
||||||
|
|
||||||
self.deck = '''\
|
self.deck = '''\
|
||||||
┌────────┐┐┐┐┐┐
|
┌────────┐┐┐┐┐┐
|
||||||
│░░░░░░░░││││││
|
│░░░░░░░░││││││
|
||||||
|
@ -48,15 +51,14 @@ o8YooP' 8 .oPYo. .oPYo. 8 .o 8 .oPYo. .oPYo. 8 .o
|
||||||
│
|
│
|
||||||
──────┘'''
|
──────┘'''
|
||||||
|
|
||||||
def make_card(self, vs, style):
|
def draw_card_part(self, vs):
|
||||||
value = vs[0]
|
value = '10' if vs[0] == '0' else 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'
|
||||||
|
|
||||||
card_part = f'''\
|
return f'''\
|
||||||
┌──
|
┌──
|
||||||
│{value}
|
│{value}
|
||||||
│{suit}
|
│{suit}
|
||||||
|
@ -65,62 +67,32 @@ o8YooP' 8 .oPYo. .oPYo. 8 .o 8 .oPYo. .oPYo. 8 .o
|
||||||
│
|
│
|
||||||
└──'''
|
└──'''
|
||||||
|
|
||||||
match style:
|
def draw_player_hand(self, player, game):
|
||||||
case 'deck':
|
card_stack = [self.draw_card_part(card) for card in player.hand]
|
||||||
return self.deck
|
card_stack.append(self.card_rest)
|
||||||
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:
|
||||||
player_cards[0] = self.make_card('na','hidden_part')
|
card_stack[0] = self.hidden_part
|
||||||
|
|
||||||
player_cards.append(self.make_card('na','card_rest'))
|
card_slices = [card.splitlines() for card in card_stack]
|
||||||
card_slices = [str(card).splitlines() for card in player_cards]
|
card_height = len(card_slices[0])
|
||||||
|
|
||||||
for i in range(7):
|
buffer = ''
|
||||||
clist = [card_slice[i] for card_slice in card_slices]
|
for i in range(card_height):
|
||||||
carriage = ''
|
buffer += ''.join([card_slice[i] for card_slice in card_slices])+'\n'
|
||||||
for chunk in clist:
|
|
||||||
carriage += chunk
|
|
||||||
print(carriage)
|
|
||||||
|
|
||||||
def clear(self):
|
return buffer[:-1]
|
||||||
print('\033c')
|
|
||||||
|
|
||||||
def intro(self):
|
def show_players(self, game):
|
||||||
self.clear()
|
buffer = ''
|
||||||
print(self.title)
|
for player in game.players:
|
||||||
|
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):
|
||||||
self.clear()
|
buffer = f'{self.clear}{self.title}{self.show_players(game)}'
|
||||||
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:
|
||||||
print(game.score())
|
buffer += '\n' + game.score()
|
||||||
|
|
||||||
def get_decks(self):
|
return buffer
|
||||||
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? ')
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue