package de.ocame.wuerfelbot.Keeproll; import java.util.*; public class KeeprollLogic { private final Random random; private int numberOfDice; private int diceCount; private int target; private int modifier; private boolean unskilled; private boolean emphases; private int explode; private boolean explodedOnce; private result[] rolls; private boolean glitches; private int resultInt; StringBuilder resultStructur; public KeeprollLogic() { this.random = new Random(); reset(); } public KeeprollLogic reset() { glitches = false; resultInt = 0; resultStructur = new StringBuilder(); return this; } /** * Führt eine Earthdawn-Würfelprobe durch. * Würfelt eine bestimmte Anzahl an Ws Abhänig von Stufe und optional Würfeln (z.b. Karma). * * @param numberOfDicePar Die Anzahl der zu würfelende Würfeln * @param diceCountPar Die Anzahl behaltende Würfelergebnisse * @param targetPar Ziel Wert, Zeigt optisch Ergebnis an * @param modifierPar Bonus oder Abzug auf Ergebnis * @param unskilledPar Würfel explodieren nicht. * @param emphasesPar gewürfelte 1 werden neu gewürfelt * @param explodePar Ab wann Explodieren Würfel, Standard ist 10 * @param explodedOncePar Würfel explodieren nur einma * * @return Ein {@link KeeprollResult}-Objekt mit den einzelnen Würfelergebnissen und Summen. * @throws IllegalArgumentException Wenn stufe < 1 oder optionale < 0 ist. */ public KeeprollResult performKeeprollRoll(int numberOfDicePar, int diceCountPar, int targetPar, int modifierPar, boolean unskilledPar, boolean emphasesPar, int explodePar, boolean explodedOncePar) { if (numberOfDicePar < 1) { throw new IllegalArgumentException("Die Stufe muss mindestens 1 sein."); } if (diceCountPar < 0) { throw new IllegalArgumentException("Karma kann nicht negativ sein."); } if (targetPar < 0) { throw new IllegalArgumentException("Meister-Karma kann nicht negativ sein"); } this.numberOfDice = numberOfDicePar; this.diceCount = diceCountPar; this.target = targetPar; this.modifier = modifierPar; this.unskilled = unskilledPar; this.emphases = emphasesPar; this.explode = explodePar; this.explodedOnce = explodedOncePar; reset(); // Korrektur gewürfelte Würfel dürfen nicht kleiner sein als gezählte Würfel if(numberOfDice < diceCount && numberOfDice <= 10) { numberOfDice = diceCount; } // Überzähle gewürfelte Würfel werden mit 2:1 auf gewertete Würfel verlegt if(numberOfDice > 10) { int diceOvflow = numberOfDice-10; numberOfDice = 10; // Wenn gewertete 10 oder mehr, überzählige gewürfelte werden 1:2 auf Modifier gerechnet if(diceCount > 10) { modifier += diceOvflow*2; } else { if(diceCount + Math.floorDiv(diceOvflow, 2) <= 10) { diceCount += Math.floorDiv(diceOvflow, 2); } else { diceCount = 10; modifier += (diceCount + Math.floorDiv(diceOvflow, 2) - 10)*2; } } } if(diceCount > 10) { modifier += (diceCount-10)*2; diceCount = 10; } // Würfelarten durchgehen und Würfeln, Sonderwürfel werden imm am Schluss abgearbeitet StringBuilder resultConstruction = new StringBuilder(); rollDice(); // Modifikator separat behandeln, da er nicht gewürfelt wird if (modifier != 0) { resultInt += modifier; // Addiere den Modifikator zur Gesamtsum if (!resultConstruction.isEmpty()) { resultConstruction.append(modifier > 0 ? " + " : " - "); // Füge + oder - hinzu } resultConstruction.append(Math.abs(modifier)); // Zeige den absoluten Wert an } return new KeeprollResult(numberOfDice, diceCount, modifier, target, resultInt, rolls, isGlitches()); } /** * Eine innere Klasse, die das Ergebnis einer Earthdawn-Probe kapselt. * Dies macht die Rückgabe mehrerer Werte einfacher und lesbarer. */ public static class KeeprollResult { private final String resultStructur; private final boolean glitch; private final String title; public boolean isGlitch() { return glitch; } public KeeprollResult(int numberOfDice, int diceCount, int modifier, int target, int resultInt, result[] rolls, boolean glitch) { this.glitch = glitch; String addition = ""; if(modifier != 0) { if(modifier < 0) { addition += " - " + (modifier*-1) + " "; } else { addition += " + " + modifier + " "; } } if(target > 0) { addition += " Schwierigkeit " + target; } title = numberOfDice + "k" + diceCount + addition + ": " + resultInt; StringBuilder description = new StringBuilder(); for(int i = 0; i < numberOfDice; i++) { if(description.length() > 0) { description.append(", "); } description.append(rolls[i].getText()); } resultStructur = description.toString(); } public String getDescription() { return "(" + resultStructur + ")"; } public String getTitle() { return title; } } public boolean isGlitches() { return glitches; } private void rollDice() { rolls = new result[numberOfDice]; int [][] sortRolls = new int[numberOfDice][2]; resultInt = 0; for(int i = 0; i < numberOfDice; i++) { rolls[i] = new result(); rolls[i].setMaxReroll(explodedOnce).setReroll1(emphases).setExplode(explode).setNoreroll(unskilled); rolls[i].roll(); sortRolls[i][0] = i; sortRolls[i][1] = rolls[i].getValue(); } // sortierung Arrays.sort(sortRolls, Comparator.comparingInt(o -> o[1])); for(int i = numberOfDice; i > numberOfDice-diceCount; i--) { resultInt += sortRolls[i-1][1]; rolls[sortRolls[i-1][0]].setMarket(); } resultInt += modifier; // Border Farbe if(resultInt < target) { glitches = true; } } }