Exemple #1
0
    // Card filter: GUARD, when played against anyone but me.
    public void GuardFilter(int TargetSittingOrder, int GuessedValue)
    {
        Debug.Assert(TargetSittingOrder != MySittingOrder);
        Debug.Assert(GuessedValue >= CardController.VALUE_PRIEST && GuessedValue <= CardController.VALUE_PRINCESS);
        int CardIndex       = GuessedValue - 1;
        int HiddenHandIndex = GetHiddenHandIndex(TargetSittingOrder);

        // Update and renormalize the appropriate matrix
        if (CurrentOpponentCount == 3)
        {
            // In case of THREE remaining opponents, update the ThreeOpponentsHandsDistribution
            ThreeOpponentsHandsDistribution.ClearSlice(HiddenHandIndex, CardIndex);
            ThreeOpponentsHandsDistribution.Renormalize();
        }
        else if (CurrentOpponentCount == 2)
        {
            // In case of TWO remaining opponents, update the TwoOpponentsHandsDistribution
            TwoOpponentsHandsDistribution.ClearSlice(HiddenHandIndex, CardIndex);
            TwoOpponentsHandsDistribution.Renormalize();
        }
        else if (CurrentOpponentCount == 1)
        {
            // In case of ONE remaining opponents, update the SingleOpponentHandDistribution
            SingleOpponentHandDistribution[CardIndex] = 0;
            SingleOpponentHandDistribution.Renormalize();
        }
    }
Exemple #2
0
    // On a knock-out, reduce the dimension of the joint distribution array and renormalize it
    public void KnockOutFilter(int SittingOrder, int DiscardedValue)
    {
        Debug.Assert(SittingOrder != MySittingOrder);
        Debug.Assert(DiscardedValue >= CardController.VALUE_GUARD && DiscardedValue <= CardController.VALUE_PRINCESS);
        int CardIndex       = DiscardedValue - 1;
        int HiddenHandIndex = GetHiddenHandIndex(SittingOrder);

        // Account for the discared card
        AccountForCard(DiscardedValue);
        // Merge down the current matrix to one dimension lower, taking the slice that corresponds to the knocked-out player's actual hand
        if (CurrentOpponentCount == 3)
        {
            TwoOpponentsHandsDistribution = ThreeOpponentsHandsDistribution.GetSlice(HiddenHandIndex, CardIndex);
            TwoOpponentsHandsDistribution.Renormalize();
            // Also, we move out the knocked-out player's sitting order to the last place of the HiddenHands array
            AIUtil.ShiftToLast(ref HiddenHands, HiddenHandIndex);
        }
        else if (CurrentOpponentCount == 2)
        {
            SingleOpponentHandDistribution = TwoOpponentsHandsDistribution.GetSlice(HiddenHandIndex, CardIndex);
            SingleOpponentHandDistribution.Renormalize();
            AIUtil.ShiftToLast(ref HiddenHands, HiddenHandIndex);
        }
        // Update player situation
        CurrentOpponentCount            -= 1;
        PlayerIsKnockedOut[SittingOrder] = true;
    }
Exemple #3
0
 // During the basic opponent turn update, we need to update the joint probability distribution
 // using just the information about which card he has just played
 protected void FilterHiddenHand(MoveData TurnData)
 {
     Debug.Assert(TurnData.Player.SittingOrder != MySittingOrder);
     Debug.Assert(!PlayerIsKnockedOut[TurnData.Player.SittingOrder]);
     Debug.Assert(TurnData.Card.Value >= CardController.VALUE_GUARD && TurnData.Card.Value <= CardController.VALUE_PRINCESS);
     // Update the hand distribution matrices
     if (CurrentOpponentCount == 3)
     {
         // Prepare a temporary array
         tempArray3D.Clear();
         // Loop through all possible world states and update the tempoprary array accordingly
         for (int h0 = 0; h0 < CARD_VECTOR_LENGTH; h0++)
         {
             for (int h1 = 0; h1 < CARD_VECTOR_LENGTH; h1++)
             {
                 for (int h2 = 0; h2 < CARD_VECTOR_LENGTH; h2++)
                 {
                     UpdatePartialHandDistribution(TurnData, h0, h1, h2, ref tempArray3D);
                 }
             }
         }
         // Renormalize the temporary array and write it back to the three-player distribution
         tempArray3D.Renormalize();
         ThreeOpponentsHandsDistribution.CopyFrom(tempArray3D);
     }
     else if (CurrentOpponentCount == 2)
     {
         // Prepare a temporary array
         tempArray2D.Clear();
         // Loop through all possible world states and update the tempoprary array accordingly
         for (int h0 = 0; h0 < CARD_VECTOR_LENGTH; h0++)
         {
             for (int h1 = 0; h1 < CARD_VECTOR_LENGTH; h1++)
             {
                 UpdatePartialHandDistribution(TurnData, h0, h1, ref tempArray2D);
             }
         }
         // Renormalize the temporary array and write it back to the two-player distribution
         tempArray2D.Renormalize();
         TwoOpponentsHandsDistribution.CopyFrom(tempArray2D);
     }
     else if (CurrentOpponentCount == 1)
     {
         // Prepare a temporary array
         tempArray1D.Clear();
         // Loop through all possible world states and update the tempoprary array accordingly
         for (int h0 = 0; h0 < CARD_VECTOR_LENGTH; h0++)
         {
             UpdatePartialHandDistribution(TurnData.Card.Value - 1, h0, ref tempArray1D);
         }
         // Renormalize the temporary array and write it back to the one-payer distribution
         tempArray1D.Renormalize();
         SingleOpponentHandDistribution.CopyFrom(tempArray1D);
     }
     // Finally, recalculate utility arrays
     RecalculateHandAndDeckdistributions();
 }
Exemple #4
0
 // The joint probabilities array is good for analysis, but slow for quick access,
 // so we instead populate smaller, 1D arrays for each hand, as well as for the deck.
 public void RecalculateHandAndDeckdistributions()
 {
     // The computation only works if there ARE any opponents left
     if (CurrentOpponentCount < 1)
     {
         return;
     }
     // Precomputation for the aggregated hand distributions update
     for (int h = 0; h < HiddenHands.Length; h++)
     {
         HandDistribution[HiddenHands[h]].Clear();
     }
     DeckDistribution.Clear();
     // Precomputations for the deck distribution update
     Array.Copy(CountUnaccountedForCards, 1, virtualRemainingCards, 0, CARD_VECTOR_LENGTH);
     // Loop through the first hidden hand
     for (int h1 = 0; h1 < CARD_VECTOR_LENGTH; h1++)
     {
         virtualRemainingCards[h1] -= 1;
         // If there is only one opponent left, update SingleOpponentHandDistribution
         if (CurrentOpponentCount < 2)
         {
             HandDistribution[HiddenHands[0]][h1] = SingleOpponentHandDistribution[h1];
             CumulativeUpdateDeckDistribution(SingleOpponentHandDistribution[h1], virtualRemainingCards, ref DeckDistribution);
         }
         else
         {
             // Otherwise, enter the second loop
             for (int h2 = 0; h2 < CARD_VECTOR_LENGTH; h2++)
             {
                 virtualRemainingCards[h2] -= 1;
                 // If there are two opponents left, update TwoOpponentsHandsDistribution
                 if (CurrentOpponentCount < 3)
                 {
                     HandDistribution[HiddenHands[0]][h1] += TwoOpponentsHandsDistribution[h1, h2];
                     HandDistribution[HiddenHands[1]][h2] += TwoOpponentsHandsDistribution[h1, h2];
                     CumulativeUpdateDeckDistribution(TwoOpponentsHandsDistribution[h1, h2], virtualRemainingCards, ref DeckDistribution);
                 }
                 else
                 {
                     // Otherwise, enter the final loop
                     for (int h3 = 0; h3 < CARD_VECTOR_LENGTH; h3++)
                     {
                         HandDistribution[HiddenHands[0]][h1] += ThreeOpponentsHandsDistribution[h1, h2, h3];
                         HandDistribution[HiddenHands[1]][h2] += ThreeOpponentsHandsDistribution[h1, h2, h3];
                         HandDistribution[HiddenHands[2]][h3] += ThreeOpponentsHandsDistribution[h1, h2, h3];
                         // And update ThreeOpponentsHandsDistribution
                         virtualRemainingCards[h3] -= 1;
                         CumulativeUpdateDeckDistribution(ThreeOpponentsHandsDistribution[h1, h2, h3], virtualRemainingCards, ref DeckDistribution);
                         virtualRemainingCards[h3] += 1;
                     }
                 }
                 virtualRemainingCards[h2] += 1;
             }
         }
         virtualRemainingCards[h1] += 1;
     }
     // Normalize distributions
     if (TheDeck.CountCardsLeft > 0)
     {
         DeckDistribution.Renormalize();
     }
     for (int h = 0; h < CurrentOpponentCount; h++)
     {
         HandDistribution[HiddenHands[h]].Renormalize();
     }
 }