/// <summary> /// Détermine si un déplacement est permis /// </summary> /// <param name="pointDepart">Coordonnée de départ</param> /// <param name="pointCible">Coordonnée de cible</param> /// <returns>Si le déplacement est permis</returns> public bool EstDeplacementPermis(Coordonnee pointDepart, Coordonnee pointCible) { return(EstCoordonneeValide(pointDepart) && EstCoordonneeValide(pointCible) && !EstCoordonneeLac(pointDepart) && !EstCoordonneeLac(pointCible) && GrilleCases[pointDepart.X][pointDepart.Y].EstDeplacementLegal(GrilleCases[pointCible.X][pointCible.Y]) ); }
/// <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> /// Effectue un déplacement /// </summary> /// <param name="pointDepart">Coordonnée de départ</param> /// <param name="pointCible">Coordonnée de cible</param> /// <returns>Les pièce éliminées (dans un objet de transport)</returns> public ReponseDeplacement ResoudreDeplacement(Coordonnee pointDepart, Coordonnee pointCible) { ReponseDeplacement reponse = new ReponseDeplacement(); CaseJeu caseDepart, caseCible; if (EstCoordonneeValide(pointDepart) && EstCoordonneeValide(pointCible)) { caseDepart = GrilleCases[pointDepart.X][pointDepart.Y]; caseCible = GrilleCases[pointCible.X][pointCible.Y]; if (caseDepart.EstOccupe() && EstDeplacementPermis(pointDepart, pointCible)) { // Faire le déplacement. reponse.PiecesEliminees = caseCible.ResoudreAttaque(caseDepart.Occupant, CouleurJoueur); caseDepart.Occupant = null; reponse.DeplacementFait = true; } else { reponse.DeplacementFait = false; } } else { reponse.DeplacementFait = false; } return(reponse); }
/// <summary> /// Construit un coup coté /// </summary> /// <param name="attaquant">Coordonnée de l'attaquant</param> /// <param name="cible">Coordonnée de la cible</param> /// <param name="jeu">Grille du jeu</param> /// <param name="couleurIA">Couleur de l'intelligence artificielle</param> public CoupCote(Coordonnee attaquant, Coordonnee cible, GrilleJeu jeu, Couleur couleurIA) { Jeu = jeu; CouleurIA = couleurIA; Attaquant = attaquant; Cible = cible; PieceAttaquant = jeu.ObtenirPiece(attaquant); PieceCible = jeu.ObtenirPiece(cible); CalculerCote(); }
/// <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> /// Détermine la position d'une pièce selon la stratégie /// </summary> /// <returns>Coordonnée de la position du coup à faire</returns> public override Coordonnee GetPosition() { // Si on n'a pas trouvé le drapeau, le trouver if (!DrapeauTrouve) { for (int x = 0; x < Largeur; x++) { for (int y = 0; y < Hauteur; y++) { if (Pieces[x, y] is Drapeau) { PositionDrapeau = new Coordonnee(x, y); DrapeauTrouve = true; } } } } List <Coordonnee> positionsPossibles = new List <Coordonnee>(); if (Pieces[PositionDrapeau.X - 1, 0] == null) { positionsPossibles.Add(new Coordonnee(PositionDrapeau.X - 1, 0)); } if (Pieces[PositionDrapeau.X, 1] == null) { positionsPossibles.Add(new Coordonnee(PositionDrapeau.X, 1)); } if (Pieces[PositionDrapeau.X + 1, 0] == null) { positionsPossibles.Add(new Coordonnee(PositionDrapeau.X + 1, 0)); } return(positionsPossibles.Count > 0 ? positionsPossibles[Aleatoire.Next(positionsPossibles.Count)] : new StrategiePlacementPieceAleatoire(Pieces, Largeur, Hauteur).GetPosition()); }
/// <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> /// Détermine le placement des pièces (en début de partie) /// </summary> /// <returns>Liste de pièces à placer</returns> public List <Piece> PlacerPieces() { Piece[,] pieces = new Piece[LARGEUR_ZONE_DEPART, HAUTEUR_ZONE_DEPART]; // Générateurs de pièces List <GenerateurPiece> generateursPieces = new List <GenerateurPiece> { new GenerateurDrapeau(), new GenerateurMarechal(), new GenerateurBombe(), new GenerateurGeneral(), new GenerateurColonel(), new GenerateurCommandant(), new GenerateurCapitaine(), new GenerateurLieutenant(), new GenerateurSergent(), new GenerateurDemineur(), new GenerateurEclaireur(), new GenerateurEspion() }; // Pile de stratégies List <StrategiePlacementPiece> strategies = new List <StrategiePlacementPiece> { new StrategiePlacementPieceDrapeau(pieces, LARGEUR_ZONE_DEPART, HAUTEUR_ZONE_DEPART), new StrategiePlacementPieceMarechal(pieces, LARGEUR_ZONE_DEPART, HAUTEUR_ZONE_DEPART), new StrategiePlacementPieceBombe(pieces, LARGEUR_ZONE_DEPART, HAUTEUR_ZONE_DEPART), new StrategiePlacementPieceAleatoire(pieces, LARGEUR_ZONE_DEPART, HAUTEUR_ZONE_DEPART), new StrategiePlacementPieceAleatoire(pieces, LARGEUR_ZONE_DEPART, HAUTEUR_ZONE_DEPART), new StrategiePlacementPieceAleatoire(pieces, LARGEUR_ZONE_DEPART, HAUTEUR_ZONE_DEPART), new StrategiePlacementPieceAleatoire(pieces, LARGEUR_ZONE_DEPART, HAUTEUR_ZONE_DEPART), new StrategiePlacementPieceAleatoire(pieces, LARGEUR_ZONE_DEPART, HAUTEUR_ZONE_DEPART), new StrategiePlacementPieceAleatoire(pieces, LARGEUR_ZONE_DEPART, HAUTEUR_ZONE_DEPART), new StrategiePlacementPieceAleatoire(pieces, LARGEUR_ZONE_DEPART, HAUTEUR_ZONE_DEPART), new StrategiePlacementPieceAleatoire(pieces, LARGEUR_ZONE_DEPART, HAUTEUR_ZONE_DEPART), new StrategiePlacementPieceAleatoire(pieces, LARGEUR_ZONE_DEPART, HAUTEUR_ZONE_DEPART) }; // Exécuter les stratégies en cascade for (int i = 0; i < generateursPieces.Count; i++) { while (generateursPieces[i].EstGenerable()) { Coordonnee position = strategies[i].GetPosition(); pieces[position.X, position.Y] = generateursPieces[i].GenererPiece(Couleur); } } // Copier les pièces dans une liste List <Piece> lstPieces = new List <Piece>(); for (int y = 0; y < HAUTEUR_ZONE_DEPART; y++) { for (int x = 0; x < LARGEUR_ZONE_DEPART; x++) { lstPieces.Add(pieces[x, y]); } } return(lstPieces); }
/// <summary> /// Obtenir la couleur d'une pièce /// </summary> /// <param name="p">La coordonnée de la case où se trouve la pièce</param> /// <returns>La couleur de la pièce</returns> public Couleur ObtenirCouleurPiece(Coordonnee p) { return(GrilleCases[p.X][p.Y].Occupant.Couleur); }
/// <summary> /// Obtenir l'occupant d'une case spécifiée /// </summary> /// <param name="p">La coordonnée de la case</param> /// <returns>La pièce occupant la case</returns> public Piece ObtenirPiece(Coordonnee p) { return(GrilleCases[p.X][p.Y].Occupant); }
/// <summary> /// Détermine si la case à une coordonnée est occupée /// </summary> /// <param name="p">La coordonnée de la case à tester</param> /// <returns>Si la case est occupée</returns> public bool EstCaseOccupee(Coordonnee p) { return((GrilleCases[(int)p.X][(int)p.Y]).EstOccupe()); }
/// <summary> /// Détermine si une coordonnée est un lac (coordonnées : I (2, 3, 6, 7) - J (4, 5)) /// </summary> /// <param name="p">La coordonnée à tester</param> /// <returns>Si la coordonnée est un lac</returns> public bool EstCoordonneeLac(Coordonnee p) => ((p.X == 2 || p.X == 3 || p.X == 6 || p.X == 7) && (p.Y == 4 || p.Y == 5));
/// <summary> /// Détermine si une coordonnée est valide /// </summary> /// <param name="p">Coordonnée à tester</param> /// <returns>Si la coordonnée est valide</returns> private bool EstCoordonneeValide(Coordonnee p) => ((p.X >= 0 && p.X < TAILLE_GRILLE_JEU) && (p.Y >= 0 && p.Y < TAILLE_GRILLE_JEU));