/**
  * Place un personnage sur le plateau
  *
  * @param j joueur qui va placer les personnages
  * @param idPersonnage numero du personnage dans l'équipe du joueur
  * @param positionCaseSelectionné position de la case à placer le joueur
  * @throws CaseNonVide Exception
  * @throws CaseAdverse Exception
  */
 public void placerPersonnage(Joueur j, int idPersonnage, int[] positionCaseSelectionné)
     throws CaseNonVide, CaseAdverse {
   if (plateau.caseEstVide(positionCaseSelectionné)) {
     if (j == joueur1 && positionCaseSelectionné[0] < TaillePlateauX / 2
         || j == joueur2 && positionCaseSelectionné[0] >= (TaillePlateauX - TaillePlateauX / 2)) {
       Personnage p = j.getPersonnage(idPersonnage);
       p.setPosition(positionCaseSelectionné);
       plateau.poser(p, positionCaseSelectionné);
     } else throw new CaseAdverse();
   } else {
     throw new CaseNonVide();
   }
 }
  /** Met à jour les personnages s'ils sont KO */
  public void MAJPVPersonnage() {
    for (Personnage p : joueur1.getEquipe()) {
      if (p.isPointVieEgal0() && !p.isKO()) {
        p.setKO();
        Case c = plateau.getCase(p.getPosition());
        c.liberer();
      }
    }

    for (Personnage p : joueur2.getEquipe()) {
      if (p.isPointVieEgal0() && !p.isKO()) {
        p.setKO();
        Case c = plateau.getCase(p.getPosition());
        c.liberer();
      }
    }
  }
 /** Met à jour l'état des personnages de l'équipe du joueur courant */
 public void majEtatPersonnage() {
   int numTour = getTour().getNumeroTour();
   for (Personnage p : getJoueurCourant().getEquipe()) {
     if (p.isRalenti() && p.getnumTourRalenti() <= numTour) p.hasNormal();
     if (p.hasDefense() && p.getnumTourDefense() <= numTour) p.finDefense();
   }
 }
 /**
  * Routine graphique permettant de ne plus voir les cases où l'on peut effectuer l'action
  *
  * @param idActionSelectionné action à effectuer
  */
 public void IhmFinVoirCasePossibleAction(int idActionSelectionné) {
   for (int[] pos : this.VoisinageCaseAction(idActionSelectionné)) {
     if (this.getCase(pos).estVide()) ihmjeu.getGuiCase(pos).setBackground(Color.WHITE);
     else if (this.comparepositionCaseSelectionné(personnageSelectionné.getPosition(), pos))
       ihmjeu.getGuiCase(pos).setBackground(Color.YELLOW);
     else if (this.joueur1.possedePersonnage(this.getCase(pos).getPersonnage()))
       ihmjeu.getGuiCase(pos).setBackground(this.joueur1.getColor());
     else if (this.joueur2.possedePersonnage(this.getCase(pos).getPersonnage()))
       ihmjeu.getGuiCase(pos).setBackground(this.joueur2.getColor());
   }
 }
 /** Routine graphique de la fin du Tour */
 public void IhmFinTour() {
   ihmjeu
       .getGuiCase(personnageSelectionné.getPosition())
       .setBackground(getJoueurCourant().getColor());
   this.finTour();
   ihmjeu.getCommande2().setVisible(false);
   ihmjeu.remove(ihmjeu.getCommande2());
   ihmjeu.setCommande2(new IHMCommandeVue2(ihmjeu, this));
   ihmjeu.getContentPane().add(ihmjeu.getCommande2(), BorderLayout.SOUTH);
   ihmjeu.afficherTerminal("Selectionner un Personnage");
   this.setPhase(Phase.SELECTION_PERSONNAGE);
 }
  /**
   * Utilise l'action du personnage selectionné
   *
   * @param p personnage selectionné
   * @param idActionSelectionné action selectionné
   * @param positionCaseSelectionné position de la case où l'on veut lancer l'attaque
   */
  public void personnageAction(
      Personnage p, int idActionSelectionné, int[] positionCaseSelectionné) {
    Class<?> c = p.getAction(idActionSelectionné);
    typePortee tp;
    try {
      Constructor<?> constructeur = c.getConstructor(new Class[] {Personnage.class, Jeu.class});
      tp = (typePortee) c.getMethod("getTypePortee").invoke(c);
      if (tp == typePortee.CIBLE) {
        for (int[] tc : this.VoisinageCaseZoneCible(positionCaseSelectionné)) {
          if (plateau.caseGetPersonnage(tc) != null)
            constructeur.newInstance(new Object[] {plateau.caseGetPersonnage(tc), this});
        }
      } else if (plateau.caseGetPersonnage(positionCaseSelectionné) != null) {
        constructeur.newInstance(
            new Object[] {plateau.caseGetPersonnage(positionCaseSelectionné), this});
      }

    } catch (Exception e) {
    }
  }
  /**
   * Retourne les cases où l'on peut utiliser l'action pour le personnage selectionné
   *
   * @param idActionSelectionné numéro de l'action selectionné
   * @return les cases où l'on peut utiliser l'action pour le personnage selectionné
   */
  public ArrayList<int[]> VoisinageCaseAction(int idActionSelectionné) {
    boolean[] obstacle = {false, false, false, false};
    ArrayList<int[]> voisinage = new ArrayList<int[]>();
    Class<?> c = personnageSelectionné.getAction(idActionSelectionné);
    int pmMin = 0;
    int pmMax = 0;
    Action.typePortee tp;
    try {
      tp = (typePortee) c.getMethod("getTypePortee").invoke(c);
      pmMin = (Integer) c.getMethod("getPorteeMin").invoke(c);
      if (tp == Action.typePortee.NORMAL) pmMax = (Integer) c.getMethod("getPorteeMax").invoke(c);
      else if (tp == Action.typePortee.CIBLE) pmMax = Math.min(TaillePlateauX, TaillePlateauY) / 2;
      else if (tp == Action.typePortee.SELF) {
        voisinage.add(personnageSelectionné.getPosition());
        return voisinage;
      }
      int x = personnageSelectionné.getPosition()[0];
      int y = personnageSelectionné.getPosition()[1];
      for (int i = 1; i <= pmMax; i++) {
        if (x - i >= 0) {
          int[] positionCaseSelectionné = {x - i, y};
          if (!obstacle[0] && !this.getCase(positionCaseSelectionné).estVide()) {
            obstacle[0] = true;
            if (i >= pmMin) {
              voisinage.add(positionCaseSelectionné);
            }
          } else if (!obstacle[0] && this.getCase(positionCaseSelectionné).estVide()) {
            if (i >= pmMin) {
              voisinage.add(positionCaseSelectionné);
            }
          } else if (personnageSelectionné.getSaitVoler() && obstacle[0]) {
            if (i >= pmMin) {
              voisinage.add(positionCaseSelectionné);
            }
          }
        }

        if (x + i < TaillePlateauX) {
          int[] positionCaseSelectionné = {x + i, y};
          if (!obstacle[1] && !this.getCase(positionCaseSelectionné).estVide()) {
            obstacle[1] = true;
            if (i >= pmMin) {
              voisinage.add(positionCaseSelectionné);
            }
          } else if (!obstacle[1] && this.getCase(positionCaseSelectionné).estVide()) {
            if (i >= pmMin) {
              voisinage.add(positionCaseSelectionné);
            }
          } else if (personnageSelectionné.getSaitVoler() && obstacle[1]) {
            if (i >= pmMin) {
              voisinage.add(positionCaseSelectionné);
            }
          }
        }

        if (y - i >= 0) {
          int[] positionCaseSelectionné = {x, y - i};
          if (!obstacle[2] && !this.getCase(positionCaseSelectionné).estVide()) {
            obstacle[2] = true;
            if (i >= pmMin) {
              voisinage.add(positionCaseSelectionné);
            }
          } else if (!obstacle[2] && this.getCase(positionCaseSelectionné).estVide()) {
            if (i >= pmMin) {
              voisinage.add(positionCaseSelectionné);
            }
          } else if (personnageSelectionné.getSaitVoler() && obstacle[2]) {
            if (i >= pmMin) {
              voisinage.add(positionCaseSelectionné);
            }
          }
        }

        if (y + i < TaillePlateauY) {
          int[] positionCaseSelectionné = {x, y + i};
          if (!obstacle[3] && !this.getCase(positionCaseSelectionné).estVide()) {
            obstacle[3] = true;
            if (i >= pmMin) {
              voisinage.add(positionCaseSelectionné);
            }
          } else if (!obstacle[3] && this.getCase(positionCaseSelectionné).estVide()) {
            if (i >= pmMin) {
              voisinage.add(positionCaseSelectionné);
            }
          } else if (personnageSelectionné.getSaitVoler() && obstacle[3]) {
            if (i >= pmMin) {
              voisinage.add(positionCaseSelectionné);
            }
          }
        }
      }
    } catch (Exception e) {
    }
    return voisinage;
  }
 /**
  * Retourne un booléen si l'equipe du joueur est KO
  *
  * @param j joueur à verifier
  * @return <code>true</code> si l'équipe est KO; <code>false</code> sinon
  */
 public boolean verifieEquipeKO(Joueur j) {
   for (Personnage p : j.getEquipe()) {
     if (!p.isKO()) return false;
   }
   return true;
 }
 /**
  * Deplace un personnage
  *
  * @param p personnage à déplacer
  * @param positionCaseSelectionné nouvelle position du personnage à déplacer
  */
 public void deplacerPersonnage(Personnage p, int[] positionCaseSelectionné) {
   plateau.libererCase(p.getPosition());
   p.deplacer(positionCaseSelectionné);
   plateau.poser(p, positionCaseSelectionné);
   this.hasDéplacé();
 }
  /**
   * Retourne les cases où l'on peut deplacer le personnage selectionné
   *
   * @param p personnage selectionné
   * @return les cases où l'on peut deplacer le personnage selectionné
   */
  public ArrayList<int[]> VoisinageCaseDeplacement(Personnage p) {
    boolean[] obstacle = {false, false, false, false, false, false, false, false};
    ArrayList<int[]> voisinage = new ArrayList<int[]>();
    int x = p.getPosition()[0];
    int y = p.getPosition()[1];
    int pm = p.getPointMouvement();
    int pmd = p.getPointMouvementDiagonale();

    for (int i = 1; i <= pm; i++) {
      if (x - i >= 0) {
        int[] positionCaseSelectionné = {x - i, y};
        if (!obstacle[0] && !this.getCase(positionCaseSelectionné).estVide()) obstacle[0] = true;
        else if (!obstacle[0] && this.getCase(positionCaseSelectionné).estVide())
          voisinage.add(positionCaseSelectionné);
        else if (p.getSaitVoler() && obstacle[0] && this.getCase(positionCaseSelectionné).estVide())
          voisinage.add(positionCaseSelectionné);
      }

      if (x + i < TaillePlateauX) {
        int[] positionCaseSelectionné = {x + i, y};
        if (!obstacle[1] && !this.getCase(positionCaseSelectionné).estVide()) obstacle[1] = true;
        else if (!obstacle[1] && this.getCase(positionCaseSelectionné).estVide())
          voisinage.add(positionCaseSelectionné);
        else if (p.getSaitVoler() && obstacle[1] && this.getCase(positionCaseSelectionné).estVide())
          voisinage.add(positionCaseSelectionné);
      }

      if (y - i >= 0) {
        int[] positionCaseSelectionné = {x, y - i};
        if (!obstacle[2] && !this.getCase(positionCaseSelectionné).estVide()) obstacle[2] = true;
        else if (!obstacle[2] && this.getCase(positionCaseSelectionné).estVide())
          voisinage.add(positionCaseSelectionné);
        else if (p.getSaitVoler() && obstacle[2] && this.getCase(positionCaseSelectionné).estVide())
          voisinage.add(positionCaseSelectionné);
      }

      if (y + i < TaillePlateauY) {
        int[] positionCaseSelectionné = {x, y + i};
        if (!obstacle[3] && !this.getCase(positionCaseSelectionné).estVide()) obstacle[3] = true;
        else if (!obstacle[3] && this.getCase(positionCaseSelectionné).estVide())
          voisinage.add(positionCaseSelectionné);
        else if (p.getSaitVoler() && obstacle[3] && this.getCase(positionCaseSelectionné).estVide())
          voisinage.add(positionCaseSelectionné);
      }
    }

    if (pmd != 0) {
      for (int i = 1; i <= pmd; i++) {

        int[] positionCaseSelectionné0 = {x - i, y - i};
        int[] positionCaseSelectionné1 = {x - i, y + i};
        int[] positionCaseSelectionné2 = {x + i, y + i};
        int[] positionCaseSelectionné3 = {x + i, y - i};
        if (x - i >= 0 && y - i >= 0) {
          if (!obstacle[4] && this.getCase(positionCaseSelectionné0).estVide())
            voisinage.add(positionCaseSelectionné0);
          else if (!obstacle[4] && !this.getCase(positionCaseSelectionné0).estVide())
            obstacle[4] = true;
          else if (obstacle[4]
              && p.getSaitVoler()
              && this.getCase(positionCaseSelectionné0).estVide())
            voisinage.add(positionCaseSelectionné0);
        }
        if (x - i >= 0 && y + i < TaillePlateauY) {
          if (!obstacle[5] && this.getCase(positionCaseSelectionné1).estVide())
            voisinage.add(positionCaseSelectionné1);
          else if (!obstacle[5] && !this.getCase(positionCaseSelectionné1).estVide())
            obstacle[5] = true;
          else if (obstacle[5]
              && p.getSaitVoler()
              && this.getCase(positionCaseSelectionné1).estVide())
            voisinage.add(positionCaseSelectionné1);
        }
        if (x + i < TaillePlateauX && y + i < TaillePlateauY) {
          if (!obstacle[6] && this.getCase(positionCaseSelectionné2).estVide())
            voisinage.add(positionCaseSelectionné2);
          else if (!obstacle[6] && !this.getCase(positionCaseSelectionné2).estVide())
            obstacle[6] = true;
          else if (obstacle[6]
              && p.getSaitVoler()
              && this.getCase(positionCaseSelectionné2).estVide())
            voisinage.add(positionCaseSelectionné2);
        }
        if (x + i < TaillePlateauX && y - i >= 0) {
          if (!obstacle[7] && this.getCase(positionCaseSelectionné3).estVide())
            voisinage.add(positionCaseSelectionné3);
          else if (!obstacle[7] && !this.getCase(positionCaseSelectionné3).estVide())
            obstacle[7] = true;
          else if (obstacle[7]
              && p.getSaitVoler()
              && this.getCase(positionCaseSelectionné3).estVide())
            voisinage.add(positionCaseSelectionné3);
        }
      }
    }
    return voisinage;
  }