from collections import namedtuple
from random import shuffle
import tkinter as tk
Carta = namedtuple('Carta', ['numero', 'naipe'])
class Observadores(object):
def __init__(self):
self.observadores = set()
def adiciona(self, observador):
self.observadores.add(observador)
def notifica(self):
for observador in self.observadores:
observador.evento()
class EstourouPontos(Exception):
def __str__(self):
return 'Perdeu !'
class Baralho(object):
numeros = '2 3 4 5 6 7 8 9 10 J Q K A'.split()
naipes = '♥ ♦ ♣ ♠'.split()
def __init__(self):
self.baralho = [Carta(numero, naipe) for numero in Baralho.numeros for naipe in Baralho.naipes]
self.embaralha()
def __len__(self):
return len(self.baralho)
def __getitem__(self, indice):
return self.baralho[indice]
def embaralha(self):
shuffle(self.baralho)
def retornaCarta(self):
return self.baralho.pop()
class Jogador(object):
def __init__(self):
self.cartas = []
self.pontos = 0
def recebeCarta(self, carta):
self.cartas.append(carta)
self.atualizaPontos(carta)
def atualizaPontos(self, carta):
self.pontos += self.verificaCarta(carta)
if self.pontos >= 21:
raise EstourouPontos()
def verificaCarta(self, carta):
if carta.numero == 'A':
return 1
elif carta.numero in ('J', 'Q', 'K'):
return 10
else:
return int(carta.numero)
class Tela(Observadores):
def __init__(self):
super().__init__()
self.root = tk.Tk()
self.root.title('Blackjack')
self.root.geometry('+100+100')
self.root.resizable(False, False)
self.fonte = ('Comic Sans MS', 12, 'bold')
self.frame1 = tk.Frame(self.root)
self.frame2 = tk.Frame(self.root)
tk.Label(self.root, text = 'BLACKJACK', font = self.fonte, fg = 'red').pack()
self.botaoIniciar = tk.Button(self.frame1, text = 'Iniciar', fg = 'green', font = self.fonte, width = 12)
self.botaoIniciar['command'] = self.telaJogo
self.botaoSair = tk.Button(self.frame1, text = 'Sair', fg = 'red', font = self.fonte, width = 12)
self.botaoSair['command'] = self.sairDoJogo
self.botaoPedeCarta = tk.Button(self.frame2, text = 'Mais uma carta', fg = 'blue', font = self.fonte, width = 12)
self.botaoPedeCarta['command'] = self.pedeCarta
self.mostraCarta = tk.Label(self.frame2, text = '--', font = self.fonte)
self.mostraPontos = tk.Label(self.frame2, text = '00 Pontos', fg = 'green', font = self.fonte)
self.botaoIniciar.pack(side = tk.LEFT)
self.botaoSair.pack(side = tk.LEFT)
self.mostraPontos.pack(side = tk.TOP)
self.mostraCarta.pack(side = tk.TOP)
self.botaoPedeCarta.pack(side = tk.BOTTOM)
self.telaInicial()
def telaInicial(self):
self.frame2.pack_forget()
self.frame1.pack(side = tk.BOTTOM)
def telaJogo(self):
self.frame1.pack_forget()
self.frame2.pack(side = tk.BOTTOM)
def sairDoJogo(self):
self.root.destroy()
def pedeCarta(self):
self.notifica()
def message(self, texto, cor = 'red'):
self.mostraPontos['text'] = texto
self.mostraPontos['fg'] = cor
def atualizaDados(self, carta, jogador):
self.mostraCarta['text'] = str(carta.numero) + carta.naipe
self.mostraPontos['text'] = str(jogador.pontos) + ' Pontos'
def mainloop(self):
self.root.mainloop()
class Blackjack(object):
def __init__(self):
self.tela = Tela()
self.jogador = Jogador()
self.baralho = Baralho()
self.tela.adiciona(self)
self.tela.mainloop()
def evento(self):
try:
carta = self.PegaCarta()
self.jogador.recebeCarta(carta)
self.tela.atualizaDados(carta, self.jogador)
except EstourouPontos as erro:
self.tela.message(erro)
def PegaCarta(self):
return self.baralho.retornaCarta()
if __name__ == '__main__':
blackjack = Blackjack()