-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
380 lines (327 loc) · 15.2 KB
/
main.py
File metadata and controls
380 lines (327 loc) · 15.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
import pygame
import os
pygame.init()
from jeu.tirage import Tirage
from jeu.cartes import Carte
from jeu.paquet import Paquet
from jeu.compteur import Compteur
from jeu.controleur import Controleur
from jeu.tour_croupier import TourCroupier
from jeu.tour_joueur import TourJoueur
from jeu.gestion_partie import GestionPartie
from jeu.bouton import Bouton
solde_initial = 1000
gestion_partie = GestionPartie(solde_initial)
#TEST DE COMBINAISON 1ere main au lancement
# carte1 = Carte("4", "Coeur")
# carte2 = Carte("6", "Carreau")
# gestion_partie.partie.joueur = [[carte1, carte2]]
# gestion_partie.partie.compteur.mise_a_j_valeur_main(gestion_partie.partie)
jeu = None
controleur = None
tour_croupier = None
tour_joueur = None
# pygame config affichage
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption(" BLACKJACK ")
font = pygame.font.Font("assets/fonts/pixel_font.ttf", 14)
background_image = pygame.image.load("assets/images/fond/background.png")
fond_image = pygame.transform.scale(background_image, screen.get_size())
images_cartes = {}
#Boutons mises avant début du jeu
saisie_mise_active = True
mise_choisie = 0
jeu_initialise = False
message_erreur_mise = False
jetons = [
{"chemin": "assets/images/jetons/jeton_rouge.png", "valeur": 25, "pos": (160, 280)},
{"chemin": "assets/images/jetons/jeton_vert.png", "valeur": 50, "pos": (270, 280)},
{"chemin": "assets/images/jetons/jeton_noir.png", "valeur": 100, "pos": (380, 280)},
]
for j in jetons:
j["image"] = pygame.image.load(j["chemin"]).convert_alpha()
j["image"] = pygame.transform.scale(j["image"], (80, 80))
j["rect"] = j["image"].get_rect(topleft=j["pos"])
def afficher_jetons(screen, jetons, font):
for j in jetons:
# Affichage de l'image
screen.blit(j["image"], j["pos"])
# Affichage de la valeur en dessous
texte = font.render(f"{j['valeur']} €", True, (255, 255, 255))
text_rect = texte.get_rect(center=(j["rect"].centerx, j["rect"].bottom + 12))
screen.blit(texte, text_rect)
bouton_lancer_partie = pygame.image.load("assets/images/boutons/lancer_partie_btn.png").convert_alpha()
position_bouton = (490, 290)
rect_bouton = bouton_lancer_partie.get_rect(topleft=position_bouton)
#clock framerate pour limiter
clock = pygame.time.Clock()
#images pour cartes
def charger_images_cartes():
dossier = "assets/images/cartes"
for fichier in os.listdir(dossier):
if fichier.endswith(".png"):
chemin = os.path.join(dossier, fichier)
image = pygame.image.load(chemin).convert_alpha()
# Redimensionne l'image
image = pygame.transform.scale(image, (100, 140))
images_cartes[fichier] = image
chemin_dos = os.path.join(dossier, "back_card.png")
if os.path.exists(chemin_dos):
image_dos = pygame.image.load(chemin_dos).convert_alpha()
image_dos = pygame.transform.scale(image_dos, (100, 140))
images_cartes["dos"] = image_dos
#AFFICHAGE style cartes / Fonction enum
def afficher_cartes(cartes, position_x_main, position_y_debut, masquee=False):
espacement_vertical = 30
for index_carte, carte in enumerate(cartes):
position_y_carte = position_y_debut + index_carte * espacement_vertical
#Décalage cartes
decalage_x = 10 if index_carte > 0 else 0
position_x_carte = position_x_main + decalage_x
#Masque 2eme carte croupier
if masquee and index_carte == 1:
dos_image = images_cartes.get("dos")
if dos_image:
screen.blit(dos_image, (position_x_carte, position_y_carte))
else:
nom_image = os.path.basename(carte.image_path())
image = images_cartes.get(nom_image)
if image:
screen.blit(image, (position_x_carte, position_y_carte))
else:
# fallback texte si image non trouvée
texte = font.render(f"{carte.valeur} {carte.couleur}", True, (0, 0, 0))
screen.blit(texte, (position_x_carte, position_y_carte))
charger_images_cartes()
def afficher_message_texte(message, x, y):
texte = font.render(message, True, (211, 211, 211))
screen.blit(texte, (x, y))
def afficher_mains_joueur(joueur):
position_y_cartes = 375
position_x_depart = 235
espacement_y = 150 #Ecart pour split
for index_main, main in enumerate(joueur):
#Gestion affichage Split
position_x_main = position_x_depart + index_main *espacement_y
afficher_cartes(main, position_x_main, position_y_cartes)
#Main active + visuel
if index_main == controleur.index_main_joueur:
pygame.draw.rect(
screen,
(255, 0, 0),
(position_x_main -10, position_y_cartes, 140, 120 + 30 * len(main)),
1
)
def afficher_mises(mises):
position_x = 200
position_y = 330
espacement = 200
for i, mise in enumerate(mises):
texte_mise = font.render(f"Mise main: {mise} €", True, (211, 211, 211))
screen.blit(texte_mise, (position_x + i * espacement, position_y))
def afficher_message_mise():
texte = font.render("Veuillez choisir une mise avant de commencer", True, (255, 0, 0))
screen.blit(texte, (50, 250))
def afficher_solde(solde):
texte_solde = font.render(f"Solde : {solde} €", True, (211, 211, 211))
screen.blit(texte_solde, (600, 550))
def afficher_score_croupier_une_carte(partie, masquee):
if masquee and len(partie.croupier) > 0:
premiere_carte = partie.croupier[0]
valeur_premiere_carte = jeu.compteur.valeurs_cartes[premiere_carte.valeur]
return f"Croupier: {valeur_premiere_carte}"
else:
return f"Croupier: {jeu.compteur.valeur_croupier}"
## TEST TERMINAL ##
if jeu and controleur:
print(jeu.croupier)
print("Masquée")
print(jeu.joueur)
print(jeu.compteur.valeur_joueur)
## GESTION PARAMETRES AFFICHAGE PYGAME ##
#BOUTONS pixel art
btn_tirer_img = pygame.image.load("assets/images/boutons/tirer_btn.png").convert_alpha()
btn_rester_img = pygame.image.load("assets/images/boutons/rester_btn.png").convert_alpha()
btn_split_img = pygame.image.load("assets/images/boutons/split_btn.png").convert_alpha()
btn_doubler_img = pygame.image.load("assets/images/boutons/doubler_btn.png").convert_alpha()
btn_rejouer_img = pygame.image.load("assets/images/boutons/rejouer_btn.png").convert_alpha()
bouton_tirer = Bouton(600, 350, 100, 40, "Tirer", None, (255, 255, 255), font, image=btn_tirer_img, visible=False)
bouton_rester = Bouton(600, 400, 100, 40, "Rester", None, (255, 255, 255), font, image=btn_rester_img,visible=False)
bouton_split = Bouton(600, 450, 100, 40, "Split", None, (255, 255, 255), font, image=btn_split_img, visible=False)
bouton_doubler = Bouton(600, 500, 100, 40, "Doubler", None, (255, 255, 255), font, image=btn_doubler_img, visible=False)
bouton_restart = Bouton(550, 350, 200, 80, "Rejouer", None, (200, 200, 200), font, image=btn_rejouer_img, visible = False)
#GESTION du rafraichissement: action/inaction
running = True
besoin_rafraichissement = True
#Index main joueur
if gestion_partie.controleur and gestion_partie.tour_croupier:
if gestion_partie.tour_croupier.en_cours:
gestion_partie.controleur.index_main_joueur = 0
else:
print("Erreur :Tour croupier ou controleur non initialisé.")
#méthode tirage carte avec index main
def tirer_carte_joueur_index(partie, index_main):
carte = partie.paquet.tirer()
partie.joueur[index_main].append(carte)
partie.compteur.mise_a_j_valeur_main(partie)
#JEU ACTIF- cycle principal pygame
while running:
##GESTION D'EVENEMENTS
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN:
pos = event.pos
#Clic Bouton Mises
if saisie_mise_active:
bouton_restart.visible = False
for j in jetons:
if j["rect"].collidepoint(pos):
solde_actuel = gestion_partie.partie.solde if gestion_partie.partie else gestion_partie.solde_initial
if mise_choisie + j["valeur"] > solde_actuel:
print("Solde insuffisant")
else:
mise_choisie += j["valeur"]
print(f"Mise choisie : {mise_choisie} €")
besoin_rafraichissement = True
break
# Récupération des objets après création de la partie
if rect_bouton.collidepoint(pos):
if mise_choisie == 0:
message_erreur_mise = True
besoin_rafraichissement = True
else:
message_erreur_mise = False
saisie_mise_active = False
jeu_initialise = True
gestion_partie.nouvelle_partie(mise_initiale=mise_choisie)
jeu = gestion_partie.partie
controleur = gestion_partie.controleur
tour_croupier = gestion_partie.tour_croupier
tour_joueur = gestion_partie.tour_joueur
bouton_tirer.visible = True
bouton_rester.visible = True
besoin_rafraichissement = True
else:
#Clic Bouton SPLIT
if bouton_split.visible and bouton_split.est_clique(pos) and not controleur.tour_joueur_fini:
tour_joueur.jouer("splitter", controleur.index_main_joueur)
besoin_rafraichissement = True
#Clic Bouton DOUBLER
elif bouton_doubler.visible and bouton_doubler.est_clique(pos) and not controleur.tour_joueur_fini:
tour_joueur.jouer("doubler", controleur.index_main_joueur)
besoin_rafraichissement = True
#Clic bouton REJOUER
elif controleur.jeu_fini and bouton_restart.est_clique(event.pos):
print("Nouvelle partie lancée")
print("Nouvelle mise attendue")
#Efface le dernier jeu
jeu = None
controleur = None
tour_joueur = None
tour_croupier = None
bouton_restart.visible = False
saisie_mise_active = True
jeu_initialise = False
mise_choisie = 0
besoin_rafraichissement = True
#Clic Bouton TIRER
elif bouton_tirer.est_clique(pos) and not controleur.tour_joueur_fini:
print("Carte tirée par le joueur")
controleur.tour_joueur.jouer("tirer")
jeu.compteur.mise_a_j_valeur_main(jeu)
controleur.controle_fin_jeu()
besoin_rafraichissement = True
#Clic Bouton RESTER
elif bouton_rester.est_clique(pos) and not controleur.tour_joueur_fini:
controleur.tour_joueur.jouer("stand")
besoin_rafraichissement = True
##AFFICHAGE CURSEUR/MAIN
pos = pygame.mouse.get_pos()
curseur_main = False
if saisie_mise_active:
if rect_bouton.collidepoint(pos):
curseur_main = True
for j in jetons:
if j["rect"].collidepoint(pos):
curseur_main = True
break
else:
for bouton in [bouton_tirer, bouton_rester, bouton_split, bouton_doubler, bouton_restart]:
if bouton.visible and bouton.rect.collidepoint(pos):
curseur_main = True
break
if curseur_main:
pygame.mouse.set_cursor(pygame.SYSTEM_CURSOR_HAND)
else:
pygame.mouse.set_cursor(pygame.SYSTEM_CURSOR_ARROW)
if controleur is not None and controleur.tour_croupier.en_cours:
controleur.tour_croupier.mise_a_jour()
besoin_rafraichissement = True
##MAJ DE L'AFFICHAGE/Chaque action
if besoin_rafraichissement:
#Efface l'écran / fond
screen.fill((50, 205, 50))
#Background image
screen.blit(background_image, (0,0))
if gestion_partie.partie:
afficher_solde(gestion_partie.partie.solde)
else:
afficher_solde(gestion_partie.solde_initial)
#Aff Boutons Mises avant débit de partie
if saisie_mise_active:
afficher_jetons(screen, jetons, font)
#bouton_lancer_partie.dessiner(screen)
screen.blit(bouton_lancer_partie, position_bouton)
texte_mise = font.render(f"Mise totale : {mise_choisie} €", True, (211, 211, 211))
screen.blit(texte_mise, (270, 200))
#Erreur si pas de mise
if message_erreur_mise:
afficher_message_mise()
#Aff Cartes
if jeu and controleur:
afficher_cartes(jeu.croupier, 235, 50, masquee=not controleur.tour_joueur_fini)
afficher_mains_joueur(jeu.joueur)
#Aff Scores
texte_compteur_joueur = font.render(f"Joueur: {jeu.compteur.valeur_joueur}", True,(211, 211, 211))
texte_compteur_croupier = font.render(afficher_score_croupier_une_carte(jeu, masquee=not controleur.tour_joueur_fini), True, (211, 211, 211))
screen.blit(texte_compteur_joueur, (50, 375))
screen.blit(texte_compteur_croupier, (50, 50))
#Mises & solde après début de partie
afficher_mises(jeu.mises)
#Gestion visibilité/condition boutons Splitter et Doubler
index_valide = 0 <= controleur.index_main_joueur < len(jeu.joueur)
bouton_split.visible = (
index_valide and
tour_joueur.peut_splitter(controleur.index_main_joueur) and
not controleur.tour_joueur_fini and
len(jeu.joueur) == 1
)
bouton_doubler.visible = (
index_valide and
tour_joueur.peut_doubler(controleur.index_main_joueur) and
not controleur.tour_joueur_fini
)
#Fin: Messages + bouton restart
if controleur.jeu_fini:
message_fin = font.render(controleur.message_jeu_fini, True, (235, 237, 239), (52, 73, 94))
screen.blit(message_fin, (150, 290))
bouton_restart.visible = True
bouton_tirer.visible = False
bouton_rester.visible = False
else:
bouton_restart.visible = False
bouton_tirer.visible = index_valide and not controleur.tour_joueur_fini
bouton_rester.visible = index_valide and not controleur.tour_joueur_fini
#Boutons
bouton_tirer.dessiner(screen)
bouton_rester.dessiner(screen)
bouton_restart.dessiner(screen)
bouton_split.dessiner(screen)
bouton_doubler.dessiner(screen)
# Màj affichage écran
pygame.time.delay(700)
pygame.display.flip()
besoin_rafraichissement = False #blocage rafraichissement inaction
#Limite en FPS:
clock.tick(2)