/
Minimax.py
140 lines (109 loc) · 3.83 KB
/
Minimax.py
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
from Node import Node
from Arbre import Arbre
import time
class Minimax:
MIN_VAL = -1000 #valeur minimale possible
MAX_VAL = 1000 #valeur maximale possible
def __init__(self, game, playerTurn =0, valFirstPlayerIsValJ2 = False):
# generation de l'arbre des differents etats possibles
debutchrono = time.time()
self.arbre = Arbre(game)
finchrono = time.time()
self.maximise = playerTurn == 1
self.invertGame = valFirstPlayerIsValJ2 # invertion is needed because the first player of the tree is J1
print('valFirstPlayerIsValJ2: ', valFirstPlayerIsValJ2)
print("Travail termine ! temps ecoule: ", str(round(finchrono - debutchrono, 3)))
self.game = game
self.node = self.arbre.node
# no -> node
# s -> etat
def Actions(self,no):
""" liste des actions possibles """
return no.nexts
# def Result(self,s,a):
# """ applique l'action dans l'etat s """
def TerminialTest(self,no): # MARCHE PAS
""" test si s est terminal """
return len(no.nexts)==1 and isinstance(no.nexts[0],int)
def Utility(self,no):
""" recupere la valeur de s """
return no.nexts[0].value
def Max(self,n1,n2):
return n1 if n1>n2 else n2
def Min(self,n1,n2):
return n1 if n1<n2 else n2
def Minimax_Decision(self, state ,alphabeta=True):
if self.invertGame :
state.invertPlayers()
if state != self.node.value:
self.node = self.node.find2(state)
val = None
if alphabeta:
if self.maximise:
print('MAXIMISE')
self.node, val = self.MaxValueAB(self.node,self.MIN_VAL,self.MAX_VAL)
else:
print('MINIMISE')
self.node, val = self.MinValueAB(self.node,self.MIN_VAL,self.MAX_VAL)
else:
if self.maximise:
print('MAXIMISE')
self.node, val = self.MaxValue(self.node)
else:
print('MINIMISE')
self.node, val = self.MinValue(self.node)
print('val trouvee: ',val)
state = self.node.value.clone()
if self.invertGame :
state.invertPlayers()
return state
def MaxValue(self,no,rang=0):
if no.value.isFinished():
return None,self.Utility(no)
v = self.MIN_VAL
node = None
for n in self.Actions(no):
nd, val = self.MinValue(n,rang+1)
if val > v:
node = n
v = max(v,val)
return node,v
def MinValue(self,no,rang=0):
if no.value.isFinished():
return None, self.Utility(no)
v = self.MAX_VAL
node = None
for n in self.Actions(no):
nd, val = self.MaxValue(n,rang+1)
if val < v:
node = n
v = min(v,val)
return node,v
def MaxValueAB(self,no,alpha,beta,rang=0):
if no.value.isFinished():
return None,self.Utility(no)
v = self.MIN_VAL
node = None
for n in self.Actions(no):
nd, val = self.MinValueAB(n,alpha,beta,rang+1)
if val > v:
node = n
v = max(v,val)
if v >= beta:
return n,v
alpha = max(alpha,v)
return node,v
def MinValueAB(self,no,alpha,beta,rang=0):
if no.value.isFinished():
return None, self.Utility(no)
v = self.MAX_VAL
node = None
for n in self.Actions(no):
nd, val = self.MaxValueAB(n,alpha,beta,rang+1)
if val < v:
node = n
v = min(v,val)
if v <= alpha:
return n,v
beta = min(beta,v)
return node,v