Bon c un morpion classique: on peut jouer à deux ou seul contre l'ordinateur avec deux niveaux de difficulté(neuneu et kasparov)
Un programme assez simple dans le principe général, mais qui demande juste un peu de recherche pour réussir à faire jouer l'ordinateur correctement contre un humain.
On part d'une grille de neuf cases :
1 2 3
4 5 6
7 8 9
on note qu'il existe alors huit possibilités pour gagner. Aligner les case 123, 456, 789, 147, 258, 369, 159 ou 357. Le but va donc consister à enregistrer, pour chaque joueur, les case cochées pour chaque combinaison. Par exemple, pour cette grille :
x x o
o x
o
On aura les valeurs suivantes dans le tableau :
Combinaison Joueur 1 Joueur 2
123 2 1
456 1 1
789 0 1
147 1 1
258 2 1
369 0 1
159 2 0
357 1 1
Si le joueur 1 coche la case 9, la valeur de la combinaison '159' pour ce joueur passe alors à 3. Il remporte donc la partie.
Ainsi, toute la gestion du jeu est basé sur ce tableau. Dès qu'une combinaison atteint 3 pour un joueur, cela indique qu'il a gagné. Pour faire jouer l'ordinateur (en mode 'Kasparov'), on étudie donc le tableau en regardant s'il est possible d'atteindre cette valeur pour chaque combinaison. Sinon, on vérifie que l'adversaire humain ne puisse pas le faire. Enfin, si rien de tout cela n'est possible, on amène l'ordinateur à cocher une case d'une combinaison qui ne soit pas déjà bloqué. C'est-à-dire qu'il faut que cette combinaison n'ait pas déjà été entamée par l'adversaire (donc, qu'il y ait bien 0 de l'autre côté du tableau).
En espérant que ces explications soient suffisantes et assez claires...
Source / Exemple :
Option Explicit
' Variable pour indiquer la fin de la partie
Dim blFin As Boolean
' Donne le tour de jeu courant (0 pour le joueur 1, 1 pour le joueur 2)
Dim inTour As Integer
' Nombre total de coups joués
Dim inCoup As Integer
' Indique le tour de l'ordinateur
Dim inOrdiTour As Integer
' Tableau des coups joués pour chaque joueur
Dim TabSol(8, 1) As Integer
' Tableau des solutions possibles
Dim Sol(8) As Long
Private Sub Form_Load()
' Création du tableau des 8 uniques possibilités de gagner la partie
Sol(1) = 132
Sol(2) = 465
Sol(3) = 798
Sol(4) = 174
Sol(5) = 285
Sol(6) = 396
Sol(7) = 375
Sol(8) = 195
End Sub
Private Sub mnu1Joueur_Click()
' Menu 1 joueur, coche la ligne correspondante,
mnu1Joueur.Checked = True
' et enlève la coche sur l'autre.
mnu2Joueurs.Checked = False
' Rend inaccessible la zone de texte du joueur 1 et mets l'ordinateur dedans.
txtJoueur1.Enabled = False
txtJoueur1.Text = "Ordinateur"
' Autorise le choix du niveau d'intelligence de l'ordinateur.
mnuNiveau.Enabled = True
End Sub
Private Sub mnu2Joueurs_Click()
' Menu 2 joueurs, coche la ligne correspondante,
mnu2Joueurs.Checked = True
' et enlève la coche sur l'autre.
mnu1Joueur.Checked = False
' Rend inaccessible la zone de texte du joueur 1.
txtJoueur1.Enabled = True
txtJoueur1.Text = "Humain"
' Enlève le choix du niveau d'intelligence de l'ordinateur.
mnuNiveau.Enabled = False
End Sub
Private Sub mnuKasparov_Click()
' Coche le niveau Kasparov pour l'ordinateur
mnuKasparov.Checked = True
mnuNeuneu.Checked = False
End Sub
Private Sub mnuNeuneu_Click()
' Coche le niveau Neuneu pour l'ordinateur
mnuNeuneu.Checked = True
mnuKasparov.Checked = False
End Sub
Private Sub mnuNouvellePartie_Click()
' Commence une nouvelle partie
Dim i As Integer
Dim stTMP As String
Dim picTMP As Object
' Initialisation des variables
inCoup = 0
blFin = False
inTour = 0
For i = 1 To 8
TabSol(i, 0) = 0
TabSol(i, 1) = 0
Next i
' Efface le terrain de jeu
For i = 1 To 9
picTab(i).Enabled = True
picTab(i).Picture = Nothing
Next i
lblComment.Caption = ""
' Ne permet plus de changer le nom des joueurs...
txtJoueur1.Enabled = False
txtJoueur2.Enabled = False
' ...et les options
mnuOptions.Enabled = False
' Demande qui commence
If MsgBox("Est-ce que " & txtJoueur1.Text & " commence ?", _
vbQuestion + vbYesNo, "Choix du joueur") <> vbYes Then
' Si c'est le joueur 2, on échange les propriétés
stTMP = txtJoueur1.Text
Set picTMP = picJoueur1.Picture
txtJoueur1.Text = txtJoueur2.Text
picJoueur1.Picture = picJoueur2.Picture
txtJoueur2.Text = stTMP
picJoueur2.Picture = picTMP
End If
If mnu1Joueur.Checked Then
' Si c'est une partie contre l'ordinateur, on regarde qui commence
inOrdiTour = 0
' Si c'est l'ordinateur qui joue le premier on appelle la fonction correspondante
If txtJoueur1.Text = "Ordinateur" Then OrdiJoue Else inOrdiTour = 1
End If
End Sub
Private Sub mnuQuitter_Click()
' Quitte l'application
Unload frmMorpion
End
End Sub
Private Sub picTab_Click(Index As Integer)
Dim i As Integer
' Si la case courante n'a pas d'image, c'est qu'elle n'a pas été cochée.
If picTab(Index).Picture = 0 Then
' En fonction de son index, on remplit le tableau des solutions du joueur.
Select Case Index
Case 1
blFin = Not (RemplirTabSol(1) And RemplirTabSol(4) And RemplirTabSol(8))
Case 2
blFin = Not (RemplirTabSol(1) And RemplirTabSol(5))
Case 3
blFin = Not (RemplirTabSol(1) And RemplirTabSol(6) And RemplirTabSol(7))
Case 4
blFin = Not (RemplirTabSol(2) And RemplirTabSol(4))
Case 5
blFin = Not (RemplirTabSol(2) And RemplirTabSol(5) _
And RemplirTabSol(7) And RemplirTabSol(8))
Case 6
blFin = Not (RemplirTabSol(2) And RemplirTabSol(6))
Case 7
blFin = Not (RemplirTabSol(3) And RemplirTabSol(4) And RemplirTabSol(7))
Case 8
blFin = Not (RemplirTabSol(3) And RemplirTabSol(5))
Case 9
blFin = Not (RemplirTabSol(3) And RemplirTabSol(6) And RemplirTabSol(8))
End Select
' En fonction du joueur courant, on place son symbole dans la case cochée
If inTour = 0 Then
picTab(Index).Picture = picJoueur1.Picture
Else
picTab(Index).Picture = picJoueur2.Picture
End If
' Change de joueur courant, si inTour=0 alors inTour devient 1, sinon devient 0
inTour = (inTour * (-1)) + 1
' Un coup de plus
inCoup = inCoup + 1
' C'est la fin de la partie, un joueur a gagné ou il n'y a plus de case disponible
If blFin Or inCoup = 9 Then
' Si on a fait 9 coups sans que la partie soit réellement finie, c'est alors un match nul
If inCoup = 9 Then lblComment.Caption = "Partie Terminée - Match Nul"
' On vérouille les cases
For i = 1 To 9
picTab(i).Enabled = False
Next i
' On ne rend accessible les zones que si elle ne représentent pas le nom de l'ordinateur
txtJoueur1.Enabled = (txtJoueur1.Text <> "Ordinateur")
txtJoueur2.Enabled = (txtJoueur2.Text <> "Ordinateur")
' Et on rend de nouveau disponible les options
mnuOptions.Enabled = True
ElseIf ((mnu1Joueur.Checked) And (inTour = inOrdiTour)) Then
' Si c'est une partie contre l'ordinateur et que
' c'est à lui de jouer, on appelle la fonction
Call OrdiJoue
End If
End If
End Sub
Public Sub JoueSolution(Solution As Integer)
Dim i As Integer, j As Integer, k As Integer
' On extrait les index des différentes cases composant la solution trouvée
i = Sol(Solution) \ 100 ' première case
j = (Sol(Solution) - (i * 100)) \ 10 ' deuxième case
k = (Sol(Solution) - (i * 100) - (j * 10)) ' troisième et dernière case
' Si la première case n'est pas cochée,
If picTab(i).Picture = 0 Then
' on s'en occupe,
Call picTab_Click(i)
' sinon, on cherche à cocher la seconde
ElseIf picTab(j).Picture = 0 Then
Call picTab_Click(j)
' en enfin la troisième.
ElseIf picTab(k).Picture = 0 Then
Call picTab_Click(k)
End If
End Sub
Public Function RemplirTabSol(Solution As Integer) As Boolean
' Remplit le tableau des solutions d'un joueur et indique si celui-ci a gagné
If TabSol(Solution, inTour) = 2 Then
' Si la valeur du tableau est déjà à 2, pas la peine
' d'aller plus loin, car il a coché la troisième case.
' Le joueur à qui s'était le tour est vainqueur
If (inTour = 1) Then
lblComment.Caption = "Gagné ! " & txtJoueur2.Text & " vainqueur..."
Else
lblComment.Caption = "Gagné ! " & txtJoueur1.Text & " vainqueur..."
End If
' Indique que l'on a pas remplit le tableau, car nous avons un gagnant
RemplirTabSol = False
Else
' C'est pas encore gagné, on augmente la valeur du tableau
TabSol(Solution, inTour) = TabSol(Solution, inTour) + 1
' Oui, on a remplit le tableau
RemplirTabSol = True
End If
End Function
Public Sub OrdiJoue()
' Fait jouer l'ordinateur
Dim i As Integer
Dim tabTmp(8) As Integer
If mnuNeuneu.Checked Then
' Niveau Neuneu pour l'ordinateur - Random...
Randomize
Do
' Coche au hasard une des neuf cases
Call picTab_Click(Int(Rnd * 9) + 1)
Loop Until (inTour <> inOrdiTour)
Else
' Niveau Kasparov pour l'ordinateur - Un peu plus de réflexion...
If inCoup = 0 Then
' L'ordinateur commence dans ce mode en débutant toujours par la plaque du milieu (5),
' celle qui donne le plus de chance pour le reste de la partie.
Call picTab_Click(5)
Else
i = 1
' On commence par chercher un endroit ou il ne reste plus
' qu'une seule case à cocher pour gagner.
' Une réponse du type (2 - 0) signifie que l'on à coché
' déjà 2 cases d'une solution et que l'adversaire aucune,
' c'est donc une victoire!
Do While ((i < 8) And ((TabSol(i, inOrdiTour) - TabSol(i, (inOrdiTour * (-1)) + 1)) <> 2))
i = i + 1
Loop
' Si on a trouvé une solution, on la joue.
If ((TabSol(i, inOrdiTour) - TabSol(i, (inOrdiTour * (-1)) + 1)) = 2) Then
Call JoueSolution(i)
Else
i = 1
' Maintenant on vérifie que l'adversaire humain ne rique
' pas de gagner en faisant l'opération inverse.
' Une réponse du type (0 - 2) signifie que joueur humain peut gagner.
Do While ((i < 8) And ((TabSol(i, inOrdiTour) - TabSol(i, (inOrdiTour * (-1)) + 1)) <> -2))
i = i + 1
Loop
' Si on a trouvé une réponse, on empêche alors notre adversaire de gagner.
If ((TabSol(i, inOrdiTour) - TabSol(i, (inOrdiTour * (-1)) + 1)) = -2) Then
Call JoueSolution(i)
Else
' On va enfin rechercher les meilleures positions pour pouvoir jouer le prochain coup.
' Il faut dans tous les cas que l'adversaire n'ait pas déjà entamé la solution.
For i = 1 To 8
If (TabSol(i, inOrdiTour) * TabSol(i, (inOrdiTour * (-1)) + 1) = 0) Then
tabTmp(i) = TabSol(i, inOrdiTour) - TabSol(i, (inOrdiTour * (-1)) + 1)
Else
tabTmp(i) = 2
End If
Next i
' Si on n'est pas encore rendu au dernier coup on tente notre coup au hasard.
If inCoup < 8 Then
Randomize
Do
' Un nombre au hasard dans les 8 solutions possibles
i = Int(Rnd * 8) + 1
Debug.Print i
' Si c'est un bon coup potentiel, on le joue.
If (tabTmp(i) <> 2) Then Call JoueSolution(i)
Loop Until (inTour <> inOrdiTour)
Else
' sinon, on joue les trois premières solutions, cela nous amènera
' à cocher forcement la dernière case qui reste
For i = 1 To 3
Call JoueSolution(i)
Next i
End If
End If
End If
End If
End If
End Sub
Conclusion :
je n ai remarqué aucun bug alors si vous en voyez 1 n hésitez surtout pas a me le dire!! mci
laissez moi vos commantaires!!
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.