예제 #1
0
        private void GetAdjacentStackables(ref card thisCard, ref column cCol, ref List <card> CardsAbove, ref List <card> CardsBelow)
        {
            int i, j;

            CardsBelow.Clear();
            CardsAbove.Clear();

            if (thisCard.iCard > cCol.top)
            {
                for (i = thisCard.iCard - 1; i >= cCol.top; i--)
                {
                    for (j = 0; j < Stackables.Count; j++)
                    {
                        if (cCol.Cards[i] == Stackables[j])
                        {
                            CardsAbove.Add(Stackables[j]);
                        }
                    }
                }
            }
            else if (thisCard.iCard != (cCol.Cards.Count - 1))
            {
                for (i = thisCard.iCard + 1; i < cCol.Cards.Count; i++)
                {
                    for (j = 0; j < Stackables.Count; j++)
                    {
                        if (cCol.Cards[i] == Stackables[j])
                        {
                            CardsBelow.Add(Stackables[j]);
                        }
                    }
                }
            }
        }
예제 #2
0
        public csosDisStrategy(int iNEC, int iNC, string strPattern, string strHoldCards, string strMoves)
        {
            string[] sSetMoves = strMoves.Split(',');
            string[] sOneMove;
            int      i;

            NumEmptyColumns = Math.Abs(iNEC);
            NumCards        = iNC;
            bMustBeTop      = false;
            if (iNEC <= 0)
            {
                bMustBeTop = true;
            }
            Pattern = strPattern;
            if (strHoldCards != "")
            {
                nCollapse   = Convert.ToInt32(strHoldCards.Substring(0, 1));
                Collapsible = new column();
                strCollapse = strHoldCards.Substring(1);
            }
            for (i = 0; i < sSetMoves.Length; i++)
            {
                sOneMove = sSetMoves[i].Split('-');
                cDisMoves cdm = new cDisMoves(sOneMove[0], sOneMove[1]);
                UnstackMoves.Add(cdm);
            }
        }
예제 #3
0
        private void ClearAnyBlocking(ref board tb, ref series s)
        {
            card   cAbove;
            card   JustMoved  = s.topCard;
            card   BottomCard = s.bottomCard;
            column cCol       = tb.ThisColumn[JustMoved.iStack]; // we moved from here so use iStack, not fStack
            int    iAbove     = JustMoved.iCard - 1;

            if (iAbove < 0)
            {
                xEmpties.Add(JustMoved.iStack);
            }
            if (!BottomCard.PartOfStackables)
            {
                PlaceHolders.Add(BottomCard);   // this has the updated fStack
            }
            cAbove = cCol.Cards[iAbove];
            if (cAbove.PartOfStackables)
            {
                return;
            }
            if (PartOfMovables.Contains(cAbove.ID))
            {
                return;
            }
            PlaceHolders.Add(cAbove);
        }
예제 #4
0
        public void InitializeReduction(ref board tb, ref card cNext)
        {
            int i, j = 13;

            tb.ReScoreBoard();
            Stackables.Clear();
            StackableIDs.Clear();
            DoNotUse.Clear();
            cNext = tb.SuitedSEQ[0].topCard;
            int suit = cNext.suit;

            foreach (series s in tb.SuitedSEQ)
            {
                DoNotUse.Add(s.iStack); // not a permanent placeholder till that card is moved (if it is moved)
                for (i = cNext.iCard; i <= s.bottom; i++)
                {
                    column cCol = tb.ThisColumn[s.iStack];
                    Stackables.Add(cCol.Cards[i]);
                    cCol.Cards[i].PartOfStackables = true;
                    Debug.Assert(j == cCol.Cards[i].rank && suit == cCol.Cards[i].suit);
                    j--;
                }
                cNext = s.AssemblyLink; // link to next card in "s" assembly
                if (cNext != null)
                {
                    StackableIDs.Add(cNext.ID);
                }
            }
            cNext = tb.SuitedSEQ[0].topCard;
        }
예제 #5
0
        /*
         * This just moves the bottom most card to another stack that has the same suit.
         * The move is not made unless it can be reversed (if bReversible is set)
         */

        public bool JoinSameSuits(ref board tb, bool bReversible)
        {
            int  n = tb.BottomMost.Count;
            card tC, bC, aC;
            int  i, j, k;
            int  RankAbove;

            for (i = 0; i < n; i++)
            {
                bC = tb.BottomMost[i];
                series s2 = tb.ThisColumn[bC.iStack].ThisSeries.Last();
                for (j = 0; j < n; j++)
                {
                    if (i == j)
                    {
                        continue;
                    }
                    tC = tb.TopMost[j];
                    if (tC.suit == bC.suit)
                    {
                        // we have a candidate to join
                        srcCol = tb.ThisColumn[tC.iStack];
                        series s = srcCol.ThisSeries.Last();
                        // s is the series that might be moved under the bottom card
                        if (s.topCard.rank >= (bC.rank - 1) &&
                            s.bottomCard.rank < bC.rank &&
                            s2.topCard.rank > s.topCard.rank)
                        // size of destination must be
                        //s2.size > s.size)
                        {
                            // we can move all or part of that series under that bottom card
                            for (k = 0; k < s.size; k++)
                            {
                                aC = srcCol.Cards[k + tC.iCard];
                                if (aC.rank + 1 == bC.rank)
                                {
                                    if (aC.iCard > 0)
                                    {
                                        // is not at top of stack
                                        // if Reversibility is required, then do not make the move
                                        // unless the the rank above allows reversing the move
                                        RankAbove = srcCol.Cards[aC.iCard - 1].rank;
                                        if ((RankAbove - 1) != aC.rank && bReversible)
                                        {
                                            return(false);
                                        }
                                    }
                                    tb.moveto(tC.iStack, aC.iCard, bC.iStack);
                                    return(true);
                                }
                            }
                        }
                    }
                }
            }
            return(false);
        }
예제 #6
0
        //PsudoMoveList must have moves inserted in the "front" to keep the move order correct
        // board tag contains destination of series to be moved to
        public bool MoveCollapsible(ref series sCollapse, ref board tb)
        {
            List <card> BackupOfCardsToMove = new List <card>();

            if (cSC.bTrigger)
            {
                Console.WriteLine(MethodBase.GetCurrentMethod().Name);
            }
            column cCol = tb.ThisColumn[sCollapse.iStack];
            int    n    = sCollapse.pattern.Length;

            if (n > 7)
            {
                return(false);
            }
            tb.CopyWorkingInts(ref xEmpties, GlobalClass.WorkingType.tEmpties);
            if (tb.tag < 0)
            {
                tb.tag = xEmpties[0];
                xEmpties.RemoveAt(0);
            }
            CollapsibleSEQCardsToMove.Clear();
            series s = sCollapse;

            for (int i = 0; i < sCollapse.pattern.Length; i++)
            {
                string a = sCollapse.pattern.Substring(i, 1);
                CollapsibleSEQCardsToMove.Add(s.topCard);
                BackupOfCardsToMove.Add(s.topCard);
                s = s.NextSeries;
            }

            for (int i = DisStrategy.Count - 1; i >= 0; i--)
            {
                // going backwards we see the max empty columns before the ones requiring help
                if (DisStrategy[i].NumSeqSeries == n)
                {
                    if (xEmpties.Count >= DisStrategy[i].nEmptyColumns)
                    {
                        if (DisStrategy[i].Ranks.Count > 0)
                        {
                            continue;                                   // must use empty stack for now JYS !!!
                        }
                        // if a placeholder was available, it would have been assigned to tab.tag
                        // since all series are rankable, they can all go under the top card
                        // JYS !!!  we could possibly have looked for another placeholder or two to make
                        //          complicated moves

                        bool bAny = FormCollapsibleMoves(i, ref tb);
                        return(bAny);
                    }
                }
            }

            return(false);
        }
예제 #7
0
        // if there is a card above ThisCard that is a member of the series we are trying to stack, then
        // ThisCard must be moved.  Only king has this problem when stacking
        private bool bStackablesAbove(ref board tb, ref card ThisCard)
        {
            column cCol = tb.ThisColumn[ThisCard.iStack];

            for (int i = ThisCard.iCard - 1; i >= cCol.top; i++)
            {
                if (cCol.Cards[i].PartOfStackables)
                {
                    return(true);
                }
            }
            return(false);
        }
예제 #8
0
        // remove cards in teh sCollapse series and put them all in one place, somewhere, if possible
        public bool TryExpose(ref series sCollapse, ref board tb)
        {
            int          n = sCollapse.size;
            int          i;
            card         SCard = sCollapse.topCard; // this is the "S" Card with which we will be decrementing the iCard value as we move
            const string cstrInxVars = "ABCD";      // jys oct2012 added E
            string       strInxvars, strPattern;
            column       tCol = tb.ThisColumn[sCollapse.topCard.iStack];

            if (n > 4)
            {
                return(false);
            }
            csosDisStrategy cds;

            strInxvars = cstrInxVars.Substring(0, n);
            AssemblePattern.Clear();
            dictLookup.Clear();
            //dictLookup.Add("S", SCard);
            // the above is not needed as we will unstack the pattern "BA" (B is actually S) to get A
            strPattern = AssemblePatternFrom(ref tb, ref sCollapse, strInxvars);
            n          = strPattern.Length;
            if (n > 4)
            {
                return(false);          // jys !!! have not created patterns bigger then 4 letters
            }
            // check first to see if we can use our empty columns
            for (i = 0; i < sosDisStrategy.Count; i++)
            {
                cds = sosDisStrategy[i];
                if (n == cds.NumCards && cds.NumEmptyColumns <= tb.NumEmptyColumns)
                {
                    if (cds.Pattern != strPattern)
                    {
                        continue;
                    }
                    if (!cds.bMustBeTop)
                    {
                        continue;
                    }
                    if (cds.Collapsible != null)
                    {
                        continue;                           // only want to use empties
                    }
                    sosUnstackE(ref tb, ref cds);
                    return(true);
                }
            }

            return(false);
        }
예제 #9
0
        private bool UnstackSeriesBelow(ref board tb, ref card cNext)
        {
            bool   bSuccess = true;
            series sCollapse;
            column cCol       = tb.ThisColumn[cNext.iStack];
            int    n          = cCol.Cards.Count;
            int    LastSeries = cCol.ThisSeries.Count - 1;

            Debug.Assert(LastSeries >= 0);
            if (cNext.WhichSEQSeries == LastSeries)
            {
                return(true);
            }

            // if only one to unstack then use a simple unstack
            if (cNext.WhichSEQSeries == (LastSeries - 1))
            {
                series ts = cCol.ThisSeries[cNext.WhichSEQSeries];
                bSuccess = UnstackOne(ref tb, ref ts);
                return(bSuccess);
            }
            // if more then one to unstack then try to move all of them using a pattern match
            sCollapse            = new series();
            sCollapse.bottomCard = cCol.Cards[n - 1];
            sCollapse.topCard    = cNext;
            sCollapse.tag        = cNext.tag; // this is destination
            sCollapse.size       = cCol.Cards.Count - cNext.iCard;
            sCollapse.iStack     = cNext.iStack;
            if (utils.bRankable(ref sCollapse, ref tb))
            {
                bSuccess = Disassemble.bCanUnstackCollapseable(ref sCollapse, ref tb, ref PermanentPlaceHolders);
                return(bSuccess);
            }

            // hmm - not rankable  JYS !!! could try a simple move SOS assumeing all are sequential
            // if that worked then mode the ABCD pattern counf of 4 max to account for simple sequential move
            // and use FillDS instead of SOS

            // the following will work but is not optimum

            int TopOfSeries = cNext.WhichSEQSeries + 1;

            // start at bottom series, work upward
            for (int i = LastSeries; i >= TopOfSeries && bSuccess; i--)
            {
                series ts = cCol.ThisSeries[i];
                bSuccess = UnstackOne(ref tb, ref ts);
            }
            return(bSuccess);
        }
예제 #10
0
        public void init()
        {
            int i;

            score            = 0;
            dead             = false;
            nchild           = 0;
            from             = 0;
            bIsCompletable   = false;
            NumEmptyColumns  = 0;
            ThisColumn       = new column[12]; // column 11 is the remaining deck and the 12th one is "complete"
            Empties          = new List <int>();
            NonEmpties       = new List <int>();
            Completed        = new List <cCompleted>();
            NewlyCompleted   = false;
            bitJustCompleted = 0;
            strSuitsRemoved  = "";
            DealString       = "";
            bWasDealtTo      = false; // not copied because it is used as a signaling variable
            for (i = 0; i < 12; i++)
            {
                ThisColumn[i]        = new column();
                ThisColumn[i].iStack = i;
                ThisColumn[i].init();
            }
            bOnLastDeal       = false;
            DealCounter       = 0; // deal 0 is the initial board
            NumCompletedSuits = 0;
            tag        = 0;
            TopMost    = new List <card>();
            BottomMost = new List <card>();
            SuitedSEQ  = new List <series>();
            NotifySuitJustCompleted = false;
            SaveCompletedBy.Push((int)GlobalClass.TypeCompletedBy.ID_UNK);
            bSignalBoardComplete = false;
            UniqueID             = BoardCounter++;
            SuitsLocked          = false;
            BuildingThisSuit     = 0; // we are building "all" suits
            for (i = 0; i < 4; i++)
            {
                SuitStatus[i] = new cSuitedStatus();
                SuitStatus[i].MissingTypes           = new List <int>();
                SuitStatus[i].MustExpose             = new List <int>();
                SuitStatus[i].BonusExposes           = new List <int>();
                SuitStatus[i].index                  = i;
                SuitStatus[i].NumCompletedAndRemoved = 0;
            }

            UnexposedTypes = new List <int>();
        }
예제 #11
0
        public int NumFacedownColumns()
        {
            int n = 0;

            foreach (int e in NonEmpties)
            {
                column cCol = ThisColumn[e];
                if (cCol.top == 0)
                {
                    continue;
                }
                n++;
            }
            return(n);
        }
예제 #12
0
        public List <int> PartOfMovables;    // if a card is part of the movables then it cannot
                                             // be used as a placeholder until it has moved.  After it has
                                             // has moved then fStack must be used, not iStack

        private bool IsTopMost(ref card thisCard, ref column cCol)
        {
            int i;

            if (thisCard.iCard == cCol.top)
            {
                return(true);
            }
            for (i = thisCard.iCard - 1; i >= cCol.top; i--)
            {
                foreach (card c in Stackables)
                {
                    if (c == cCol.Cards[i])
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
예제 #13
0
        // return true if an out of order series can be put into order
        // suit makes no difference
        public static bool bRankable(ref series s, ref board tb)
        {
            int    i, d, r = s.topCard.rank;
            column tCol = tb.ThisColumn[s.iStack];
            int    n    = s.size;

            int[] CardIndex = new int[n];
            for (i = 0; i < n; i++)
            {
                CardIndex[i] = tCol.Cards[s.topCard.iCard + i].rank;
            }
            Array.Sort(CardIndex);
            for (i = 1; i < n; i++)
            {
                d = Math.Abs(CardIndex[i] - CardIndex[i - 1]);
                if (d != 1)
                {
                    return(false);
                }
            }
            return(r == CardIndex[n - 1]);   // the one to be exposed must be the biggest
        }
예제 #14
0
        private string AssemblePatternFrom(ref board tb, ref series sCollapse, string strInxvars)
        {
            int    i, j, n = sCollapse.size;
            card   c;
            string strPattern = "";
            column cCol       = tb.ThisColumn[sCollapse.iStack];

            for (i = 0; i < n; i++)
            {
                c = cCol.Cards[i + sCollapse.topCard.iCard];
                cAssemblePattern cap = new cAssemblePattern(ref c, i);
                AssemblePattern.Add(cap);

                // the original pattern needs to be recovered when performing moves
                // ie: if the cards are 5h,3C,4C we move 4C then 3C then bring them back to the faceup 5H
                // We sort only to get the pattern
            }

            AssemblePattern.Sort(delegate(cAssemblePattern c1, cAssemblePattern c2)
            {
                return(Comparer <int> .Default.Compare(c1.c.rank, c2.c.rank));
            });
            for (i = 0; i < AssemblePattern.Count; i++)
            {
                AssemblePattern[i].PatLetter = strInxvars.Substring(i, 1);
            }

            for (i = 0; i < AssemblePattern.Count; i++)
            {
                j = AssemblePattern[i].index;
                string a = APLookup(ref AssemblePattern, i);
                dictLookup.Add(a, cCol.Cards[i + sCollapse.topCard.iCard]);
                strPattern += a;
            }
            return(strPattern);
        }
예제 #15
0
        public int RemoveCompletedSuit(int iCol)
        {
            column tc = ThisColumn[iCol];
            int    i, j, n = tc.ThisSeries.Count - 1;
            int    suit = tc.ThisSeries[n].sSuit;

            Debug.Assert(n >= 0);
            j = tc.ThisSeries[n].bottom;           // position of last card in last series
            Debug.Assert(j == tc.Cards.Count - 1); // should always be last card
            // instead of deleting 13 cards from location top
            // we will move 13 cards from the bottom of the stack to stack 11 (12th stack)
            for (i = 0; i < 13; i++)
            {
                card c = tc.Cards[j - i];
                ThisColumn[11].Cards.Add(c);
            }
            tc.Cards.RemoveRange(tc.ThisSeries[n].top, 13);
            n = tc.Cards.Count - 1;
            if (n >= 0)
            {
                tc.Cards[n].bFaceUp = true;
            }
            return(suit);
        }
예제 #16
0
        // spin a suit at a time (causes problems, need to spin each card in turn)
        // do NOT move a king to an empty column unless the
        // exposed card frees up another column -OR-
        // there is a king above it that has a larger series value
        // nov2012 do not move king if suit is buildable ???? (maybe)
        // nov2012-1 king must be moved if it hides ALL others
        public bool SpinThisSuitedColumn(ref board tb, int iColumn)
        {
            if (cSC.bTrigger)
            {
                Console.WriteLine(MethodBase.GetCurrentMethod().Name);
            }
            column c = tb.ThisColumn[iColumn];
            series s, ss;
            int    i, cSeriesValue;
            int    RankAbove;
            int    n = c.ThisSeries.Count;
            int    cntAbove;

            Debug.Assert(n > 0);

            s = c.ThisSeries.Last();
            if (s.topCard.rank == 13 && s.top == 0)
            {
                return(true);   // do not move a king from one empty to another
            }
            // nov2012 do not move king if that suit is buildable
            if (s.topCard.rank == 13)
            {
                if (tb.SuitStatus[s.topCard.suit].bSuitsCompletable)
                {
                    return(true);
                }
                // must move a king if all (or any?) above it are required!!!!
                if (tb.bOnLastDeal)
                {
                    cSC.Suitable.PerformSuitabiltyStudy(ref tb, s.topCard.suit);
                    if (cSC.Suitable.ExposesRequired.Count > 0)
                    {
                        return(SpinTheseCards(ref tb, iColumn, s.top));
                    }
                }
            }



            if (!tb.SuitsLocked)
            {
                cntAbove = 1 + (c.ThisSeries[0].bottom - c.ThisSeries[0].top);
                if (s.topCard.rank == 13 && s.top > 0)  // do not move a king unless ...
                {
                    RankAbove = c.Cards[s.top - 1].rank;
                    if (tb.NumEmptyColumns > 0)
                    {
                        for (i = 0; i < 10; i++)
                        {
                            if (tb.ThisColumn[i].Cards.Count == 0)
                            {
                                continue;
                            }
                            series t = tb.ThisColumn[i].ThisSeries.Last();  // bottom series
                            if ((RankAbove - 1) == t.topCard.rank)
                            {
                                int ThisCnt = 1 + (s.bottom - s.top);
                                if (((cntAbove + ThisCnt) > 7 && (s.topCard.suit == c.ThisSeries[0].topCard.suit)) || t.top == 0)
                                {
                                    // spinning this king can result in swapping one empty column
                                    // for another or building a series that is probably close enough
                                    return(SpinTheseCards(ref tb, iColumn, s.top));
                                }
                            }
                        }
                    }
                    cSeriesValue = s.nValue; // current series value
                    n--;                     // move up above the bottom series
                    // n was is the count, if 0 then nothing more to process
                    if (n == 0)
                    {
                        return(true);
                    }
                    while (n >= 0)
                    {
                        ss = c.ThisSeries[n];
                        n--;
                        if (ss.topCard.rank == 13)
                        {
                            if (ss.nValue > cSeriesValue)
                            {
                                return(SpinTheseCards(ref tb, iColumn, s.top));
                            }
                        }
                    }
                    return(true);
                }
            }
            return(SpinTheseCards(ref tb, iColumn, s.top));
        }
예제 #17
0
        // exchange cards that are under the wrong suit
        public bool CombineLikeSuits(ref board tb)
        {
            column      cCol = null;
            int         n = 0;
            bool        ChangedAnyBoards = false;
            int         OriginalSrcStack = 0;
            card        bm, Src = null, Des = null;
            bool        bFound = false, bAny = false;
            List <card> LastSEQ = new List <card>();  // this holds the top card of the last SEQ series
            card        BelowBM, cAbove;

            // Below Bm rank + 1 must equal to cAbove rank to swap (unless one card is top)

            tb.AssignCompletedID(GlobalClass.TypeCompletedBy.ID_COMBN);
            do
            {
                bFound = false;
                LastSEQ.Clear();
                bAny = FreeSuitedSuits(ref tb, ref LastSEQ);
                if (tb.NumEmptyColumns == 0)
                {
                    return(bAny);
                }


                //tb.ExplainBoard("before");

                // locate the bottom card of the upper series, if any
                foreach (int e in tb.NonEmpties)
                {
                    cCol = tb.ThisColumn[e];
                    n    = cCol.ThisSeries.Count;
                    if (n < 2)
                    {
                        continue;
                    }
                    bm = cCol.ThisSeries[n - 2].bottomCard;
                    foreach (card tm in LastSEQ)
                    {
                        if (tm.iStack == bm.iStack)
                        {
                            continue;
                        }
                        if ((bm.rank - 1) == tm.rank && bm.suit == tm.suit)
                        {
                            OriginalSrcStack = tm.iStack;
                            int iCardAbove = tm.iCard - 1; // this card must either be null (top of column)
                                                           // or it must be 1 greater in rank
                            if (iCardAbove > -1)           // there is at least one card above us.  It can be facedown too
                            {
                                cAbove = tb.ThisColumn[tm.iStack].Cards[iCardAbove];
                                if (cAbove.rank != (tm.rank + 1))
                                {
                                    continue;
                                }
                                BelowBM = cCol.Cards[bm.iCard + 1];
                                if (BelowBM.rank != (cAbove.rank - 1))
                                {
                                    continue;
                                }
                            }
                            bFound = true;
                            Src    = tm;
                            Des    = bm;
                            break;
                        }
                    }
                    if (bFound == true)
                    {
                        break;
                    }
                }
                if (bFound)
                {
                    card MustMove = cCol.ThisSeries[n - 1].topCard;
                    int  nDest    = GetBestMove(Src, ref tb);

                    if (nDest < 0)
                    {
                        nDest = tb.Empties[0];
                    }
                    tb.moveto(MustMove.iStack, MustMove.iCard, nDest);
                    tb.moveto(Src.iStack, Src.iCard, Des.iStack);
                    // do not bother moving from one top to another top when doing a swap
                    if (!(tb.ThisColumn[nDest].Cards.Count == 1 &&
                          tb.ThisColumn[OriginalSrcStack].Cards.Count == 0))
                    {
                        tb.moveto(nDest, MustMove.iCard, OriginalSrcStack);
                    }

                    tb.ReScoreBoard();
                    if (tb.NotifySuitJustCompleted)
                    {
                        tb.ExplainNoRescoreBoard("Combine Like Suits succeeded");
                        tb.NotifySuitJustCompleted = false;
                    }
                    ChangedAnyBoards = true;
                }
            } while (bFound == true);

            tb.AssignCompletedID();
            //tb.ExplainBoard("after2");
            return(ChangedAnyBoards);
        }
예제 #18
0
        // select only 1 card even if more than 1 in suit
        // if more then 1 in a suit then try both of those card
        // repeat until the entire suit has been spun from this column
        public bool SpinThisColumn(ref board tb, int iColumn)
        {
            if (cSC.bTrigger)
            {
                Console.WriteLine(MethodBase.GetCurrentMethod().Name);
            }
            int    i, ThisSuit, ThisRank;
            series s = tb.ThisColumn[iColumn].ThisSeries.Last();
            card   CardAbove;
            column c = tb.ThisColumn[iColumn];
            int    n = c.Cards.Count;

            Debug.Assert(n > 0);
            n--;                        // point to bottom most card
            ThisSuit = c.Cards[n].suit; // this suit and this rank are being moved
            ThisRank = c.Cards[n].rank;



            while (n >= s.top)
            {
                if (ThisRank == 13)
                {
                    if (tb.NumEmptyColumns == 0 || c.Cards[n].iCard == 0)
                    {
                        return(true);
                    }
                    // a king cannot be moved anywhere except an empty column
                    // never move a king if it is already in an otherwise empty column
                    // move it only if the card exposed can hold some other column
                    CardAbove = tb.ThisColumn[iColumn].Cards[n - 1];
                    for (i = 0; i < 10; i++)
                    {
                        if (tb.ThisColumn[i].ThisSeries.Count == 1)   // only 1 sequential series
                        {
                            s = tb.ThisColumn[i].ThisSeries[0];
                            if (s.topCard.rank == (CardAbove.rank - 1))
                            {
                                //nb = new board(ref tb);
                                if (!SpinTheseCards(ref tb, iColumn, n))
                                {
                                    return(false);
                                }
                            }
                        }
                    }
                }

                if (!SpinTheseCards(ref tb, iColumn, n))
                {
                    return(false);
                }
                n--;
                if (n < 0 || cSC.bSignalSpinDone)
                {
                    break;
                }
                ThisRank++; // one above it must be 1 higher and same rank
                if (ThisSuit != c.Cards[n].suit || ThisRank != c.Cards[n].rank)
                {
                    break;
                }
            }
            return(true);
        }
예제 #19
0
        // returns the card exposed by the move, if any
        public card PerformMove(int FromStack, int FromLoc, int ToStack, int NumMoved)
        {
            bool   bWasFacedown = false;
            int    i, suit;
            card   NewCard, TopCardMoved;
            card   CardExposed = null;
            column sCol        = ThisColumn[FromStack];

            TopCardMoved = sCol.Cards[FromLoc];
            bool bWasUp = TopCardMoved.bFaceUp;
            int  RankAbove, RankBelow, ToLoc;

            suit = TopCardMoved.suit;

#if DEBUG
            Debug.Assert((FromLoc + NumMoved) == sCol.Cards.Count);

            for (int j = 0; j < NumMoved; j++)
            {
                Debug.Assert(suit == sCol.Cards[j + FromLoc].suit);
            }
            Debug.Assert(bWasUp);
#endif

            ToLoc = ThisColumn[ToStack].Cards.Count;
            if (ToLoc > 0)
            {
                RankBelow = sCol.Cards[FromLoc].rank;
                RankAbove = ThisColumn[ToStack].Cards[ToLoc - 1].rank;
                Debug.Assert((RankAbove - RankBelow) == 1);
                if ((RankAbove - RankBelow) != 1)
                {
                    ShowRawBoard();
                    return(null);// 0;
                }
            }


            for (i = 0; i < NumMoved; i++)
            {
                NewCard        = sCol.Cards[FromLoc + i];
                NewCard.iStack = ToStack;   // the and the following are needed in case this card needs to be
                NewCard.iCard  = i + ToLoc; // accessed before the ReScore is called
                ThisColumn[ToStack].Cards.Add(NewCard);
            }
            sCol.Cards.RemoveRange(FromLoc, NumMoved);
            i = (ThisColumn[FromStack].Cards.Count);
            if (i > 0)
            {
                card cCrd = sCol.Cards[i - 1];
                if (!cCrd.bFaceUp)
                {
                    int           b   = 1 << cCrd.rank;
                    cSuitedStatus css = SuitStatus[cCrd.suit];
                    css.SuitedRankBits |= b;
                    AreAnySuitsCompletable();
                    b = ~b;
                    b = b & 0xffff;             // keep to int size
                    css.UnexposedRankBits &= b; // remove from unexposed "bits" and the list
                    UnexposedTypes.Remove(cCrd.type);
                    if (css.MustExpose.Contains(cCrd.type))
                    {
                        SuitStatus[cCrd.suit].BonusExposes.Add(cCrd.type);
                    }
                    bWasFacedown = true;
                }
                cCrd.bFaceUp = true;
                CardExposed  = cCrd;
            }
            MyMoves.AddMove(TopCardMoved.ID, FromStack, ToStack, score, bWasFacedown, NumMoved);
            return(CardExposed);
        }
예제 #20
0
        public int FormDupList(int SrcCol, int SrcCard, int DesCol, int DesCard, ref int[] des, ref Int64 ChkValue)
        {
            int    i, j, top, nCount, desptr = 0;
            int    NumToMove;
            Int64  t;
            column tc = ThisColumn[SrcCol];
            card   dc;
            int    WouldBeTop, WouldBeCount;
            int    odesptr;
            int    n            = tc.Cards.Count;
            bool   bCollapsible = (tc.Cards[n - 1].rank == 1); // must have an ace at the bottom of the move seq
            int    suit         = (int)tc.Cards[SrcCard].suit; // suit of each of the cards we are moving
            int    NumAltSuits  = 0;

            if (ThisColumn[DesCol].ThisSeries.Count > 0)
            {
                series lseq = ThisColumn[DesCol].ThisSeries.Last();
                dc            = ThisColumn[DesCol].Cards[DesCard - 1];
                bCollapsible &= ((tc.Cards[SrcCard].rank + 1) == dc.rank);
                bCollapsible &= (suit == dc.suit);
                bCollapsible &= (suit == lseq.sSuit);
                bCollapsible &= (lseq.topCard.rank == 13);
            }
            else
            {
                bCollapsible = false;   // would never have got this far as it would have already collapsed
            }
            // the above shows we can concat similar suits but we need to check the ones above the
            // destination card to see if they run up to king and also have the same suit



            NumToMove = ThisColumn[SrcCol].Cards.Count - SrcCard;
            Debug.Assert(NumToMove > 0);
            ChkValue = 0;
            for (i = 0; i < 10; i++)
            {
                tc     = ThisColumn[i];
                nCount = tc.Cards.Count;
                top    = tc.top;

                if (i == SrcCol)
                {
                    WouldBeCount = nCount - NumToMove;
                    WouldBeTop   = SrcCard - 1;
                    if (WouldBeCount == 0)
                    {
                        des[desptr++] = 0;
                        continue;        //all were moved so column would be empty and nothing to shift for ChkWord
                    }
                    if (WouldBeTop < top)
                    {
                        Debug.Assert((top - WouldBeTop) == 1);
                        // we would have exposed a new card: there are no leftovers
                        des[desptr++] = 1;  // only 1 card, the newly exposed one
                        des[desptr++] = tc.Cards[top - 1].GetValue();
                    }
                    else
                    {
                        if (WouldBeTop > top)
                        {
                            WouldBeTop    = top;
                            des[desptr++] = WouldBeCount - WouldBeTop;
                            for (j = WouldBeTop; j < WouldBeCount; j++)
                            {
                                des[desptr++] = tc.Cards[j].GetValue();
                            }
                        }
                        else
                        {
                            des[desptr++] = 1;
                            des[desptr++] = tc.Cards[top].GetValue();
                        }
                    }
                }
                else if (i == DesCol)
                {
                    WouldBeCount = nCount + NumToMove;
                    WouldBeTop   = nCount > 0 ? top : 0;
                    // there are more cards in this column than the board shows so
                    // we have to sequence it manually to avoid going beyond the actual count
                    // we also need to see if the suit would have collapsed and the 13 cards removed
                    odesptr       = desptr;
                    des[desptr++] = WouldBeCount - WouldBeTop;
                    for (j = top; j < nCount; j++)
                    {
                        des[desptr++] = tc.Cards[j].GetValue();
                    }
                    for (j = 0; j < NumToMove; j++)
                    {
                        des[desptr++] = ThisColumn[SrcCol].Cards[SrcCard + j].GetValue();
                    }
                    // check the last 13 cards and see if they form a completed suit
                    if (bCollapsible)
                    {
                        des[odesptr] -= 13;
                        desptr       -= 13;
                    }
                }
                else
                {
                    WouldBeTop    = top;
                    des[desptr++] = nCount - top;    // number exposed boards
                    for (j = top; j < nCount; j++)
                    {
                        des[desptr++] = tc.Cards[j].GetValue();
                    }
                }
                t         = WouldBeTop;
                t         = (t & 31) << (i * 5);
                ChkValue |= t;
            }
            NumAltSuits = CalcNumAltSuits(desptr, ref des);
            t           = NumAltSuits;
            t           = t << 50;
            ChkValue   |= t;

            //return desptr;
            return(utils.ReOrderDups(desptr, ref des));
        }