private void UpdateDisplay(bool updateLED = true, bool UpdateCharacter = true, bool UpdateInventory = true, bool forceUpdate = false) { if (!_NO_SIMULATION_RUNNING && !forceUpdate) { return; } if (UpdateCharacter) { CharacterText.text = _character.Name; CharacterText.color = _colorValues[(int)_season]; if (updateLED) { OffLED.SetActive(!_spellBonus); OnLED.SetActive(_spellBonus); } } if (UpdateInventory) { InventoryText.text = _inventory[_currentInventoryItem].Item; } StageNumberText.text = string.Format("{0}", _losses + 1); IncidentSet incident = new IncidentSet(); if ((int)_incident < _incidedentSets.Count && (int)_incident >= 0) { incident = _incidedentSets[(int)_incident]; } IncidentText.text = incident.Name; }
private void PrintIncident(IncidentSet incident, bool boss1, bool bossbonus, out int distance, out int range) { if (incident == null) { distance = 0; range = 0; return; } Boss boss = boss1 ? incident.Boss1 : incident.Boss2; if (boss == null) { distance = 0; range = 0; return; } distance = boss.BaseDistance + boss.EdgeworkBonusDistance; range = boss.BaseRange + boss.EdgeworkBonusRange; if (bossbonus) { distance += boss.BonusDistance; range += boss.BonusRange; } if (_widgetbonus) { distance += boss.WidgetBonusDistance; range += boss.WidgetBonusRange; } if (!_NO_SIMULATION_RUNNING) { return; } BombModule.LogFormat("Fighting {0} - Distance = {1}, Range = {2}", boss.Name, boss.BaseDistance, boss.BaseRange); if (bossbonus) { PrintBonus(boss.BonusDistance, boss.BonusRange, incident.BonusReason); } PrintBonus(boss.EdgeworkBonusDistance, boss.EdgeworkBonusRange, incident.EdgeworkBonusReason); if (_widgetbonus) { PrintBonus(boss.WidgetBonusDistance, boss.WidgetBonusRange, incident.WidgetBonusReason); } }
void ReportWinResults(int BossBuff, bool printBuffInfo) { if (_WINSBOSS1 > 0 || _LOSSESBOSS1 > 0) { IncidentResults[_incident][0]++; IncidentResults[_incident][1] += _WINSBOSS1; IncidentResults[_incident][2] += _LOSSESBOSS1; } if (_WINSBOSS2 > 0 || _LOSSESBOSS2 > 0) { IncidentResults[_incident][3]++; IncidentResults[_incident][4] += _WINSBOSS2; IncidentResults[_incident][5] += _LOSSESBOSS2; } IncidentSet incident = _incidedentSets[(int)_incident]; if (printBuffInfo) { BombModule.LogFormat("results with {0}/{0} Dist/Range {1}:", BossBuff, (BossBuff < 0 ? "penalty" : (BossBuff > 0 ? "bonus" : "bonus/penalty"))); } if (_WINSBOSS1 > 0 || _LOSSESBOSS1 > 0) { BombModule.LogFormat("Boss #1 ({0}): W/L: {1}/{2}", incident.Boss1.Name, _WINSBOSS1, _LOSSESBOSS1); } if (_WINSBOSS2 > 0 || _LOSSESBOSS2 > 0) { BombModule.LogFormat("Boss #2 ({0}): W/L: {1}/{2}", incident.Boss2.Name, _WINSBOSS2, _LOSSESBOSS2); } _WINSBOSS1 = 0; _LOSSESBOSS1 = 0; _WINSBOSS2 = 0; _LOSSESBOSS2 = 0; }
private void Initialize(int BossBuff, bool TwoFactorUpdate) { if (_solved) { return; } int BossDistance; int BossRange; IncidentSet incident = new IncidentSet { Name = "Error" }; if ((int)_incident < _incidedentSets.Count && (int)_incident >= 0) { incident = _incidedentSets[(int)_incident]; } bool boss1 = true; bool bossbonus = false; if (!TwoFactorUpdate) { RandomizeCharacter(); RandomizeInventory(); if (_NO_SIMULATION_RUNNING) { UpdateDisplay(); BombModule.LogFormat("Resolving Incident: {0}", incident.Name); } } else { if (_NO_SIMULATION_RUNNING) { UpdateDisplay(); BombModule.LogFormat("Updating Incident {0} results based on a change in the Two Factor sum", incident.Name); } } bool Strikes = false; OddStrikes: if (_incident == Incidents.WorldlyDesires) { NoSimulationLog(!Strikes ? "Calculating the results for Even number of Strikes" : "Calculating the results for Odd number of Strikes"); } int CharacterDistance = _characterBaseDistance; int CharacterRange = _characterBaseRange; NoSimulationLog("Chararcter: {0} - Distance = {1}, Range = {2}, Season = {3}", _character.Name, CharacterDistance, CharacterRange, _season); if (_character.Heroine) { CharacterDistance++; CharacterRange++; NoSimulationLog("Character is a Heroine, Gets a bonus of 1/1 to Distance/Range"); } if (_spellBonus) { CharacterDistance += _character.DistanceBonus; CharacterRange += _character.RangeBonus; NoSimulationLog("Spell Bonus is Active. Character gets a bonus of {0} to Distance and {1} to Range", _character.DistanceBonus, _character.RangeBonus); } switch (_incident) { case Incidents.CosmicWeather: bossbonus = _season == CharacterSeasons.Summer; break; case Incidents.EndlessParty: boss1 = _edgeworkDefinedBoss; break; case Incidents.FairyWars: boss1 = _season == CharacterSeasons.Fall || _season == CharacterSeasons.Winter; bossbonus = _season == CharacterSeasons.Winter || _season == CharacterSeasons.Summer; break; case Incidents.LilyBlackandWhite: boss1 = _season == CharacterSeasons.Summer || _season == CharacterSeasons.Fall; bossbonus = _season == CharacterSeasons.Spring || _season == CharacterSeasons.Summer; break; case Incidents.LunarWar: boss1 = _edgeworkDefinedBoss; break; case Incidents.OccultInvasion: bossbonus = _season == CharacterSeasons.Spring || _season == CharacterSeasons.Summer; break; case Incidents.OverdrivenNight: boss1 = _season == CharacterSeasons.Fall || _season == CharacterSeasons.Winter; break; case Incidents.UndefinedFantasticObject: boss1 = _edgeworkDefinedBoss; break; case Incidents.ScarletMist: boss1 = _edgeworkDefinedBoss; break; case Incidents.WorldlyDesires: boss1 = Strikes; break; case Incidents.None: ForcePass("No idea why Incident.None was picked. That should not have happened."); return; default: ForcePass("Unknown Incident: {0}", _incident); return; } PrintIncident(incident, boss1, bossbonus, out BossDistance, out BossRange); foreach (Inventory item in _inventory.OrderBy(x => x.Item)) { string footer = ""; if (item == FindBestDistanceAdvantage) { int i = item.Distance; footer = " <--- Best Distance advantage"; if (_inventory.Count(x => x.Distance == i) > 1) { footer += " and worst Range disadvantage"; } } else if (item == FindBestRangeAdvantage) { int i = item.Range; footer = " <--- Best Range advantage"; if (_inventory.Count(x => x.Range == i) > 1) { footer += " and worst Distance disadvantage"; } } NoSimulationLog("Item: {0}, Distance: {1}, Range: {2}{3}", item.Item, item.Distance, item.Range, footer); } CharacterDistance += FindBestDistanceAdvantage.Distance; CharacterRange += FindBestDistanceAdvantage.Range; CharacterDistance += FindBestRangeAdvantage.Distance; CharacterRange += FindBestRangeAdvantage.Range; NoSimulationLog("Final character results - Distance = {0}, Range = {1}", CharacterDistance, CharacterRange); NoSimulationLog("Final Boss results - Distance = {0}, Range = {1}", BossDistance, BossRange); BossRange += BossBuff; BossDistance += BossBuff; bool BossWins = BossRange >= CharacterDistance; bool CharacterWins = CharacterRange >= BossDistance; if (CharacterWins) { NoSimulationLog(BossWins ? "Although the Boss was defeated, the character died in the process." : "The Boss was defeated and the character returned victorious"); } else { NoSimulationLog(BossWins ? "The character was killed by the boss" : "The Battle ended in a stale-mate"); } IncidentResult correctResult; if (CharacterWins && BossWins) { correctResult = _losses < 2 ? IncidentResult.Loss : IncidentResult.Win; } else { correctResult = CharacterWins ? IncidentResult.Win : IncidentResult.Loss; } NoSimulationLog("Expecting {0} to be pressed.", correctResult); if (!Strikes) { _correctIncidentResultEvenStrike = correctResult; } else { _correctIncidentResultOddStrike = correctResult; } if (boss1) { if (CharacterWins && BossWins) { _BOTHDEFEATEDLOSS = !_BOTHDEFEATEDLOSS; if (_BOTHDEFEATEDLOSS) { _WINSBOSS1++; } else { _LOSSESBOSS1++; } } else if (CharacterWins) { _WINSBOSS1++; } else { _LOSSESBOSS1++; } } else { if (CharacterWins && BossWins) { _BOTHDEFEATEDLOSS = !_BOTHDEFEATEDLOSS; if (_BOTHDEFEATEDLOSS) { _WINSBOSS2++; } else { _LOSSESBOSS2++; } } else if (CharacterWins) { _WINSBOSS2++; } else { _LOSSESBOSS2++; } } if (_incident == Incidents.WorldlyDesires) { NoSimulationLog(!Strikes ? "Done calculating for Even strikes" : "Done calculating for Odd strikes"); if (!Strikes) { Strikes = true; goto OddStrikes; } } else { _correctIncidentResultOddStrike = _correctIncidentResultEvenStrike; } }
private void SetEdgeworkBonus() { _characterBaseDistance = BombInfo.GetBatteryCount() == 0 ? 3 : BombInfo.GetBatteryCount(); _characterBaseRange = BombInfo.GetBatteryHolderCount() == 0 ? 3 : BombInfo.GetBatteryHolderCount(); if (!_widgetbonus) { while (_characterBaseDistance > 5) { _characterBaseDistance -= 5; } while (_characterBaseRange > 5) { _characterBaseRange -= 5; } } else { while (_characterBaseDistance < 5) { _characterBaseDistance += 5; } while (_characterBaseRange < 5) { _characterBaseRange += 5; } while (_characterBaseDistance > 10) { _characterBaseDistance -= 5; } while (_characterBaseRange > 10) { _characterBaseRange -= 5; } } IncidentSet incident = new IncidentSet { Name = "Error" }; if ((int)_incident < _incidedentSets.Count && (int)_incident >= 0) { incident = _incidedentSets[(int)_incident]; } switch (_incident) { case Incidents.CosmicWeather: bool heavenlyNoEmptyPlatesBonus = BombInfo.GetPortPlates().All(x => x.Length != 0) && (BombInfo.GetPortCount() % 2) == 1; int heavenlyBonus = (BombInfo.GetPortCount() / 2); if (heavenlyNoEmptyPlatesBonus) { heavenlyBonus++; } incident.Boss1.EdgeworkBonusDistance = heavenlyBonus; incident.EdgeworkBonusReason = string.Format("port counts divided by two{0}", heavenlyNoEmptyPlatesBonus ? " rounded up" : " rounded down"); break; case Incidents.EndlessParty: _edgeworkDefinedBoss = BombInfo.CountUniquePorts() < 3; int shamanBonus = BombInfo.GetSerialNumberNumbers().Min(); if (shamanBonus == 0) { shamanBonus = 10; } incident.EdgeworkBonusReason = "the last serial number digit"; incident.Boss1.EdgeworkBonusDistance = shamanBonus; incident.Boss2.EdgeworkBonusRange = shamanBonus; break; case Incidents.FairyWars: int FairyBonus = BombInfo.CountUniquePorts(); incident.Boss1.EdgeworkBonusDistance = FairyBonus; incident.Boss1.EdgeworkBonusRange = FairyBonus; incident.Boss2.EdgeworkBonusDistance = FairyBonus; incident.Boss2.EdgeworkBonusRange = FairyBonus; incident.EdgeworkBonusReason = "unique ports divided by two"; break; case Incidents.LilyBlackandWhite: break; case Incidents.LunarWar: _edgeworkDefinedBoss = BombInfo.CountDuplicatePorts() != 1; if (BombInfo.GetSerialNumberNumbers().Sum() <= 11) { incident.Boss1.EdgeworkBonusDistance = incident.Boss1.BonusDistance; incident.Boss1.EdgeworkBonusRange = incident.Boss1.BonusRange; incident.Boss2.EdgeworkBonusDistance = incident.Boss2.BonusDistance; incident.Boss2.EdgeworkBonusRange = incident.Boss2.BonusRange; incident.EdgeworkBonusReason = incident.BonusReason; } break; case Incidents.OccultInvasion: int LegendaryBonus = BombInfo.GetModuleNames().Count % 5; bool LegendaryIndicator = BombInfo.GetOnIndicators().Count(x => "LEGEND".Contains(x.ToUpperInvariant().ToCharArray().Last())) == 2; if (LegendaryBonus == 0 && LegendaryIndicator) { LegendaryBonus = 5; } incident.Boss1.EdgeworkBonusDistance = LegendaryBonus; incident.EdgeworkBonusReason = LegendaryBonus == 5 ? "Two indicators ending in a letter contained in \"LEGEND\"" : "Module count modulo 5"; break; case Incidents.OverdrivenNight: incident.Boss1.EdgeworkBonusRange = BombInfo.GetOffIndicators().Count(); incident.Boss2.EdgeworkBonusRange = BombInfo.GetOffIndicators().Count(); incident.EdgeworkBonusReason = "the number of unlit Indicators"; break; case Incidents.UndefinedFantasticObject: _edgeworkDefinedBoss = BombInfo.GetOffIndicators().Count() > BombInfo.GetOnIndicators().Count(); int undefineduniqueports = BombInfo.CountUniquePorts(); incident.Boss1.EdgeworkBonusDistance = undefineduniqueports; incident.Boss1.EdgeworkBonusRange = undefineduniqueports; incident.Boss2.EdgeworkBonusRange = undefineduniqueports; incident.EdgeworkBonusReason = "the number of unique port types"; break; case Incidents.ScarletMist: _edgeworkDefinedBoss = BombInfo.GetSerialNumberLetters().Count() > BombInfo.GetSerialNumberNumbers().Count(); int scarletdisadvantage = BombInfo.GetOnIndicators().Count(); if (_NO_SIMULATION_RUNNING) { _twofactorsum = BombInfo.IsTwoFactorPresent() ? BombInfo.GetTwoFactorCodes().Sum(twofactor => twofactor % 10) : BombInfo.GetSerialNumberNumbers().Last(); foreach (int twofactor in BombInfo.GetTwoFactorCodes()) { BombModule.LogFormat("Two Factor code changed: {0}", twofactor); } } else { _twofactorsum = BombInfo.IsTwoFactorPresent() ? 0 : BombInfo.GetSerialNumberNumbers().Last(); } scarletdisadvantage += _twofactorsum; incident.Boss1.EdgeworkBonusDistance = -scarletdisadvantage; incident.Boss1.EdgeworkBonusRange = -scarletdisadvantage; incident.Boss2.EdgeworkBonusDistance = -scarletdisadvantage; incident.Boss2.EdgeworkBonusRange = -scarletdisadvantage; incident.EdgeworkBonusReason = string.Format("based on the number of lit indicators and {0}", BombInfo.IsTwoFactorPresent() ? "two factor least significant digit sum" : "last serial number digit"); break; case Incidents.WorldlyDesires: int hermitpenalty = -BombInfo.GetPortCount(); incident.Boss1.EdgeworkBonusRange = hermitpenalty; incident.Boss2.EdgeworkBonusRange = hermitpenalty; incident.EdgeworkBonusReason = "the number of ports"; break; case Incidents.None: ForcePass("No idea why Incident.None was picked. That should not have happened."); return; default: ForcePass("Unknown Incident: {0}", _incident); return; } }
IEnumerator SimulatateBattles(int debuff, int buff) { if (IsSimulationRunning) { IsItMyTurnYet = BombModule.GetIDNumber(); IsSimulationRunning = false; } yield return(null); yield return(null); _NO_SIMULATION_RUNNING = false; BombModule.LogFormat("DEBUGGING MODE ENABLED"); while (IsItMyTurnYet < BombModule.GetIDNumber()) { yield return(null); } IsSimulationRunning = true; if (_sets == 0) { InitializeItemSets(); } if (!BombSerialNumber.Equals(BombInfo.GetSerialNumber())) { BombSerialNumber = BombInfo.GetSerialNumber(); BombModule.LogFormat("------------------"); BombModule.LogFormat("Simulation Results"); BombModule.LogFormat("------------------"); BombModule.LogFormat(""); foreach (Incidents incident in _incidents.Skip(1)) { _incident = incident; int battles = _sets * 4 * 2 * _characters.Count(x => x.ForbiddenIncident != _incident); SetEdgeworkBonus(); IncidentSet incidentSet = _incidedentSets[(int)_incident]; BombModule.LogFormat("Simulating Incident: {0}", incidentSet.Name); IncidentText.text = _incident.ToString(); InventoryText.characterSize = 0.7f; for (int j = debuff; j <= buff; j++) { int i = 0; foreach (Character c in _characters.Where(x => x.ForbiddenIncident != incident)) { _character = c; foreach (CharacterSeasons s in _seasons) { _season = s; foreach (Inventory[] items in _itemSets.Values) { _inventory = items.ToList(); _spellBonus = false; Initialize(j, true); _spellBonus = true; Initialize(j, true); i += 2; if ((i % 50) == 0) { UpdateDisplay(true, true, false, true); InventoryText.text = string.Format("{0}/{1}\n{2}: {3}/{4}", i + 1, battles, j < 0 ? "penalty" : "bonus", j, buff); yield return(null); } } } } ReportWinResults(j, debuff != buff); } } BombModule.LogFormat(""); BombModule.LogFormat("---------------"); BombModule.LogFormat("Average Results"); BombModule.LogFormat("---------------"); BombModule.LogFormat(""); foreach (Incidents incident in _incidents.Skip(1)) { IncidentSet incidentSet = _incidedentSets[(int)incident]; BombModule.LogFormat("Incident {0}:", incidentSet.Name); if (IncidentResults[incident][0] > 0) { BombModule.LogFormat("Boss #1 ({0}): W/L: {1:0.##}/{2:0.##} ({3} Bombs)", incidentSet.Boss1.Name, (float)IncidentResults[incident][1] / IncidentResults[incident][0], (float)IncidentResults[incident][2] / IncidentResults[incident][0], IncidentResults[incident][0]); } if (IncidentResults[incident][3] > 0) { BombModule.LogFormat("Boss #2 ({0}): W/L: {1:0.##}/{2:0.##} ({3} Bombs)", incidentSet.Boss2.Name, (float)IncidentResults[incident][4] / IncidentResults[incident][3], (float)IncidentResults[incident][5] / IncidentResults[incident][3], IncidentResults[incident][3]); } } BombModule.LogFormat(""); } BombModule.LogFormat("--------------"); BombModule.LogFormat("Battle Results"); BombModule.LogFormat("--------------"); BombModule.LogFormat(""); _NO_SIMULATION_RUNNING = true; foreach (Incidents incident in _incidents.Skip(1)) { BombModule.LogFormat("--------------"); _incident = incident; Initialize(); BombModule.LogFormat("--------------"); } IsItMyTurnYet++; IsSimulationRunning = false; BombModule.HandlePass(); if (IsItMyTurnYet <= KMBombModuleExtensions.HighestConsecutiveID) { yield break; } yield return(new WaitForSeconds(1)); BombModule.HandleStrike(); }