menator01
Gold Coder
Blackjack with python and tkinter. Still has a few bugs but works. May not work on all os's. I'm using ubuntu and. Not tested on windows and macs.
Python:
import random as rnd
import tkinter as tk
class CheckCards:
def winner(self, player, dealer):
if player > 21:
msg = 'Player Busted!'
elif dealer > 21:
msg = 'Dealer Busted!'
elif player > dealer:
msg = 'Player Wins!'
elif dealer > player:
msg = 'Dealer Wins!'
else:
msg = 'Tie Game'
return msg
def get_hand(self, hand):
val = 0
for card in hand:
if card[1] in Card.face_cards.keys():
val += 10
else:
val += card[1]
if card[0] in [chr(0x1F0A1), chr(0x1F0B1), chr(0x1F0C1), chr(0x1F0D1)]:
val -= 1
item = list(card)
item[1] = 11
card = tuple(item)
if val + card[1] > 21:
val += 1
else:
val += card[1]
return val
class Card:
Clubs = u'\N{BLACK CLUB SUIT}'
Diamonds = u'\N{BLACK DIAMOND SUIT}'
Hearts = u'\N{BLACK HEART SUIT}'
Spades = u'\N{BLACK SPADE SUIT}'
Jack = 11
Queen = 12
King = 13
Ace = 1
Card_back = chr(0x1f0a0)
face_cards = {
11: 'Jack',
12: 'Queen',
13: 'King',
}
def __init__(self, rank: int, suit: str) -> None:
assert suit in (Card.Clubs, Card.Diamonds, Card.Hearts, Card.Spades)
assert 1 <= rank < 14
self.rank = rank
self.suit = suit
self.order = rank
@property
def image(self) -> str:
suit = {
Card.Spades: 0x1F0A0,
Card.Hearts: 0x1F0B0,
Card.Diamonds: 0x1F0C0,
Card.Clubs: 0x1F0D0,
}[self.suit]
rank = self.rank if self.rank < 12 else self.rank + 1
return chr(suit+rank)
class Deck(Card):
def __init__(self, shuffle=False):
suits = [Card.Clubs, Card.Spades, Card.Hearts, Card.Diamonds]
self.cards = [(Card(i, suit).image,i) for i in range(1, 14) for suit in suits]
if shuffle:
rnd.shuffle(self.cards)
def __len__(self):
return len(self.cards)
def deal(self, count):
cards = self.cards[:count]
self.cards = self.cards[count:]
return cards
class View:
def __init__(self, parent):
parent.columnconfigure(0, weight=1)
parent.rowconfigure(0, weight=1)
container = tk.Frame(parent)
container.grid(column=0, row=0, sticky='news')
container.grid_columnconfigure(0, weight=3)
self.player_container = tk.Frame(container, height=50)
self.player_container['borderwidth'] = 0
self.player_container['highlightcolor'] = 'black'
self.player_container['highlightbackground'] = 'black'
self.player_container['highlightthickness'] = 1
self.player_container.grid(column=0, row=1, sticky='news', padx=5, pady=5)
label = tk.Label(container, pady=12, relief='ridge')
label['text'] = f'BlackJack {Card(1, Card.Hearts).image} {Card(11,Card.Spades).image}'
label['font'] = (None, 25, 'bold')
label['bg'] = 'antiquewhite'
label.grid(column=0, row=0, sticky='new', padx=5, pady=5)
player = tk.Label(self.player_container, text='Player', bg='lightsteelblue', pady=5)
player['font'] = (None, 16, 'bold')
player.grid(column=0, row=0, sticky='new', pady=5, ipadx=100)
dealer = tk.Label(self.player_container, text='Dealer', bg='gray', pady=5)
dealer['font'] = (None, 16, 'bold')
dealer.grid(column=0, row=1, sticky='new', pady=5, ipadx=100)
self.player_card_frame = tk.Frame(self.player_container)
self.player_card_frame.grid(column=1, row=0, sticky='new', padx=5, pady=5)
self.dealer_card_frame = tk.Frame(self.player_container)
self.dealer_card_frame.grid(column=1, row=1, sticky='new', padx=5, pady=5)
btn_container = tk.Frame(container)
btn_container.grid(column=0, row=2, sticky='new', padx=5, pady=5)
for i in range(3):
btn_container.grid_columnconfigure(i, weight=3, uniform='button')
self.deal_btn = tk.Button(btn_container, text='Deal', cursor='hand2')
self.deal_btn.grid(column=0, row=0, sticky='new', padx=(2,1))
self.hit_btn = tk.Button(btn_container, text='Hit Me', cursor='hand2')
self.hit_btn.grid(column=1, row=0, sticky='new', padx=1)
self.call_btn = tk.Button(btn_container, text='Call', cursor='hand2')
self.call_btn.grid(column=2, row=0, sticky='new', padx=(1,2))
self.msg_label = tk.Label(container, anchor='nw', padx=8)
self.msg_label['font'] = (None, 12, 'normal')
self.msg_label['relief'] = 'ridge'
self.msg_label['fg'] = 'steelblue'
self.msg_label.grid(column=0 ,row=3, sticky='new', padx=5, pady=5)
class Controller:
def __init__(self, deck, check, view):
self.deck = deck
self.check = check
self.view = view
# Buttons
self.view.deal_btn['command'] = self.deal
self.view.hit_btn['command'] = self.hitme
self.view.hit_btn['state'] = 'disabled'
self.view.call_btn['command'] = self.call
self.view.call_btn['state'] = 'disabled'
def hitme(self):
self.player.append(*self.deck.deal(1))
self.player_cards = [card[0] for card in self.player]
self.player_total = self.check.get_hand(self.player)
for i, card in enumerate(self.player_cards):
label = tk.Label(self.view.player_card_frame)
label['text'] = card
label['font'] = (None, 18, 'bold')
label.grid(column=i, row=0, sticky='news', padx=2, pady=2)
if self.player_total > 21:
self.view.deal_btn['state'] = 'normal'
self.view.hit_btn['state'] = 'disabled'
self.view.call_btn['state'] = 'disabled'
self.view.msg_label['text'] = f'You Busted! You have a total of {self.player_total}'
else:
self.view.msg_label['text'] = f'Player has: {self.player_total}'
def call(self):
self.view.deal_btn['state'] = 'normal'
self.view.hit_btn['state'] = 'disabled'
self.view.call_btn['state'] = 'disabled'
while self.dealer_total < 17:
self.dealer.append(*self.deck.deal(1))
self.dealer_total = self.check.get_hand(self.dealer)
self.dealer_cards = [card[0] for card in self.dealer]
for i, card in enumerate(self.dealer_cards):
label = tk.Label(self.view.dealer_card_frame)
label['text'] = card
label['font'] = (None, 20, 'bold')
label.grid(column=i, row=1, sticky='news', padx=2, pady=2)
self.deck = Deck(True)
self.view.msg_label['text'] = self.check.winner(self.player_total, self.dealer_total)
def deal(self):
self.deck = Deck(True)
self.view.msg_label['text'] = ''
self.view.player_card_frame.destroy()
self.view.player_card_frame = tk.Frame(self.view.player_container)
self.view.player_card_frame.grid(column=1, row=0, sticky='new', padx=5, pady=5)
self.view.dealer_card_frame.destroy()
self.view.dealer_card_frame = tk.Frame(self.view.player_container)
self.view.dealer_card_frame.grid(column=1, row=1, sticky='new', padx=5, pady=5)
self.view.deal_btn['state'] = 'disabled'
self.view.hit_btn['state'] = 'normal'
self.view.call_btn['state'] = 'normal'
self.player = self.deck.deal(2)
self.dealer = self.deck.deal(2)
self.player_cards = [card[0] for card in self.player]
self.dealer_cards = [card[0] for card in self.dealer]
for i, card in enumerate(self.player_cards):
label = tk.Label(self.view.player_card_frame)
label['text'] = card
label['font'] = (None, 20, 'bold')
label.grid(column=i, row=0, sticky='news', padx=2, pady=2)
for i, card in enumerate(self.dealer_cards):
label = tk.Label(self.view.dealer_card_frame)
if i == 0:
label['text'] = chr(0x1f0a0)
else:
label['text'] = card
label['font'] = (None, 20, 'bold')
label.grid(column=i, row=1, sticky='news', padx=2, pady=2)
self.player_total = self.check.get_hand(self.player)
self.dealer_total = self.check.get_hand(self.dealer)
self.view.msg_label['text'] = f'Player has: {self.player_total}'
if __name__ == '__main__':
root = tk.Tk()
root.geometry('800x300+300+300')
Controller(Deck(True), CheckCards(), View(root))
root.mainloop()