Help pour TP de programmation

Bonjour à tous,

Je suis toute nouvelle sur le forum et toute novice en VBA.

J'ai un TP à faire sur Excel :

chaque joueur doit répéter à son tour la liste des lettres données par le joueur précédent et en ajouter une.
le joueur qui se trompe a perdu.

Pour le moment, j'ai fait ça :

Sub PP_Jeu()
Dim Liste1 As String
Dim Fin As Boolean
Dim joueurs As Integer
Dim Liste2 As String
Dim Compteur As Integer
Dim nouvellelettre As String

Liste1 = InputBox("Entrer une lettre")
Fin = False
joueurs = 1
Liste2 = ""
Compteur = 1
MsgBox (Liste1)

While Fin = False Or Compteur > 50
Call Echange_J
Liste2 = InputBox("Entrer la liste")

If Liste1 = Liste2 Then
nouvellelettre = InputBox("entrez une nouvelle lettre")
Liste1 = Liste1 & nouvellelettre
Liste1 = Liste1 & MsgBox(Liste1)
Call Echange_J
Else: Fin = True
End If

Compteur = Compteur + 1

Wend

MsgBox ("Bravo")
End Sub

Sub Echange_J()

Dim joueurs
joueurs = 1

If joueurs = 1 Then
joueurs = 2
Else: joueurs = 1
End If

End Sub

Problème : le jeu s'arrête alors qu'il ne devrait pas !

SVP help ! je ne comprends pas ou je 'bug'.

Bonne journée, merci de m'avoir lue.
Configuration: Windows Vista

12 réponses

  1. Bonjour

    Cette ligne n'est pas correcte
    Liste1 = Liste1 & MsgBox(Liste1)

    Enlève la

    De plus ton Sub Echange_J ne fait rien
    1) la déclaration Dim joueurs à l'intérieur de la procédure en fait une variable locale, elle n'est pas visible ou accessible en dehors de cette procédure

    2) tu mets joueurs = 1
    et ensuite tu teste If joueurs = 1 Then joueurs = 2 ...
    ce test est toujours vérifié et joueurs sera toujours égale à 2

    3)dans la sub PP_Jeu qui appelle Echange_J, tu ne fais jamais référence à joueurs.

    A+
    1. rebonjour,

      merci tech pour ta reponse.

      j'ai un peu retravaillé dessus, voici ce que ça donne :

      /CODE/

      Sub PP()
      Dim liste As String
      Dim rep As String
      Dim lettre As String
      Dim fin As Boolean
      Dim joueur As Byte

      'on initialise
      fin = False
      joueur = 1
      compteur = 1
      lettre = InputBox("Joueur" & joueur & "entre une première lettre")

      If Len(lettre) <> 1 Or lettre <> tableau Then
      MsgBox ("entrez une seule lettre de l'alphabet en minuscule s'il vous plaît")
      Else
      While Len(lettre) = 1 And lettre = tableau
      liste = lettre
      Wend
      End If

      'on commence le jeu
      While fin = False Or Len(liste) < 50
      joueur = Abs(joueur - 2) + 1
      rep = InputBox("joueur" & joueur & "entre la liste" & Chr(13) & "(" & Len(liste) & "caractère(s))")
      If rep <> liste Then
      fin = True
      Else

      lettre = InputBox("Joueur" & joueur & "entre la lettre suivante")
      If Len(lettre) <> 1 Or lettre <> tableau Then
      MsgBox ("entrez une seule lettre de l'alphabet en minuscule s'il vous plaît")
      End If

      While Len(lettre) = 1 And lettre = tableau(i)
      liste = liste & lettre
      Wend

      End If
      Wend

      End Sub

      Function tableau()

      tableau(1) = "a"
      tableau(2) = "b"
      tableau(3) = "c"
      tableau(4) = "d"
      tableau(5) = "e"
      tableau(6) = "f"
      tableau(7) = "g"
      tableau(8) = "h"
      tableau(9) = "i"
      tableau(10) = "j"
      tableau(11) = "k"
      tableau(12) = "l"
      tableau(13) = "m"
      tableau(14) = "n"
      tableau(15) = "o"
      tableau(16) = "p"
      tableau(17) = "q"
      tableau(18) = "r"
      tableau(19) = "s"
      tableau(20) = "t"
      tableau(21) = "u"
      tableau(22) = "v"
      tableau(23) = "w"
      tableau(24) = "x"
      tableau(25) = "y"
      tableau(26) = "z"

      End Function

      /CODE/

      seulement le souci c'est que ça bug dès la première lettre. il me dit "erreur d éxécution 28" et propose "fin" ou "débogage"
      apparemment c'est dans ma fonction tableau que ç pêche mais je ne comprends pas pourquoi?
      1. Bonjour,

        La fonction tableau est mal déclarée.
        En fait, une fonction est appelée en général avec un ou plusieurs arguments (ou paramètres ou valeurs) et retourne une valeur du meme type que la fonction.
        Ex: imagine une fonction qui ajoute 1 à un nombre donné

        Function ajoute1(n as integer) as integer
        ajoute1=n+1
        end function

        Cette fonction reçoit un entier en paramètre et retourne un entier, et on s'en sert comme ça:
        i=1
        i=ajoute1(i)

        -> i reçoit la valeur 2

        Or ta fonction Tableau n'a pas de type défini. De plus tu utilise le nom de la fonction pour initialiser une table non dimensionnée. Une table doit etre dimensionnée avant d'etre utilisée:
        Dim Table1(26) as tring ce qui veut dire Table1 est une table de 26 éléments maxi de type string

        Courage, c'est en programmant qu'on devient programmeur.

        A+.
        1. Re tech_57,

          c'est lilutresor mais cette fois je me suis inscrite...

          donc j'ai tenté de faire ce que tu viens de me dire càd déclarer 26cases : ça ne marche pas, il dit que ce n'est pas le bon argument il me semble.

          je tourne en rond, je ne sais vraiment pas comment m'en sortir. sur un autre forum on m'a donné des solutions directes mais le problème est qu'il y a certaines choses que je n'ai pas vu en cours donc si je me ramène avec un truc qui marche mais qui ne correspond pas au cours, le prof va évidemment comprendre que je ne suis pas l'auteur du prog. et c'est pas le but. mais bon jsuis vmt pas une lumiere en prog.

          bref. j'ai refait mon arbre et ça me semble bon pourtant.

          pffff. je vais poster ce que je fais aujourd'hui.

          à tutaleer
      2. voici ma nouvelle solution mais en fait, j'ai l'impression qu'il ne rentre pas dans le si :

        CODE :
        Sub PP_Jeu()
        Dim Solution As String
        Dim fin As Boolean
        Dim Nb As Integer
        Dim Joueur As Integer
        Dim Proposition As String
        Dim Compteur As Integer
        Dim nouvellelettre As String

        Solution = InputBox("Entrer une lettre")
        fin = False
        Nb = 2
        Joueur = 1
        Proposition = ""
        Compteur = 1
        MsgBox (Solution)

        While fin = False Or Compteur < 10
        Joueur = Abs(Joueur - 2) + 1
        Proposition = InputBox("Entrer la liste")
        If Solution = Proposition Then
        nouvellelettre = InputBox("entrez une nouvelle lettre")
        Solution = Solution & nouvellelettre
        Solution = Solution & MsgBox(Solution)
        Joueur = Abs(Joueur - 2) + 1
        Else: fin = True
        End If

        Compteur = Compteur + 1

        Wend

        MsgBox ("Bravo")

        End Sub


        /CODE
        1. Salut,

          Regarde dans la boucle While ... Wend
          j'ai rajouté une ligne pour afficher les variables de controle à chaque tour
          Comme ça tu peux voir ce qui cloche

          While fin = False Or Compteur < 10
          Joueur = Abs(Joueur - 2) + 1
          Proposition = InputBox("Entrer la liste")
          MsgBox "compteur= " & Compteur & " : Joueur=" & Joueur & " : Proposition= " & Proposition & " : Solution= " & Solution
          If Solution = Proposition Then
          nouvellelettre = InputBox("entrez une nouvelle lettre")
          Solution = Solution & nouvellelettre
          Solution = Solution & MsgBox(Solution) ' <- il y a une erreur ici
          Joueur = Abs(Joueur - 2) + 1
          Else: fin = True
          End If
          Compteur = Compteur + 1
          Wend

          Essaye de corriger, ou bien est-ce que je peux te proposer une solution?

          A+.
          1. coucou tech_57,

            alors voilà j'ai tout repris depuis le début :

            Sub jeu()
            
            Dim compteur As Integer
            Dim joueur As Integer
            Dim solution, proposition, lettre As String
            Dim arret As Boolean
            Dim final As Variant
            Dim i As Integer
            
            arret = False
            compteur = 1
            joueur = 1
            solution = InputBox("Joueur  " & joueur & Chr(13) & "Entrez une première lettre")
            
            While arret = False And compteur < 5
            
            joueur = Abs(joueur - 2) + 1
            proposition = InputBox("Joueur  " & joueur & Chr(13) & "Entrez votre proposition")
            compteur = compteur + 1
            
            If proposition = solution Then
            lettre = InputBox("Joueur  " & joueur & Chr(13) & "Entrez une nouvelle lettre")
            solution = solution & lettre
            MsgBox ("la nouvelle lettre est  " & lettre & Chr(13) & "il faut rentrer  " & compteur & "  caractères")
            Else
            arret = True
            End If
            Wend
            Call resultat(arret, joueur)
            End Sub
            
            Sub resultat(arret As Boolean, joueur As Integer)
            
            If arret = True Then
            MsgBox ("le joueur  " & joueur & " a perdu")
            Else
            MsgBox "Egalité"
            End If
            
            End Sub
            
            
            


            XD CA FONCTIONNE ! ;-)

            Bon maintenant je voudrais faire les 'finitions' càd, si le joueur entre autre chose qu'une lettre en dehors de abc[...]z en minuscule ou plus d'une lettre alors une msgbox s'affiche demandant de recommencer.
            là j'ai un peu plus de mal est ce que tu peux me filer un coup de pouce?

            mais bon, déjà je pense qu'avec ça je m'assure la moyenne.

            peux tu me dire si ma sub est correcte pour le résultat?
            1. OK , ça fonctionne

              Pour verifier les entrées, il faut comparer les chaines de caractères
              j'ai ajouté ce test:

                    If lettre = "" Or lettre < "a" Or lettre > "z" Or Len(lettre) > 1 Then
                       MsgBox "ERREUR DE SAISIE - RECOMMENCEZ"
                       erreur = True
                  Else
                      erreur = False
                      solution = solution & lettre
                      MsgBox ("La nouvelle lettre est  " & lettre)
                  End If
              


              Bien sur il a fallu aussi adapter le code, voici la sub rectifiée au complet , dis-moi si des choses sont hors programme, on simplifiera.

              Sub jeu()
              
              Dim compteur As Integer
              Dim joueur As Integer
              Dim solution, proposition, lettre As String
              Dim arret As Boolean, erreur As Boolean
              Dim final As Variant
              Dim i As Integer
              
              arret = False: erreur = False
              compteur = 1
              joueur = 1
              solution = InputBox("Joueur  " & joueur & Chr(13) & "Entrez une première lettre")
              
              While arret = False And compteur < 5
                 If erreur = False Then
                   joueur = Abs(joueur - 2) + 1
                   proposition = InputBox("Joueur  " & joueur & Chr(13) & "Entrez votre proposition." & " Il faut entrer  " & compteur & "  caractères")
                   compteur = compteur + 1
                 End If
                 If proposition = solution Then
                    If erreur = False Then MsgBox "EXACT!!"
                    lettre = InputBox("Joueur  " & joueur & Chr(13) & "Entrez une nouvelle lettre")
                    If lettre = "" Or lettre < "a" Or lettre > "z" Or Len(lettre) > 1 Then
                       MsgBox "ERREUR DE SAISIE - RECOMMENCEZ"
                       erreur = True
                  Else
                      erreur = False
                      solution = solution & lettre
                      MsgBox ("La nouvelle lettre est  " & lettre)
                  End If
              Else
                 arret = True
              End If
              
              Wend
              Call resultat(arret, joueur)
              End Sub
              


              A+.
              1. re tech_,

                alors justement j'ai créé une solution qui ressemble à la tienne mais à partir de proposition je tourne en rond je n'arrive pas à sortir de mon tant que. c'est une histoire avec les len à mon avis, peux tu me corriger?

                Sub jeu()

                Dim compteur As Integer
                Dim joueur As Integer
                Dim solution As String
                Dim proposition As String
                Dim lettre As String
                Dim arret As Boolean
                Dim mot As String

                arret = False
                compteur = 1
                joueur = 1
                mot = "abcdefghijklmnopqrstuvwxyz"
                solution = InputBox("Joueur " & joueur & Chr(13) & "Entrez une première lettre")
                While contient(solution, mot) = False Or Len(solution) <> 1
                MsgBox ("il faut saisir un caractère en minuscule compris entre a et z!")
                solution = InputBox("Joueur " & joueur & Chr(13) & "Entrez à nouveau une première lettre")
                Wend

                While arret = False And compteur < 5

                joueur = Abs(joueur - 2) + 1
                proposition = InputBox("Joueur " & joueur & Chr(13) & "Entrez votre proposition")
                While contient(proposition, mot) = False Or Len(proposition) <> Len(solution)
                MsgBox ("il faut saisir " & compteur & " caractère(s) en minuscule compris entre a et z!")
                proposition = InputBox("Joueur " & joueur & Chr(13) & "Entrez à nouveau votre proposition")
                Wend

                compteur = compteur + 1

                If proposition = solution Then
                lettre = InputBox("Joueur " & joueur & Chr(13) & "Entrez une nouvelle lettre")
                While contient(lettre, mot) = False Or Len(lettre) <> 1
                MsgBox ("il faut saisir un caractère en minuscule compris entre a et z!")
                lettre = InputBox("Joueur " & joueur & Chr(13) & "Entrez à nouveau une nouvelle lettre")
                Wend

                solution = solution & lettre
                MsgBox ("la nouvelle lettre est " & lettre & Chr(13) & "il faut rentrer " & compteur & " caractères")
                Else
                arret = True
                End If
                Wend
                Call resultat(arret, joueur)
                End Sub

                Sub resultat(arret As Boolean, joueur As Integer)

                If arret = True Then
                MsgBox ("le joueur " & joueur & " a PERDU" & Chr(13) & "le joueur " & Abs(joueur - 2) + 1 & " a GAGNE")
                Else
                MsgBox "Egalité"
                End If

                End Sub

                Function contient(lettre As String, mot As String) As Boolean
                Dim cont As Boolean
                Dim i As Integer

                cont = False

                For i = 1 To Len(mot)

                If Mid(mot, i, 1) = lettre Then
                cont = True
                End If
                Next i

                contient = cont

                End Function
                1. L'erreur est dans la fonction contient.

                  Cette fonction verifie si une lettre est contenue dans un mot, ça marche avec une seule lettre

                  or tu fais ce test

                  While contient(proposition, mot) = False Or Len(proposition) <> Len(solution)
                  ...
                  Wend

                  au premier passage, proposition a un seul caractère, alors ça marche
                  au deuxième passage, proposition a deux caractères, alors dans la fonction contient, le premier parametre (lettre) prend la valeur de solution, et la comparaison If Mid(mot, i, 1) = lettre compare un caractère de mot à la chaine lettre toute entière comme par exemple "a" = "ab", et donc le test sera faux, d'où la boucle sans fin.

                  Voila, je crois que tu dois tester uniquement les entrées des nouvelles lettres.
                  La proposition est soit juste, soit fausse, tant pis pour le joueur qui se trompe. Ou bien il faut revoir ta fonction.

                  A+.
                  1. re,

                    j'essaie de revoir ma fonction mais je n'y arrive pas. je ne comprends pas ce que je peux changer. peux tu m'éclairer?
                    1. Bonjour,

                      Voici l'astuce, il faut utiliser la fonction Instr qui recherche une chaine contenue dans une autre chaine.
                      Si oui, elle renvoie la position de la chaine recherchée dans l'autre chaine
                      Si non, elle renvoie 0
                      Exemple: Instr("abc","b") retourne 2, Instr("abc","ab") retourne 1 , Instr("abc","x") retourne 0

                      On regarde si chaque caractère de lettre est contenu dans mot
                      Si un seul caractère n'est pas dans mot alors cont=false

                      Ca donne ceci

                      Function contient(lettre As String, mot As String) As Boolean
                      Dim cont As Boolean
                      Dim i As Integer
                      
                      cont = True
                      
                      For i = 1 To Len(lettre)
                      
                      If InStr(mot, Mid(lettre, i, 1)) = 0 Then
                         cont = False
                      End If
                      
                      Next i
                      
                      contient = cont
                      
                      End Function


                      A+.