6 votes

Tic Tac Toe - Détecter une victoire, une défaite ou un match nul

C'est un générateur de tic tac toe. Ordinateur contre ordinateur seulement, un peu différent de l'habituel joueur contre ordinateur. J'ai écrit la plupart de mon code pour cela, mais le problème que j'ai est que parfois, lorsque je génère le jeu, le tableau entier se remplit et il y aura une ligne de X et une ligne de O et il y aura une égalité. Parfois, il y a deux lignes de X ou deux lignes de O générées, et le jeu ne s'arrête pas après la première ligne avec 3 dans une rangée ... des idées ? Merci.

namespace TicTacToe
{
    public partial class Form1 : Form
    {
        private Random rn = new Random();

        const int SIZE = 9;
        char[] cell = new char[SIZE];
        char firstPlayer = ' ', secondPlayer = ' ';

        private void button1_Click(object sender, EventArgs e)
        {
            //Clear the labels and starting values

            for (int i = 0; i < SIZE; i++)
            {
                cell[i] = ' ';
            }
            label10.Text = "";

            //Pick X or O to go first
            switch (rn.Next(2))
            {
                case 0: firstPlayer = 'O'; secondPlayer = 'X'; break;
                case 1: firstPlayer = 'X'; secondPlayer = 'O'; break;
            }

            //Get five non-repeating numbers from 0 to 8
            int[] positions = new int[5];
            positions[0] = rn.Next(9);
            for (int i = 1; i < 5; i++)
            {
                int temp = rn.Next(9);
                for (int j = 0; j < i; j++)
                {
                    if (temp == positions[j])
                    {
                        i--;
                        break;
                    }
                    else
                    {
                        positions[i] = temp;
                    }
                }
            }

            //Set each position found to have first players letter
            for (int i = 0; i < 5; i++)
            {
                cell[positions[i]] = firstPlayer;
            }

            for (int i = 0; i < SIZE; i++)
            {
                if (cell[i] != firstPlayer)
                {
                    cell[i] = secondPlayer;
                }
            }
            //Place cell values into the labels
            label1.Text = cell[0].ToString();
            label2.Text = cell[1].ToString();
            label3.Text = cell[2].ToString();
            label4.Text = cell[3].ToString();
            label5.Text = cell[4].ToString();
            label6.Text = cell[5].ToString();
            label7.Text = cell[6].ToString();
            label8.Text = cell[7].ToString();
            label9.Text = cell[8].ToString();

            //Check for a winner
            switch(checkWinner())
            {
                case 'T' : label10.Text = "It's a tie!"; break;
                case 'O' : label10.Text = "O Wins!"; break;
                case 'X' : label10.Text = "X Wins!"; break;
                default: label10.Text = "This will never appear"; break;
            }
        }

        private char checkWinner()
        {
            //return either 'T' for tie, 'O' for O wins, and 'X' for X wins
            char winner = ' ';
            int winning_line = 0;
            //check for a row win
            if(cell[0].Equals(cell[1]) && cell[0].Equals(cell[2]))
            {
                winning_line++;
                winner = cell[0];
            }
            if (cell[3].Equals(cell[4]) && cell[3].Equals(cell[5]))
            {
                winning_line++;
                winner = cell[3];
            }
            if (cell[6].Equals(cell[7]) && cell[6].Equals(cell[8]))
            {
                winning_line++;
                winner = cell[6];
            }

            //check for column wins
            if (cell[0].Equals(cell[3]) && cell[0].Equals(cell[6]))
            {
                winning_line++;
                winner = cell[0];
            }
            if (cell[1].Equals(cell[4]) && cell[1].Equals(cell[7]))
            {
                winning_line++;
                winner = cell[1];
            }
            if (cell[2].Equals(cell[5]) && cell[2].Equals(cell[8]))
            {
                winning_line++;
                winner = cell[2];
            }
            //check for diagonal winner
            if (cell[0].Equals(cell[4]) && cell[0].Equals(cell[8]))
            {
                winning_line++;
                winner = cell[0];
            }
            if (cell[2].Equals(cell[4]) && cell[2].Equals(cell[8]))
            {
                winning_line++;
                winner = cell[2];
            }

            if (winning_line == 0 || winning_line > 1)
            winner = 'T';

            return winner;
        }

        public int i { get; set; }
    }
}

3voto

SteveP Points 8509
if (winning_line == 0 || winning_line > 1)

S'il y a deux lignes, il y aura égalité. Si vous voulez vous arrêter lorsqu'une ligne est formée, vous devez vérifier s'il y a un gagnant après chaque coup, et non après que tout le plateau ait été rempli.

2voto

MrFox Points 1492

Le deuxième chèque gagnant diagonal devrait être de 6 au lieu de 8.

Vous êtes en train de vérifier :
X O O
O X O
O O X

et :
O O X
O X O
O O X

Il est évident que le dernier x doit être à gauche.

En outre, comme d'autres l'ont déjà fait, il est possible d'obtenir des informations supplémentaires. Faire deux lignes ne devrait pas entraîner une égalité. Un joueur peut même faire deux lignes tout seul, ce qui entraîne une égalité.
Modifiez la fonction pour qu'elle renvoie un résultat dès qu'elle trouve une ligne gagnante et qu'elle le vérifie après chaque coup.

1voto

Foemilod Points 125

Ça marche : Vous devez vous débarrasser de la...

si (ligne_gagnante == 0 || ligne_gagnante > 1)

remplacez cette ligne de code par ces trois morceaux de code :

    if (winnerX == " X ")
    {
        theWinner = winnerX;
    }
    if (winnerO == " O ")
    {
        theWinner = winnerO;
    }
    if(winnerX == " X " && winnerO == " O ")
    {
        winnerT = " T ";
        theWinner = winnerT;
    }

Donc ce que j'ai fait, c'est changer quelques trucs. Je n'ai pas utilisé le bout de code "winning_line++ ;". A la place, j'ai fait quelque chose comme ça pour chacune des vérifications de l'instruction if.

    if (cell[2, 0].Equals(cell[1, 1]) && cell[2, 0].Equals(cell[0, 2]))
        {
            if (cell[2, 0] == 0)
            {
                winnerX = " X ";
            }

            else if (cell[2, 0] == 1)
            {
                winnerO = " O ";
            }
        }

J'ai donc 4 chaînes que j'utilise, une pour garder la trace si X a une ligne gagnante, de même pour O. J'ai ensuite la chaîne winnerT pour garder la trace de l'égalité. Elle est seulement utilisée à la place de l'ancienne déclaration de vérification de l'égalité.

Vous devrez également modifier votre instruction switch si vous décidez d'utiliser des chaînes de caractères au lieu d'entiers, par exemple

    switch (checkWinner())
        {
            case " X ": 
                textBox1.Text = "X Wins!";
                break;
            case " O ":
                textBox1.Text = "O Wins!";
                break;
            case " T ": 
                textBox1.Text = "It's a tie!";
                break;
        }

0voto

Thomas Points 662

Je pense que vous devriez avoir une fonction qui, étant donné une grille et un nouveau pion, vous dise si la partie est terminée. Ensuite, si la partie est terminée, vous savez que le gagnant est le dernier pion joué.

Je pense que le projet Open source MikMak de Marthyi a une implémentation parfaite de cela, voir

bool IsFinished(Grid currentState, Pawn newPawn)

dans :

https://github.com/Marthyi/MikMak/blob/master/MikMakSolution/Morpion/MorpionManager.cs

Bonne chance !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X