Erase I, J
Puis la pile sera remise à zéro ?
Option Explicit
'Mon troisième code utilisant VBA sous excel, soyez indulgent! :)
'mail: r.toky.olivier@gmail.com
' Trois mots utilisés en "mémoire" permettant l'usage de certaines parties du programme
Public ModA As Byte 'Bit mémoire pour empêcher les étapes lié au joueur humain
Public ModB As Byte ' Bit mémoire pour empêcher les boites de dialogues lors d'un recommencer niveau + 1
Public ModC As Byte 'Mémoire trace
' permettent la récursivité
Public na As Integer ' nombre de disques utilisés
Public Da As Byte ' emplacement de départ
Public Aa As Byte ' emplacement d'arrivée
Public Ia As Byte ' emplacement intermédiaire
' Permettent le programme Hanoi "lclassique"
Public Piquet As Integer
Public Selected As Integer
Public Disque(1 To 3, 1 To 8) As Integer
Public NbrDisques(1 To 3) As Integer
Public NbrCoups As Integer
Public Niveau As Integer
' valeur utilisées dans le mot "Mot" pour la Trace
Public PpA As Byte 'emplacement prise de départ Trace
Public PpB As Byte 'emplacement prise d'arrivée Trace
Public Mc As Integer 'Mot utilisé pour le décalage de case des phrases pour trace
'position cartésienne Ms pour la prise, Mp pour la dépose
Public Mpx As Integer ' position prise x
Public Mpy As Integer ' position prise y
Public Mpz As Integer ' position prise z
Public Mdx As Integer ' position pose x
Public Mdy As Integer ' position pose y
Public Mdz As Integer ' position pose z
' Mots affichant les phrases dans l'onglet feuil1 pour la Trace
Public MotP As String ' phrase prise
Public MotD As String ' phrase dépose
Public Mot As String ' phrase complétant les emplacements trace
'Mots permettant la reprise des valeurs de position départ/arrivée
Public MDa As Byte 'mémoire position de départ
Public MAa As Byte 'mémoire position arrivée
Public Mna As Byte ' valeur courante de na
Public ret As Integer 'permet la l'écriture de la troisième boucle
'Mots permettant la reprise des valeurs de Nbrdisques pour les phrases Trace
Public posdiscS As Integer 'variable position courante nbrdisque sub soulever
Public posdiscP As Integer 'variable position courant Nbrdisque sub poser
Sub AfficherBas() 'Afficher les flêches bas
If ModA = 0 Then
Dim myDocument As Object
Set myDocument = Worksheets(1)
myDocument.Shapes.Range(Array("AutoShape 2", "AutoShape 3", "AutoShape 4")).Visible = False 'pour trouver les noms des formes automatiques (flèche, etc...), sélectionner la forme et lire sur la barre de référence
myDocument.Shapes.Range(Array("AutoShape 5", "AutoShape 6", "AutoShape 7")).Visible = True
End If
End Sub
Sub AfficherHaut() 'Afficher les flêches hauts
If ModA = 0 Then
Dim myDocument As Object
Set myDocument = Worksheets(1)
myDocument.Shapes.Range(Array("AutoShape 2", "AutoShape 3", "AutoShape 4")).Visible = True
myDocument.Shapes.Range(Array("AutoShape 5", "AutoShape 6", "AutoShape 7")).Visible = False
End If
End Sub
Sub AfficherTout() 'Afficher les flêches , ce n'est pas necessaire :)
Dim myDocument As Object
Set myDocument = Worksheets(1)
myDocument.Shapes.Range(Array("AutoShape 2", "AutoShape 3", "AutoShape 4")).Visible = True
myDocument.Shapes.Range(Array("AutoShape 5", "AutoShape 6", "AutoShape 7")).Visible = True
End Sub
Sub CacherTout() 'Cacher les flêches , ce n'est pas necessaire :)
Dim myDocument As Object
Set myDocument = Worksheets(1)
myDocument.Shapes.Range(Array("AutoShape 2", "AutoShape 3", "AutoShape 4")).Visible = False
myDocument.Shapes.Range(Array("AutoShape 5", "AutoShape 6", "AutoShape 7")).Visible = False
End Sub
Sub EffacerTout()
With Sheets("Hanoi")
.Unprotect
.Range("B5:U23").Interior.Color = RGB(153, 255, 153)
.Range("K12:L22").Interior.Color = RGB(160, 160, 160)
.Range("W5:AP23").Interior.Color = RGB(153, 255, 153)
.Range("AF12:AG22").Interior.Color = RGB(160, 160, 160)
.Range("AR5:BK23").Interior.Color = RGB(153, 255, 153)
.Range("BA12:BB22").Interior.Color = RGB(160, 160, 160)
.Protect
End With
End Sub
Sub DessinerPiles() 'dessiner les piles
Dim I, j, k As Integer
Dim x, y, z As Integer
Dim myDocument As Object
Set myDocument = Worksheets(1)
myDocument.Unprotect
For j = 1 To 3 'numero de Piquet
k = 0
For I = 1 To 8 'hauteur de Pile
If Disque(j, I) > 0 Then
k = k + 1
Select Case j
Case 1: 'Piquet num 1
x = 22 - k
y = 11 - Disque(j, I)
z = 12 + Disque(j, I)
Case 2: 'piquet 2
x = 22 - k
y = 32 - Disque(j, I)
z = 33 + Disque(j, I)
Case 3: 'piquet 3
x = 22 - k
y = 53 - Disque(j, I)
z = 54 + Disque(j, I)
End Select
myDocument.Range(myDocument.Cells(x, y), myDocument.Cells(x, z)).Interior.ColorIndex = 1 'On dessine le disque
End If
Next I
Next j
myDocument.Protect
End Sub
Sub Soulever(tig As Integer) 'on soulève un disque
Dim myDocument As Object
Set myDocument = Worksheets(1)
Dim j, k As Integer 'valeur variables soulever
Dim x, y, z As Integer
ActiveSheet.Unprotect 'enlève la protection sur la feuille pour pouvoir faire des modification
If NbrDisques(tig) > 0 Then
posdiscS = NbrDisques(tig)
AfficherBas 'afficher les flêches bas
Selected = Disque(tig, NbrDisques(tig)) 'selected: le disque choisi
coordonées_mot_prise 'appel de la maccro liée à Trace
Disque(tig, NbrDisques(tig)) = 0 'on enlève le disque du piquet
NbrDisques(tig) = NbrDisques(tig) - 1 'on décrémente le nombre disques sur le piquet choisi
EffacerTout 'on nettoie tout
DessinerPiles 'et redessine toutes les piles
myDocument.Unprotect
myDocument.Range("C6:T6,X6:AO6,AS6:BJ6").Interior.ColorIndex = 35 'effacer le disque soulever, on utilise la couleur du fond
k = Selected
For j = 1 To 3
Select Case j
Case 1:
x = 6
y = 11 - k
z = 12 + k
Case 2:
x = 6
y = 32 - k
z = 33 + k
Case 3:
x = 6
y = 53 - k
z = 54 + k
End Select
myDocument.Range(myDocument.Cells(x, y), myDocument.Cells(x, z)).Interior.ColorIndex = 1
Next j
End If
Range("A1").Select
ActiveSheet.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True 'on protège la feuille
End Sub
Sub VerifierFin() 'Vérification si on a terminé le niveau ou le jeu
If ModA = 0 Then
Dim I As Integer
Dim TheEnd As Boolean
TheEnd = True
For I = 1 To Niveau
If Disque(3, I) <> 8 - I + 1 Then 'si un disque est malplacé, alors le niveau n'est pas terminé
TheEnd = False
Exit For
End If
Next I
If TheEnd Then 'fin du niveau
If Niveau = 8 Then 'fin du jeu
MsgBox "Félicitation!", , "Hanoi"
Else
If MsgBox("Gagné! Voulez-vous passez au niveau suivant?", vbYesNo, "Hanoi") = vbYes Then 'Recommencer
Niveau = Niveau + 1 'mais le niveau est incrémenté de 1
InitGame (Niveau)
AfficherHaut
DessinerPiles
End If
End If
End If
End If
End Sub
Sub Poser(tig As Integer)
If Selected = 0 Then Exit Sub 'si rien n'a été choisi, alors, ne fait rien
If NbrDisques(tig) > 0 Then
If Disque(tig, NbrDisques(tig)) < Selected Then Exit Sub 'et on fait de même si le disque sur le piquet est plus petit que celui choisi
End If
Dim myDocument As Object
Set myDocument = Worksheets(1)
myDocument.Unprotect
NbrDisques(tig) = NbrDisques(tig) + 1 'on augmente le nombre de disque sur le piquet
Disque(tig, NbrDisques(tig)) = Selected 'on met le disque choisi
posdiscP = NbrDisques(tig)
coordonées_mot_pose
EffacerTout 'on efface tout
DessinerPiles ' et redessine le jeu
myDocument.Unprotect
myDocument.Range("C6:T6,X6:AO6,AS6:BJ6").Interior.ColorIndex = 35 'on efface la place pour le disque choisi
AfficherHaut
Selected = 0
NbrCoups = NbrCoups + 1 'augmente le nombre de coups
Worksheets(1).Shapes("AutoShape 10").TextFrame.Characters.Text = Format(NbrCoups, "000") 'et affiche ensuite ce nombre de coups
VerifierFin 'on vérifie la fin du jeu
Range("A1").Select
ActiveSheet.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True 'et on protège la feuille
myDocument.Protect
End Sub
Sub InitGame(niv As Integer) 'initialisation du jeu
Dim I As Integer, j As Integer
Dim myDocument As Object
Set myDocument = Worksheets(1)
Mc = 0
Dim Best(1 To 6) As Integer 'Meilleurs coups (plus petit) que J'AI PU FAIRE, peut-être que vous pouvez faire mieux
For I = 1 To 3
For j = 1 To 8
Disque(I, j) = 0 'remise à zéro de chaque pile
Next j
Next I
For I = 1 To niv 'initialisation des disques sur la pile la plus à gauche
Disque(1, I) = 8 - I + 1
Next I
NbrDisques(1) = niv
NbrDisques(2) = 0
NbrDisques(3) = 0
Best(1) = 7 'En jouant, j'ai trouvé que les meilleurs coups pour chaque niveau est de: 7,15,31,63,127,255... Une suite: U(n+1)=U(n)*2+1
For I = 2 To 6 'Je ne sais pas si vous pouvez trouvez mieux mais bon!!!
Best(I) = Best(I - 1) * 2 + 1
Next I 'Comme ça, vous pouvez augmenter le niveau 7, 8, 9, 10 ...
NbrCoups = 0
With myDocument
.Unprotect
.Shapes("AutoShape 10").TextFrame.Characters.Text = Format(NbrCoups, "000") 'raz du nombre de coups
.Shapes("AutoShape 11").TextFrame.Characters.Text = Format(Best(niv - 2), "000") 'on affiche le Best pour chaque niveau
.Protect
End With
EffacerTout
End Sub
Sub Formeautomatique12_QuandClic() 'Le numéro 12 a été modifié... Il y avait une erreur sur la fiche on a du remplacer toutes les formaes automatique...
Piquet = 1 'numéro du piquet, juste pour faciliter la lecture, on peut bien mettre Poser(1)
Poser (Piquet)
End Sub
Sub Formeautomatique14_QuandClic()
Piquet = 2
Poser (Piquet)
End Sub
Sub Formeautomatique11_QuandClic()
Piquet = 3
Poser (Piquet)
End Sub
Sub Formeautomatique10_QuandClic()
Piquet = 1
Soulever (Piquet)
End Sub
Sub Formeautomatique9_QuandClic()
Piquet = 2
Soulever (Piquet)
End Sub
Sub Formeautomatique7_QuandClic()
Piquet = 3
Soulever (Piquet)
End Sub
Sub Formeautomatique18_QuandClic() 'Nouveau jeu!
Dim s As String, n As Integer
ActiveSheet.Unprotect 'enlève la protection
1:
s = InputBox("Entrer le niveau (1-6):", "Hanoi")
If s = "" Then Exit Sub
n = Val(s)
If n < 1 Or n > 6 Then
MsgBox "Veuillez entrer un niveau entre 1 à 6!"
GoTo 1
End If
n = n + 2 'Niveau 1 -> Nombre de disque = 3 et ainsi de suite
Niveau = n
InitGame (n) 'initialisation du jeu
AfficherHaut 'afficher les flêches hauts pour commencer
DessinerPiles 'dessiner les piles
Range("A1").Select
ActiveSheet.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True 'protéger la fiche
End Sub
Sub Lancer_Hanoi()
ModA = 1
If ModB = 0 Then
Mode_automatique
Else
Mode_automatique_Nouveau_niveau
End If
Da = 1
Aa = 3
Ia = 2
na = Niveau
Call Hanoi(na, Da, Aa, Ia)
End Sub
Sub Hanoi(na, Da, Aa, Ia)
Dim y As Integer
Dim z As Integer ' Variable de l'algorithme f(x)=2^X-1
valeur_ret
If na = 1 Then 'si n = 1 alors
MsgBox ("Deplacer le disque de " & Da & " vers " & Aa) 'Deplacer le disque de D vers A
Soulever (Da) 'Appel de la maccro soulever en position Da
Poser (Aa) 'Appel de la maccro Poser en position Aa
If ModC = 1 Then 'Si Trace activé
ret = 0 'utilisation de ret
Mna = na
PpA = Da
PpB = Aa
MDa = Da
MAa = Aa
ABBA
End If
VerifierFin_Auto
Else
Call Hanoi(na - 1, Da, Ia, Aa) 'Hanoi(n-1,D,I,A)-> récursivité
MsgBox ("Deplacer le disque de " & Da & " vers " & Aa) 'Deplacer le disque de D vers A
Soulever (Da)
Poser (Aa)
If ModC = 1 Then
Mna = na
PpA = Da
PpB = Aa
MDa = Da
MAa = Aa
ABBA
End If
Call Hanoi(na - 1, Ia, Aa, Da) 'Hanoi(n-1,I,A,D)-> récursivité
If ModC = 1 Then 'Si Trace activé
If ret = 1 Then
Mna = na
PpA = Da
PpB = Aa
MDa = Da
MAa = Aa
ABBA
ret = 0
End If
End If
End If
End Sub
Sub ABBA()
Mot = "Le disque " & Mna & " est déplacé de la pile " & PpA & " Vers la pile " & PpB 'Implementation de Mot
MotD = "Pose en " & MAa & ", Disque N° " & (Mdx) & ", Colonne N°" & (Mdy) & ", Position " & (Mdz) 'implementation de la valeur de MotD
MotP = "Prise en " & MDa & ", Disque N° " & (Mpx) & ", Colonne N°" & (Mpy) & ", Position " & (Mpz) 'implementation de la valeur de MotP
With Sheets("Feuil1")
.Unprotect 'retire la protection en écriture
.Range("A5").Offset(Mc, 0) = Mot
.Range("A6").Offset(Mc, 0) = MotP
.Range("A7").Offset(Mc, 0) = MotD
.Protect
End With
Mc = Mc + 3
End Sub
Sub valeur_ret()
If NbrCoups = 2 ^ Niveau - 2 Then
ret = 1
End If
End Sub
Sub coordonées_mot_prise()
Dim b As Integer 'variable égale à selected utilisée pour cette maccro
Dim a As Integer
Dim n As Integer
b = Selected
n = 9
a = n - b
If Da = 1 Then
Mpx = a
Mpy = 1
Mpz = posdiscS
Else
If Da = 2 Then
Mpx = a
Mpy = 2
Mpz = posdiscS
Else
Mpx = a
Mpy = 3
Mpz = posdiscS
End If
End If
End Sub
Sub coordonées_mot_pose()
Dim b As Integer 'variable égale à selected utilisée pour cette maccro
Dim a As Integer
Dim n As Integer
b = Selected
n = 9
a = n - b
If Aa = 1 Then
Mdx = a
Mdy = 1
Mdz = posdiscP
Else
If Aa = 2 Then
Mpx = a
Mpy = 2
Mpz = posdiscP
Else
Mdx = a
Mdy = 3
Mdz = posdiscP
End If
End If
End Sub
Sub Mode_automatique() 'Nouveau jeu mode auto!
Dim s As String, n As Integer
ActiveSheet.Unprotect 'enlève la protection
1:
s = InputBox("Entrer le niveau (1-6):", "Hanoi")
If s = "" Then Exit Sub
n = Val(s)
If n < 1 Or n > 6 Then
MsgBox "Veuillez entrer un niveau entre 1 à 6!"
GoTo 1
End If
n = n + 2 'Niveau 1 -> Nombre de disque = 3 et ainsi de suite
Niveau = n
InitGame (n) 'initialisation du jeu
DessinerPiles 'dessiner les piles
Range("A1").Select
ActiveSheet.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True 'protéger la fiche
End Sub
Sub Mode_automatique_Nouveau_niveau() 'Nouveau jeu mode auto! equivalent de mode auto, modif relatives au nouveau niveau
Dim s As String, n As Integer
ActiveSheet.Unprotect 'enlève la protection
InitGame (Niveau) 'initialisation du jeu
DessinerPiles 'dessiner les piles
Range("A1").Select
ActiveSheet.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True 'protéger la fiche
End Sub
Sub VerifierFin_Auto() 'Vérification si on a terminé le niveau ou le jeu en auto
If ModA = 1 Then
Dim I As Integer
Dim TheEnd As Boolean
TheEnd = True
For I = 1 To Niveau
If Disque(3, I) <> 8 - I + 1 Then 'si un disque est malplacé, alors le niveau n'est pas terminé
TheEnd = False
Exit For
End If
Next I
If TheEnd Then 'fin du niveau
If Niveau = 8 Then 'fin du jeu
MsgBox "Félicitation ! Vous avez terminé le jeu.", , "Hanoi"
ModA = 0 ' mise à Zéro des mots utilisés dans les différentes maccros
ModB = 0
ModC = 0
Else
If MsgBox("Gagné! Voulez-vous passez au niveau suivant?", vbYesNo, "Hanoi Automatique") = vbYes Then 'Recommencer
ModB = 1
Niveau = Niveau + 1 'mais le niveau est incrémenté de 1
InitGame (Niveau) 'nouvelle initialisation du jeu
DessinerPiles 'Appel de dessiner piles pour être sûr de la "propreté" du jeu
Lancer_Hanoi 'Démarrer le jeu automatique
Else
MsgBox "Game Over", , "Hanoi Automatique"
Niveau = 0 ' mise à Zéro des mots utilisés dans les différentes maccros
CacherTout 'appel de la maccro qui va efacer les flèches
End If
ModA = 0 ' mise à Zéro des mots utilisés dans les différentes maccros
ModB = 0
ModC = 0
End If
End If
End If
End Sub
Sub trace() 'appui sur le bouton trace
ModC = 1 'mot ModC = 1 permet de continuer dans certains module
MsgBox " Le résultat se trouve dans l'onglet Résultats" 'permet de montrer que l'action est prise en compte
End Sub
Sub Clear()
With Sheets("Feuil1")
.Unprotect
.Range("A5:A260").ClearContents 'Efface le résultat précédent de trace
.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True 'protéger la fiche
End With
End Sub
'debug
Sub blblblblb()
ModC = 0
End Sub
Sub retirer_protection()
ActiveSheet.Unprotect
End Sub
Sub mettre_protection()
ActiveSheet.Protect
End Sub
Sub blanc()
ActiveSheet.Unprotect
Range("B5:BK23").Interior.ColorIndex = 2
ActiveSheet.Protect
End Sub
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre questiondite moi si vous trouvé quelque amélioration a rajouter :)
For I = 1 To 3
For j = 1 To 8
Disque(I, j) = 0 'remise à zéro de chaque pile
Next j
Next I
For I = 1 To 3
For j = 1 To 8
Disque(I, j) = 0 'remise à zéro de chaque pile
Next j
Next I
Erase I, J