/** * Détermine si une position est ou non disponible en fonction d'un blason donné * * @param blason le blason que l'on cherche à placer sur la position * @param position la position ou placer ce blason * @return <i>true</i> si l'on arrive à placer le blason sur la position, <i>false</i> sinon */ public boolean isSlotAvailable(Blason blason, int position) { boolean placable = true; if (concurrents[position] != null) return false; // Ancrage ancrage = blason.getAncrage(position); for (int i = 0; i < concurrents.length; i++) { if (concurrents[i] != null) { // int otherPosition = concurrent.getPosition(); DistancesEtBlason db = DistancesEtBlason.getDistancesEtBlasonForConcurrent(reglement, concurrents[i]); Blason otherBlason = db.getTargetFace(); if (blason.getNbArcher() > 2 || otherBlason.getNbArcher() > 2) { if (!otherBlason.equals(blason)) { placable = false; break; } } else if (blason.getNbArcher() > 1) { if (!((!otherBlason.equals(blason) && !blason.isOver(position, otherBlason, i)) || otherBlason.equals(blason))) { placable = false; break; } } else { if (blason.isOver(position, otherBlason, i)) { placable = false; break; } } } } return placable; }
/** * Retourne l'objet DistancesEtBlason associé à un concurrent pour un règlement donné. * * @param reglement le règlement déterminant le DistancesEtBlason du concurrent * @param concurrent le concurrent pour lequel retourné l'objet * @return l'objet DistancesEtBlason correspondant au concurrent */ public static DistancesEtBlason getDistancesEtBlasonForConcurrent( Reglement reglement, Concurrent concurrent) { List<DistancesEtBlason> ldb = reglement.getDistancesEtBlasonFor( concurrent.getCriteriaSet().getFilteredCriteriaSet(reglement.getPlacementFilter())); if (concurrent.isUseAlternativeTargetFace()) { for (DistancesEtBlason db : ldb) { if (concurrent.getAlternativeTargetFace().equals(db.getTargetFace())) return db; } } if (ldb.size() > 0) return ldb.get(0); return null; }
/** * Retourne le nombre d'archer present sur la cible pour un DistancesEtBlason donnée * * @param db le DistancesEtBlason pour lequelle retourner le nombre d'archers * @return le nombre d'archer sur le DistancesEtBlason présent sur la cible */ public int getNbArcherFor(DistancesEtBlason db) { int nbArcher = 0; for (Concurrent concurrent : concurrents) { if (concurrent != null) { DistancesEtBlason concDb = DistancesEtBlason.getDistancesEtBlasonForConcurrent(reglement, concurrent); if (db.equals(concDb)) { nbArcher++; } } } return nbArcher; }
/** * Place un concurrent sur la cible à la position donné * * @param concurrent le concurrent à placer * @param position la positionn de ce concurrent * @throws PlacementException invoqué en cas d'echec d'insertion du concurrent */ protected void setConcurrentAt(Concurrent concurrent, int position) throws PlacementException { if (concurrent != null) { if (position == -1) { Repartition repartition = Repartition.ACBD; if (concurrents.length == 2) repartition = Repartition.ABCD; insertConcurrent(concurrent, repartition); return; } else if (position >= 0 && position < concurrents.length && !isReservedPosition(position)) { DistancesEtBlason dbConcurrent = DistancesEtBlason.getDistancesEtBlasonForConcurrent(reglement, concurrent); assert dbConcurrent != null : "un concururrent doit toujours avoir un DistancesEtBlason associé"; //$NON-NLS-1$ if (getDistancesEtBlason().size() > 0 && !Arrays.equals( dbConcurrent.getDistance(), getDistancesEtBlason().get(0).getDistance())) throw new PlacementException(PlacementException.Nature.BAD_DISTANCES); if (isSlotAvailable(dbConcurrent.getTargetFace(), position)) { if (concurrent.isHandicape() && position % 2 != 0) throw new PlacementException( PlacementException.Nature.POSITION_AVAILABLE_FOR_VALID_CONCURRENT); concurrent.setCible(numCible); concurrent.setPosition(position); if (concurrents[position] != null) removeConcurrentAt(position); if (concurrent.isHandicape()) removeConcurrentAt(position + 1); nbArcher++; if (concurrent.isHandicape()) nbHandicap++; concurrent.addPropertyChangeListener(this); concurrents[position] = concurrent; fireConcurrentJoined(concurrent); return; } throw new PlacementException(PlacementException.Nature.BAD_TARGETFACE); } else { if (isReservedPosition(position)) throw new PlacementException(PlacementException.Nature.POSITION_RESERVED_FOR_HANDICAP); throw new PlacementException(PlacementException.Nature.ANY_AVAILABLE_POSITION); } } throw new PlacementException(PlacementException.Nature.NULL_CONCURRENT); }
/** * Retourne le nombre de position disponible pour l'objet DistancesEtBlason fournit en parametre * * @param distancesEtBlason l'objet DistancesEtBlason permettant de déterminer le nombre de * position disponible * @return le nombre de slot disponible pour le DistancesEtBlason */ public int getNbAvailableSlotsFor(DistancesEtBlason distancesEtBlason) { if (nbArcher > 0) { if (Arrays.equals( getDistancesEtBlason().get(0).getDistance(), distancesEtBlason.getDistance())) { int availableSlots = 0; for (int i = 0; i < concurrents.length; i++) { if (concurrents[i] == null && !isReservedPosition(i) && isSlotAvailable(distancesEtBlason.getTargetFace(), i)) { availableSlots++; } } return availableSlots; } return 0; } return concurrents.length; }
/** * Donne la disposition de la cible * * @return DistancesEtBlason - la disposition de la cible */ public List<DistancesEtBlason> getDistancesEtBlason() { // DistancesEtBlason db = null; List<DistancesEtBlason> dbs = new ArrayList<DistancesEtBlason>(); if (nbArcher > 0) { // Concurrent firstConcurrent = null; for (Concurrent concurrent : concurrents) { if (concurrent != null) { DistancesEtBlason db = DistancesEtBlason.getDistancesEtBlasonForConcurrent(reglement, concurrent); if (!dbs.contains(db)) dbs.add(db); // firstConcurrent = concurrent; // break; } } // db = DistancesEtBlason.getDistancesEtBlasonForConcurrent(reglement, firstConcurrent); } return dbs; }
/** * insere un concurrent à la premiere position libre et retourne cette position ou produit une * exception PlacementException en cas d'echec * * <p>L'insertion peut se dérouler en mode <i>réel</i> auquel cas, les informations de placement * seront ajouté au concurrent ou en mode </i>simulation</i> si l'on souhaite simplement voir si * l'on peut placer les archers sur la cible sans affecter les valeurs de placement au concurrent. * * @param concurrent le concurrent à inserer * @param repartition le mode de distribution des archers sur la cible * @param simulationMode <i>true</i> si l'on souhaite une insertion en mode simulation, * <i>false</i> sinon * @return la position de concurrent * @throws PlacementException si l'insertion du concurrent est impossible */ protected int insertConcurrent( Concurrent concurrent, Repartition repartition, boolean simulationMode) throws PlacementException { int position = -1; if (concurrent != null) { // verifie qu'il reste des places disponible if (nbArcher < concurrents.length - nbHandicap) { DistancesEtBlason concurrentDb = DistancesEtBlason.getDistancesEtBlasonForConcurrent(reglement, concurrent); List<DistancesEtBlason> targetDbs = getDistancesEtBlason(); // verifie que la distance est bonne if (targetDbs.size() > 0 && !Arrays.equals(concurrentDb.getDistance(), targetDbs.get(0).getDistance())) throw new PlacementException(PlacementException.Nature.BAD_DISTANCES); // si l'archer est handicapé, vérifié que les condition spécifique sont remplis if (concurrent.isHandicape()) { if (nbArcher < concurrents.length - (nbHandicap + 1)) { // dans le cas d'un archer handicapé, on boucle sur les emplacements 2 à 2 for (int i = 0; i < concurrents.length; i += 2) { if (isSlotAvailable(concurrentDb.getTargetFace(), i) && concurrents[i + 1] == null) { placeConcurrent(concurrent, i, simulationMode); nbHandicap++; position = i; break; } } if (position == -1) throw new PlacementException(PlacementException.Nature.BAD_TARGETFACE); } else { throw new PlacementException( PlacementException.Nature.POSITION_AVAILABLE_FOR_VALID_CONCURRENT); } } else { if (repartition == Repartition.ABCD) { // on boucle sur les emplacements et on remplit le premier qui est libre for (int i = 0; i < concurrents.length; i++) { if (isSlotAvailable(concurrentDb.getTargetFace(), i)) { if (isReservedPosition( i)) // la position est libre mais reservé pour un archer handicapé continue; placeConcurrent(concurrent, i, simulationMode); position = i; break; } } } else { // tente le placement en AC for (int i = 0; i < concurrents.length; i += 2) { if (isSlotAvailable(concurrentDb.getTargetFace(), i)) { placeConcurrent(concurrent, i, simulationMode); position = i; break; } } // si AC en echec tente en BD if (position == -1) { for (int i = 1; i < concurrents.length; i += 2) { if (isSlotAvailable(concurrentDb.getTargetFace(), i)) { if (isReservedPosition( i)) // la position est libre mais reservé pour un archer handicapé continue; placeConcurrent(concurrent, i, simulationMode); position = i; break; } } } } if (position == -1) throw new PlacementException(PlacementException.Nature.BAD_TARGETFACE); } } else { if (nbHandicap > 0) throw new PlacementException(PlacementException.Nature.POSITION_RESERVED_FOR_HANDICAP); throw new PlacementException(PlacementException.Nature.ANY_AVAILABLE_POSITION); } } else { throw new PlacementException(PlacementException.Nature.NULL_CONCURRENT); } return position; }