Optimisation, procédures bouton

florianlens Messages postés 6 Date d'inscription vendredi 21 août 2009 Statut Membre Dernière intervention 17 janvier 2011 - 16 nov. 2010 à 09:40
l0r3nz1 Messages postés 218 Date d'inscription mercredi 20 février 2008 Statut Membre Dernière intervention 17 mars 2012 - 23 nov. 2010 à 16:10
Bonjour,

J'ai créé un Morpion en C# mais j'aimerais optimiser le code car les 9 boutons correspondant à chaque cases alourdissent mon code et n'est pas très apprécié à l'examen.

Le codage de mes 9 boutons est le même si ce n'est le nom des boutons qui changent.
Voici le code entier de mon bouton 3 :
private void button3_Click(object sender, EventArgs e)
        {
            if (tour 1 || tour 3 || tour == 5 || tour == 7 || tour == 9)
            {
                button3.BackgroundImage = Morpion.Properties.Resources.croix;
                c3 = "croix";
                button3.Enabled = false;
                tour++;

                if ((c3 "croix" && c6 "croix" && c11 == "croix") || (c3 == "croix" && c4 == "croix" && c5 == "croix") || (c3 == "croix" && c7 == "croix" && c10 == "croix"))
                {
                    label8.Text = "Joueur 1, vous avez gagné";
                    button3.Enabled false; button4.Enabled false; button5.Enabled = false; button6.Enabled = false; button7.Enabled = false; button8.Enabled = false; button9.Enabled = false; button10.Enabled = false; button11.Enabled = false;
                    J1point++;
                    label2.Text = Convert.ToString(J1point);
                }
                else
                {
                    label8.Text = "Joueur 2, c'est à vous";
                }
            }
            else
            {
                button3.BackgroundImage = Morpion.Properties.Resources.rond;
                c3 = "rond";
                button3.Enabled = false;
                tour++;

                if ((c3 "rond" && c6 "rond" && c11 == "rond") || (c3 == "rond" && c4 == "rond" && c5 == "rond") || (c3 == "rond" && c7 == "rond" && c10 == "rond"))
                {
                    label8.Text = "Joueur 2, vous avez gagné";
                    button3.Enabled false; button4.Enabled false; button5.Enabled = false; button6.Enabled = false; button7.Enabled = false; button8.Enabled = false; button9.Enabled = false; button10.Enabled = false; button11.Enabled = false;
                    J2point++;
                    label5.Text = Convert.ToString(J2point);
                }
                else
                {
                    label8.Text = "Joueur 1, c'est à vous";
                }
            }
            if (tour == 10)
            {
                label8.Text = "           Match nul";
                Egalite++;
                label7.Text = Convert.ToString(Egalite);
            }
        }

4 réponses

Shaolyne Messages postés 155 Date d'inscription jeudi 12 mai 2005 Statut Membre Dernière intervention 8 mars 2011 1
16 nov. 2010 à 10:15
Bien le bonjour Florianlens,

Voici une discussion reflétant une problématique similaire à la tienne : Problème procédure boutons. Personnellement, je suis d'avis qu'une solution toute faite risque de ne pas t'aider pour ton examen. Par contre, je serai ravi de t'aider si tu as des questions lorsque tu rendras ton code générique.

Shao.
0
cs_casy Messages postés 7741 Date d'inscription mercredi 1 septembre 2004 Statut Membre Dernière intervention 24 septembre 2014 40
16 nov. 2010 à 10:38
La technique est simple.
Dans l'onglet évènement pour l'évènement Click de chaque bouton, tu indique la procédure qui va traiter l'évènement. Tu peux très bien indiquer la même procédure pour les 9 boutons.

Ensuite dans ta procédure de traitement de l'évènement (quelque soit les évènements d'ailleurs) tu as toujours un premier paramètre qui s'appelle Sender. Ce paramètre de type Object contient en réalité le controle (ici les boutons) qui a déclenché la procédure.

Donc si dans ta procédure, tu as besoin d'acceder à ton controle (bouton) tu peux le faire à travers le paramètre Sender.




[i][b]---- Sevyc64 (alias Casy) ----
[hr]# LE PARTAGE EST NOTRE FORCE #/b/i
0
krimog Messages postés 1860 Date d'inscription lundi 28 novembre 2005 Statut Membre Dernière intervention 14 février 2015 49
16 nov. 2010 à 14:55
Salut

Comme dit précédemment, utilise la même méthode pour tous tes boutons.

Quelques petites optimisations cependant :

if (tour 1 || tour 3 || tour == 5...)

peut être remplacé par
if (tour % 2 == 1) 
// Si le reste de la division euclidienne de tour par 2 est égale à 1
// Donc si tour est impair


De plus, plutôt que de créer une à une tes cases, tes boutons... il vaut largement mieux les placer dans un tableau, à deux dimensions.

Ensuite, je vois que tous les cX sont des string, mais qui n'ont comme valeur que "croix", "rond" et une troisième ("" ou "vide" ou je-ne-sais-quoi). C'est l'occasion rêvée de faire un enum plutôt qu'un string. C'est facile, c'est rapide, c'est pratique, c'est léger.
enum EtatCase
{
    vide,
    croix,
    rond
}


Egalement, tu fais des tests sur, en l'occurrence, c3 pour voir si le joueur a gagné. Seulement, tu définis la valeur de c3 juste avant. Donc inutile de retester la case.

Enfin, je ferais une fonction de vérification de victoire plus travaillée que tester chaque solution manuellement.
C'est peut-être plus long, mais c'est beaucoup plus évolutif. Ma solution fonctionne pour un morpion simple, pour un plus grand plateau, pour plus de pions à aligner...
// x et y correspondent aux coordonnées de la dernière case sur laquelle on a joué.
bool aGagne(int x, int y)
{
    if (compteAlignes(x, y, 1, 0) >= nbPourVictoire // Horizontal
        || compteAlignes(x, y, 0 , 1) >= nbPourVictoire // Vertical
        || compteAlignes(x, y, 1 , 1) >= nbPourVictoire // Diagonale1
        || compteAlignes(x, y, 1 , -1) >= nbPourVictoire) // Diagonale2
    {
        // Le joueur courant a gagné.
    }
}

int compteAlignes(int x, int y, int dX, int dY)
{
    int nbAlignes = 1;
    EtatCase etat = c[x, y];
    // Dans un sens
    for (int i = 1; x - i * dX >= 0 && 
                    y - i * dY >= 0 && 
                    y - i * dY < largeurGrille && 
                    x - i * dX < largeurGrille && 
                    c[x - i * dX, y - i * dY] == etat; i++)
    {
        nbAlignes++;
    }
    // Dans l'autre
    for (int i = 1; x + i * dX >= 0 && 
                    y + i * dY >= 0 && 
                    x + i * dX < largeurGrille && 
                    y + i * dY < largeurGrille && 
                    c[x + i * dX, y + i * dY] == etat; i++)
    {
        nbAlignes++;
    }
}

Attention que là, j'ai considéré que tu avais mis l'état de tes cases dans un tableau à deux dimensions de EtatCase.

Krimog : while (!(succeed = try())) ;
- Nous ne sommes pas des décodeurs ambulants. Le style SMS est prohibé. -
0
l0r3nz1 Messages postés 218 Date d'inscription mercredi 20 février 2008 Statut Membre Dernière intervention 17 mars 2012
23 nov. 2010 à 16:10
Salut,

je n'ai pas detaillé le code mais as tu pensé a ulilser la programmation objet?
- un objet case qui a en variables 6 cases voisines, un etat non coché, croix ou rond.
- un objet grille qui contient les cases, si une case est dans un état coché et que deux voisines adjacentes le sont de la même maniere, la grille est finie.
- un objet joueur.

tu peux abonner ta case aux evenements:
this.moncontrole += new System.EventHandler(this.lafonctionSiEvenement);

et la tu n'as même plus besoin de
"private void button3_Click(object sender, EventArgs e)"
et t'as un code tout propre tout beau, en essayant de ne pas repeter deux fois la même chose.

en faire le plus possible en en faisant le moins possible quoi!
0
Rejoignez-nous