예제 #1
0
        /// <summary>
        /// Same as Combin, contains additional user-defined parameter that will be passed to the delegate.
        /// </summary>
        // Code is copied from non-generic Combin. Code reuse decreases performace by 10%.
        public static void Combin <ParamT>(DeckDescriptor deckDescr, int count, CardSet sharedCards, CardSet deadCards, EnumerateActionDelegate <ParamT> action, ParamT param)
        {
            UInt64 deadMask = deadCards.bits | sharedCards.bits;

            UInt64 *pLiveCardMasks = stackalloc UInt64[deckDescr.Size];
            int     liveCardsCount = 0;

            for (int c = 0; c < deckDescr.Size; ++c)
            {
                UInt64 bits = deckDescr.CardSets[c].bits;
                if ((bits & deadMask) == 0)
                {
                    pLiveCardMasks[liveCardsCount++] = bits;
                }
            }
            CombinInternal(sharedCards.bits, pLiveCardMasks, liveCardsCount, count, action, param);
        }
예제 #2
0
        private static void CombinInternal <ParamT>(ulong m0, ulong *pLiveCardMasks, int liveCardsCount, int count, EnumerateActionDelegate <ParamT> action, ParamT param)
        {
            ulong   m1;
            ulong   m2;
            ulong   m3;
            ulong   m4;
            CardSet result;

            // Alogritm for liveCardsCount = 10, count = 3:
            // Live Masks:    0 1 2 3 4 5 6 7 8 9
            // 1st loop           b      ->     e
            // 2nd loop         b      ->     e
            // 3rd loop       b      ->     e

            switch (count)
            {
            case 0:
                result.bits = m0;
                action(ref result, param);
                break;

            case 1:
                for (int c1 = 0; c1 < liveCardsCount; ++c1)
                {
                    result.bits = m0 | pLiveCardMasks[c1];
                    action(ref result, param);
                }
                break;

            case 2:
                for (int c1 = 1; c1 < liveCardsCount; ++c1)
                {
                    m1 = m0 | pLiveCardMasks[c1];
                    for (int c2 = 0; c2 < c1; ++c2)
                    {
                        result.bits = m1 | pLiveCardMasks[c2];
                        action(ref result, param);
                    }
                }
                break;

            case 3:
                for (int c1 = 2; c1 < liveCardsCount; ++c1)
                {
                    m1 = m0 | pLiveCardMasks[c1];
                    for (int c2 = 1; c2 < c1; ++c2)
                    {
                        m2 = m1 | pLiveCardMasks[c2];
                        for (int c3 = 0; c3 < c2; ++c3)
                        {
                            result.bits = m2 | pLiveCardMasks[c3];
                            action(ref result, param);
                        }
                    }
                }
                break;

            case 4:
                for (int c1 = 3; c1 < liveCardsCount; ++c1)
                {
                    m1 = m0 | pLiveCardMasks[c1];
                    for (int c2 = 2; c2 < c1; ++c2)
                    {
                        m2 = m1 | pLiveCardMasks[c2];
                        for (int c3 = 1; c3 < c2; ++c3)
                        {
                            m3 = m2 | pLiveCardMasks[c3];
                            for (int c4 = 0; c4 < c3; ++c4)
                            {
                                result.bits = m3 | pLiveCardMasks[c4];
                                action(ref result, param);
                            }
                        }
                    }
                }
                break;

            case 5:
                for (int c1 = 4; c1 < liveCardsCount; ++c1)
                {
                    m1 = m0 | pLiveCardMasks[c1];
                    for (int c2 = 3; c2 < c1; ++c2)
                    {
                        m2 = m1 | pLiveCardMasks[c2];
                        for (int c3 = 2; c3 < c2; ++c3)
                        {
                            m3 = m2 | pLiveCardMasks[c3];
                            for (int c4 = 1; c4 < c3; ++c4)
                            {
                                m4 = m3 | pLiveCardMasks[c4];
                                for (int c5 = 0; c5 < c4; ++c5)
                                {
                                    result.bits = m4 | pLiveCardMasks[c5];
                                    action(ref result, param);
                                }
                            }
                        }
                    }
                }
                break;

            default:
                for (int c1 = count - 1; c1 < liveCardsCount; ++c1)
                {
                    m1 = m0 | pLiveCardMasks[c1];
                    for (int c2 = count - 2; c2 < c1; ++c2)
                    {
                        m2 = m1 | pLiveCardMasks[c2];
                        for (int c3 = count - 3; c3 < c2; ++c3)
                        {
                            m3 = m2 | pLiveCardMasks[c3];
                            for (int c4 = count - 4; c4 < c3; ++c4)
                            {
                                m4 = m3 | pLiveCardMasks[c4];
                                for (int c5 = count - 5; c5 < c4; ++c5)
                                {
                                    CombinInternal(m4 | pLiveCardMasks[c5], pLiveCardMasks, c5, count - 5, action, param);
                                }
                            }
                        }
                    }
                }
                break;
            }
        }