public float[] GetCardProbabilitiesInDeck() { float[] result = new float[CardController.VALUE_PRINCESS + 1]; float sum = 0; for (int i = CardController.VALUE_GUARD; i <= CardController.VALUE_PRINCESS; i++) { result[i] = GetCardProbabilityInDeck(i); sum += result[i]; } Debug.AssertFormat(sum <= 0 || AIUtil.Approx(sum, 1f) || MyController.Game.Deck.CountCardsLeft < 1, "{0}: Deck card probabilities don't sum up to 1! ({1})", MyController, sum); return(result); }
// Precomputes the static arrays for quicker access protected static void PrecomputeStaticArrays() { // Initialized base deck distribution BaseDeckDistribution = new Distribution1D(CARD_VECTOR_LENGTH); for (int CardIndex = 0; CardIndex < CARD_VECTOR_LENGTH; CardIndex++) { BaseDeckDistribution[CardIndex] = ((float)GameController.CARD_COUNT[CardIndex + 1]) / GameController.TOTAL_CARD_COUNT; } // Initialize base joint hand distribution BaseThreeOpponentsHandsDistribution = new Distribution3D(CARD_VECTOR_LENGTH, CARD_VECTOR_LENGTH, CARD_VECTOR_LENGTH); // Optimization for the following calculation: int[] tempRemainingCards = new int[CARD_VECTOR_LENGTH]; // We can't use virtualRemainingCards in a static method... Array.Copy(GameController.CARD_COUNT, 1, tempRemainingCards, 0, CARD_VECTOR_LENGTH); float SumOfArray = 0, ScalingFactor = 1f / GameController.TOTAL_CARD_COUNT / (GameController.TOTAL_CARD_COUNT - 1) / (GameController.TOTAL_CARD_COUNT - 2); // Calculate base joint hand distribution for (int Hand1Index = 0; Hand1Index < CARD_VECTOR_LENGTH; Hand1Index++) { // Account for this value of the first hand float Hand1Prob = ScalingFactor * tempRemainingCards[Hand1Index]; tempRemainingCards[Hand1Index] -= 1; // And loop through all possible second and third hidden hands for (int Hand2Index = 0; Hand2Index < CARD_VECTOR_LENGTH; Hand2Index++) { // Account for this value of the second hand float Hand2JointProb = Hand1Prob * tempRemainingCards[Hand2Index]; tempRemainingCards[Hand2Index] -= 1; // And loop through all possible third hidden hands for (int Hand3Index = 0; Hand3Index < CARD_VECTOR_LENGTH; Hand3Index++) { // If this is an impossible case, just jump to the next iteration if (Hand2JointProb <= 0 || tempRemainingCards[Hand3Index] <= 0) { continue; } // Otherwise, calculate the joint probability of this case and store it float jointProb = Hand2JointProb * tempRemainingCards[Hand3Index]; BaseThreeOpponentsHandsDistribution[Hand1Index, Hand2Index, Hand3Index] = jointProb; SumOfArray += jointProb; } // Reset card counts for the next iteration tempRemainingCards[Hand2Index] += 1; } // Reset card counts for the next iteration tempRemainingCards[Hand1Index] += 1; } Debug.Assert(AIUtil.Approx(SumOfArray, 1f)); }
public float[] GetCardProbabilitiesInHand(PlayerController Player) { float[] result = new float[CardController.VALUE_PRINCESS + 1]; // If no player is specified (when called for a non-targeted card), just return an empty array if (Player != null) { float sum = 0; for (int i = CardController.VALUE_GUARD; i <= CardController.VALUE_PRINCESS; i++) { result[i] = GetCardProbabilityInHand(Player, i); sum += result[i]; } Debug.AssertFormat(sum <= 0 || AIUtil.Approx(sum, 1f), "{0}: Hand card probabilities of {2} don't sum up to 1! ({1})", MyController, sum, Player); } return(result); }