diff --git a/blackjack_oo/rafaelhenrique/blackjack.py b/blackjack_oo/rafaelhenrique/blackjack.py deleted file mode 100644 index 7f1419e..0000000 --- a/blackjack_oo/rafaelhenrique/blackjack.py +++ /dev/null @@ -1,123 +0,0 @@ -# -*- coding: utf-8 -*- -from decimal import Decimal -from random import shuffle - - -class Player: - def __init__(self, money='2000.0'): - self.money = Decimal(money) - self._hand = [] - - @property - def hand(self): - return self._hand - - @hand.setter - def hand(self, value): - if isinstance(value, str): - self._hand.append(value) - elif isinstance(value, list): - self._hand += value - else: - raise ValueError('Este valor deve ser uma string ou lista!') - - def show_hand(self): - """Show all cards on hand""" - qty_cards = len(self.hand) - if qty_cards >= 2: - cards = ", ".join(self.hand) - msg = "{} cards: {}".format(qty_cards, cards) - elif qty_cards == 1: - cards = ", ".join(self.hand) - msg = "{} card: {}".format(qty_cards, cards) - else: - msg = "You dont have cards on hand!" - print(msg) - - def hit(self, deck): - """ - This function get one card of an deck and - remove this card from original deck - """ - card = deck.pop(0) - self.hand = card - - -class Blackjack: - numbers = ["A", "2", "3", "4", "5", "6", - "7", "8", "9", "10", "Q", "J", - "K"] - suits = ["♣", "♦", "♥", "♠"] - - def __init__(self): - self.deck = ["{}{}".format(number, suit) - for suit in self.suits - for number in self.numbers] - self.money = Decimal('2000.0') - - # def hit(self): - # """ - # This function get one card of an deck and - # remove this card from original deck - # """ - # card = self.deck.pop(0) - # self.hand.append(card) - # return card - - def show_points(self): - """Calculate and return points from actual hand""" - points = 0 - for card in self.hand: - # solution with regex: - # pattern = re.compile("\d+") - # match = pattern.match(card) - number = card[:-1] - - if number == "A": - points += 1 - elif number in ("K", "J", "Q"): - points += 10 - else: - number = int(number) - points += number - print("Points: {}".format(points)) - - def show_money(self): - print("Money: R$ {:.2f}".format(self.money)) - - def bet(self, coin): - if coin not in (1, 5, 25, 100): - raise Exception("Invalid coin to bet") - if self.money >= coin: - self.money -= coin - return coin - return None - - def surrender(self): - print("Finish with...") - self.show_points() - raise SystemExit - - -if __name__ == "__main__": - player1 = Player() - print(player1.money) - # import ipdb; ipdb.set_trace() - player1.show_hand() - - # game = Blackjack() - # print(game.deck) - # game.show_hand() - # game.show_points() - # total_bet = [game.bet(100) for _ in range(4)] - # print("My coins: {}".format(total_bet)) - # try: - # game.bet(30) - # except Exception as e: - # print(e) - # game.show_money() - # print("*"*20) - # # Add one more card on hand to verify - # # how surrender function works - # game.hit() - # game.surrender() diff --git a/blackjack_oo/rafaelhenrique/core/blackjack.py b/blackjack_oo/rafaelhenrique/core/blackjack.py new file mode 100644 index 0000000..5f27c02 --- /dev/null +++ b/blackjack_oo/rafaelhenrique/core/blackjack.py @@ -0,0 +1,53 @@ +""" +Doctest for Blackjack + +>>> from core.frenchdeck import FrenchDeck +>>> from core.blackjack import Blackjack +>>> from core.player import Player +>>> deck = FrenchDeck() +>>> player = Player("Rafael", 2000.0) +>>> dealer = Player("Dealer", 0) +>>> game = Blackjack(dealer, player, deck) +>>> game.start() +>>> len(dealer.hand) == 2 +True +""" + +from random import shuffle + + +class Blackjack: + def __init__(self, dealer, player, deck): + self.dealer = dealer + self.player = player + self.deck = deck + self.started = False + self.current_bet = 0 + + def __repr__(self): + return "Blackjack(dealer={!r}, player={!r}, current_bet={!r})".format( + self.dealer.name, self.player.name, self.current_bet) + + def start(self): + if self.started: + return + shuffle(self.deck) + for _ in range(2): + card = self.deck.pop(0) + self.dealer.hand.append(card) + self.started = True + + @property + def header(self): + msg = ("BLACKJACK -> Saldo: {} | Aposta Atual: {} | Seus pontos: {}\n" + "Dealer hand -> {}\n" + "Player hand -> {}\n") + + dealer_hand = str(self.dealer.hand).split(',')[:-1] + ['HIDE CARD'] + dealer_hand = ",".join(dealer_hand) + + return msg.format(self.player.money, + self.current_bet, + self.player.points, + dealer_hand, + self.player.hand) diff --git a/blackjack_oo/rafaelhenrique/core/frenchdeck.py b/blackjack_oo/rafaelhenrique/core/frenchdeck.py new file mode 100644 index 0000000..392ea7b --- /dev/null +++ b/blackjack_oo/rafaelhenrique/core/frenchdeck.py @@ -0,0 +1,29 @@ +import collections + +Card = collections.namedtuple('Card', ['rank', 'suit']) + + +class FrenchDeck: + """This class is based on ... + Sample code for Chapter 1 - "The Python Data Model" + From the book "Fluent Python" by Luciano Ramalho (O'Reilly, 2015) + http://shop.oreilly.com/product/0636920032519.do + """ + ranks = [str(n) for n in range(2, 11)] + list('JQKA') + suits = 'spades diamonds clubs hearts'.split() + + def __init__(self): + self._cards = [Card(rank, suit) for suit in self.suits + for rank in self.ranks] + + def __len__(self): + return len(self._cards) + + def __getitem__(self, position): + return self._cards[position] + + def __setitem__(self, position, value): + self._cards[position] = value + + def pop(self, index): + return self._cards.pop(index) diff --git a/blackjack_oo/rafaelhenrique/core/player.py b/blackjack_oo/rafaelhenrique/core/player.py new file mode 100644 index 0000000..e5dc895 --- /dev/null +++ b/blackjack_oo/rafaelhenrique/core/player.py @@ -0,0 +1,88 @@ +""" +Doctest for Player + +>>> from core.frenchdeck import Card +>>> player = Player("Rafael", 2000.0) +>>> card = Card('Q', 'spades') +>>> player.hand.append(card) +>>> player.points +10 +>>> print(player.hand) +1 card: Q spades +>>> card = Card('A', 'spades') +>>> player.hand.append(card) +>>> print(player.hand) +2 cards: Q spades,A spades +>>> player.points +11 +""" + +from decimal import Decimal + + +class Hand: + + def __init__(self, cards=None): + if not cards: + self._cards = [] + else: + self._cards = cards + + def append(self, item): + self._cards.append(item) + + def __str__(self): + cards_quantity = len(self._cards) + if cards_quantity == 0: + return "You dont have cards on hand!" + else: + cards = ["{} {}".format(card.rank, card.suit) + for card in self._cards] + cards = ",".join(cards) + if cards_quantity > 1: + message = "{} cards: {}".format(cards_quantity, cards) + else: + message = "{} card: {}".format(cards_quantity, cards) + return message + + def __getitem__(self, position): + return self._cards[position] + + def __repr__(self): + return "Hand(cards={!r})".format(self._cards) + + def __len__(self): + return len(self._cards) + + +class Player: + + def __init__(self, name, money): + self.name = name + self.hand = Hand() + self.money = Decimal(money) + + def __repr__(self): + return "Player(name={!r}, money={!r}, hand={!r})".format( + self.name, self.money, self.hand) + + def bet(self, coin): + if coin not in (1, 5, 25, 100): + raise ValueError("Invalid coin to bet") + if self.money >= coin: + self.money -= coin + return coin + return None + + @property + def points(self): + """Calculate and return points from actual hand""" + points = 0 + for card in self.hand: + if card.rank == "A": + points += 1 + elif card.rank in ("K", "J", "Q"): + points += 10 + else: + points += int(card.rank) + return points diff --git a/blackjack_oo/rafaelhenrique/play.py b/blackjack_oo/rafaelhenrique/play.py new file mode 100644 index 0000000..ca1af89 --- /dev/null +++ b/blackjack_oo/rafaelhenrique/play.py @@ -0,0 +1,27 @@ +import os + +from core.frenchdeck import FrenchDeck +from core.blackjack import Blackjack +from core.player import Player + + +def menu(): + """Clear screen and create option menu""" + msg = ("Jogar: O que gostaria de fazer?\n" + "\t1. Apostar\n" + "\t2. Comprar carta\n" + "\t3. Dobrar aposta\n" + "\t4. Parar/Finalizar jogada\n" + "\t5. Chorar pra mãe\n" + "Digite número desejado: ") + return msg + +if __name__ == "__main__": + deck = FrenchDeck() + player = Player("Rafael", 2000.0) + dealer = Player("Dealer", 0) + game = Blackjack(dealer, player, deck) + game.start() + os.system('cls' if os.name == 'nt' else 'clear') + print(game.header) + print(menu()) diff --git a/blackjack_oo/rafaelhenrique/tests.py b/blackjack_oo/rafaelhenrique/tests.py deleted file mode 100644 index d9714ce..0000000 --- a/blackjack_oo/rafaelhenrique/tests.py +++ /dev/null @@ -1,134 +0,0 @@ -# -*- coding: utf-8 -*- -import unittest -from blackjack import Blackjack, Player - - -class TestPlayer(unittest.TestCase): - def setUp(self): - self.player = Player() - - def test_hand_property(self): - self.player.hand = "A♣" - self.assertEqual(self.player.hand, ["A♣"]) - - def test_show_hand_one_card(self): - """Test show_hand output with one card""" - import sys - from io import StringIO - self.player.hand = "A♣" - - saved_stdout = sys.stdout - try: - fake_out = StringIO() - sys.stdout = fake_out - self.player.show_hand() - output = fake_out.getvalue().strip() - self.assertEqual(output, '1 card: A♣') - finally: - sys.stdout = saved_stdout - - def test_show_hand_more_than_two_card(self): - """Test show_hand output with more than two cards""" - import sys - from io import StringIO - self.player.hand = ["A♣", "2♣", "3♣"] - - saved_stdout = sys.stdout - try: - fake_out = StringIO() - sys.stdout = fake_out - self.player.show_hand() - output = fake_out.getvalue().strip() - self.assertEqual(output, '3 cards: A♣, 2♣, 3♣') - finally: - sys.stdout = saved_stdout - - def test_hit_card(self): - deck = ["A♣", "2♣", "3♣"] - self.player.hit(deck) - self.assertEqual(self.player.hand, ["A♣"]) - self.assertEqual(len(deck), 2) - - -class TestBlackjack(unittest.TestCase): - def setUp(self): - self.blackjack = Blackjack() - self.deck = self.blackjack.deck - self.suits = ["♣", "♦", "♥", "♠"] - self.numbers = ["A", "2", "3", "4", "5", "6", - "7", "8", "9", "10", "Q", "J", - "K"] - - def test_create_deck_attribute(self): - """Function create_deck needs be 52 cards""" - deck_size = len(self.deck) - self.assertEqual(deck_size, 52) - - # def test_hit_card_size_deck_after(self): - # """ - # Hit one card and remove this card from deck - # resulting deck needs be have 51 cards - # """ - # self.blackjack.hit() - # deck_size = len(self.deck) - # self.assertEqual(deck_size, 51) - - # def test_hit_card_valid(self): - # """Hit one card and verify if is a valid card""" - # card = self.blackjack.hit() - # number, suit = card[:-1], card[-1] - # self.assertIn(number, self.numbers) - # self.assertIn(suit, self.suits) - - # def test_show_points_with_three_cards(self): - # """Test show_points calculate with three card""" - # import sys - # from io import StringIO - # self.blackjack.hand = ["A♣", "2♣", "3♣"] - - # saved_stdout = sys.stdout - # try: - # fake_out = StringIO() - # sys.stdout = fake_out - # self.blackjack.show_points() - # output = fake_out.getvalue().strip() - # self.assertEqual(output, 'Points: 6') - # finally: - # sys.stdout = saved_stdout - - # def test_show_points_with_two_cards(self): - # """Test show_points calculate with two cards""" - # import sys - # from io import StringIO - # self.blackjack.hand = ["10♣", "2♣"] - - # saved_stdout = sys.stdout - # try: - # fake_out = StringIO() - # sys.stdout = fake_out - # self.blackjack.show_points() - # output = fake_out.getvalue().strip() - # self.assertEqual(output, 'Points: 12') - # finally: - # sys.stdout = saved_stdout - - # def test_surrender_finish_with_systemexit(self): - # """Test if surrender raise SystemExit""" - # with self.assertRaises(SystemExit): - # self.blackjack.surrender() - - def test_shuffle_deck(self): - """Deck needs be random sequence after shuffle""" - from random import shuffle - deck_before_shuffle = self.deck[0:51] - shuffle(self.deck) - deck_after_shuffle = self.deck[0:51] - self.assertNotEqual(deck_after_shuffle, deck_before_shuffle) - - # Tests missing: show_money and bet - - def tearDown(self): - pass - -if __name__ == '__main__': - unittest.main() diff --git a/blackjack_oo/rafaelhenrique/tests/test_blackjack.py b/blackjack_oo/rafaelhenrique/tests/test_blackjack.py new file mode 100644 index 0000000..abd53ef --- /dev/null +++ b/blackjack_oo/rafaelhenrique/tests/test_blackjack.py @@ -0,0 +1,34 @@ +import unittest +from core.player import Player +from core.frenchdeck import FrenchDeck +from core.blackjack import Blackjack +from core.frenchdeck import Card + + +class TestBlackjack(unittest.TestCase): + + def setUp(self): + self.deck = FrenchDeck() + self.player = Player("Rafael", 2000.0) + self.dealer = Player("Dealer", 0) + self.game = Blackjack(self.dealer, self.player, self.deck) + + def test_repr(self): + expected = ( + "Blackjack(dealer='Dealer', player='Rafael', current_bet=0)") + self.assertEqual(repr(self.game), expected) + + def test_start(self): + self.game.start() + self.assertEqual(len(self.dealer.hand), 2) + + def test_header(self): + self.dealer.hand.append(Card('Q', 'spades')) + self.dealer.hand.append(Card('Q', 'diamonds')) + self.dealer.hand.append(Card('Q', 'clubs')) + + expected = ( + 'BLACKJACK -> Saldo: 2000 | Aposta Atual: 0 | Seus pontos: 0\n' + 'Dealer hand -> 3 cards: Q spades,Q diamonds,HIDE CARD\n' + 'Player hand -> You dont have cards on hand!\n') + self.assertEqual(self.game.header, expected) diff --git a/blackjack_oo/rafaelhenrique/tests/test_player.py b/blackjack_oo/rafaelhenrique/tests/test_player.py new file mode 100644 index 0000000..b9a2f01 --- /dev/null +++ b/blackjack_oo/rafaelhenrique/tests/test_player.py @@ -0,0 +1,46 @@ +import unittest +from core.player import Player +from core.frenchdeck import Card + + +class TestPlayer(unittest.TestCase): + + def setUp(self): + self.player = Player('Rafael', 2000.0) + self.card_one = Card('Q', 'spades') + self.card_two = Card('A', 'spades') + + def test_repr(self): + expected = ("Player(name='Rafael', money=Decimal('2000'), " + "hand=Hand(cards=[]))") + self.assertEqual(repr(self.player), expected) + + def test_points(self): + self.player.hand.append(self.card_one) + self.assertEqual(self.player.points, 10) + + def test_one_card_on_hand_append(self): + self.player.hand.append(self.card_one) + self.assertEqual(str(self.player.hand), "1 card: Q spades") + + def test_two_cards_on_hand_append(self): + self.player.hand.append(self.card_one) + self.player.hand.append(self.card_two) + self.assertEqual(str(self.player.hand), "2 cards: Q spades,A spades") + + def test_show_money(self): + self.assertEqual(str(self.player.money), "2000") + + def test_bet(self): + coin = self.player.bet(100) + self.assertEqual(self.player.money, 1900.0) + self.assertEqual(coin, 100) + + def test_bet_invalid_coin(self): + with self.assertRaises(ValueError): + self.player.bet(200) + + def test_len_hand(self): + self.player.hand.append(self.card_one) + self.player.hand.append(self.card_one) + self.assertEqual(len(self.player.hand), 2)