Mon code ferme Excel

Bonjour,

Je suis en train de coder le jeu du Taquin en vba. Seulement, une fois lancé, excel ne repond plus.

Je vous met ici mon code:

Option Explicit
Sub jeuduTaquin_vba()

Dim Taquin(3, 3) As Variant
Dim continuer As Boolean
Dim x As Single
Dim case_vide_ligne As Integer
Dim case_vide_colonne As Integer
Dim ligne As Integer
Dim Nb As Integer
Dim colonne As Integer
Dim coup As Integer
Dim verification As Integer
Dim verification_ligne As Integer
Dim verification_colonne As Integer
Dim entree As Integer
Dim entree_ligne As Integer
Dim entree_colonne As Integer
Dim ind1 As Integer
Dim ind2 As Integer

Call MsgBox("Vous allez entrer dans le jeu du taquin dont le but est de résoudre un damier 3x3 aux valeurs aléatoires en un damier aux valeurs qui se suivent. Pour y arriver, vous avez une case vide, vous ne pouvez donc que déplacer une case adjacente à la case vide dans cette dernière. Le damier gagnant est comme suit")
Call MsgBox("la case comportant le 0 etant la case vide")
continuer = True
For ind1 = 1 To 3
    For ind2 = 1 To 3
        Taquin(ind1, ind2) = 0
    Next
Next
entree = 0
entree_ligne = 1
entree_colonne = 1
Do While entree <= 8
    Nb = Int(1 + 7 * Rnd(x))
    If (Nb <> Taquin(1, 1)) And (Nb <> Taquin(1, 2)) And (Nb <> Taquin(1, 3)) And (Nb <> Taquin(2, 1)) And (Nb <> Taquin(2, 2)) And (Nb <> Taquin(2, 3)) And (Nb <> Taquin(3, 1)) And (Nb <> Taquin(3, 2)) And (Nb <> Taquin(3, 3)) Then
        Taquin(entree_ligne, entree_colonne) = Nb
        Cells(entree_ligne, entree_colonne).Value = Taquin(entree_ligne, entree_colonne)
        entree = entree + 1
        If entree_colonne = 3 Then
            entree_colonne = 1
            entree_ligne = entree_ligne + 1
        End If
        entree_colonne = entree_colonne + 1
    End If
Loop
case_vide_ligne = 3
case_vide_colonne = 3
Do While continuer = True
    Call MsgBox(Taquin(1, 1), Taquin(1, 2), Taquin(1, 3))
    Call MsgBox(Taquin(2, 1), Taquin(2, 2), Taquin(2, 3))
    Call MsgBox(Taquin(3, 1), Taquin(3, 2), Taquin(3, 3))
    ligne = InputBox("entrer la ligne de la case a deplacer dans la case vide")
    colonne = InputBox("entrer la colonne de la case a deplacer dans la case vide")
    If (((case_vide_ligne = ligne) And (case_vide_colonne = colonne + 1)) Or ((case_vide_ligne = ligne) And (case_vide_colonne = colonne - 1)) Or ((case_vide_ligne = ligne + 1) And (case_vide_colonne = colonne)) Or ((case_vide_ligne = ligne - 1) And (case_vide_colonne = colonne))) Then
        Taquin(case_vide_ligne, case_vide_colonne) = Taquin(ligne, colonne)
        Taquin(ligne, colonne) = 0
        case_vide_ligne = ligne
        case_vide_colonne = colonne
        coup = coup + 1
    Else
        Call MsgBox("la ligne et la colonne saisie ne correspondent pas a une case adjacente a la case vide")
    End If
    verification = 1
    For verification_ligne = 1 To 3
        For verification_colonne = 1 To 3
            If Taquin(verification_ligne, verification_colonne) = verification Then
                verification = verification + 1
            End If
        Next
    Next
    If verification = 8 Then
        Call MsgBox("FELICITATIONS VOUS AVEZ COMPLETEZ LE JEU EN", coup, "COUPS")
        continuer = False
    End If
Loop

End Sub

A savoir que le problème se trouve dans la boucle Do While entree<=8 .

En esperant avoir une réponse,

VicKing

Bonsoir VicKing,

Je te confirme, ton code tourne en rond

 Do While entree <= 8
   ' Nb ne varie jamais,car X n'a pas de valeur initiale
    Nb = Int(1 + 7 * Rnd(x))
    'Ce test est toujours passé
    If (Nb <> Taquin(1, 1)) And (Nb <> Taquin(1, 2)) And (Nb <> Taquin(1, 3)) And (Nb <> Taquin(2, 1)) And (Nb <> Taquin(2, 2)) And (Nb <> Taquin(2, 3)) And (Nb <> Taquin(3, 1)) And (Nb <> Taquin(3, 2)) And (Nb <> Taquin(3, 3)) Then
      Taquin(entree_ligne, entree_colonne) = Nb
      Cells(entree_ligne, entree_colonne).Value = Taquin(entree_ligne, entree_colonne)
      entree = entree + 1
      If entree_colonne = 3 Then
        entree_colonne = 1
        entree_ligne = entree_ligne + 1
      End If
      entree_colonne = entree_colonne + 1
      ' Et donc à ce niveau entree n'a pas évolué
    End If
  Loop

@+

Salut,

Sympa le jeu du taquin je m'en souvenais plus de celui la, cela me donne envie d'en faire un aussi ^^

Quand ton code plante tu peux tester en mode Pas à Pas (F8)

Sinon en plus de la réponse de BrunoM45:

- Ton tableau Taquin est mal initialisé je pense:

tableau

D'ailleurs on voit qu'il est en 4x4 alors que tu mets 3x3 dans ton énoncé, de base excel travaille en base 0, si tu veux rester sur le même code et avoir un tableau 3x3 il te faut déclarer spécifiquement en début de module

Option Base 1

- Ton

Nb = Int(1 + 7 * Rnd(x))

vaudra toujours la même chose vu que ton X ne change pas (et que c'est ta seed), regarde la doc pour des exemples d'utilisation (tu surlignes "Rnd" dans ton code et tu appuis sur F1)

- tu veux afficher la grille via le code

Call MsgBox(Taquin(1, 1), Taquin(1, 2), Taquin(1, 3))
Call MsgBox(Taquin(2, 1), Taquin(2, 2), Taquin(2, 3))
Call MsgBox(Taquin(3, 1), Taquin(3, 2), Taquin(3, 3))

nan?

d'une part cela ne donnera pas du tout l'effet voulu car tu ne respectes pas la syntaxe du MsgBox:

MsgBox(prompt[, buttons] [, title] [, helpfile, context])

par exemple si tu l'affiches après ta boucle qui mets des "0" partout le premier msgbox donne:

exemple msgbox

Et surtout ce n'est pas sexy et lisible ^^, il te faut afficher toute les lignes dans un seul msgbox

D'autres remarque générales:

  • A noter que le taquin se joue en 4x4 de base et pas 3x3
  • Attention si tu remplis en RND, certaines configuration n'ont pas de solution possible (sur 4x4 en tout cas mais j'imagine que le 3x3 à surement ce genre de cas)
  • Mets des commentaires et indente ton code vindiou
  • au vu de ton code et de tes soucis, il te faut tester et vérifier ce que tu utilises au fur et a mesure et pas seulement à la fin

Courage

ECG

Bonjour,

Un grand merci a vous deux !

Pour info, c'est mon mini-projet de ma matière d'algorithmique. Et c'est bien en 3x3 que j'ai besoin de le faire. J'ai déjà codé en C le jeu du taquin mais ils me demandent en vba mais j'ai du mal avec vba, d'ou les problemes de syntaxe . J'ai rajouté "option base 1" au début (comme ca c'est plus simple pour l'utilisateur de commencer à mettre la ligne 1 et pas 0 ; après il m'aurait suffit de faire -1 ) et j'ai aussi rajouté "randomize" avant nb, le problème avec l'initialisation de ma grille est résolu, MERCI A VOUS DEUX !

Aussi, entre temps j'ai changer ma méthode de présentation de la grille, plutot que de le faire dans la boucle de dialogue (comme avant et comme en C) j'ai afficher dans les cellules A1:C3 et ça fonctionne

Mais maintenant, je n'arrive jamais à entrer dans cette boucle if , il passe direct à else, le mode debugage ma mis "erreur d'excution 13":

If (((case_vide_ligne = ligne) And (case_vide_colonne = colonne + 1)) Or ((case_vide_ligne = ligne) And (case_vide_colonne = colonne - 1)) Or ((case_vide_ligne = ligne + 1) And (case_vide_colonne = colonne)) Or ((case_vide_ligne = ligne - 1) And (case_vide_colonne = colonne))) Then
        Taquin(case_vide_ligne, case_vide_colonne) = Taquin(ligne, colonne)
        Taquin(ligne, colonne) = 0
        case_vide_ligne = ligne
        case_vide_colonne = colonne
        coup = coup + 1
    Else
        Call MsgBox("la ligne et la colonne saisie ne correspondent pas a une case adjacente a la case vide")
    End If  

Pourtant case_vide_ligne et colonne sont bien enoncés au début à 3...

C c'est mieux

mets ton fichier ou ton code car la comme ça dur de voir ce que tu as refais comme code au final

le voici

9code.txt (2.91 Ko)

C'est bon j'ai trouvé mon erreur, j'ai mal initialisé mes variables.

je les ai initialisé comme en C alors qu'en vba il faut ajouter As Integer a chaque fois.

C'est pas grave, maintenant il marche parfaitement !

Merci à vous !

VicKing

Salut,

je les ai initialisé comme en C alors qu'en vba il faut ajouter As Integer a chaque fois.

si tu mets pas de type, excel les prends en comptes comme Variant donc en general le code fonctionne quand même, cela prend juste plus de place mémoire il me semble

Attention quand tu déclares dans ton code

Dim Taquin(3, 3), a, b,etc, entree_colonne As Integer

tu as que entree_colonne qui est déclaré en Integer, le reste est en variant, il te faudrait faire

Dim Taquin(3, 3) As Integer, a As Integer, b As Integer,etc

et heureusement ici car Taquin(3,3) n'est pas un Integer mais un tableau ^^

C'est pas grave, maintenant il marche parfaitement !

je viens de tester et dès le premier essai j'ai une erreur:

erreur 1

la case en ligne 2 colonne 3 est bien adjacente à celle vide pourtant

Si tu annules les 2 msgbox cela fait planter ton jeu:

erreur 2

d'ailleurs et si on y mets du textes et pas un chiffres tu as regardé ce que cela donne? ou si on mets rien? ^^

Il faut que tu prennes l'habitude de tester tous les mauvais cas de figures qui peuvent se présenter, c'est chiant et long des fois mais nécessaire ^^

Si tu es en classe info cela sera une bonne habitude

Pour ton msgbox du début, regarde sur le net pour faire un retour à la ligne, cela sera vraiment plus sympa d'avoir:

info msgbox

Juste à noter qu'avec ton RND ici tout se passe bien car ton tableau est petit mais attention tu pourrais avoir des soucis sur d'autres situations (car ici tu refais un rnd tant que tu tombes sur un chiffre que tu n'as pas encore eu, avec pas de chance cela peut prendre un temps infinis )

Par exemple par curiosité j'ai rajouté un compteur "NB_ITERATION" dans ta boucle, cela indique donc le nombre de fois qu'on a du faire une boucle de RND:

info rnd

J'ai fais quelques matière de prog à l'école et en général les professeurs aimait bien voir les évolutions/faiblesse du code (par exemple le RND qui peut boucler énormément mais vu la petite taille du tableau c'est un temps imperceptible donc acceptable mais au moins tu en as conscience) et aussi c'est une bonne pratique de réfléchir à son programme en général de cette façon.

Par exemple:

- si je veux quitter en cours de jeu je fais comment? tu as un bouton pour?

- si je sors et je veux reprendre ma partie en cours je fais comment?

- si j'y connais rien à excel VBA, je lance comment ton jeu?

Après tu dois réfléchir aussi en général en informatique à:

- encapsuler/rendre générique ton code le plus possible (ce qui te permet de faire des tests unitaire aussi au passage beaucoup plus facilement et mieux identifier les soucis),

- et maintenable (avec des commentaires, des fonctions qui fonctionnent quelque soit tes données entrées)

Par exemple rapidement ton

Do While entree < 8

qui reprends donc ton nombre de case -1 de la valeur 0 pourrais être écrite de la façon suivante

Do While entree < (UBound(Taquin, 1) * UBound(Taquin, 2) - 1)

ainsi si demain tu passes en 4x4 cette partie du code est toujours vrais, tu vas sur 4*4-1 = 15 cases

à ta place je ferais encore un peu d'update avant de livrer ton projet mais c'est à toi de voir^^

Salut,

oui tu as raison, de toute manière j'ai encore du temps devant moi. Mais si je demande à chaque étape s'il veut sortir, ca va le géner pour jouer.

Ou sinon il faudrait que je mette un nombre particulier (si il initialise ligne et colonne par 0, je le fais sortir du jeu, en le prévenant avant de commencer le jeu). Je vais faire ça...

Pour le nb d'itérations, c'est hyper intéressant btw. Mais en fait c'est le 8 le pb, c'est le plus chiant à avoir, donc plus il arrive tardivement, plus il y a de nb d'itérations.

Pour remédier ce pb, j'avais penser, à plutot que donner des valeurs aléatoires, je pourrais faire un mélange de ma grille. C'est-a-dire que je commence avec ma grille juste et avec une boucle for (et des nb saisies aléatoirement entre 1 et 3), je pourrais mélanger ma grille en echangeant donc au hasard ma grille. je vais tester ca plus tard....

après, ma consigne est bien de faire fonctionner pour une grille 3x3, mais pourquoi pas essayer de le généraliser...

Pour le retour à la ligne, j'ai trouvé et je l'ai ajouté à qqs endroits de mon code.

Pour la sauvegarde de la partie, pour le moment, c'est impossible pour moi (ma matière d'algo c'est la première proposé par mon école donc pour le moment on a pas vu ça....

Merci,

A+

oui tu as raison, de toute manière j'ai encore du temps devant moi. Mais si je demande à chaque étape s'il veut sortir, ca va le géner pour jouer.

Je pense aussi yes

Ou sinon il faudrait que je mette un nombre particulier (si il initialise ligne et colonne par 0, je le fais sortir du jeu, en le prévenant avant de commencer le jeu). Je vais faire ça...

C'est une solution

Après tu as beaucoup d'argument

MsgBox (prompt, [ buttons, ] [ title, ] [ helpfile, context ])

de la lecture au pire https://docs.microsoft.com/fr-fr/office/vba/language/reference/user-interface-help/msgbox-function

Surtout par exemple l'argument Buttons qui m'a l'air intéressant... je te laisse tester dans vba

Et dans la documentation il y a un exemple très intéressant avec la variable

Response 

, cela pourrait peut être te convenir

Pour le nb d'itérations, c'est hyper intéressant btw. Mais en fait c'est le 8 le pb, c'est le plus chiant à avoir, donc plus il arrive tardivement, plus il y a de nb d'itérations.

Pour remédier ce pb, j'avais penser, à plutot que donner des valeurs aléatoires, je pourrais faire un mélange de ma grille. C'est-a-dire que je commence avec ma grille juste et avec une boucle for (et des nb saisies aléatoirement entre 1 et 3), je pourrais mélanger ma grille en echangeant donc au hasard ma grille. je vais tester ca plus tard....

Vu que je fais aussi un taquin (tu m'as donné envie de tester ^^), personnellement même si un full rnd au final fonctionne comme on a vu je suis quand même parti sur une solution plus propre

Tout comme un tirage au sort sans remise en jeu:

  • je fait une liste/array de mes valeurs à tirer au sort (de 1 à 9 ou 0 à 8 par exemple)
  • je tire en rnd parmi le nombre de valeur restante
  • je retire cette valeur de l'array et je la mets dans la première case de mon taquin
  • je recommence pour remplir toute la grille

un exemple sur 3 valeurs

ma liste contient: 7 4 8

je tire au hasard un chiffre entre 1 et 3 (mon nombre de valeur restants dans ma liste étant de 3)

cela me sors 2, soit la valeur 4, je la retire et je la mets dans ma première case de mon taquin

ma liste contient: 7 8

je tire au hasard un chiffre entre 1 et 2 (mon nombre de valeur restants dans ma liste étant de 2)

cela me sors 1, soit la valeur 7, je la retire et je la mets dans ma première case de mon taquin

il reste qu'une valeur (le 8), je la mets dans la dernière case de mon taquin

après, ma consigne est bien de faire fonctionner pour une grille 3x3, mais pourquoi pas essayer de le généraliser...

C'est facultatif et "more than expected" en effet, te casse pas trop la tête

De toute façon on le découvre tous un jour ou l'autre, quand on change une variable de son programme et que plus rien ne va car on a tout mis en dur... on commence à réfléchir pour être générique et ne plus se faire avoir

Pour le retour à la ligne, j'ai trouvé et je l'ai ajouté à qqs endroits de mon code.

En général l'aide/documentation ou google sont la pour t'aider, il est toujours bon de regarder les exemples ou voir les arguments que les fonctions demandent

A force d'utiliser des fonctions pour la même chose on oublie ce qu'elles peuvent faire au total ^^, il est bon d'être curieux en informatique (et surtout un autre jour tu te diras peut-être "ah mais j'ai lu un truc sur cette fonction qui peut servir à faire ce que je cherche pratiquement" )

Pour la sauvegarde de la partie, pour le moment, c'est impossible pour moi (ma matière d'algo c'est la première proposé par mon école donc pour le moment on a pas vu ça...

Pas de soucis surtout en VBA

au final en 3x3 le nombre de grille faisable reste limité mais en 4x4 il y en a 10 461 394 944 000 d'après le wiki pouah !

Rechercher des sujets similaires à "mon code ferme"