diff --git a/chris_demo/__pycache__/card.cpython-313.pyc b/chris_demo/__pycache__/card.cpython-313.pyc new file mode 100644 index 0000000..bf11b86 Binary files /dev/null and b/chris_demo/__pycache__/card.cpython-313.pyc differ diff --git a/chris_demo/__pycache__/dealer.cpython-313.pyc b/chris_demo/__pycache__/dealer.cpython-313.pyc new file mode 100644 index 0000000..1defc51 Binary files /dev/null and b/chris_demo/__pycache__/dealer.cpython-313.pyc differ diff --git a/chris_demo/__pycache__/deck.cpython-313.pyc b/chris_demo/__pycache__/deck.cpython-313.pyc new file mode 100644 index 0000000..6d883ec Binary files /dev/null and b/chris_demo/__pycache__/deck.cpython-313.pyc differ diff --git a/chris_demo/card.py b/chris_demo/card.py new file mode 100644 index 0000000..bf16a06 --- /dev/null +++ b/chris_demo/card.py @@ -0,0 +1,146 @@ + +suits = ['♠', '♥', '♦', '♣'] +colors = ['black', 'red', 'red', 'black'] +ranks = "A23456789TJQK" + +class Card: + """A card is not an agent itself, but it manages two agents + which are always next to each other, representing + the card as something like '♠A'. + """ + display = False + + def __init__(self, position, index, hidden=False, selected=False): + """When creating a card, you pass an index, which should be a number between + 0 and 51. If you imagine a deck of playing cards in order (all the spades from A-K, + then all the hearts from A-K, etc.), then the index is all we need to identify which + card this is. See the CardSuit and CardRank classes below for the math we can use + to convert an index value to a suit or a rank. + """ + self.index = index + self.name = str(index) + self.agents = [CardSuit(index, hidden, selected), CardRank(index, hidden, selected)] + self.set_position(position) + + def __str__(self): + return ''.join(a.character for a in self.agents) + + def __repr__(self): + return f"" + + def value(self): + """Returns how many points this card is worth. Currently treats aces as worth 1. + Later we might need a way of considering that an ace could be worth 1 or 11 in + blackjack. + """ + rank_index = self.index % 13 + return rank_index + 1 + + def set_position(self, position): + """When the Card's position gets set, it updates + the position of its suit and rank. In this way, we have one + agent (Card) which manages the positions of two agents on the + screen. + """ + x, y = position + suit, rank = self.agents + self.position = position + suit.position = position + rank.position = (x+1, y) + + def set_z(self, z): + suit, rank = self.agents + suit.z = z + rank.z = z + + def hide(self): + for agent in self.agents: + agent.hide() + + def show(self): + for agent in self.agents: + agent.show() + + def select(self): + for agent in self.agents: + agent.select() + + def deselect(self): + for agent in self.agents: + agent.deselect() + +class CardSuit: + def __init__(self, index, hidden=False, selected=False): + self.name = f"{index}_suit" + self.index = index + self.suit_color = colors[index // 13] + self.hidden = hidden + self.selected = selected + self.update_display() + + def select(self): + self.selected = True + self.update_display() + + def deselect(self): + self.selected = False + self.update_display() + + def show(self): + self.hidden = False + self.update_display() + + def hide(self): + self.hidden = True + self.update_display() + + def update_display(self): + if self.hidden: + self.character = "▒" + fg = "blue" + else: + self.character = suits[self.index //13] + fg = self.suit_color + if self.selected: + bg = "yellow" + else: + bg = "gray" + self.color = fg + "_on_" + bg + +class CardRank: + def __init__(self, index, hidden=False, selected=False): + self.name = f"{index}_rank" + self.index = index + self.suit_color = colors[index // 13] + self.hidden = hidden + self.selected = selected + self.update_display() + + def select(self): + self.selected = True + self.update_display() + + def deselect(self): + self.selected = False + self.update_display() + + def show(self): + self.hidden = False + self.update_display() + + def hide(self): + self.hidden = True + self.update_display() + + def update_display(self): + if self.hidden: + self.character = "▒" + fg = "blue" + else: + self.character = ranks[self.index % 13] + fg = self.suit_color + if self.selected: + bg = "yellow" + else: + bg = "gray" + self.color = fg + "_on_" + bg diff --git a/chris_demo/dealer.py b/chris_demo/dealer.py new file mode 100644 index 0000000..88cbb78 --- /dev/null +++ b/chris_demo/dealer.py @@ -0,0 +1,88 @@ +from deck import Deck + +class Dealer: + """The Dealer runs the game, following these rules: + + I have a card class that returns a card value + I have a dealer file that has a function that deals the first two cards + I'm still a little lost on how this works into the Game class + and how to organize the play. + I want to: + + 1. deal two cards to each dealer and player + 2. hide one of the dealers cards + 3. present the user with their cards and let them + choose * hit me OR * stay. + 4. If they hit, deal another card to them and calculate if they + went over 21. If they went over 21 end the game with BUST Dealer WINS!. + If they didn't go over 21, calculate their score and allow the dealer + their turn. + 5. If they stay, calculate their score and let the dealer have their turn. + 6. Dealer - checks their cards and compares them to the player. Then + chooses to hit or stay. Print choice to screen. If they hit, show the card + to the player. + """ + + display = False + playing = False + dealer_origin = (1, 3) + player_origin = (1, 5) + + def __init__(self, position): + self.position = position + self.dealer_cards = [] + self.player_cards = [] + + def play_turn(self, game): + if not self.playing: + self.set_up_new_round(game) + self.playing = True + + def handle_keystroke(self, keystroke, game): + game.log(keystroke) + if keystroke == "h": + self.deal_card_to_player() + game.state["score"] = self.get_player_score() + + def set_up_new_round(self, game): + self.deck = Deck(self.position) + for agent in self.deck.get_agents(): + game.add_agent(agent) + self.deal_card_to_dealer(hidden=True) + self.deal_card_to_dealer(hidden=False) + self.deal_card_to_player() + self.deal_card_to_player() + game.state["score"] = self.get_player_score() + + def deal_card_to_dealer(self, hidden=True): + card = self.deck.draw() + if hidden: + card.hide() + else: + card.show() + card.set_position(self.get_position_of_next_dealer_card()) + self.dealer_cards.append(card) + + def deal_card_to_player(self, hidden=False): + card = self.deck.draw() + if hidden: + card.hide() + else: + card.show() + card.set_position(self.get_position_of_next_player_card()) + self.player_cards.append(card) + + def get_position_of_next_player_card(self): + x, y = self.player_origin + return (x + 4 * len(self.player_cards), y) + + def get_position_of_next_dealer_card(self): + x, y = self.dealer_origin + return (x + 4 * len(self.dealer_cards), y) + + def get_player_score(self): + return sum([card.value() for card in self.player_cards]) + + def end_round(self, game): + for agent in self.deck.get_agents(): + game.remove_agent(agent) diff --git a/chris_demo/deck.py b/chris_demo/deck.py new file mode 100644 index 0000000..b9a7e84 --- /dev/null +++ b/chris_demo/deck.py @@ -0,0 +1,20 @@ +from card import Card +from random import shuffle + +class Deck: + def __init__(self, position, hidden=True, shuffled=True): + self.position = position + self.cards = [Card(position, i, hidden=hidden) for i in range(52)] + if shuffled: + shuffle(self.cards) + + def draw(self): + return self.cards.pop() + + def get_agents(self): + agents = [] + for card in self.cards: + agents.append(card) + agents += card.agents + return agents + diff --git a/chris_demo/game.py b/chris_demo/game.py new file mode 100644 index 0000000..4580853 --- /dev/null +++ b/chris_demo/game.py @@ -0,0 +1,11 @@ +from retro.game import Game +from dealer import Dealer + +dealer = Dealer((1, 1)) +state = { + "score": 0, + "options": "h to hit or s to stay", +} +game = Game([dealer], state) +game.play() +