-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnimWithGUI.py
More file actions
155 lines (134 loc) · 5.33 KB
/
Copy pathnimWithGUI.py
File metadata and controls
155 lines (134 loc) · 5.33 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
import pygame
from random import randint
from copy import deepcopy
class etat:
def __init__(self, d=None, t=0):
if d is None:
self.allumettes = {
1: ["X"],
2: ["X", "X", "X"],
3: ["X", "X", "X", "X", "X"],
4: ["X", "X", "X", "X", "X", "X", "X"]
}
else:
self.allumettes = deepcopy(d)
self.ordre = t
def choixValide(self, ligne, nbr):
if ligne not in [1, 2, 3, 4] or nbr <= 0:
return False
if nbr > min(len(self.allumettes[ligne]), 3):
return False
return True
def estEtatFinal(self):
return all(len(self.allumettes[i]) == 0 for i in range(1, 5))
def changerEtat(self, ligne, nbr):
if self.choixValide(ligne, nbr):
self.allumettes[ligne] = self.allumettes[ligne][:len(self.allumettes[ligne]) - nbr]
def coupsPossibles(self):
resultat = []
if not self.estEtatFinal():
for ligne in range(1, 5):
for nbr in range(1, min(3, len(self.allumettes[ligne])) + 1):
resultat.append((ligne, nbr))
return resultat
def minmax(etatActuel, joueur):
if etatActuel.estEtatFinal():
return (-1 if joueur == 0 else 1), None
meilleurscore = float("-inf") if joueur == 1 else float("inf")
meilleurcoup = None
for coup in etatActuel.coupsPossibles():
nouvelEtat = etat(deepcopy(etatActuel.allumettes), (etatActuel.ordre + 1) % 2)
nouvelEtat.changerEtat(coup[0], coup[1])
score, _ = minmax(nouvelEtat, (joueur + 1) % 2)
if joueur == 1 and score > meilleurscore:
meilleurscore, meilleurcoup = score, coup
elif joueur == 0 and score < meilleurscore:
meilleurscore, meilleurcoup = score, coup
return meilleurscore, meilleurcoup
pygame.init()
WIDTH, HEIGHT = 900, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Jeu de Nim")
FONT = pygame.font.SysFont("arial", 24)
BIG_FONT = pygame.font.SysFont("arial", 32)
clock = pygame.time.Clock()
tour = etat()
selected = []
game_over = False
winner = None
message = "(donner des valeurs valides)"
def draw_game():
screen.fill((30, 30, 30))
for line in range(1, 5):
matches = tour.allumettes[line]
for i, _ in enumerate(matches):
x = 100 + i * 40
y = 100 + (line - 1) * 100
color = (255, 0, 0) if (line, i) in selected else (255, 255, 255)
pygame.draw.rect(screen, color, (x, y, 10, 60))
pygame.draw.rect(screen, (0, 200, 0), (650, 500, 180, 50))
screen.blit(FONT.render("Valider le choix", True, (0, 0, 0)), (660, 515))
if not game_over:
screen.blit(FONT.render("cliquer sur les allumettes :", True, (255, 255, 255)), (520, 100))
if selected:
screen.blit(FONT.render(f"Ligne selectionnee: {selected[0][0]}", True, (255, 255, 255)), (580, 130))
screen.blit(FONT.render("donner nb d allumettes a retirer (1-3):", True, (255, 255, 255)), (520, 180))
screen.blit(FONT.render(f"Nb selectionnees: {len(selected)}", True, (255, 255, 255)), (600, 210))
else:
screen.blit(FONT.render("Aucune selection", True, (255, 255, 255)), (600, 130))
screen.blit(FONT.render(message, True, (255, 255, 0)), (30, 500))
if game_over:
msg = "ous avez gagne" if winner == 0 else "vous avvez perdu"
screen.blit(BIG_FONT.render(msg, True, (255, 255, 0)), (300, 20))
else:
msg = "A vous de jouer" if tour.ordre == 0 else "tour du PC (fel 39al a sa7bi)"
screen.blit(FONT.render(msg, True, (255, 255, 255)), (30, 20))
pygame.display.flip()
def handle_player_click(pos):
global selected, message
if 650 <= pos[0] <= 830 and 500 <= pos[1] <= 550:
if selected:
ligne = selected[0][0]
nbr = len(selected)
if tour.choixValide(ligne, nbr):
tour.changerEtat(ligne, nbr)
selected.clear()
tour.ordre = 1
message = ""
else:
message = "(donner des valeurs valides)"
else:
for line in range(1, 5):
y = 100 + (line - 1) * 100
for i in range(len(tour.allumettes[line])):
x = 100 + i * 40
rect = pygame.Rect(x, y, 10, 60)
if rect.collidepoint(pos):
if (line, i) in selected:
selected.remove((line, i))
elif len(selected) < 3 and (not selected or selected[0][0] == line):
selected.append((line, i))
break
def handle_pc_turn():
global tour
pygame.time.wait(1000)
_, coup = minmax(tour, 1)
if coup:
tour.changerEtat(coup[0], coup[1])
tour.ordre = 0
running = True
while running:
clock.tick(30)
draw_game()
if not game_over and tour.estEtatFinal():
game_over = True
# winner = (tour.ordre + 1) % 2
winner = tour.ordre
if not game_over and tour.ordre == 1:
handle_pc_turn()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN and not game_over and tour.ordre == 0:
handle_player_click(pygame.mouse.get_pos())
pygame.quit()