-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Updated to fix bug #3, and added pre-commit linting, type check…
…, and pytests, complete with refactor to make the codebase compliant.
- Loading branch information
Showing
39 changed files
with
5,263 additions
and
2,770 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
[style] | ||
indent_width = 2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,119 +1,131 @@ | ||
# pylint: skip-file | ||
# pytype: skip-file | ||
import random | ||
|
||
|
||
# Define the Card class | ||
class Card: | ||
def __init__(self, suit, rank): | ||
self.suit = suit | ||
self.rank = rank | ||
|
||
@property | ||
def value(self): | ||
return { | ||
"2": 2, | ||
"3": 3, | ||
"4": 4, | ||
"5": 5, | ||
"6": 6, | ||
"7": 7, | ||
"8": 8, | ||
"9": 9, | ||
"10": 10, | ||
"J": 10, | ||
"Q": 10, | ||
"K": 10, | ||
"A": 11, | ||
}[self.rank] | ||
def __init__(self, suit, rank): | ||
self.suit = suit | ||
self.rank = rank | ||
|
||
@property | ||
def value(self): | ||
return { | ||
"2": 2, | ||
"3": 3, | ||
"4": 4, | ||
"5": 5, | ||
"6": 6, | ||
"7": 7, | ||
"8": 8, | ||
"9": 9, | ||
"10": 10, | ||
"J": 10, | ||
"Q": 10, | ||
"K": 10, | ||
"A": 11, | ||
}[self.rank] | ||
|
||
|
||
# Define the Deck class | ||
class Deck: | ||
def __init__(self): | ||
self.cards = [ | ||
Card(suit, rank) | ||
for suit in ["Hearts", "Diamonds", "Clubs", "Spades"] | ||
for rank in [str(n) for n in range(2, 11)] + ["J", "Q", "K", "A"] | ||
] | ||
random.shuffle(self.cards) | ||
def __init__(self): | ||
self.cards = [ | ||
Card(suit, rank) for suit in ["Hearts", "Diamonds", "Clubs", "Spades"] | ||
for rank in [str(n) for n in range(2, 11)] + ["J", "Q", "K", "A"] | ||
] | ||
random.shuffle(self.cards) | ||
|
||
def deal_card(self): | ||
return self.cards.pop() | ||
def deal_card(self): | ||
return self.cards.pop() | ||
|
||
|
||
# Define the Hand class | ||
class Hand: | ||
def __init__(self): | ||
self.cards = [] | ||
self.value = 0 | ||
self.aces = 0 | ||
def __init__(self): | ||
self.cards = [] | ||
self.value = 0 | ||
self.aces = 0 | ||
|
||
def add_card(self, card): | ||
self.cards.append(card) | ||
self.value += card.value | ||
if card.rank == "A": | ||
self.aces += 1 | ||
def add_card(self, card): | ||
self.cards.append(card) | ||
self.value += card.value | ||
if card.rank == "A": | ||
self.aces += 1 | ||
|
||
def adjust_for_ace(self): | ||
while self.value > 21 and self.aces: | ||
self.value -= 10 | ||
self.aces -= 1 | ||
def adjust_for_ace(self): | ||
while self.value > 21 and self.aces: | ||
self.value -= 10 | ||
self.aces -= 1 | ||
|
||
|
||
# Define the Game class | ||
class Game: | ||
def __init__(self): | ||
self.deck = Deck() | ||
self.player_hand = Hand() | ||
self.dealer_hand = Hand() | ||
|
||
def start_game(self): | ||
print("Welcome to Blackjack!") | ||
self.player_hand.add_card(self.deck.deal_card()) | ||
self.player_hand.add_card(self.deck.deal_card()) | ||
self.dealer_hand.add_card(self.deck.deal_card()) | ||
self.dealer_hand.add_card(self.deck.deal_card()) | ||
self.show_hands() | ||
self.player_turn() | ||
self.dealer_turn() | ||
self.show_result() | ||
|
||
def player_turn(self): | ||
while input("Hit or Stand? (h/s): ").lower() == "h": | ||
self.player_hand.add_card(self.deck.deal_card()) | ||
self.player_hand.adjust_for_ace() | ||
self.show_hands() | ||
if self.player_hand.value > 21: | ||
print("Player busts!") | ||
return | ||
self.dealer_turn() | ||
|
||
def dealer_turn(self): | ||
while self.dealer_hand.value < 17: | ||
self.dealer_hand.add_card(self.deck.deal_card()) | ||
self.dealer_hand.adjust_for_ace() | ||
|
||
def show_hands(self): | ||
print("Player's Hand:", *[f"{card.rank} of {card.suit}" for card in self.player_hand.cards]) | ||
print("Dealer's Hand:", *[f"{card.rank} of {card.suit}" for card in self.dealer_hand.cards[:1]], "and [HIDDEN]") | ||
|
||
def show_result(self): | ||
self.adjust_final_hands() | ||
print("Final Hands:") | ||
self.show_hands() | ||
if self.player_hand.value > 21: | ||
print("Dealer wins!") | ||
elif self.dealer_hand.value > 21 or self.player_hand.value > self.dealer_hand.value: | ||
print("Player wins!") | ||
elif self.player_hand.value < self.dealer_hand.value: | ||
print("Dealer wins!") | ||
else: | ||
print("It's a tie!") | ||
|
||
def adjust_final_hands(self): | ||
self.player_hand.adjust_for_ace() | ||
self.dealer_hand.adjust_for_ace() | ||
def __init__(self): | ||
self.deck = Deck() | ||
self.player_hand = Hand() | ||
self.dealer_hand = Hand() | ||
|
||
def start_game(self): | ||
print("Welcome to Blackjack!") | ||
self.player_hand.add_card(self.deck.deal_card()) | ||
self.player_hand.add_card(self.deck.deal_card()) | ||
self.dealer_hand.add_card(self.deck.deal_card()) | ||
self.dealer_hand.add_card(self.deck.deal_card()) | ||
self.show_hands() | ||
self.player_turn() | ||
self.dealer_turn() | ||
self.show_result() | ||
|
||
def player_turn(self): | ||
while input("Hit or Stand? (h/s): ").lower() == "h": | ||
self.player_hand.add_card(self.deck.deal_card()) | ||
self.player_hand.adjust_for_ace() | ||
self.show_hands() | ||
if self.player_hand.value > 21: | ||
print("Player busts!") | ||
return | ||
self.dealer_turn() | ||
|
||
def dealer_turn(self): | ||
while self.dealer_hand.value < 17: | ||
self.dealer_hand.add_card(self.deck.deal_card()) | ||
self.dealer_hand.adjust_for_ace() | ||
|
||
def show_hands(self): | ||
print( | ||
"Player's Hand:", | ||
*[f"{card.rank} of {card.suit}" for card in self.player_hand.cards], | ||
) | ||
print( | ||
"Dealer's Hand:", | ||
*[ | ||
f"{card.rank} of {card.suit}" | ||
for card in self.dealer_hand.cards[:1] | ||
], | ||
"and [HIDDEN]", | ||
) | ||
|
||
def show_result(self): | ||
self.adjust_final_hands() | ||
print("Final Hands:") | ||
self.show_hands() | ||
if self.player_hand.value > 21: | ||
print("Dealer wins!") | ||
elif (self.dealer_hand.value > 21 | ||
or self.player_hand.value > self.dealer_hand.value): | ||
print("Player wins!") | ||
elif self.player_hand.value < self.dealer_hand.value: | ||
print("Dealer wins!") | ||
else: | ||
print("It's a tie!") | ||
|
||
def adjust_final_hands(self): | ||
self.player_hand.adjust_for_ace() | ||
self.dealer_hand.adjust_for_ace() | ||
|
||
|
||
if __name__ == "__main__": | ||
game = Game() | ||
game.start_game() | ||
game = Game() | ||
game.start_game() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,45 @@ | ||
# pylint: skip-file | ||
# pytype: skip-file | ||
from blackjack import Card, Deck, Game, Hand | ||
|
||
|
||
def test_card_value(): | ||
assert Card("Hearts", "2").value == 2 | ||
assert Card("Hearts", "A").value == 11 | ||
assert Card("Hearts", "2").value == 2 | ||
assert Card("Hearts", "A").value == 11 | ||
|
||
|
||
def test_deck_deal_card(): | ||
deck = Deck() | ||
assert isinstance(deck.deal_card(), Card) | ||
assert len(deck.cards) == 51 | ||
deck = Deck() | ||
assert isinstance(deck.deal_card(), Card) | ||
assert len(deck.cards) == 51 | ||
|
||
|
||
def test_hand_add_card_and_value(): | ||
hand = Hand() | ||
hand.add_card(Card("Hearts", "2")) | ||
hand.add_card(Card("Hearts", "3")) | ||
assert hand.value == 5 | ||
assert hand.aces == 0 | ||
hand.add_card(Card("Hearts", "A")) | ||
assert hand.value == 16 | ||
assert hand.aces == 1 | ||
hand = Hand() | ||
hand.add_card(Card("Hearts", "2")) | ||
hand.add_card(Card("Hearts", "3")) | ||
assert hand.value == 5 | ||
assert hand.aces == 0 | ||
hand.add_card(Card("Hearts", "A")) | ||
assert hand.value == 16 | ||
assert hand.aces == 1 | ||
|
||
|
||
def test_game_flow(): | ||
game = Game() | ||
# Mocking the player and dealer turns to simulate game flow without user input | ||
game.player_turn = lambda: None | ||
game.dealer_turn = lambda: None | ||
game.start_game() | ||
# Assuming the game starts with two cards each for player and dealer | ||
assert len(game.player_hand.cards) == 2 | ||
assert len(game.dealer_hand.cards) == 2 | ||
# Adjusting for ace should be tested in a scenario where it affects the outcome | ||
hand = Hand() | ||
hand.add_card(Card("Hearts", "A")) | ||
hand.add_card(Card("Hearts", "9")) | ||
hand.add_card(Card("Hearts", "2")) # Total would be 22, but ace adjustment should bring it to 12 | ||
hand.adjust_for_ace() | ||
assert hand.value == 12 | ||
game = Game() | ||
# Mocking the player and dealer turns to simulate game flow without user input | ||
game.player_turn = lambda: None | ||
game.dealer_turn = lambda: None | ||
game.start_game() | ||
# Assuming the game starts with two cards each for player and dealer | ||
assert len(game.player_hand.cards) == 2 | ||
assert len(game.dealer_hand.cards) == 2 | ||
# Adjusting for ace should be tested in a scenario where it affects the outcome | ||
hand = Hand() | ||
hand.add_card(Card("Hearts", "A")) | ||
hand.add_card(Card("Hearts", "9")) | ||
hand.add_card( | ||
Card("Hearts", | ||
"2")) # Total would be 22, but ace adjustment should bring it to 12 | ||
hand.adjust_for_ace() | ||
assert hand.value == 12 |
Oops, something went wrong.