/* * Perform Bayesian updates to calculate the true probability distribution * over enemy elements given the region, attributes, and actions. */ public static ElementDistribution ComputePosterior( Region region, Attribute attr, List <PlayerActionResult> player_actions, List <EnemyActionResult> enemy_actions) { // Step 1: Incorporate the prior information from the region. ElementDistribution prior = P_ELEMENT_GIVEN_REGION[region]; ElementDistribution posterior = Normalize(prior); // Step 2: Incorporate the attribute that was observed. ElementDistribution p_attr_all_elements = new ElementDistribution(); // i.e p(furry | water) List <Element> element_list = new List <Element>(P_ATTR_GIVEN_ELEMENT.Keys); for (int i = 0; i < element_list.Count; ++i) { Element element = element_list[i]; p_attr_all_elements.Add(element, P_ATTR_GIVEN_ELEMENT[element][attr]); } posterior = Normalize(Multiply(posterior, p_attr_all_elements)); // Step 3: Incorporate player actions. for (int i = 0; i < player_actions.Count; ++i) { PlayerActionResult action = player_actions[i]; for (int el_i = 0; el_i < element_list.Count; ++i) { Element possible_enemy_element = element_list[i]; int matchup_multiplier = ElementOrdering.Compare(action.element, possible_enemy_element); double accuracy_vs_element = ClampZeroOne(action.attack.accuracy + matchup_multiplier * GameStateManager.GameConstants.SUPER_EFFECTIVE_ACCURACY_BONUS); // For this possible enemy element, what is the probability of the outcome observed? double p_of_result = action.successful ? accuracy_vs_element : (1.0 - accuracy_vs_element); posterior[possible_enemy_element] *= p_of_result; } } posterior = Normalize(posterior); // Normalize again. // Step 4: Incorporate enemy actions. for (int i = 0; i < enemy_actions.Count; ++i) { EnemyActionResult action = enemy_actions[i]; for (int el_i = 0; el_i < element_list.Count; ++i) { Element possible_enemy_element = element_list[i]; int matchup_multiplier = ElementOrdering.Compare(possible_enemy_element, action.player_element_during); double accuracy_vs_player = ClampZeroOne(action.accuracy + matchup_multiplier * GameStateManager.GameConstants.SUPER_EFFECTIVE_ACCURACY_BONUS); // For this possible enemy element, what is the probability that their attack hit/missed? double p_of_result = action.successful ? accuracy_vs_player : (1.0 - accuracy_vs_player); posterior[possible_enemy_element] *= p_of_result; } } posterior = Normalize(posterior); // Normalize again. return(posterior); }
private void OnClick() { // Tell the BattleManager that an element was selected in the UI. UIHUDCanvas.GetComponent <BattleManager>().UISelectPlayerElement(this.thisButtonElement); // Indicate that this button is selected. UICurrentElementText.GetComponent <TextMeshProUGUI>().text = this.thisButtonElement.ToString(); Element effectiveElement = ElementOrdering.GetEffective(thisButtonElement); Element ineffectiveElement = ElementOrdering.GetIneffective(thisButtonElement); UIAccuracyModifierDescriptionText.GetComponent <TextMeshProUGUI>().text = "+30% accuracy against " + effectiveElement + "\n" + "-30% accuracy against " + ineffectiveElement; this.transform.parent.gameObject.SetActive(false); }
/* * Perform a specified attack on another ActorManager. * This function will simulate whether the attack hits, * and apply the damage to the target if so. */ public bool DoAttack(ActorManager target, Attack attack) { double random_val = rng.NextDouble(); // Although the player doesn't know the enemy's element type, the attack simulator // here needs to know it. int matchup_multiplier = ElementOrdering.Compare(this.Element, target.Element); double accuracy = attack.accuracy + matchup_multiplier * GameStateManager.GameConstants.SUPER_EFFECTIVE_ACCURACY_BONUS; // Simulate whether the attack should hit. if (random_val <= accuracy) { target.ReceiveDamage(attack.damage); return(true); } return(false); }