/// <summary> /// Generates a characteristic stat for a Character, based on parent stats /// </summary> /// <returns>Double containing characteristic stat</returns> /// <param name="mummyStat">The mother's characteristic stat</param> /// <param name="daddyStat">The father's characteristic stat</param> public static Double GenerateKeyCharacteristics(Double mummyStat, Double daddyStat) { Double newStat = 0; // get average of parents' stats Double parentalAverage = (mummyStat + daddyStat) / 2; // generate random (0 - 100) to determine relationship of new stat to parentalAverage double randPercentage = Utility_Methods.GetRandomDouble(100); // calculate new stat if (randPercentage <= 35) { newStat = parentalAverage; } else if (randPercentage <= 52.5) { newStat = parentalAverage - 1; } else if (randPercentage <= 70) { newStat = parentalAverage + 1; } else if (randPercentage <= 80) { newStat = parentalAverage - 2; } else if (randPercentage <= 90) { newStat = parentalAverage + 2; } else if (randPercentage <= 95) { newStat = parentalAverage - 3; } else { newStat = parentalAverage + 3; } // make sure new stat falls within acceptable range if (newStat < 1) { newStat = 1; } else if (newStat > 9) { newStat = 9; } return(newStat); }
/// <summary> /// Calculates casualties from a battle for both sides /// </summary> /// <returns>double[] containing percentage loss modifier for each side</returns> /// <param name="attackerTroops">uint containing attacking army troop numbers</param> /// <param name="defenderTroops">uint containing defending army troop numbers</param> /// <param name="attackerValue">uint containing attacking army battle value</param> /// <param name="defenderValue">uint containing defending army battle value</param> /// <param name="attackerVictorious">bool indicating whether attacking army was victorious</param> public static double[] CalculateBattleCasualties(uint attackerTroops, uint defenderTroops, uint attackerValue, uint defenderValue, bool attackerVictorious) { double[] battleCasualties = new double[2]; double largeArmyModifier = 0; bool largestWon = true; // determine highest/lowest battle value double maxBV = Math.Max(attackerValue, defenderValue); double minBV = Math.Min(attackerValue, defenderValue); // use BVs to determine high mark for base casualty rate of army with smallest battle value (see below) double highCasualtyRate = maxBV / (maxBV + minBV); // determine base casualty rate for army with smallest battle value double smallestModifier = Utility_Methods.GetRandomDouble(highCasualtyRate, min: 0.1); // determine if army with largest battle value won if (maxBV == attackerValue) { if (!attackerVictorious) { largestWon = false; } } else { if (attackerVictorious) { largestWon = false; } } // if army with largest battle value won if (largestWon) { // calculate casualty modifier for army with largest battle value // (based on adapted version of Lanchester's Square Law - i.e. largest army loses less troops than smallest) largeArmyModifier = (1 + ((minBV * minBV) / (maxBV * maxBV))) / 2; // attacker is large army if (attackerVictorious) { battleCasualties[1] = smallestModifier; // determine actual troop losses for largest army based on smallest army losses, // modified by largeArmyModifier uint largeArmyLosses = Convert.ToUInt32((defenderTroops * battleCasualties[1]) * largeArmyModifier); // derive final casualty modifier for largest army battleCasualties[0] = largeArmyLosses / (double)attackerTroops; } // defender is large army else { battleCasualties[0] = smallestModifier; uint largeArmyLosses = Convert.ToUInt32((attackerTroops * battleCasualties[0]) * largeArmyModifier); battleCasualties[1] = largeArmyLosses / (double)defenderTroops; } } // if army with smallest battle value won else { // calculate casualty modifier for army with largest battle value // this ensures its losses will be roughly the same as the smallest army (because it lost) largeArmyModifier = Utility_Methods.GetRandomDouble(1.20, min: 0.8); // defender is large army if (attackerVictorious) { // smallest army losses reduced because they won battleCasualties[0] = smallestModifier / 2; // determine actual troop losses for largest army based on smallest army losses, // modified by largeArmyModifier uint largeArmyLosses = Convert.ToUInt32((attackerTroops * battleCasualties[0]) * largeArmyModifier); // derive final casualty modifier for largest army battleCasualties[1] = largeArmyLosses / (double)defenderTroops; } // attacker is large army else { battleCasualties[1] = smallestModifier / 2; uint largeArmyLosses = Convert.ToUInt32((defenderTroops * battleCasualties[1]) * largeArmyModifier); battleCasualties[0] = largeArmyLosses / (double)attackerTroops; } } return(battleCasualties); }