/** * written by Alex Shields * March 21, 2008 * Compiled and ran with Java 1.5.0_06 */ /* In a battle of Legion vs. Phalanx, each with the following info: Legion: 2 hp, att of 3, firepower of 1 Phalanx: 2 hp, def of 2, firepower of 1 Legion is the attacker. Make all combinations. Those are: L L L L L P L P L L P P P L L P L P P P L P P P Assign percentages to each slot. .6 .6 .6 .6 .6 .4 .6 .4 .6 .6 .4 .4 .4 .6 .6 .4 .6 .4 .4 .4 .6 .4 .4 .4 Compute each of those lines using multiplication. .216 .144 .144 .096 .144 .096 .096 .064 Add all of those to see if we get 1. They do. Now compute the results as Legion wins with x hitpoints remaining, Phalanx wins with x hitpoints remaining. L wins with 2 hp 36% L wins with 2 hp L wins with 1 hp 28.8% P wins with 1 hp 19.2% L wins with 1 hp P wins with 1 hp P wins with 2 hp 16% P wins with 2 hp Algorithm: The number of rounds is: ad=int(attackerHp/defenderFp) da=int(defenderHp/attackerFp) numRounds=ad+da-1 Build an array with numRounds elements. For each element in the array, assign a value to it indicating that the attacker or the defener hit. For example: A,A,A and then A,A,D and so on. For each combination of values, determine what is the percentage that it would occur. For the legion vs. the phalanx, A,A,A has a 3/5 ^ 3 chance of occuring. For A,A,D, it is 3/5 * 3/5 * 2/5. Double variable types must be used due to the immense values that the denominator could have if using integers only. Consider a civ2 battleship vs another battleship. Each have 40 hp. After computing the percentage chance that a particular combination will happen, determine who would win that particular combination. Store that percent into a HashMap. */ import java.io.*; import java.util.*; public class UnitCombatPercents { private int attValue, defValue, attHp, defHp, attFp, defFp; // How many of each show the number of victories with this many // hitpoints remaining. key=number of hitpoints. value=the number of times // that particular hitpoint number resulted in the rounds of battle. HashMap attackerWins, defenderWins; public UnitCombatPercents(int attValue, int defValue, int attHp, int defHp, int attFp, int defFp) { this.attValue=attValue; this.defValue=defValue; this.attHp=attHp; this.defHp=defHp; this.attFp=attFp; this.defFp=defFp; attackerWins=new HashMap(); defenderWins=new HashMap(); } /** */ public String[] getStatisticalResults() { int numRounds, a, b, attackerHp, defenderHp, sumOfAttAndDef; double attTotalVictories, defTotalVictories; Double doubleVal; ArrayList results; double percentOfRounds; double percentForAttHit, percentForDefHit; double finalPercentForAttWin, finalPercentForDefWin; boolean hasReachedTheEnd, hasAttWon, hasDefWon; int attRemainingHpAtVictory, defRemainingHpAtVictory; // Only has 1 or 0 in it! // 0 is attacker hit, 1 is defender hit. int[] counterOfRounds; attTotalVictories=0L; defTotalVictories=0L; a=(int)Math.ceil(attHp/(double)defFp); b=(int)Math.ceil(defHp/(double)attFp); numRounds=a+b-1; sumOfAttAndDef=attValue+defValue; percentForAttHit=attValue/(double)sumOfAttAndDef; percentForDefHit=defValue/(double)sumOfAttAndDef; //out("numRounds is " + numRounds); //out("sumOfAttAndDef is " + sumOfAttAndDef); //out("percentForAttHit is " + percentForAttHit); //out("percentForDefHit is " + percentForDefHit); out("The number of combinations to handle is " + Math.pow(2.0, (double)numRounds)); counterOfRounds=new int[numRounds]; // Initialization for (int i=0; i1) { counterOfRounds[i]=0; counterOfRounds[i+1]++; } } } // Build results. results=new ArrayList(); finalPercentForAttWin=finalPercentForDefWin=0; for (attackerHp=attHp;attackerHp>0;attackerHp--) { doubleVal=attackerWins.get(attackerHp); if (doubleVal==null) continue; finalPercentForAttWin+=doubleVal.doubleValue(); results.add("Attacker wins with " + attackerHp + " hitpoints remaining. Probability: " + doubleVal.doubleValue() * 100 + "%"); } for (defenderHp=defHp;defenderHp>0;defenderHp--) { doubleVal=defenderWins.get(defenderHp); if (doubleVal==null) continue; finalPercentForDefWin+=doubleVal.doubleValue(); results.add("Defender wins with " + defenderHp + " hitpoints remaining. Probability: " + doubleVal.doubleValue() * 100 + "%"); } results.add("Attacker wins: Probability: " + finalPercentForAttWin*100+ "%"); results.add("Defender wins: Probability: " + finalPercentForDefWin*100+ "%"); return (String[])results.toArray(new String[0]); } public static void main(String[] args) throws Exception { int attV, defV, attH, defH, attF, defF; BufferedReader reader; InputStreamReader isr; isr=new InputStreamReader(System.in); reader=new BufferedReader(isr); out("Press ^C to stop this program."); out("Enter the attacker's attack value:"); attV=readInt(reader); out("Enter the defender's defense value."); defV=readInt(reader); out("Enter the attacker's hitpoints."); attH=readInt(reader); out("Enter the defender's hitpoints."); defH=readInt(reader); out("Enter the attacker's firepower."); attF=readInt(reader); out("Enter the defender's firepower."); defF=readInt(reader); UnitCombatPercents uc=new UnitCombatPercents(attV, defV, attH, defH, attF, defF); String[] results; results=uc.getStatisticalResults(); out("attValue: " + attV + ", attHp: " + attH + ", attFp: " + attF); out("defValue: " + defV + ", defHp: " + defH + ", defFp: " + defF); for (int i=0; i0) out("Exception caught while trying to read an Integer. Please enter your integer again."); } } return i; } }