/// <summary>
        /// Crée les affichages des pièces
        /// </summary>
        private void InitialiserAffichagePieces()
        {
            Coordonnee position;
            Rectangle  imageAffichage;

            GrillePieces = new List <List <Rectangle> >();

            for (int i = 0; i < GrilleJeu.TAILLE_GRILLE_JEU; i++)
            {
                GrillePieces.Add(new List <Rectangle>());

                for (int j = 0; j < GrilleJeu.TAILLE_GRILLE_JEU; j++)
                {
                    position = new Coordonnee(i, j);

                    if (GrillePartie.EstCaseOccupee(position))
                    {
                        imageAffichage = CreerAffichagePiece(GrillePartie.ObtenirPiece(position));

                        Grid.SetColumn(imageAffichage, i);
                        Grid.SetRow(imageAffichage, j);

                        grdPartie.Children.Add(imageAffichage);

                        GrillePieces[i].Add(imageAffichage);
                    }
                    else
                    {
                        GrillePieces[i].Add(null);
                    }
                }
            }
        }
        /// <summary>
        /// S'exécute lorsque l'on clique sur une case.
        /// </summary>
        /// <param name="sender">Objet appelant</param>
        /// <param name="e">Arguments</param>
        private void ResoudreSelectionCase(object sender, MouseButtonEventArgs e)
        {
            Rectangle caseSelectionnee = (Rectangle)sender;

            Coordonnee pointSelectionne = new Coordonnee(Grid.GetColumn(caseSelectionnee), Grid.GetRow(caseSelectionnee));
            Coordonnee pointActif;

            ReponseDeplacement reponse;

            // Tour du joueur
            if (TourJeu == CouleurJoueurs.CouleurJoueur)
            {
                if (grdPartie.Children.Contains(SelectionActive))
                {
                    pointActif = new Coordonnee(Grid.GetColumn(SelectionActive), Grid.GetRow(SelectionActive));

                    if (pointSelectionne == pointActif)
                    {
                        grdPartie.Children.Remove(SelectionActive);
                    }
                    else
                    {
                        reponse = ExecuterCoup(pointActif, pointSelectionne);

                        if (reponse.DeplacementFait)
                        {
                            grdPartie.Children.Remove(SelectionActive);
                        }
                    }
                }
                else
                {
                    if (GrillePartie.EstCaseOccupee(pointSelectionne) &&
                        GrillePartie.ObtenirCouleurPiece(pointSelectionne) == CouleurJoueurs.CouleurJoueur)
                    {
                        Grid.SetColumn(SelectionActive, pointSelectionne.X);
                        Grid.SetRow(SelectionActive, pointSelectionne.Y);

                        grdPartie.Children.Add(SelectionActive);
                    }
                }
            }
        }
        /// <summary>
        /// Crée une texture à mettre au fond d'une case
        /// </summary>
        /// <param name="colonne">Position abscisse</param>
        /// <param name="rangee">Position ordonnée</param>
        /// <returns>La texture</returns>
        private Rectangle CreerFondCase(int colonne, int rangee)
        {
            Rectangle rect = new Rectangle();

            rect.Width  = TAILLE_CASES_GRILLE;
            rect.Height = TAILLE_CASES_GRILLE;

            if (GrillePartie.EstCoordonneeLac(new Coordonnee(colonne, rangee)))
            {
                rect.Fill = new ImageBrush(new BitmapImage(new Uri("textures/lake.png", UriKind.Relative)));
            }
            else
            {
                rect.Fill = new ImageBrush(new BitmapImage(new Uri("textures/terrain.png", UriKind.Relative)));
            }

            Grid.SetZIndex(rect, 0);
            Grid.SetColumn(rect, colonne);
            Grid.SetRow(rect, rangee);

            return(rect);
        }
        /// <summary>
        /// Détermine si le joueur peut jouer (s'il a des coups disponibles)
        /// </summary>
        /// <returns>Si le joueur peut jouer</returns>
        private bool JoueurACoupsPermis()
        {
            List <CoupCote> listeCoups = new List <CoupCote>();
            Coordonnee      pointDepart, pointCible;

            for (int i = 0; i < GrilleJeu.TAILLE_GRILLE_JEU; i++)
            {
                for (int j = 0; j < GrilleJeu.TAILLE_GRILLE_JEU; j++)
                {
                    pointDepart = new Coordonnee(i, j);

                    if (GrillePartie.EstCaseOccupee(pointDepart) &&
                        GrillePartie.ObtenirCouleurPiece(pointDepart) == CouleurJoueurs.CouleurJoueur)
                    {
                        if (GrillePartie.ObtenirPiece(pointDepart) is Eclaireur)
                        {
                            // Valider les coups vers la gauche.
                            for (int k = pointDepart.X; k >= 0; k--)
                            {
                                pointCible = new Coordonnee(k, pointDepart.Y);
                                if (GrillePartie.EstDeplacementPermis(pointDepart, pointCible))
                                {
                                    listeCoups.Add(new CoupCote(pointDepart, pointCible, GrillePartie, CouleurJoueurs.CouleurJoueur));
                                }
                            }
                            // Valider les coups vers le haut.
                            for (int k = pointDepart.Y; k >= 0; k--)
                            {
                                pointCible = new Coordonnee(pointDepart.X, k);
                                if (GrillePartie.EstDeplacementPermis(pointDepart, pointCible))
                                {
                                    listeCoups.Add(new CoupCote(pointDepart, pointCible, GrillePartie, CouleurJoueurs.CouleurJoueur));
                                }
                            }
                            // Valider les coups vers la droite.
                            for (int k = pointDepart.X; k < GrilleJeu.TAILLE_GRILLE_JEU; k++)
                            {
                                pointCible = new Coordonnee(k, pointDepart.Y);
                                if (GrillePartie.EstDeplacementPermis(pointDepart, pointCible))
                                {
                                    listeCoups.Add(new CoupCote(pointDepart, pointCible, GrillePartie, CouleurJoueurs.CouleurJoueur));
                                }
                            }
                            // Valider les coups vers le bas.
                            for (int k = pointDepart.Y; k < GrilleJeu.TAILLE_GRILLE_JEU; k++)
                            {
                                pointCible = new Coordonnee(k, pointDepart.Y);
                                if (GrillePartie.EstDeplacementPermis(pointDepart, pointCible))
                                {
                                    listeCoups.Add(new CoupCote(pointDepart, pointCible, GrillePartie, CouleurJoueurs.CouleurJoueur));
                                }
                            }
                        }
                        else
                        {
                            // Valider un coup vers la gauche.
                            pointCible = new Coordonnee(pointDepart.X - 1, pointDepart.Y);
                            if (GrillePartie.EstDeplacementPermis(pointDepart, pointCible))
                            {
                                listeCoups.Add(new CoupCote(pointDepart, pointCible, GrillePartie, CouleurJoueurs.CouleurJoueur));
                            }

                            // Valider un coup vers l'avant.
                            pointCible = new Coordonnee(pointDepart.X, pointDepart.Y - 1);
                            if (GrillePartie.EstDeplacementPermis(pointDepart, pointCible))
                            {
                                listeCoups.Add(new CoupCote(pointDepart, pointCible, GrillePartie, CouleurJoueurs.CouleurJoueur));
                            }

                            // Valider un coup vers la droite.
                            pointCible = new Coordonnee(pointDepart.X + 1, pointDepart.Y);
                            if (GrillePartie.EstDeplacementPermis(pointDepart, pointCible))
                            {
                                listeCoups.Add(new CoupCote(pointDepart, pointCible, GrillePartie, CouleurJoueurs.CouleurJoueur));
                            }

                            // Valider un coup vers l'arrière.
                            pointCible = new Coordonnee(pointDepart.X, pointDepart.Y + 1);
                            if (GrillePartie.EstDeplacementPermis(pointDepart, pointCible))
                            {
                                listeCoups.Add(new CoupCote(pointDepart, pointCible, GrillePartie, CouleurJoueurs.CouleurJoueur));
                            }
                        }
                    }
                }
            }

            return(listeCoups.Count > 0);
        }
        /// <summary>
        /// Exécuter un coup
        /// </summary>
        /// <param name="caseDepart">Case de départ</param>
        /// <param name="caseCible">Case de cible</param>
        /// <returns></returns>
        public ReponseDeplacement ExecuterCoup(Coordonnee caseDepart, Coordonnee caseCible)
        {
            if (EstPartieTerminee)
            {
                return(new ReponseDeplacement());
            }

            Thread executionIA = new Thread(LancerIA);

            ReponseDeplacement reponse = new ReponseDeplacement();

            Piece     attaquant;
            Rectangle affichageAttaquant;

            Piece     cible;
            Rectangle affichageCible;

            if (caseCible != caseDepart)
            {
                // Prendre les informations avant de faire le coup.
                attaquant          = GrillePartie.ObtenirPiece(caseDepart);
                affichageAttaquant = GrillePieces[caseDepart.X][caseDepart.Y];

                cible          = GrillePartie.ObtenirPiece(caseCible);
                affichageCible = GrillePieces[caseCible.X][caseCible.Y];

                if (GrillePartie.EstDeplacementPermis(caseDepart, caseCible) && cible != null && attaquant != null && !attaquant.EstVisible)
                {
                    affichageAttaquant.Fill = new ImageBrush(
                        new BitmapImage(
                            new Uri(
                                "sprites/" + (attaquant.EstDeCouleur(Couleur.Rouge) ? "Rouge/" : "Bleu/") + attaquant.Nom + ".png",
                                UriKind.Relative
                                )
                            )
                        );
                    attaquant.EstVisible = true;
                }
                if (GrillePartie.EstDeplacementPermis(caseDepart, caseCible) && cible != null && !cible.EstVisible)
                {
                    affichageCible.Fill = new ImageBrush(
                        new BitmapImage(
                            new Uri(
                                "sprites/" + (cible.EstDeCouleur(Couleur.Rouge) ? "Rouge/" : "Bleu/") + cible.Nom + ".png",
                                UriKind.Relative
                                )
                            )
                        );
                    cible.EstVisible = true;
                }

                reponse = GrillePartie.ResoudreDeplacement(caseDepart, caseCible);

                foreach (Piece piece in reponse.PiecesEliminees)
                {
                    if (piece.EstDeCouleur(CouleurJoueurs.CouleurIA))
                    {
                        ConteneurPiecesCapturees.AjouterPiece(piece);
                    }
                }

                if (reponse.DeplacementFait)
                {
                    // Retrait de la pièce attaquante de sa position d'origine.
                    grdPartie.Children.Remove(affichageAttaquant);
                    GrillePieces[caseDepart.X][caseDepart.Y] = null;

                    if (reponse.PiecesEliminees.Count == 2)
                    {
                        // Retrait de la pièce attaquée.
                        grdPartie.Children.Remove(GrillePieces[caseCible.X][caseCible.Y]);
                        GrillePieces[caseCible.X][caseCible.Y] = null;
                    }
                    else if (reponse.PiecesEliminees.Count == 1 && reponse.PiecesEliminees[0] != attaquant ||
                             reponse.PiecesEliminees.Count == 0)
                    {
                        // Remplacement de la pièce attaquée par la pièce attaquante.
                        grdPartie.Children.Remove(GrillePieces[caseCible.X][caseCible.Y]);
                        GrillePieces[caseCible.X][caseCible.Y] = null;

                        GrillePieces[caseCible.X][caseCible.Y] = affichageAttaquant;

                        Grid.SetColumn(affichageAttaquant, caseCible.X);
                        Grid.SetRow(affichageAttaquant, caseCible.Y);
                        grdPartie.Children.Add(affichageAttaquant);
                    }

                    if (EstDebutPartie)
                    {
                        EstDebutPartie = false;
                    }

                    // Permet de faire jouer l'IA.
                    if (TourJeu == CouleurJoueurs.CouleurJoueur)
                    {
                        executionIA.Start();
                    }
                    ChangerTourJeu();
                }
            }
            else
            {
                reponse.DeplacementFait = false;
            }

            // Si le joueur ne peut plus jouer, l'IA gagne.
            if (!JoueurACoupsPermis())
            {
                ((JeuStrategoControl)GestionnaireEcransJeu.GetEcranPresent()).TerminerPartie();
                MessageBox.Show("Vous avez perdu (plus de mouvements possibles)...", "Échec");
            }

            return(reponse);
        }
 /// <summary>
 /// Cette méthode existe principalement pour que le jeu soit testable.
 /// On ne veut évidemment pas toujours commencer une partie avec exactement les même positions.
 /// </summary>
 /// <param name="pieces">Les pièces à positionner</param>
 /// <returns>Si les pièces à positionner sont valides (bon nombre de chaque et bonnes couleurs)</returns>
 private bool PositionnerPieces(List <Piece> pieces)
 {
     return(GrillePartie.PositionnerPieces(pieces, CouleurJoueurs.CouleurJoueur) &&
            GrillePartie.PositionnerPieces(IA.PlacerPieces(), CouleurJoueurs.CouleurIA));
 }