Bonjour ! Je vous propose un script qui vous permet de jouer au morpion contre l'ordinateur. Le jeu de l'ordinateur est basé sur l'algorithme Minimax. Le script est l'adaptation d'un programme en C de Bernard Helmstetter :

http://c.developpez.com/telecharger/...Minimax-MinMax

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
 
-- morpion_minimax.lua
-- Traduction en Lua d'un programme de Bernard Helmstetter :
-- http://c.developpez.com/telecharger/detail/id/454/Utilisation-de-l-algorithme-Minimax-MinMax
 
local VIDE, CROIX, ROND = 0, 1, 2
 
function autre_joueur(joueur)
  return 3 - joueur
end
 
local INFINI = 2
 
local plateau = {}
local nb_pions, compteur_noeuds
local ordinateur_joue_x, ordinateur_joue_o = true, false
 
function afficher_plateau()
  for i = 3, 1, -1 do
    io.write(i, ' ')
    for j = 1, 3 do
      if plateau[i][j] == CROIX then
        io.write('x ')
      elseif plateau[i][j] == ROND then
        io.write('o ')
      else
        io.write('. ')
      end
    end
    io.write('\n')
  end
  io.write('  ')
  for j = 0, 2 do
    io.write(string.char(string.byte('a') + j), ' ')
  end
  io.write('\n')
end
 
function initialiser_plateau()
  for i = 1, 3 do
    plateau[i] = {}
    for j = 1, 3 do
      plateau[i][j] = VIDE
    end
  end
  nb_pions = 0
end
 
function est_gagne(joueur)
  return (
    ((plateau[1][1] == joueur) and (plateau[1][2] == joueur) and (plateau[1][3] == joueur)) or
    ((plateau[2][1] == joueur) and (plateau[2][2] == joueur) and (plateau[2][3] == joueur)) or
    ((plateau[3][1] == joueur) and (plateau[3][2] == joueur) and (plateau[3][3] == joueur)) or
    ((plateau[1][1] == joueur) and (plateau[2][1] == joueur) and (plateau[3][1] == joueur)) or
    ((plateau[1][2] == joueur) and (plateau[2][2] == joueur) and (plateau[3][2] == joueur)) or
    ((plateau[1][3] == joueur) and (plateau[2][3] == joueur) and (plateau[3][3] == joueur)) or
    ((plateau[1][1] == joueur) and (plateau[2][2] == joueur) and (plateau[3][3] == joueur)) or
    ((plateau[1][3] == joueur) and (plateau[2][2] == joueur) and (plateau[3][1] == joueur))
  )
end
 
function jouer_coup(joueur, i, j)
  assert(plateau[i][j] == VIDE)
  plateau[i][j] = joueur
  nb_pions = nb_pions + 1
end
 
function dejouer_coup(joueur, i, j)
  assert(plateau[i][j] == joueur)
  plateau[i][j] = VIDE
  nb_pions = nb_pions - 1
end
 
function minimax(joueur, meilleur_coup)
-- Renvoie +1 (croix gagne), -1 (rond gagne) ou 0 (partie nulle).
  local i, j, eval, e
  local _ = {}
 
  compteur_noeuds = compteur_noeuds + 1
 
  if nb_pions == 9 then
    return 0
  end
 
  if joueur == ROND then
    eval = INFINI
 
    for i = 1, 3 do
      for j = 1, 3 do
        if plateau[i][j] == VIDE then
          jouer_coup(ROND, i, j)
 
          if est_gagne(ROND) then
            meilleur_coup.i = i
            meilleur_coup.j = j
            eval = -1
          else
            e = minimax(CROIX, _)
 
            if e < eval then
              meilleur_coup.i = i
              meilleur_coup.j = j
              eval = e
            end
          end
 
          dejouer_coup(ROND, i, j)
        end
      end
    end
 
    return eval
  else
    eval = -INFINI
 
    for i = 1, 3 do
      for j = 1, 3 do
        if plateau[i][j] == VIDE then
          jouer_coup(CROIX, i, j)
 
          if est_gagne(CROIX) then
            meilleur_coup.i = i
            meilleur_coup.j = j
            eval = 1
          else
            e = minimax(ROND, _)
 
            if e > eval then
              meilleur_coup.i = i
              meilleur_coup.j = j
              eval = e
            end
          end
 
          dejouer_coup(CROIX, i, j)
        end
      end
    end
 
    return eval
  end
end
 
function demander_coup(joueur, coup)
-- Le coup est attendu sous la forme "a1".
  local saisie
  repeat
    coup.i = -1
    coup.j = -1
    io.write(string.format('Votre coup (%s) ? ', joueur == CROIX and 'x' or 'o'))
    saisie = io.read()
    if string.len(saisie) == 2 then
      coup.j = string.byte(string.sub(saisie, 1, 1)) - string.byte('a') + 1
      coup.i = string.byte(string.sub(saisie, 2, 2)) - string.byte('1') + 1
    end
  until (coup.i >= 1) and (coup.i <= 3) and (coup.j >= 1) and (coup.j <= 3) and (plateau[coup.i][coup.j] == VIDE)
end
 
local eval, joueur
local coup = {}
 
initialiser_plateau()
joueur = CROIX
 
afficher_plateau()
 
while true do
  if ((joueur == CROIX) and ordinateur_joue_x) or ((joueur == ROND) and ordinateur_joue_o) then
    compteur_noeuds = 0
    eval = minimax(joueur, coup)
    io.write(compteur_noeuds, ' noeuds\n')
    io.write('eval = ', eval, ' ')
    if eval == 1 then
      io.write('(x gagne)\n')
    elseif eval == -1 then
      io.write('(o gagne)\n')
    else
      io.write('(partie nulle)\n')
    end
  else
    demander_coup(joueur, coup)
  end
 
  jouer_coup(joueur, coup.i, coup.j)
  afficher_plateau()
 
  if est_gagne(joueur) then
    io.write(string.format('%s gagne\n', joueur == CROIX and 'x' or 'o'))
    break
  end
 
  if nb_pions == 9 then
    io.write('partie nulle\n')
    break
  end
 
  joueur = autre_joueur(joueur)
end
 
os.execute('pause')
Qu'en pensez-vous ?