Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
L'organisation des batailles
Prenons le problème dans l'autre sens, la colère de l'empereur.

Soit 10 spaces marines Intercessor tirant durant la doctrine tactique.

Marine VS Scorpion
Touche 3+ (2/3) blesse 3+ (2/3) et sauvegarde 5+ (2/3) soit une proba de 8/27. Il y a 20 tirs, soit 5 morts (presque 6).

Marine VS Banshee
Touche 3+ (2/3) blesse 3+ (2/3 et sauvegarde 6+ (5/6) soit une proba de 20/54 = 10/27. Pour un total de 7 morts.

Marine VS Dépeceurs
Touche 3+ (2/3) blesse 4+ (1/2) sauvegarde 6+ (5/6) mais se relève sur 5+ (2/3) soit une proba de (2*5*2)/(3*2*6*3) = 5/(3*3*3) = 5/27 soit 3 morts (3,7 au total).

Conclusion
Là où la moitié des scorpions meurent, où 70% des banshee meurent, on a seulement 15% des dépeceurs qui meurent ...

Certes, les intercessors ont aussi un stratagème pour tirer 2 fois.
Ce qui dans ce cas là annihile les banshee et les scorpions, mais pas les dépeceurs (dans ce cas, 6 morts soit 30%).

Imaginez les ressources qu'il faut déployer sur une vraie bataille (généralement en urgence) pour faire face à cette menace (rappel 10pts) qui en général, est dans les lignes ennemies (Frappe en profondeur...) .
A noter que les scorpions n'ont pas frappe en profondeur, mais position avancée. (c'est au déploiement).
Reply
Haha tu te lances dans les stats 40k avec ton projet c'est sympa biggrin

Les dépeceurs sont plus résistant points pour points que les scorpions c'est sûr mais ils sont moins bon offensivement. En plus leur resistance dépend du protocole de réanimation, si tu réussis à tuer 20 d'un coup, et il y a plein d'unité capable de faire ça, pas de résurrection :(

Ensuite chaque unité a une efficacité qui dépend de sa cible, par exemple les 10 scorpions tuent 3 terminators normaux, alors alors que les 20 dépeceurs n'en tuent que 1,5.

C'est pareil pour les règles, la frappe en profondeur n'est utile que si tu as un moyen d'améliorer la charge après, sinon c'est inutile pour une unité de corps à corps car une charge à 9 à moins d'une chance sur 3 de passer :

- No modifiers 28%
- Re-roll both dice 48%
- Re-roll one or both dice 58%
- Turn one die into a 6 92%
- Roll 3D6 74%
Reply
Tiens, sert à quelque chose. Ai-je oublié des  choses, et des cas de test aussi Boidleau 

Code:
package com.calculateur.warhammer.data;

import java.util.List;
import java.util.Map;

public interface IReglesSpeciales {

    // Pour toucher
    /**
     * Attaquant
     *
     * @return La modification que l'attaquant a au jet de touche
     */
    Integer getModificationTouche();

    /**
     * Attaquant
     *
     * @return Le jet qui donne une blessure mortelle, et on s'arrête là.
     */
    Integer getJetToucheBlessureMortelle();

    /**
     * Attaquant
     *
     * @return Le jet qui donne une blessure mortelle, en plus des autres blessures.
     */
    Integer getJetToucheBlessureMortelleEnPlusDeToutesAutresBlessures();

    /**
     * Attaquant. Utilisé pour la simulation.
     *
     * @return Le jet et le nombre d'attaque supplémentaire que donne le jet.
     */
    Map<Integer, Integer> getJetsDonnantAttaqueSuplémentaires();

    /**
     * Attaquant. Utilisé pour la simulation.
     *
     * @return Les jets qui donnent des attaques supplémentaires à relancer.
     */
    List<Integer> getAttaqueSuplementairesARelancer();

    /**
     *
     * @return Les échecs qui peuventt être relancées
     */
    List<Integer> getJetsTouchesRelancees();

    /**
     * Defeuseur
     *
     * @return Le jet minimum pour être touché
     */
    List<Integer> getJetsMinimumPourEtreTouche();

    // Pour bleseer
    /**
     * Attaquant/Defenseur
     *
     * @return La modification au jet de blessure
     */
    Integer getModificationJetBlessure();

    /**
     * Attaquant
     *
     * @return Le jet de blessure qui donne une mortelle, et on s'arrête là.
     */
    Integer getJetBlessuresMortelles();

    /**
     * Attaquant
     *
     * @return Le jet qui donne une blessure mortelle, en plus de toute autres
     */
    Integer getJetBlessuresMortellesEnPlusDeToutesAutresBlessures();

    /**
     * Attaquant
     *
     * @return Le jet et la modification de sauvegarde associé
     */
    Map<Integer, Integer> getJetAjouteModificateurSauvegarde();

    /**
     * Attaquant
     *
     * @return Le jet minimum pour blesser.
     */
    Integer getJetMinimumPourBlesser();

    /**
     * Defenseur
     *
     * @return Le jet minimum pour être blessé.
     */
    Integer getJetsMinimuimPourEtreBlesse();

    // Sauvegare
    /**
     * Attaquant
     *
     * @return vrai si l'unité ignore les sauvegarde invulnérable.
     */
    boolean isIgnoreSauvegardeInvulnerable();

    /**
     * Défenseur
     *
     * @return L'amélioration de sauvegarde que peut avoir une unité
     */
    Integer getAmeliorationSauvegarde();

    // Ignore Blessure
    /**
     * Defenseur, simulation
     *
     * @return Après le jet de sauvegarde, le jet de dé qui ignore les blessures.
     */
    Integer getJetIgnoreBlessure();

    // Se relève
    /**
     * Défenseur, principalement nécron
     *
     * @return Le jet pour relever une figurine morte.
     */
    Integer getJetPourSeRelever();
}
Reply
La correction:


package com.calculateur.warhammer.data;

import java.util.List;
import java.util.Map;

/**
* Les règles spéciales applicables
*
* @author phili
*
*/
public interface IReglesSpeciales {

// Pour toucher
/**
* Attaquant
*
* @return La modification que l'attaquant a au jet de touche
*/
Integer getModificationTouche();

/**
* Attaquant
*
* @return Le jet qui donne une blessure mortelle, et on s'arrête là.
*/
Integer getJetToucheBlessureMortelle();

/**
* Attaquant
*
* @return Le jet qui donne une blessure mortelle, en plus des autres blessures.
*/
Integer getJetToucheBlessureMortelleEnPlusDeToutesAutresBlessures();

/**
* Attaquant. Utilisé pour la simulation.
*
* @return Le jet et le nombre d'attaque supplémentaire que donne le jet.
*/
Map<Integer, Integer> getJetsDonnantAttaqueSuplémentaires();

/**
* Attaquant. Utilisé pour la simulation.
*
* @return Les jets qui donnent des attaques supplémentaires à relancer.
*/
List<Integer> getAttaqueSuplementairesARelancer();

/**
*
* @return Les échecs qui peuventt être relancées
*/
List<Integer> getJetsTouchesRelancees();

/**
* Defeuseur
*
* @return Le jet minimum pour être touché
*/
Integer getJetMinimumPourEtreTouche();

// Pour bleseer
/**
* Attaquant/Defenseur
*
* @return La modification au jet de blessure
*/
Integer getModificationJetBlessure();

/**
* Attaquant
*
* @return Le jet de blessure qui donne une mortelle, et on s'arrête là.
*/
Integer getJetBlessuresMortelles();

/**
* Attaquant
*
* @return Le jet qui donne une blessure mortelle, en plus de toute autres
*/
Integer getJetBlessuresMortellesEnPlusDeToutesAutresBlessures();

/**
* Attaquant
*
* @return Le jet et la modification de sauvegarde associé
*/
Map<Integer, Integer> getJetAjouteModificateurSauvegarde();

/**
* Attaquant
*
* @return Le jet minimum pour blesser.
*/
Integer getJetMinimumPourBlesser();

/**
* Defenseur
*
* @return Le jet minimum pour être blessé.
*/
Integer getJetsMinimuimPourEtreBlesse();

// Sauvegare
/**
* Attaquant
*
* @return vrai si l'unité ignore les sauvegarde invulnérable.
*/
boolean isIgnoreSauvegardeInvulnerable();

/**
* Défenseur
*
* @return L'amélioration de sauvegarde que peut avoir une unité
*/
Integer getAmeliorationSauvegarde();

// Ignore Blessure
/**
* Defenseur, simulation
*
* @return Après le jet de sauvegarde, le jet de dé qui ignore les blessures.
*/
Integer getJetIgnoreBlessure();

/**
* Death guard, Simulation, Défense.
*
* @return Nombre de blessure ignoré
*/
Integer getNombreBlessureIgnorees();

// Se relève
/**
* Défenseur, principalement nécron
*
* @return Le jet pour relever une figurine morte.
*/
Integer getJetPourSeRelever();
}
Reply
La preuve que le Mamar sert à rien.

J'avais oublié la Death Guard (retire de l'endurance), que le guerrier nécron se relève, et que il existe des auras pour les capitaines/Lieutenant Space marine/Soeurs de bataille Boidleau
Reply
(16-04-2022, 12:29 PM)sdm Wrote: Haha tu te lances dans les stats 40k avec ton projet c'est sympa biggrin

Les dépeceurs sont plus résistant points pour points que les scorpions c'est sûr mais ils sont moins bon offensivement. En plus leur resistance dépend du protocole de réanimation, si tu réussis à tuer 20 d'un coup, et il y a plein d'unité capable de faire ça, pas de résurrection :(

Ensuite chaque unité a une efficacité qui dépend de sa cible, par exemple les 10 scorpions tuent 3 terminators normaux, alors alors que les 20 dépeceurs n'en tuent que 1,5.

C'est pareil pour les règles, la frappe en profondeur n'est utile que si tu as un moyen d'améliorer la charge après, sinon c'est inutile pour une unité de corps à corps car une charge à 9 à moins d'une chance sur 3 de passer :

- No modifiers 28%
- Re-roll both dice 48%
- Re-roll one or both dice 58%
- Turn one die into a 6 92%
- Roll 3D6 74%

Bonnet d’âne pour Mamar Caillou . La probabilité de réussir une charge (sans rien relancer) est de 5/13 soit exactement 38.46...% Boidleau .
Je n'ai pas eu le courage et/ou occasion de vérifier les autres affirmations Boidleau .
Reply
Si c'est une formule de ton programme je pense qu'il faut faire une petite correction ^^
https://www.thedarkfortress.co.uk/tech_r..._rolls.php
Reply
Si tu lances 2D6, il y a 36 possibilités. De fait, tu peux faire (sur un cahier par exemple) un carré de 6 * 6.
La diagonale du carré (de 6 vers 6) représente une somme de 7.

     1    2    3    4    5    6
1   2    3    4    5    6    7
2   3    4    5    6    7    8
3   4    5    6    7    8    9
4   5    6    7    8    9  10
5   6    7    8    9  10  11
6   7    8    9  10  11  12

Il y a 36 possibilités. Il suffit de compter celles où le résultat est 9 ou plus. Il y en a 10.
a
Du coup, sur 2D6, P(9) = 10/36 = 5/18 de fait 27% (merde, je viens de me rappeler qu'entre temps, j'avais corrigé mon TU car je n'avais pas divisé par 2 entre temps,  redaface2 ).
Reply
Le contrat:

Quote:package com.calculateur.warhammer.de;

import java.util.List;

import org.apache.commons.math3.fraction.Fraction;

/**
* Calcul et simulation sur un jet de dé
*
* @author phili
*
*/
public interface IJetDe {

/**
*
* @return Moyenne du jet de dé
*/
double moyenne();

/**
*
* @param nombreDe Nombre dé lancé
* @return La moyenne sur le nombre de dé
* @throws LanceDeException
*/
double moyenne(Integer nombreDe) throws LanceDeException;

/**
*
* @param nombreDe Nomnre dé lancé
* @param score    Score à obtenir
* @return Score à obtenir
* @throws LanceDeException
*
*/
Fraction probabileScore(Integer nombreDe, Integer score) throws LanceDeException;

/**
*
* @param isLogiqueOptimiste Si vrai, privilégie les bon scores
* @param nombreLance        Le nombre de dé lancé.
* @return La liste des dé obtenu
*/
List<IDe> simuleJet(boolean isLogiqueOptimiste, Integer nombreLance) throws LanceDeException;

/**
*
* @param score Score à obtenir
* @return La probabilité d'obtenir le score.
* @throws LanceDeException
*/
List<IDe> getLancePourScore(Integer score) throws LanceDeException;
}


L'implémentation:

Quote:package com.calculateur.warhammer.de;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.math3.fraction.Fraction;

import com.calculateur.warhammer.calcul.proba.ArbreProbabilite;
import com.calculateur.warhammer.calcul.proba.EvenementImplementation;
import com.calculateur.warhammer.calcul.proba.IArbreProbabilite;
import com.calculateur.warhammer.calcul.proba.IEvenement;
import com.calculateur.warhammer.calcul.proba.IProbabilite;
import com.calculateur.warhammer.calcul.proba.ProbabiliteException;
import com.calculateur.warhammer.calcul.proba.ProbabiliteImplementation;
import com.calculateur.warhammer.calcul.proba.SommeProbabilite;

/**
* Implementation pour les calcul et la simulation des jets de dés
*
* @author phili
*
*/
public class JetDeImplementation implements IJetDe {

private final List<IDe> resultatsPossibles;

public JetDeImplementation(List<IDe> resultatsPossibles) {
this.resultatsPossibles = resultatsPossibles;
}

@Override
public double moyenne() {
Fraction resultat = new Fraction(0);
Fraction rEtape;
Fraction pEtape;
Fraction mEtape;
for (IDe de : resultatsPossibles) {
rEtape = new Fraction(de.getResultat());
pEtape = de.getProbabilite();
mEtape = rEtape.multiply(pEtape);
resultat = resultat.add(mEtape);
}
return resultat.doubleValue();
}

@Override
public double moyenne(Integer nombreDe) throws LanceDeException {
verifieNombreLance(nombreDe);
return moyenne() * nombreDe.doubleValue();
}

@Override
public Fraction probabileScore(Integer nombreDe, Integer score) throws LanceDeException {
verifieNombreLance(nombreDe);
verifieScore(score, nombreDe);
try {
Map<Integer, Map<IEvenement, Integer>> mapMapScore = new HashMap<>();
IArbreProbabilite arbre = getArbreEtRemplirMap(mapMapScore, nombreDe);
Map<IEvenement, Integer> mapResultat = mapMapScore.get(nombreDe - 1);

SommeProbabilite probaSomme = new SommeProbabilite(
new EvenementImplementation("obetenir." + score + ".sur." + nombreDe + ".lancees"));
for (Entry<IEvenement, Integer> entry : mapResultat.entrySet()) {
if (entry.getValue() >= score) {
probaSomme.addProbabilite(
new ProbabiliteImplementation(entry.getKey(), arbre.getProbabilite(entry.getKey())));
}
}
return probaSomme.getProbabilite();
} catch (ProbabiliteException e) {
throw new LanceDeException(e);
}
}

@Override
public List<IDe> simuleJet(boolean isLogiqueOptimiste, Integer nombreLance) throws LanceDeException {
verifieNombreLance(nombreLance);
List<IDe> listeCalcul = new ArrayList<>();
listeCalcul.addAll(resultatsPossibles);
Collections.sort(listeCalcul, new ComparatorDe(isLogiqueOptimiste));
List<IDe> lReturn = new ArrayList<>();

if (nombreLance <= listeCalcul.size()) {
remplirJetPeuDe(lReturn, listeCalcul, nombreLance);
} else {
remplirPleinDes(lReturn, listeCalcul, nombreLance);
}
return lReturn;
}

@Override
public List<IDe> getLancePourScore(Integer score) throws LanceDeException {
verifieScore(score, 1);
List<IDe> lReturn = new ArrayList<>();
for (IDe de : resultatsPossibles) {
if (de.getResultat() >= score) {
lReturn.add(de);
}
}
return lReturn;
}

private IArbreProbabilite getArbreEtRemplirMap(Map<Integer, Map<IEvenement, Integer>> mapMapScore,
Integer nombreLance) throws ProbabiliteException {
Integer indiceLance = 0;
IEvenement eRacine = new EvenementImplementation("racine");
IEvenement eCourant;
IArbreProbabilite arbreProbabilite = new ArbreProbabilite(eRacine);
StringBuilder sbEvenement;
List<IEvenement> ePrecedents = new ArrayList<IEvenement>();
List<IEvenement> eSuivants = new ArrayList<>();
ePrecedents.add(eRacine);
List<IProbabilite> toAdd = new ArrayList<>();
Map<IEvenement, Integer> mapCourante;
Map<IEvenement, Integer> mapPrecedente;
Integer resultat;
while (indiceLance < nombreLance) {
eSuivants.clear();
for (IEvenement ePrecedent : ePrecedents) {
toAdd.clear();
for (IDe de : resultatsPossibles) {
sbEvenement = new StringBuilder();
sbEvenement.append(ePrecedent.getId());
sbEvenement.append(".");
sbEvenement.append(de.getId());

eCourant = new EvenementImplementation(sbEvenement.toString());
toAdd.add(new ProbabiliteImplementation(eCourant, de.getProbabilite()));

// Score
mapPrecedente = mapMapScore.get(indiceLance - 1);
resultat = (mapPrecedente != null) ? mapPrecedente.get(ePrecedent) : 0;
resultat = resultat + de.getResultat();

mapCourante = mapMapScore.computeIfAbsent(indiceLance, k -> new HashMap<>());
mapCourante.put(eCourant, resultat);
eSuivants.add(eCourant);
}
arbreProbabilite.addProbabilites(ePrecedent, toAdd);
}

indiceLance++;
ePrecedents.clear();
ePrecedents.addAll(eSuivants);
}

return arbreProbabilite;
}

private void remplirJetPeuDe(List<IDe> lReturn, List<IDe> iTravail, Integer nombreTirage) {
Integer increment = (nombreTirage > (iTravail.size() / 2)) ? 1 : 2;
int i = 0;
int nb = 0;
while (i < iTravail.size() && nb < nombreTirage) {
lReturn.add(iTravail.get(i));
i = i + increment;
nb++;
}
}

private void remplirPleinDes(List<IDe> lReturn, List<IDe> iTravail, Integer nombreTirage) {
Integer reste = nombreTirage;
Fraction score;
Integer nombre;
for (IDe de : iTravail) {
score = de.getProbabilite().multiply(new Fraction(nombreTirage));
nombre = score.getNumerator() / score.getDenominator();
for (int i = 0; i < nombre; i++) {
lReturn.add(de);
}
reste = reste - nombre;
}
if (reste > 0) {
for (int i = 0; i < reste; i++) {
lReturn.add(iTravail.get(0));
}
}
}

private void verifieNombreLance(Integer nombreDe) throws LanceDeException {
if (nombreDe == null) {
throw new LanceDeException(new NullPointerException("Le nombre de dé à lancer est null"));
}
if (nombreDe < 1) {
throw new LanceDeException(
"Il faut lancer au moins 1 D, et le nombre de lancé est strictrment positif (Nombre de lancé : "
+ nombreDe.toString() + ")");
}
}

private void verifieScore(Integer score, Integer nombreLance) throws LanceDeException {
if (score == null) {
throw new LanceDeException(new NullPointerException("Le score est null"));
}
Integer min = resultatsPossibles.stream().map(d -> d.getResultat()).toList().stream().min(Integer::compare)
.get();
Integer max = resultatsPossibles.stream().map(d -> d.getResultat()).toList().stream().max(Integer::compare)
.get();
if (score < (min * nombreLance)) {
throw new LanceDeException("Avec ce dé, le score minimum est " + min.toString()
+ " et on ne peut pas atteindre " + score.toString());
}
if (score > (max * nombreLance)) {
throw new LanceDeException("Avec ce dé, le score maximum est " + max.toString()
+ " et on ne peut pas atteindre " + score.toString());
}
}
}


Et le TU:

Quote:package com.calculateur.warhammer.de;

import static org.junit.jupiter.api.Assertions.fail;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.math3.fraction.Fraction;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;

public class JetDeImplementationTest {

private final IJetDe jetDe;

public JetDeImplementationTest() {
jetDe = new JetDeImplementation(Arrays.asList(D6.values()));
}

@Test
public void testMoyenne() {
Assertions.assertThat(jetDe.moyenne()).isEqualTo(3.5);
}

@Test
public void testMoyenneNombreDesNull() {
try {
jetDe.moyenne(null);
fail();
} catch (LanceDeException e) {
Assertions.assertThat(e.getCause()).isInstanceOf(NullPointerException.class);
}
}

@Test
public void testMoyenneNombreNegatif() {
try {
jetDe.moyenne(-1);
fail();
} catch (LanceDeException e) {
Assertions.assertThat(e.getCause()).isNull();
}
}

@Test
public void testMoyenne2D() {
try {
Assertions.assertThat(jetDe.moyenne(2)).isEqualTo(7.0);
} catch (LanceDeException e) {
fail();
}
}

@Test
public void testMoyenne3D() {
try {
Assertions.assertThat(jetDe.moyenne(3)).isEqualTo(10.5);
} catch (LanceDeException e) {
fail();
}
}

@Test
public void testMoyenne4D() {
try {
Assertions.assertThat(jetDe.moyenne(4)).isEqualTo(14.0);
} catch (LanceDeException e) {
fail();
}
}

@Test
public void testProbabileScoreNombreJetNull() {
try {
jetDe.probabileScore(null, 5);
fail();
} catch (LanceDeException e) {
Assertions.assertThat(e.getCause()).isInstanceOf(NullPointerException.class);
}
}

@Test
public void testProbabileScoreNombreJetNegatif() {
try {
jetDe.probabileScore(-5, 5);
fail();
} catch (LanceDeException e) {
Assertions.assertThat(e.getCause()).isNull();
}
}

@Test
public void testProbabileScoreScoreNull() {
try {
jetDe.probabileScore(3, null);
fail();
} catch (LanceDeException e) {
Assertions.assertThat(e.getCause()).isInstanceOf(NullPointerException.class);
}
}

@Test
public void testProbabileScoreScoreNegatif() {
try {
jetDe.probabileScore(5, -5);
fail();
} catch (LanceDeException e) {
Assertions.assertThat(e.getCause()).isNull();
}
}

@Test
public void testProbabileScoreScoreTropGrand() {
try {
jetDe.probabileScore(3, 25);
fail();
} catch (LanceDeException e) {
Assertions.assertThat(e.getCause()).isNull();
}
}

@Test
public void testProbabileScoreSur2D() {
try {
Assertions.assertThat(jetDe.probabileScore(2, 9)).isEqualTo(new Fraction(5, 18));
} catch (LanceDeException e) {
fail();
}
}

@Test
public void testProbabileScoreSur3D() {
try {

int score = 15;
int nb = 0;
int total = 6 * 6 * 6;
List<IDe> l1 = Arrays.asList(D6.values());
List<IDe> l2 = Arrays.asList(D6.values());
List<IDe> l3 = Arrays.asList(D6.values());

Integer eSomme;
for (IDe d1 : l1) {
for (IDe d2 : l2) {
for (IDe d3 : l3) {
eSomme = d1.getResultat() + d2.getResultat() + d3.getResultat();
if (eSomme >= score) {
nb++;
}
}
}
}

Assertions.assertThat(jetDe.probabileScore(3, score)).isEqualTo(new Fraction(nb, total));
} catch (LanceDeException e) {
fail();
}
}

@Test
public void testSimuleJetNombreJetNull() {
try {
jetDe.simuleJet(true, null);
fail();
} catch (LanceDeException e) {
Assertions.assertThat(e.getCause()).isInstanceOf(NullPointerException.class);
}
}

@Test
public void testSimuleJetNombreJetNegatif() {
try {
jetDe.simuleJet(true, -5);
fail();
} catch (LanceDeException e) {
Assertions.assertThat(e.getCause()).isNull();
}
}

@Test
public void testSimuleJetOptimiste2D() {
try {
List<IDe> esperes = Arrays.asList(D6.D6_RESULTAT_6, D6.D6_RESULTAT_4);
List<IDe> resultats = jetDe.simuleJet(true, 2);
assertSimulation(esperes, resultats);
} catch (LanceDeException e) {
fail();
}
}

@Test
public void testSimuleJetPessimiste2D() {
try {
List<IDe> esperes = Arrays.asList(D6.D6_RESULTAT_1, D6.D6_RESULTAT_3);
List<IDe> resultats = jetDe.simuleJet(false, 2);
assertSimulation(esperes, resultats);
} catch (LanceDeException e) {
fail();
}
}

@Test
public void testSimuleJetOptimiste3D() {
try {
List<IDe> esperes = Arrays.asList(D6.D6_RESULTAT_6, D6.D6_RESULTAT_4, D6.D6_RESULTAT_2);
List<IDe> resultats = jetDe.simuleJet(true, 3);
assertSimulation(esperes, resultats);
} catch (LanceDeException e) {
fail();
}
}

@Test
public void testSimuleJetPessimiste3D() {
try {
List<IDe> esperes = Arrays.asList(D6.D6_RESULTAT_1, D6.D6_RESULTAT_3, D6.D6_RESULTAT_5);
List<IDe> resultats = jetDe.simuleJet(false, 3);
assertSimulation(esperes, resultats);
} catch (LanceDeException e) {
fail();
}
}

@Test
public void testSimuleJetPessimiste5D() {
try {
List<IDe> esperes = Arrays.asList(D6.D6_RESULTAT_1, D6.D6_RESULTAT_2, D6.D6_RESULTAT_3, D6.D6_RESULTAT_4,
D6.D6_RESULTAT_5);
List<IDe> resultats = jetDe.simuleJet(false, 5);
assertSimulation(esperes, resultats);
} catch (LanceDeException e) {
fail();
}
}

@Test
public void testSimuleJetOptimiste5D() {
try {
List<IDe> esperes = Arrays.asList(D6.D6_RESULTAT_6, D6.D6_RESULTAT_5, D6.D6_RESULTAT_4, D6.D6_RESULTAT_3,
D6.D6_RESULTAT_2);
List<IDe> resultats = jetDe.simuleJet(true, 5);
assertSimulation(esperes, resultats);
} catch (LanceDeException e) {
fail();
}
}

@Test
public void testSimuleJetPessimiste18D() {
try {
List<IDe> esperes = new ArrayList<>();
esperes.add(D6.D6_RESULTAT_1);
esperes.add(D6.D6_RESULTAT_1);
esperes.add(D6.D6_RESULTAT_1);
esperes.add(D6.D6_RESULTAT_2);
esperes.add(D6.D6_RESULTAT_2);
esperes.add(D6.D6_RESULTAT_2);
esperes.add(D6.D6_RESULTAT_3);
esperes.add(D6.D6_RESULTAT_3);
esperes.add(D6.D6_RESULTAT_3);
esperes.add(D6.D6_RESULTAT_4);
esperes.add(D6.D6_RESULTAT_4);
esperes.add(D6.D6_RESULTAT_4);
esperes.add(D6.D6_RESULTAT_5);
esperes.add(D6.D6_RESULTAT_5);
esperes.add(D6.D6_RESULTAT_5);
esperes.add(D6.D6_RESULTAT_6);
esperes.add(D6.D6_RESULTAT_6);
esperes.add(D6.D6_RESULTAT_6);
List<IDe> resultats = jetDe.simuleJet(false, 18);
assertSimulation(esperes, resultats);
} catch (LanceDeException e) {
fail();
}
}

@Test
public void testSimuleJetOptimiste18D() {
try {
List<IDe> esperes = new ArrayList<>();
esperes.add(D6.D6_RESULTAT_6);
esperes.add(D6.D6_RESULTAT_6);
esperes.add(D6.D6_RESULTAT_6);
esperes.add(D6.D6_RESULTAT_5);
esperes.add(D6.D6_RESULTAT_5);
esperes.add(D6.D6_RESULTAT_5);
esperes.add(D6.D6_RESULTAT_4);
esperes.add(D6.D6_RESULTAT_4);
esperes.add(D6.D6_RESULTAT_4);
esperes.add(D6.D6_RESULTAT_3);
esperes.add(D6.D6_RESULTAT_3);
esperes.add(D6.D6_RESULTAT_3);
esperes.add(D6.D6_RESULTAT_2);
esperes.add(D6.D6_RESULTAT_2);
esperes.add(D6.D6_RESULTAT_2);
esperes.add(D6.D6_RESULTAT_1);
esperes.add(D6.D6_RESULTAT_1);
esperes.add(D6.D6_RESULTAT_1);
List<IDe> resultats = jetDe.simuleJet(false, 18);
assertSimulation(esperes, resultats);
} catch (LanceDeException e) {
fail();
}
}

@Test
public void testSimuleJetPessimiste20D() {
try {
List<IDe> esperes = new ArrayList<>();
esperes.add(D6.D6_RESULTAT_1);
esperes.add(D6.D6_RESULTAT_1);
esperes.add(D6.D6_RESULTAT_1);
esperes.add(D6.D6_RESULTAT_1);
esperes.add(D6.D6_RESULTAT_1);
esperes.add(D6.D6_RESULTAT_2);
esperes.add(D6.D6_RESULTAT_2);
esperes.add(D6.D6_RESULTAT_2);
esperes.add(D6.D6_RESULTAT_3);
esperes.add(D6.D6_RESULTAT_3);
esperes.add(D6.D6_RESULTAT_3);
esperes.add(D6.D6_RESULTAT_4);
esperes.add(D6.D6_RESULTAT_4);
esperes.add(D6.D6_RESULTAT_4);
esperes.add(D6.D6_RESULTAT_5);
esperes.add(D6.D6_RESULTAT_5);
esperes.add(D6.D6_RESULTAT_5);
esperes.add(D6.D6_RESULTAT_6);
esperes.add(D6.D6_RESULTAT_6);
esperes.add(D6.D6_RESULTAT_6);
List<IDe> resultats = jetDe.simuleJet(false, 20);
assertSimulation(esperes, resultats);
} catch (LanceDeException e) {
fail();
}
}

@Test
public void testSimuleJetOptimiste20D() {
try {
List<IDe> esperes = new ArrayList<>();
esperes.add(D6.D6_RESULTAT_6);
esperes.add(D6.D6_RESULTAT_6);
esperes.add(D6.D6_RESULTAT_6);
esperes.add(D6.D6_RESULTAT_6);
esperes.add(D6.D6_RESULTAT_6);
esperes.add(D6.D6_RESULTAT_5);
esperes.add(D6.D6_RESULTAT_5);
esperes.add(D6.D6_RESULTAT_5);
esperes.add(D6.D6_RESULTAT_4);
esperes.add(D6.D6_RESULTAT_4);
esperes.add(D6.D6_RESULTAT_4);
esperes.add(D6.D6_RESULTAT_3);
esperes.add(D6.D6_RESULTAT_3);
esperes.add(D6.D6_RESULTAT_3);
esperes.add(D6.D6_RESULTAT_2);
esperes.add(D6.D6_RESULTAT_2);
esperes.add(D6.D6_RESULTAT_2);
esperes.add(D6.D6_RESULTAT_1);
esperes.add(D6.D6_RESULTAT_1);
esperes.add(D6.D6_RESULTAT_1);
List<IDe> resultats = jetDe.simuleJet(true, 20);
assertSimulation(esperes, resultats);
} catch (LanceDeException e) {
fail();
}
}

@Test
public void testLancePourScoreScoreNull() {
try {
jetDe.getLancePourScore(null);
fail();
} catch (LanceDeException e) {
Assertions.assertThat(e.getCause()).isInstanceOf(NullPointerException.class);
}
}

@Test
public void testLancePourScoreScoreNegatif() {
try {
jetDe.getLancePourScore(-5);
fail();
} catch (LanceDeException e) {
Assertions.assertThat(e.getCause()).isNull();
}
}

@Test
public void testLancePourScoreScoreTropGrand() {
try {
jetDe.getLancePourScore(7);
fail();
} catch (LanceDeException e) {
Assertions.assertThat(e.getCause()).isNull();
}
}

@Test
public void testLancePourScoreScore3() {
try {
List<IDe> esperes = Arrays.asList(D6.D6_RESULTAT_3, D6.D6_RESULTAT_4, D6.D6_RESULTAT_5, D6.D6_RESULTAT_6);
List<IDe> resultat = jetDe.getLancePourScore(3);

assertSimulation(esperes, resultat);
} catch (LanceDeException e) {
fail();
}
}

private void assertSimulation(List<IDe> esperes, List<IDe> resultats) {
Assertions.assertThat(resultats).hasSize(esperes.size());
Map<IDe, Integer> mapEsperes = getMapCount(esperes);
Map<IDe, Integer> mapResultats = getMapCount(resultats);

Assertions.assertThat(mapResultats).hasSize(mapEsperes.size());
for (Entry<IDe, Integer> entry : mapResultats.entrySet()) {
Assertions.assertThat(entry.getValue()).isNotNull();
Assertions.assertThat(mapEsperes.get(entry.getKey())).isNotNull();
Assertions.assertThat(entry.getValue()).isEqualTo(mapEsperes.get(entry.getKey()));
}
}

private Map<IDe, Integer> getMapCount(List<IDe> list) {
Map<IDe, Integer> map = new HashMap<>();
int nombre;
for (IDe de : list) {
nombre = (map.get(de) != null) ? map.get(de) : 0;
map.put(de, nombre + 1);
}

return map;
}
}
Comme c'est long, j'avais fait une pause Mamar et, je me suis trompé en divisant par 2 Mur . Mais le TU, lui, il est bon !
Reply
Hehe pas de problème, mais du coup mon argument est valable, hors moyen de sécuriser ta charge en sortie de FeP, c'est du suicide de baser une stratégie sur un jet à 28% de proba ^^

En tout cas j'ai hâte de tester cette Dataslate, tes soeurs ont pris un sacré buff entre Armor of Contempt et les dés de foi par tour.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)