PROBLEME de FICHIER AVEC MACRO
Je vous remercie beaucoup, je comprends mieux maintenant.
Dans la foulée, je soumets à ta méditation, la procédurede cumul des résultats :
Sub nbpartieGPN()
Dim J%, g%, i%, nbtmax
With ActiveSheet
J = Val(Replace(.Name, "Jeu", ""))
With .Range("K25")
For i = 1 To 3
If .Cells(i, 1 - (J = 3)) > 0 Then
g = i: Exit For
End If
Next i
End With
If g > 0 Then
With .Range("R5")
For i = 1 To 3
With .Cells(i, 1 - (g <> i))
.Value = .Value + 1
End With
Next i
End With
Else
nbtmax = Array(0, 10, 14, 19)
If .Range("P7").Offset(0 + (J = 3)) = nbtmax(J) Then
With .Range("T5")
For i = 1 To 3
.Cells(i, 1) = .Cells(i, 1) + 1
Next i
End With
End If
End If
End With
End SubElle est pareillement conçue pour s'appliquer à toutes les feuilles, mais les petits calculs d'ajustement sont un peu plus compliqués que précédemment.
D'abord, on procède par addition de 1 à la valeur antérieure dans les cellules concernées par chaque cas. Ensuite les variations dépendent du type de feuille (1, 2 ou 3) comme précédemment. On l'extrait de la même façon dans la variable J.
Puis du gagnant : là on va boucler sur les cellules K25 à K27, mais en prenant comme référence K25 [en adressage relatif à K25, K25 sera .Cells(1, 1), K26 .Cells(2, 1) et K27 .Cells(3, 1)]. On les parcours donc avec une boucle i= 1 à 3 et quand .Cells(i, 1) est supérieur à 0, on a notre gagnant (qu'on récupère dans la variable g).
Cela est bon pour les feuilles type 1 et 2, mais pour le type 3 la colonne est passée en L ! Il faut donc qu'on ait 2 au lieu de 1 comme numéro de colonne dans ce cas. Ce qu'on va obtenir en définissant la colonne dans l'expression par 1 - (J = 3) : (J = 3) placé entre parenthèses est une expression booléenne qui renverra VRAI si J est 3 ou FAUX si ce n'est pas le cas ; le propre d'une expression booléenne est de se prêter à des calculs, lorsqu'on l'inclut dans une opération, elle renverra 0 pour FAUX et -1 pour VRAI. Donc, si on est dans une feuille type 3 en retranchant -1 à 1, on fera passer notre indication de colonne à 2...
[NB - Noter que c'est -1 en VBA, mais 1 dans Excel...]
Ayant un gagnant, on utilisera la même astuce en parcourant les cellules R5 à R7, avec l'expression pour indiquer la colonne : 1 - (g <> i). i indiquant la ligne 1, 2 ou 3, si on est dans la ligne du gagnant (g <> i) vaut 0 et on incrémente la cellule en R, sur les autres lignes l'expression vaut -1 et on va incrémenter la cellule en S (perdants).
Une autre petite difficulté se posait pour la détection de la partie nulle. En testant P7 on vérifie que le dernier joueur a joué et qu'il est au max de tours de jeux, donc toutes les cases sont remplies. Mais le nombre de tours va varier selon les types de jeux (feuilles) : 10 pou 1, 14 pou 2 et 19 pour 3, avec cette particularité que le 3e joueur n'atteindra que 18 (56 cases et non 57) et donc que là le test de fin se fera sur le 2e joueur (P6).
D'abord lier la suite 10, 14, 19 à 1, 2, 3 par algorithme de calcul paraît un peu compliqué, on va donc placer ces trois valeurs dans un tableau : variable nbtmax de type Variant dans laquelle on place un tableau en utilisant la fonction Array. Les tableaux étant d'indice minimal 0 par défaut, on fait en sorte que nos 3 valeurs occupent les indices 1, 2 et 3, ainsi en appelant nbtmax(J) on appellera la valeur correspondant à la feuille sur laquelle on est.
Puis même astuce pour tester : on teste P7 .Offset(0 + (J = 3)), soit avec un décalage ligne 0 sauf si on est sur un type 3 où (J = 3) fera passer le décalage à -1, ce qui pointera sur P6. [Le 0 est indispensable, car il faut un calcul pour que l'expression booléenne renvoie une valeur numérique.]
Ensuite pas de difficulté, on incrémente tout le monde de T5 à T7.
Je vais tout de même la vérifier car une erreur de frappe se produit toujours facilement.
Je n'ai testé que sommairement, mais elle semble fonctionner correctement...
Une petite nouvelle en prime :
Sub CJouer()
Dim k%, Jec%, i%
With ActiveSheet
Jec = .Range("K21")
k = .Shapes(Application.Caller).TopLeftCell.Column
.Cells(26, k) = .Cells(27, k)
For i = 3 To 7
If .Cells(i, k) <> "" Then
.Cells(i, k).Font.color = .Range("O5:O7").Cells(Jec, 1).Font.color
Exit For
End If
Next i
End With
End SubCette procédure fait à elle toute seule la copie de la ligne 27 vers la ligne 26 et la coloration du "jeton" joué, pour toutes les colonnes...
Elle a vocation à être complétée pour opérer sur toutes les feuilles, mais je n'avais pas le temps de prendre en comptes les écarts à ajuster selon les feuilles, elle ne fait donc provisoirement que le type 1. Et elle ne fonctionne que pour le Jeu1-1 (dans le classeur sur lequel j'ai travaillé), car il faut prendre le temps d'affecter la macro à toutes les petites flèches (et défusionner les cellules dans lesquelles elles sont).
Le principe : les flèches que tu as placées sont des objets Shapes (des formes), on peut y affecter des macros, ce que tu as fait. Mais on dispose d'une propriété : Application.Caller qui permet de savoir comment a été appelée la macro. Cette propriété peut renvoyer des choses très diverses selon les cas, dont beaucoup inutilisables, mais dans le cas d'éléments qui se rattachent à la collection Shapes, elle renvoie le nom de la forme.
Ainsi en affectant la même macro à toutes ces flèches, on peut donc savoir lors de l'exécution de la macro qui l'a lancée.
Le nom en soi n'est pas une information particulièrement utile (sauf quand on les a modifiés à cette fin), ce qu'on veut savoir c'est quelle est la colonne concernée par le lancement de la macro.
Or un objet Shape dispose d'une propriété TopLeftCell qui renvoie la cellule dans laquelle se trouve l'angle supérieur gauche de la forme en tant qu'objet (il faut donc bien les positionner, mais une fois que c'est fait...) Et disposant de la cellule, on peut aisément en extraire la colonne.
On récupère donc en une ligne de commande le numéro de colonne, et en une autre le joueur (K21) qui va nous servir pour attribuer la couleur.
On n'a plus qu'à faire la copie... mais il faut bien voir que copier-coller, si on y est contraint en manuel, ce n'est pas le cas pour VBA et il faut donc toujours avoir présent à l'esprit que si l'on peut faire autrement, c'est mieux, et ce sera surtout plus rapide.
Et affecter la valeur de la ligne 27 de la colonne à la ligne 26 de la même colonne est quelque chose de très simple comme tu peux voir, qui permet de se passer d'une copie chronophage...
Pour ce qui est de la couleur, on n'a pas besoin de colorer à chaque fois tous les jetons présents ! Seul le dernier arrivé n'est pas coloré, les autres l'ont été lors de leur insertion. On connaît la colonne, on sait que c'est le premier qu'on rencontrera en descendant la colonne, et sa couleur est celle du joueur.
On descend donc la colonne et quand on le trouve on le colore. On prélève la couleur en O5:O7, de façon à préserver le choix des couleurs qui pourrait introduire des variations.
Je te remets le fichier pour que tu puisses tester (mais ce n'est en place que pour Jeu1-1).
Cordialement.
Merci encore pour votre aide. J'essaie d'avancer de mon coté aussi car je dois rendre le projet demain.
Je bloque sur les points suivants:
- Avoir la possibilité de choisir le nombre de joueur ( de 1 joueur à 3
joueurs max). Actuellement mes grilles de jeu sont programmées pour jouer à
3 .
- Avoir la possibilité d'annuler le dernier coup joué. J'ai commencé une
macro (module 17) mais elle permet d'annuler plusieurs coup (or je veux que
ça fonctionne uniquement pour le dernier pions joué) et en plus elle ne
prend pas en compte le placement du dernier pions.
- Avoir un chronomètre pour un temps de réponse maximum qui varie selon
les niveaux de difficulté. De plus j'ai un bouton "Pause" qui faudrait lié
à ce chronomètre. ==> J'ai réussi à mettre un compte à rebours, mais je dois pourvoir le mettre en pause avec le bouton pause et pouvoir reprendre là ou il s'est arrêté. Et il faut aussi que je trouve comment faire pour qu'il démarre quand le premier pion est joué.
- Avoir des effets sonores pour chaque joueur lorsqu'il joue un pion.
- Pouvoir utiliser le clavier ou la sourie pour jouer.
- Avoir le classement des 10 meilleurs joueurs dans l'onglet "Classement"
La macro qui compte le nombre totale de partie jouée / gagnée / perdue / nul ne fonctionne pas correctement car cela s'arrete à 1, il ne cumul pas lorsqu'on recommence une nouvelle partie .
Merci par avance
Cdlt
Alice
Bonjour,
J'essaie d'avancer de mon coté aussi car je dois rendre le projet demain.
Avec ta liste de points qui suit, il y a un temps conséquent de travail à plein temps...
Un problème fonctionnel que tu ne soulèves pas, qui me paraît pourtant avoir une certaine priorité, c'est que la partie ne s'arrête pas ! tu as un gagnant, et on peut continuer à jouer, et même en fin si on arrive à arracher le nul... On ne devrait plus pouvoir une fois que la partie a atteint un résultat !
Choisir le nombre de joueurs doit être possible mais un certain nombre de dispositions ne fonctionneront pas pour 2 à l'heure actuelle... Il convient de s'assurer du bon fonctionnement à 3 d'abord.
1 ? Je ne conseille pas ! Là tu changerais de registre : construction d'un programme de simulation car un joueur joue alors contre l'ordinateur...
Annulation : certainement possible... Chrono : il s'agit là de compte-temps par joueur... Classement des joueurs : dès lors qu'on conserve en mémoire... Mais il me semble qu'avant tout ça, ilfaut d'abord savoir arrêter une partie !
Jouer à la souris, c'est ce qu'on fait... clavier, c'est un peu autre chose s'il faut dédier des touches à certaines actions, tu te lances dans une reprogrammation du clavier qu'il faudra rétablir en fin de jeu...
Effets sonores ? C'est encore un autre domaine, Excel n'incorpore plus de sons depuis longtemps, les sons système ne présentant pas d'intérêt, il faut créer une bibliothèque de sons et le programme permettant de les utiliser...
En tout cas sur ces points tu sors d'Excel pour piloter d'autres applications.
La macro qui compte le nombre totale de partie jouée / gagnée / perdue / nul ne fonctionne pas correctement car cela s'arrete à 1, il ne cumul pas lorsqu'on recommence une nouvelle partie .
Là tu n'as pas tout suivi, j'ai réécrit cette macro, pour qu'elle cumule les points, et pour tous les jeux !
Et je te conseille aussi de regarder la dernière que j'ai fournie, encore dans un état transitoire mais qui vise à remplacer tout le code relatif au dispositif de copie permettant de faire apparaître les jetons et à la coloration de ces derniers.
Ça, je vais le finaliser, sur quelques autres points je pourrai trouver quelques moments pour intervenir, mais tu comprendras qu'il est hors de question que je me mette à plein temps sur ton fichier, et de plus pour une période dont on ne voit pas le terme...
Je laisse ton fichier de côté, je ne sais pas quelles modifications il incorpore, et j'ai pour habitude dès lors que j'ai commencé à travailler sur fichier de continuer sur le même, toujours à partir du dernier exemplaire modifié par moi, car je sais ce qu'il contient et ce qu'il ne contient pas...
Cordialement.
Bonjour,
Oui je sais projet irréalisable dans sa totalité =(
Pour la macro que vous avez réécrit concernant le nb de partie ... elle fonctionne mais uniquement si je vais dessus et la relance à chaque fois. Comment faire pour que cela se fasse automatiquement ?
Et en effet il faut que je mette fin à la partie quand le joueur a gagné ou quand c'est match nul ...
Merci infiniment pour votre aide
Elle est lancée par la procédure Change de la feuille, et autant que je sache tu ne l'as incluse que pour Jeu1-1, elle est donc ignorée sur les autres feuilles...
Je ne me suis pas occupé de cela car une procédure Change sur toutes les feuilles, il est logique et économique de les remplacer par une seule procédure SheetChange au niveau classeur, qui s'occupera de toutes les feuilles Jeu, mais je n'avais pas le temps de faire la délimitation de la plage surveillée selon le type de jeu...
ah oui c'est bon j'ai compris le problème
Pour mettre fin à la partie j'ai fais ça : (je pense qu'il doit y avoir moins long )
Mon problème est que quand je le met dans la feuille change avec les autres , ça passe directement à Zéro, on ne voit pas où le dernier pions est placé et le nom du joueur qui gagne
Sub finpartie()
Dim n%
With ActiveSheet
If Range("K25") > 0 Then
With ActiveSheet
n = Val(Replace(.Name, "Jeu", ""))
Application.EnableEvents = False
.Range("A25").Offset(n).Resize(, 5 + n).ClearContents
Application.EnableEvents = True
.Range("J4").Select
End With
If Range("K26") > 0 Then
With ActiveSheet
n = Val(Replace(.Name, "Jeu", ""))
Application.EnableEvents = False
.Range("A25").Offset(n).Resize(, 5 + n).ClearContents
Application.EnableEvents = True
.Range("J4").Select
End With
If Range("K27") > 0 Then
With ActiveSheet
n = Val(Replace(.Name, "Jeu", ""))
Application.EnableEvents = False
.Range("A25").Offset(n).Resize(, 5 + n).ClearContents
Application.EnableEvents = True
.Range("J4").Select
End With
If Range("P7") = 10 Then
With ActiveSheet
n = Val(Replace(.Name, "Jeu", ""))
Application.EnableEvents = False
.Range("A25").Offset(n).Resize(, 5 + n).ClearContents
Application.EnableEvents = True
.Range("J4").Select
End With
End If
End If
End If
End If
End With
End Sub
Je ne vois pas trop ce que tu as voulu faire... !
NB- Prends l'habitude de placer ton code cité sous balises Code, le bouton qui présente ce symbôle </>,
car le code laissé à l'état de brouillon n'est pas lisible, du moins il faut plus de temps pour le lire (qu'on ne passe pas à une activité plus intéressante !
J'ai généralisé la procédure CJouer pour qu'elle opère sur toutes les feuilles, ce qu'elle fait donc.
J'ai défini la procédure SheetChange (à voir dans ThisWorkbook) qui lancera donc la procédure nbpartieGPN pour toutes les feuilles, et parallèlement supprimé les procédures Change des feuilles.
Pour ce qui est de la fin de partie, il convenait que d'avoir un critère pour chaque feuille, de façon que l'arrêt de jeu sur l'une n'empêche pas la poursuite du jeu sur les autres. J'ai donc choisi de placer une mention "STOP" en K4 lorsqu'une partie est finie. Et modifié la formule en J4 de façon qu'elle affiche "FINI" au lieu du joueur suivant dans ce cas.
Il revenait à la procédure nbpartieGPN, où se détecte la fin de partie, d'opérer cette inscription. J'y ai donc ajouté une variable booléenne fin (pour plus de commodité), que l'on passe à True dans les cas de fin de partie, et en fin ce procédure, si la variable est à True, l'inscription de "STOP" est opérée.
Sub nbpartieGPN()
Dim J%, g%, i%, nbtmax, fin As Boolean
With ActiveSheet
'[...]
If g > 0 Then
'[...]
fin = True
Else
nbtmax = Array(0, 10, 14, 19)
If .Range("P7").Offset(0 + (J = 3)) = nbtmax(J) Then
[...]
fin = True
End If
End If
If fin Then .Range("K4") = "STOP"
End With
End SubPour assurer que l'on ne puisse plus continuer à jouer, la version généralisée de la procédure CJouer ci-dessous incorpore une condition pour ne pas s'exécuter si "STOP" figure en K4.
Sub CJouer()
Dim J%, k%, Jec%, i%
With ActiveSheet
If .Range("K4") = "STOP" Then Exit Sub
J = Val(Replace(.Name, "Jeu", ""))
Jec = .Range("K21").Offset(, 0 - (J = 3))
k = .Shapes(Application.Caller).TopLeftCell.Column
.Cells(25 + J, k) = .Cells(26 + J, k)
For i = 3 To 6 + J
If .Cells(i, k) <> "" Then
.Cells(i, k).Font.Color = .Range("O5:O7").Cells(Jec, 1).Font.Color
Exit For
End If
Next i
End With
End SubEt évidemment, la procédure Nouvellepartie effacera K4 pour démarrer une nouvelle partie :
Sub Nouvellepartie()
'[...]
Application.EnableEvents = True
.Range("K4").ClearContents
.Range("J4").Select
End With
End SubIl y a un point que je n'ai pas inventorié, c'est comment s'opère la prise en compte de 3, 4 ou 5 jetons selon le niveau de difficulté, dont j'ai crains un moment qu'elle n'impacte les procédure... mais les procédures fonctionnent selon ces niveaux, et je plongerai dans les détails plus tard si besoin.
Cordialement.
Pour le code ... j'essaie a taton .. pas évident quand on connaît pas trop le langage
Merci pour les codes, ils fonctionnent tous niquel
La prise en compte de 3,4 ou 5 jetons sont gérés sans VBA.
Sous le jeu, par les formule =ESTERREUR(CHERCHE(111;M21;1)) OU =ESTERREUR(CHERCHE(1111;M21;1)) OU =ESTERREUR(CHERCHE(11111;M21;1))
Une procédure pour annuler le dernier coup...
Sub AnnulerDernierCoup()
Dim J%, jj%
With ActiveSheet
J = Val(Replace(.Name, "Jeu", ""))
jj = CInt(Right(.Name, 1)) + (J - 1) * 3
If kk(jj) > 0 Then
With .Cells(25 + J, kk(jj))
.Value = Left(.Value, Len(.Value) - 1)
End With
kk(jj) = 0
End If
End With
End SubElle repose sur une variable niveau Module dans laquelle on enregistre la colonne du dernier coup joué :
Dim kk(1 To 9) As IntegerVariable tableau pour pouvoir stocker le dernier coup pour toutes les feuilles...
Connaissant la colonne, on va ôter le dernier caractère sur la ligne 26, 27 ou 28 selon les jeux, ce qui annule le coup.
On repasse la valeur de la variable à 0 de façon à n'annuler que le dernier coup.
C'est évidemment la procédure CJouer qui stocke la colonne dans la variable à chaque coup :
Sub CJouer()
Dim J%, jj%, k%, Jec%, i%
With ActiveSheet
If .Range("K4") = "STOP" Then Exit Sub
J = Val(Replace(.Name, "Jeu", ""))
jj = CInt(Right(.Name, 1)) + (J - 1) * 3
'[...]
kk(jj) = k
'[...]
End SubParallèlement il faut aussi ramener la variable à 0 pour une nouvelle partie (le clic sur annuler déclencherait une erreur) :
Sub Nouvellepartie()
Dim n%, nn%
With ActiveSheet
n = Val(Replace(.Name, "Jeu", ""))
nn = CInt(Right(.Name, 1)) + (n - 1) * 3
'[...]
kk(nn) = 0
.Range("J4").Select
End With
End SubEt également en cas de fin de partie :
Sub nbpartieGPN()
Dim J%, jj%, g%, i%, nbtmax, fin As Boolean
With ActiveSheet
J = Val(Replace(.Name, "Jeu", ""))
jj = CInt(Right(.Name, 1)) + (J - 1) * 3
'[...]
If fin Then .Range("K4") = "STOP": kk(jj) = 0
End With
End SubJ'ai aussi fait un peu de ménage...
Mais ce ne sera pas pour aujourd'hui !
Cordialement.
Bonjour,
Si tu abandonnes, il faudrait le dire... Je n'ai aucune raison de continuer dans ce cas !
Enfin ! Pour le choix des jetons et des couleurs, c'est en place : j'ai ajouté 3 jetons pour qu'il y ait un minimum de choix, on peut éventuellement en ajouter, pour les couleurs j'ai limité à 12, on peut également en ajouter ou les modifier. Les choix se font par boutons toupies par joueur, cela fait défiler les choix dans un sens ou sens (et ça boucle, pas d'arrêt obligeant à revenir en arrière). Quand un joueur choisit, les choix actuel des autres ne lui sont pas proposés, on ne peut donc choisir le jeton ou la couleur d'un autre joueur tant qu'il n'en a pas changé.
Le jeu à 2 est également en place. Il se commande à partir d'un bouton bascule qui permet donc de choisir 2 ou 3, le 3 restant par défaut. L'application des jetons et couleurs choisis et du jeu à 2 ou 3 se fait lors de la sélection d'un jeu. Les éléments de la feuille de jeu concernée sont modifiés en conséquence.
Un autre bouton bascule permet de choisir d'aller sur jeu en appliquant les paramètres actuellement choisis (sur la feuille paramétrage) ou d'y aller sans modifier les paramètres existants sur la feuille. En effet, quelqu'un a pu paramétrer un jeu pour son utilisation, quelqu'un d'autre a pu modifier les paramètres pour paramétrer un autre jeu, le premier conserve donc la possibilité d'aller sur son jeu initial sans en voir les paramètres modifiés par des choix qui ne sont plus les siens...
Les 2 boutons bascule sont systèmatiquement ramenés à une valeur par défaut : 3 et Sans modifier, de façon à limiter les risques d'erreurs (application de paramètres non recherchés) en la matière.
Pour les dimensionnements de lignes et colonnes je suis plus réservé : en tout état de cause, on ne peut les dissocier, la forme des cellules doit rester carrée, et c'est à relier à l'écran, sa taille, sa résolution d'un côté, le fait qu'on utilise le jeu en plein écran ou non de l'autre... La marge de manoeuvre est étroite et il me semble difficile d'offrir plus qu'un choix réduit à 2 ou 3 possibilités. Et travaillant sur un 15 pouces, j'ai même du mal à imaginer les possibilités entre lesquelles on pourrait alterner...
De toute façon les 2 macros concernant le dimensionnement sont inactives...
J'ai trouvé astucieux la façon d'approcher la largeur de colonne à partir d'un choix en cm...
Pour la classement, il faudrait que tu définisses des critères à partir desquels on doit l'opérer, ensuite il ne s'agit que d'enregistrer et conserver les résultats... et prévoir un vidage (réinitialisation) pour repartir à zéro.
Pour les sons, as-tu déjà une idée des sons que tu souhaites mettre, et disposes-tu de fichier audio utilisables ?
Quant aux compte-temps, il convient aussi de définir les règles d'utilisation...
J'ai également simplifié un peu la partie traduction qui occupait un gros volume à elle seule, cela a diminué mais cela reste conséquent, d'autant que c'est à compléter pour les libellés des boutons (facile, intermédiaire, difficile, et ceux que j'ai rajoutés), qui y ont échappés, et il y aura probablement quelques ajouts à intégrer... S'agissant d'un aspect très particulier et quasiment indépendant du jeu lui-même, j'ai déplacé le code dans un module dédié, les boutons l'appellent et passant un paramètres de langue.
Cordialement, en attendant de te revoir par ici...
Bon dimanche.