Beispiel #1
0
        /// <summary>
        /// Enumerate indexes.
        /// </summary>
        /// Developer notes: I tried to use a pointer for cards[] too, but it does not changes the speed.
        static void CombinInternal <ParamT>(int *liveCards, int liveCardsCount, int count, int[] cards, int startPos, EnumerateActionIdxDelegate <ParamT> action, ParamT param)
        {
            switch (count)
            {
            case 0:
                action(cards, param);
                break;

            case 1:
                for (int c1 = 0; c1 < liveCardsCount; ++c1)
                {
                    cards[startPos] = liveCards[c1];
                    action(cards, param);
                }
                break;

            case 2:
                for (int c1 = 1; c1 < liveCardsCount; ++c1)
                {
                    cards[startPos] = liveCards[c1];
                    for (int c2 = 0; c2 < c1; ++c2)
                    {
                        cards[startPos + 1] = liveCards[c2];
                        action(cards, param);
                    }
                }
                break;

            case 3:
                for (int c1 = 2; c1 < liveCardsCount; ++c1)
                {
                    cards[startPos] = liveCards[c1];
                    for (int c2 = 1; c2 < c1; ++c2)
                    {
                        cards[startPos + 1] = liveCards[c2];
                        for (int c3 = 0; c3 < c2; ++c3)
                        {
                            cards[startPos + 2] = liveCards[c3];
                            action(cards, param);
                        }
                    }
                }
                break;

            case 4:
                for (int c1 = 3; c1 < liveCardsCount; ++c1)
                {
                    cards[startPos] = liveCards[c1];
                    for (int c2 = 2; c2 < c1; ++c2)
                    {
                        cards[startPos + 1] = liveCards[c2];
                        for (int c3 = 1; c3 < c2; ++c3)
                        {
                            cards[startPos + 2] = liveCards[c3];
                            for (int c4 = 0; c4 < c3; ++c4)
                            {
                                cards[startPos + 3] = liveCards[c4];
                                action(cards, param);
                            }
                        }
                    }
                }
                break;

            case 5:
                for (int c1 = 4; c1 < liveCardsCount; ++c1)
                {
                    cards[startPos] = liveCards[c1];
                    for (int c2 = 3; c2 < c1; ++c2)
                    {
                        cards[startPos + 1] = liveCards[c2];
                        for (int c3 = 2; c3 < c2; ++c3)
                        {
                            cards[startPos + 2] = liveCards[c3];
                            for (int c4 = 1; c4 < c3; ++c4)
                            {
                                cards[startPos + 3] = liveCards[c4];
                                for (int c5 = 0; c5 < c4; ++c5)
                                {
                                    cards[startPos + 4] = liveCards[c5];
                                    action(cards, param);
                                }
                            }
                        }
                    }
                }
                break;

            default:
                for (int c1 = count - 1; c1 < liveCardsCount; ++c1)
                {
                    cards[startPos] = liveCards[c1];
                    for (int c2 = count - 2; c2 < c1; ++c2)
                    {
                        cards[startPos + 1] = liveCards[c2];
                        for (int c3 = count - 3; c3 < c2; ++c3)
                        {
                            cards[startPos + 2] = liveCards[c3];
                            for (int c4 = count - 4; c4 < c3; ++c4)
                            {
                                cards[startPos + 3] = liveCards[c4];
                                for (int c5 = count - 5; c5 < c4; ++c5)
                                {
                                    cards[startPos + 4] = liveCards[c5];
                                    CombinInternal(liveCards, c5, count - 5, cards, startPos + 5, action, param);
                                }
                            }
                        }
                    }
                }
                break;
            }
        }
Beispiel #2
0
        /// <summary>
        /// Combin all possible combinations of cards and calls an action for each combination.
        /// </summary>
        /// <param name="cards">Array to put the cards to.</param>
        /// <param name="startPos">Starting position in the cards array.</param>
        /// <param name="deadCards">Dead cards. If some shared cards are necessary, put it manually to both cards and deadCards.</param>
        public static void Combin <ParamT>(DeckDescriptor deckDescr, int count, int[] cards, int startPos, int[] deadCards, int deadCardsCount, EnumerateActionIdxDelegate <ParamT> action, ParamT param)
        {
            int[] deckCopy = deckDescr.FullDeckIndexes.ShallowCopy();
            for (int i = 0; i < deadCardsCount; ++i)
            {
                deckCopy[deadCards[i]] = -1;
            }
            int  liveCardsLength = deckCopy.Length - deadCardsCount;
            int *liveCards       = stackalloc int[liveCardsLength];
            int  cnt             = 0;

            for (int i1 = 0; i1 < deckCopy.Length; ++i1)
            {
                if (deckCopy[i1] >= 0)
                {
                    liveCards[cnt++] = deckCopy[i1];
                }
            }
            Debug.Assert(cnt == liveCardsLength);
            CombinInternal(liveCards, liveCardsLength, count, cards, startPos, action, param);
        }