/* * 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); }
public void AppendEnemyLogEntry(EnemyActionResult result) { GameObject entry = Instantiate(moveLogEntryPrefab); string entryText = "Enemy attack " + (result.successful ? "hit!" : "failed"); entry.GetComponent <TextMeshProUGUI>().text = entryText; entry.transform.SetParent(this.transform, false); // Really important to use false here!!!! entries.Add(entry); }
/* * Waits asynchronously for a few seconds before taking the enemy's turn. */ private IEnumerator HandleEnemyTurn(GameObject enemy_unit) { yield return(new WaitForSeconds(2.0f)); bool successful = enemyManager.DoAttack(playerManager, new GenericEnemyAttack()); StartCoroutine(ShowEnemyHitOrMissText(successful)); if (successful) { IEnumerator coroutine = DoBlinkingEffect(0.2f, 0.05f); StartCoroutine(coroutine); } // It's critical that the playerManager.Element doesn't change between when the enemy // does its attack and when this action result is added to the move log. EnemyActionResult enemy_result = new EnemyActionResult(successful, playerManager.Element); UIMoveLogMenu.GetComponent <MoveLogManager>().AppendEnemyLogEntry(enemy_result); this.NextTurn(); }
public ExecuteActionsState(BattleUIManager ui, PlayerActionResult playerAction, EnemyActionResult enemyAction) { uiManager = ui; this.playerAction = playerAction; this.enemyAction = enemyAction; }