Igra Black Jack

Rokovalnik izpisa na platno izpiše ustrezno besedilo. Za izris kart pa pokliče metodo narisi_karte razreda Igralec, ki poskrbi za izpis vseh kart, ki jih ima igralec v roki. Metoda Igralec.narisi_karte() pa nadalje pokliče metodo narisi razreda Karta, ki poskrbi za izpis oziroma izris slike karte na ustreznem mestu na platnu.

class BlackJack():
  # ...

  def narisi(self, platno):
    self._igralec.narisi_karte(platno, [50, 220])
    self._delivec.narisi_karte(platno, [50, 400])
    # Skrij prvo karto delivca, če igra poteka
    if self._igra_poteka:
      self._delivec.obrni_karto(platno, [50, 400])

    _txt1 = "Black Jack"
    _txt2 = "Tvoje karte"
    _txt3 = "Jackove karte"
    _txt4 = "STANJE: " + self._izid
    _txt5 = "REZULTAT: zmage: " + str(self._REZULTAT["ZMAGE"]) \
            + ", skupaj: " + str(self._REZULTAT["SKUPAJ"])

    platno.draw_text(_txt1, [50, 70], 40, "white")
    platno.draw_text(_txt2, [50, 200], 20, "white")
    platno.draw_text(_txt3, [50, 380], 20, "white")
    platno.draw_text(_txt4, [50, 140], 20, "white")
    platno.draw_text(_txt5, [50, 560], 20, "white")

Razrede Karta, Igralec in Komplet smo sicer spoznali že v prejšnji učni enoti. Tukaj smo jih samo priredili (in izbrisali metode, ki jih ne potrebujemo), da jih lahko uporabimo v GUI vmesniku programa.


Izvedi Počisti


  1 # encoding: utf-8
  2 import tkinter as tk
  3 import random
  4 
  5 # Definicija konstant
  6 VEL = (86, 120) # Velikost posamezne karte
  7 SRED = (43, 60) # Središče posamezne karte
  8 KARTE = {}      # Slovar bo vseboval slike kart
  9 
 10 # Definicija globalnih spremenljivk za karte
 11 BARVE = ("S", "H", "D", "C")  # Spade/Heart/Diamond/Club
 12 ZNAKI = ("♠", "♥", "♦", "♣")
 13 OPISI = ("A", "2", "3", "4", "5", "6", "7",
 14          "8", "9", "X", "J", "Q", "K")
 15 VREDNOSTI = {"A":1, "2":2, "3":3, "4":4, "5":5, "6":6, "7":7,
 16              "8":8, "9":9, "X":10, "J":10, "Q":10, "K":10}
 17 
 18 
 19 # Definicija razreda 'Karta'
 20 class Karta:
 21 
 22   def __init__(self, barva, opis):
 23     """ Inicializator """
 24     if (barva in BARVE) and (opis in OPISI):
 25       self._barva = barva
 26       self._opis = opis
 27     else:
 28       self._barva = None
 29       self._opis = None
 30       print("Neveljavna karta: ", barva, opis)
 31 
 32   def __str__(self):
 33     """ Vrne niz, ki predstavlja karto """
 34     return self._barva + self._opis
 35 
 36   def vrni_barvo(self):
 37     """ Vrne barvo karte """
 38     return self._barva
 39 
 40   def vrni_opis(self):
 41     """ Vrne opis ali rang karte """
 42     return self._opis
 43 
 44   def narisi(self, platno, poz):
 45     """ Nariše sliko karte na platnu, na danem položaju """
 46     k = self._barva + self._opis
 47     platno.create_image(poz[0], poz[1], \
 48       anchor=tk.NW, image=KARTE[k])
 49 
 50 
 51 # Definicija razreda 'Komplet'
 52 class Komplet:
 53 
 54   def __init__(self):
 55     """ Inicializator """
 56     self._karte = []
 57     for barva in BARVE:
 58       for opis in OPISI:
 59         self._karte.append(Karta(barva, opis))
 60 
 61   def __str__(self):
 62     """ Vrne niz, ki predstavlja komplet kart """
 63     sporocilo = "Komplet vsebuje"
 64     for karta in self._karte:
 65       sporocilo += " " + str(karta)
 66     return sporocilo
 67 
 68   def premesaj(self):
 69     """ Premeša karte v kompletu """
 70     random.shuffle(self._karte)
 71 
 72   def sprazni(self):
 73     """ Sprazni komplet kart """
 74     self._karte = []
 75 
 76   def deli_karto(self):
 77     """ Deli naslednjo karto iz kompleta """
 78     return self._karte.pop()
 79 
 80 
 81 # Definicija razreda 'Igralec'
 82 class Igralec(Komplet):
 83 
 84   def __init__(self, delivec=False):
 85     """ Inicializator """
 86     self._karte = []
 87     self._delivec = delivec
 88     self._skrij_karto = False
 89 
 90   def __str__(self):
 91     """ Vrne niz, ki predstavlja igralčeve karte """
 92     sporocilo = ""
 93     skrita_karta = self._skrij_karto
 94     for karta in self._karte:
 95       if self._delivec and skrita_karta:
 96         sporocilo += " ??"
 97         skrita_karta = False
 98       else:
 99         sporocilo += " " + str(karta)
100     return sporocilo
101 
102   def dodaj_karto(self, karta):
103     """ Igralcu doda nov objekt 'Karta' """
104     self._karte.append(karta)
105 
106   def vrednost_kart(self):
107     """ Vrne skupno vrednost kart, ki jih igralec drži v roki """
108     # Če ima igralec v roki karto as, jo šteje kot 1 in nato, če
109     # vrednost kart v roki ne preseže 21, doda vrednosti še 10 -
110     # saj je as vreden 1 ali 11 točk.
111     vrednost = 0
112     asi = 0
113     for karta in self._karte:
114       vrednost += VREDNOSTI[karta._opis]
115       if karta._opis == "A":
116         asi += 1
117     for a in range(asi):
118       # Če je vrednost kart v roki igralca dovolj nizka, lahko
119       # štejemo asa kot 11, namesto 1...
120       # To pomeni: vrednosti dodaj dodatnih 10 točk!
121       if vrednost <= 11:
122         vrednost += 10
123     return vrednost
124 
125   def narisi_karte(self, platno, poz):
126     """ Nariše karte - uporabi metodo narisi razreda 'Karta' """
127     ROB = 10
128     i = 0
129     for karta in self._karte:
130       karta.narisi(platno, [poz[0]+i*(VEL[0]+ROB),poz[1]])
131       i += 1
132 
133   def skrij_karto(self):
134     """ Skrije prvo karto delivca """
135     self._skrij_karto = True
136 
137   def razkrij_karto(self):
138     """ Razkrije prvo karto delivca """
139     self._skrij_karto = False
140 
141   def obrni_karto(self, platno, poz):
142     """ Prvo karto delivca nariše obrnjeno na hrbtno stran """
143     if self._delivec:
144       platno.create_image(poz[0], poz[1], \
145         anchor=tk.NW, image=KARTE['BG'])
146 
147 
148 # Definicija razreda 'BlackJack'
149 class BlackJack():
150 
151   _igra_poteka = False
152   _izid = ""
153   _REZULTAT = {"SKUPAJ":0, "ZMAGE":0}
154 
155   _komplet = Komplet()
156 
157   def __init__(self):
158     """ Inicializator """
159     # Ustvari okno, okvir in platno
160     self.okno = tk.Tk()
161     self.okno.title("Black Jack")
162     self.okno.geometry("840x640")
163     self.okvir = tk.Frame(self.okno)
164     self.okvir.grid(row=0, column=0, pady=20)
165     self.platno = tk.Canvas(self.okno, width=650, height=600)
166     self.platno.configure(bg="darkgreen")
167     self.platno.grid(row=0, column=1, pady=20)
168 
169     # Naloži slike kart. Slike kart so v podmapi 'karte', ki je v isti
170     # mapi kot datoteka 'blackjack.py'
171     global KARTE
172     KARTE = {'BG': tk.PhotoImage(file="karte/BG1.gif")}
173     for barva in BARVE:
174       for opis in OPISI:
175         karta = barva + opis
176         datoteka = "karte/" + karta + ".gif"
177         KARTE[karta] = tk.PhotoImage(file=datoteka)
178 
179     # Ustvari gumbe in jih poveži z dogodkovnimi rokovalniki
180     self.gumb1 = tk.Button(self.okvir, text="Deli", command=self.deli)
181     self.gumb1.configure(width=10)
182     self.gumb1.grid(row=0, column=0, padx=45)
183     self.gumb2 = tk.Button(self.okvir, text="Vleci", command=self.vleci)
184     self.gumb2.configure(width=10)
185     self.gumb2.grid(row=1, column=0, padx=45)
186     self.gumb3 = tk.Button(self.okvir, text="Obdrži", command=self.obdrzi)
187     self.gumb3.configure(width=10)
188     self.gumb3.grid(row=2, column=0, padx=45)
189 
190     # Dodaj igralca in delivca
191     self._igralec = Igralec()
192     self._delivec = Igralec(True)
193 
194     # Razdeli karte
195     self.deli()
196 
197     # Zaženi dogodkovno zanko
198     self.okno.mainloop()
199 
200   def deli(self):
201     """ Rokovalnik gumba 'Deli' """
202     # Ustvari nov komplet kart in ga premešaj
203     self._komplet = Komplet()
204     self._komplet.premesaj()
205 
206     # Dodaj igralca in delivca ter začni igro
207     self._igralec._karte = []
208     self._delivec._karte = []
209     self._igra_poteka = True
210     self._delivec.skrij_karto()
211     self._izid = ""
212 
213     # Izmenično razdeli dve karti igralcu in delivcu
214     self._igralec.dodaj_karto(self._komplet.deli_karto())
215     self._delivec.dodaj_karto(self._komplet.deli_karto())
216     self._igralec.dodaj_karto(self._komplet.deli_karto())
217     self._delivec.dodaj_karto(self._komplet.deli_karto())
218 
219     # Nariši karte igralca in delivca
220     self.narisi()
221 
222   def vleci(self):
223     """ Rokovalnik gumba 'Vleci' """
224     if self._igra_poteka:
225       self._igralec.dodaj_karto(self._komplet.deli_karto())
226 
227     # Če igralec preseže 21, priredi sporočilo spremeljivki _izid
228     # ter posodobi vrednosti spremeljivk _igra_poteka in _REZULTAT
229     if self._igralec.vrednost_kart() > 21:
230       self._izid = "Imaš več kot 21. Jack je zmagal. Nova igra?"
231       self._igra_poteka = False
232       self._REZULTAT["SKUPAJ"] += 1
233       # Končaj igro
234       self._igra_poteka = False
235       self._delivec.razkrij_karto()
236 
237     # Nariši karte igralca in delivca
238     self.narisi()
239 
240   def obdrzi(self):
241     """ Rokovalnik gumba 'Obdrži' """
242     # Če igra poteka, potem delivec vleče karte, dokler ni njihova
243     # skupna vrednost 17 ali več
244     while self._delivec.vrednost_kart() < 17:
245       self._delivec.dodaj_karto(self._komplet.deli_karto())
246     
247     # Končaj igro
248     self._igra_poteka = False
249     self._delivec.razkrij_karto()
250 
251     # Priredi sporočilo spremeljivki _izid ter posodobi vrednosti
252     # spremeljivk _igra_poteka in _REZULTAT
253     if self._delivec.vrednost_kart() > 21:
254       self._izid = "Jack ima več kot 21. Zmagal si! Nova igra?"
255       self._REZULTAT["SKUPAJ"] += 1
256       self._REZULTAT["ZMAGE"] += 1
257     else:
258       # Določi zmagovalca
259       self._REZULTAT["SKUPAJ"] += 1
260       if self._igralec.vrednost_kart() > self._delivec.vrednost_kart():
261         self._izid = "Zmagal si! Nova igra?"
262         self._REZULTAT["ZMAGE"] += 1
263       else:
264         self._izid = "Jack je zmagal. Nova igra?"
265 
266     # Nariši karte igralca in delivca ter izid igre
267     self.narisi()
268 
269   def narisi(self):
270     """ Rokovalnik izpisa oz. izrisa """
271     # Izbriši vsebino platna
272     self.platno.delete("all")
273 
274     # Nariši karte igralca in delivca
275     self._igralec.narisi_karte(self.platno, [50, 220])
276     self._delivec.narisi_karte(self.platno, [50, 400])
277     # Skrij prvo karto delivca, če igra poteka
278     if self._igra_poteka:
279       self._delivec.obrni_karto(self.platno, [50, 400])
280 
281     _txt1 = "Black Jack"
282     _txt2 = "Tvoje karte"
283     _txt3 = "Jackove karte"
284     _txt4 = "STANJE: " + self._izid
285     _txt5 = "REZULTAT: zmage: " + str(self._REZULTAT["ZMAGE"]) \
286             + ", skupaj: " + str(self._REZULTAT["SKUPAJ"])
287 
288     self.platno.create_text(50, 50, fill="white", anchor=tk.NW, \
289       text=_txt1, font=("Times", 30))
290     self.platno.create_text(50, 180, fill="white", anchor=tk.NW, \
291       text=_txt2, font=("Times", 15))
292     self.platno.create_text(50, 360, fill="white", anchor=tk.NW, \
293       text=_txt3, font=("Times", 15))
294     self.platno.create_text(50, 120, fill="white", anchor=tk.NW, \
295       text=_txt4, font=("Times", 15))
296     self.platno.create_text(50, 540, fill="white", anchor=tk.NW, \
297       text=_txt5, font=("Times", 15))
298 
299 
300 # Zaženemo igro
301 BlackJack()
302 
303 

Izvorna koda Slike kart