/*
     * 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();
    }
Example #4
0
 public ExecuteActionsState(BattleUIManager ui, PlayerActionResult playerAction, EnemyActionResult enemyAction)
 {
     uiManager         = ui;
     this.playerAction = playerAction;
     this.enemyAction  = enemyAction;
 }