Пример #1
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);
        }
Пример #2
0
        // if the kings are in the same stack they will still be different SEQ and the lower king
        // will always have 1 better cost to unstack.  If the size of K2 is the same (or greater than K1)
        // then K2 will be selected.  If K1 is 1 or more greater in size then K2 must be discarded
        private series sGetKing(ref List <series> SortedSEQ, ref int cost)
        {
            series sKing = null;
            int    rank  = SortedSEQ[0].topCard.rank;

            Debug.Assert(rank == 13);
            bool bHaveTwoKings = (SortedSEQ[1].topCard.rank == 13);

            if (bHaveTwoKings)
            {
                int costK1 = SortedSEQ[0].nEmptiesToUnstack - SortedSEQ[0].size;
                int costK2 = SortedSEQ[1].nEmptiesToUnstack - SortedSEQ[1].size;
                if (costK2 <= costK1)
                {
                    cost  = SortedSEQ[1].nEmptiesToUnstack;
                    sKing = SortedSEQ[1];
                }
                else
                {
                    cost  = SortedSEQ[0].nEmptiesToUnstack;
                    sKing = SortedSEQ[0];
                }
                SortedSEQ.RemoveRange(0, 2);
                return(sKing);
            }
            sKing = SortedSEQ[0];
            SortedSEQ.RemoveAt(0);
            return(sKing);
        }
Пример #3
0
        private void GetRemainingSOS(int StartIndex, ref List <series> xThisSOS)
        {
            series ThisList;
            int    PrevIndex = StartIndex;
            bool   bStillDoingStackables;

            PrevIndex--;
            if (StartIndex == (Cards.Count))
            {
                xThisSOS[xThisSOS.Count - 1].bottom     = PrevIndex;
                xThisSOS[xThisSOS.Count - 1].bottomCard = Cards[PrevIndex];
                return;
            }
            bStillDoingStackables = Cards[StartIndex].PartOfStackables;
            if ((Cards[StartIndex].rank + 1 == Cards[PrevIndex].rank) &&
                (bStillDoingStackables == bDoingStackables))
            {
                StartIndex++;
                GetRemainingSOS(StartIndex, ref xThisSOS);
                return;
            }
            else
            {
                bDoingStackables = bStillDoingStackables;
                xThisSOS[xThisSOS.Count - 1].bottomCard = Cards[PrevIndex];
                xThisSOS[xThisSOS.Count - 1].bottom     = PrevIndex;
                ThisList         = new series();
                ThisList.top     = StartIndex;
                ThisList.topCard = Cards[StartIndex];
                xThisSOS.Add(ThisList);
                StartIndex++;
                GetRemainingSOS(StartIndex, ref xThisSOS);
            }
        }
Пример #4
0
        // find the sequence that contains the ExpectedRank.  if more than one do the same analysis as the king
        private series sGetNext(ref board tb, ref List <series> SortedSEQ, int ExpectedRank, ref int cost)
        {
            series s1 = null, s2 = null;
            bool   bFound1 = false, bFound2 = false;
            card   c1 = null, c2 = null;
            column cCol;
            int    cost1, cost2;

            foreach (series s in SortedSEQ)
            {
                if (s.topCard.rank >= ExpectedRank && ExpectedRank >= s.bottomCard.rank)
                {
                    if (!bFound1)
                    {
                        s1      = s;
                        bFound1 = true;
                        cCol    = tb.ThisColumn[s.iStack];
                        for (int i = s.top; i <= s.bottom; i++)
                        {
                            c1 = cCol.Cards[i];
                            if (c1.rank == ExpectedRank)
                            {
                                break;
                            }
                        }
                        continue;
                    }
                    else
                    {
                        s2      = s;
                        bFound2 = true;
                        cCol    = tb.ThisColumn[s.iStack];
                        for (int i = s.top; i <= s.bottom; i++)
                        {
                            c2 = cCol.Cards[i];
                            if (c2.rank == ExpectedRank)
                            {
                                break;
                            }
                        }
                        break;
                    }
                }
            }
            if (bFound1 && bFound2)
            {
                cost1 = s1.nEmptiesToUnstack - c1.next;
                cost2 = s2.nEmptiesToUnstack - c2.next;
                if (cost2 <= cost1)
                {
                    s1 = s2;
                    c1 = c2;
                }
            }
            cost            = s1.nEmptiesToUnstack;
            s1.AssemblyLink = c1;
            return(s1);
        }
Пример #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
        private bool MoveSeriesBelow(ref board tb, ref series sKeep)
        {
            series sCollapse = sKeep.NextSeries;

            tb.tag = utils.GetBestMove(sCollapse.topCard, ref tb, ref PlaceHolder);
            // note that tag could be negative:  need to get an empty column
            bool bAny = cSC.Suitable.Disassemble.MoveCollapsible(ref sCollapse, ref tb);

            return(bAny);
        }
Пример #8
0
 private void AddTopRanks(int sStart, ref List <cRankIndex> Ranks)
 {
     //int n = ThisSeries.Count;
     //for (int i = sStart; i < n; i++)
     {
         series     s   = ThisSeries[sStart];
         cRankIndex cri = new cRankIndex(s.topCard.rank, sStart);
         Ranks.Add(cri);
     }
     Ranks.Sort(delegate(cRankIndex r1, cRankIndex r2) { return(r2.rank.CompareTo(r1.rank)); });
 }
Пример #9
0
        public static int CalcSOSSeriesValue(series s)
        {
            int v, n = s.bottom - s.top;

            s.sSuit = -1;
            v       = 1;
            if (n > 0)
            {
                v += n;
            }
            s.nValue = (v);
            return(v);
        }
Пример #10
0
        // this just checks empty columns for space right now
        // and only looks at SEQ
        public int ExposeTop(ref board tb)
        {
            int i, j, n, nT, nE;
            int sCost;  // cost of all the series that need to be unstacked to expose the facedown card
                        // is the sum of all the SEQ costs plus 1
            int    tlCount = 0;
            column cCol;
            series sCollapse = new series();   // out of sequence series we want to collapse to a series of series

            for (i = 0; i < 10; i++)
            {
                nE   = tb.NumEmptyColumns;
                cCol = tb.ThisColumn[i];
                n    = cCol.Cards.Count;
                if (n < 2 || cCol.top == 0)
                {
                    continue;
                }
                sCost = 1;
                for (j = 0; j < cCol.ThisSeries.Count; j++)
                {
                    sCost += cCol.ThisSeries[j].nEmptiesToUnstack;
                }
                if (sCost <= nE)    // series is moveable using empties
                {
                    sCollapse.bottomCard = cCol.Cards[n - 1];
                    nT = cCol.top - 1;  // point to first un-exposed card
                    sCollapse.topCard = cCol.Cards[nT];
                    sCollapse.size    = cCol.Cards.Count - nT;
                    sCollapse.iStack  = sCollapse.topCard.iStack;
                    sCollapse.tag     = nT; // this is destination
                    if (utils.bRankable(ref sCollapse, ref tb))
                    {
                        if (true)
                        {
                            if (!DisAssemble.TryExpose(ref sCollapse, ref tb))
                            {
                                continue;
                            }
                            tlCount += 1;
                            break;
                        }
                    }
                }
            }
            if (tlCount > 0)
            {
                tb.ReScoreBoard();
            }
            return(tlCount);
        }
Пример #11
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);
        }
Пример #12
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);
        }
Пример #13
0
        private bool UnstackOne(ref board tb, ref series ts)
        {
            int iStack = GetBestMove(ref ts.topCard, ref tb);

            if (iStack < 0)
            {
                if (tb.Empties.Count == 0)
                {
                    return(false);
                }
                iStack = tb.Empties[0];
                tb.Empties.RemoveAt(0);
            }
            tb.PerformMove(ts.iStack, ts.top, iStack, ts.size);
            return(true);
        }
Пример #14
0
        public static int CalcSEQSeriesValue(series s, int BoardState)
        {
            double x, y = 2.33;// that gives 5 for two suited cards and 2.69 was for using only one series
            int    v, n = s.bottom - s.top;

            if (n == 12)
            {
                s.nValue = 1000;
                s.sSuit  = s.topCard.suit;
                return(1000);
            }
            if (n == 0)
            {
                v = 1;
            }
            else
            {
                x = n + 1;
                x = Math.Pow(x, y);
                v = Convert.ToInt32(x);
            }
            s.sSuit = s.topCard.suit;
            // 8nov2012 add value of top card and boost extra if rank was 12
            if (s.topCard.rank == 13)
            {
                v += 20 * (n + 1);
            }
            v       += s.topCard.rank;
            s.nValue = v;
            if (s.size == 1)
            {
                // there is only one card in the series. if ace or king give it 0 value
                int nOne = (s.topCard.rank == 13 || s.topCard.rank == 2) ? 0 : 1;
                // if the suit is buildable then use its rank as shown above
                if ((BoardState & 0xf & (1 << s.sSuit)) > 0)
                {
                    return(v);
                }
                v        = nOne;
                s.nValue = v;
            }
            return(v);
        }
Пример #15
0
        public int FormSOSseries(int iFromColumn, int itop, ref List <series> xThisSOS)
        {
            series ThisList;
            int    i;
            int    SOSvalue = 0;
            int    ThisTop  = itop;

            xThisSOS.Clear();
            if (Cards.Count == 0 || itop >= Cards.Count)
            {
                return(0);
            }
            ThisList         = new series();
            ThisList.top     = ThisTop;
            ThisList.topCard = Cards[ThisTop];
            bDoingStackables = ThisList.topCard.PartOfStackables;
            xThisSOS.Add(ThisList);
            ThisTop++;
            GetRemainingSOS(ThisTop, ref xThisSOS);
            for (i = 0; i < xThisSOS.Count; i++)
            {
                xThisSOS[i].iStack = iFromColumn;
                //  xThisSOS[i].nEmptiesToUnstack = xThisSOS.Count - i - 1;
                // the above number would be true if the series was all one suit
                // the number of suit changes needs to be added to it.
                // for example: 10H,9H,8H,7D at the bottom of a column shows "0" to unstack
                // however, the 7D does need to be unstacked first.
                xThisSOS[i].nEmptiesToUnstack = xThisSOS.Count - i - 1 + xThisSOS[i].FormPatternSOS(ref Cards);
            }
            for (i = 0; i < xThisSOS.Count; i++)
            {
                utils.CalcSOSSeriesValue(xThisSOS[i]);
                xThisSOS[i].size = xThisSOS[i].bottom - xThisSOS[i].top + 1;
            }
            if (xThisSOS.Count == 0)
            {
                return(0);
            }
            SOSvalue = xThisSOS.Last().nValue;
            return(SOSvalue);
        }
Пример #16
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
        }
Пример #17
0
        private void GetRemainingSEQ(int StartIndex)
        {
            series ThisList;
            int    PrevIndex = StartIndex;
            card   PrevCard;

            PrevIndex--;

            PrevCard = Cards[PrevIndex];
            if (StartIndex == (Cards.Count))
            {
                ThisSeries[ThisSeries.Count - 1].bottom     = PrevIndex;
                ThisSeries[ThisSeries.Count - 1].bottomCard = PrevCard;
                return;
            }

            // is the card sequential with the previous one
            if (Cards[StartIndex].rank + 1 == PrevCard.rank &&
                Cards[StartIndex].suit == PrevCard.suit)
            {
                StartIndex++;
                GetRemainingSEQ(StartIndex);
                return;
            }
            else
            {
                ThisSeries[ThisSeries.Count - 1].bottomCard = PrevCard;
                ThisSeries[ThisSeries.Count - 1].bottom     = PrevIndex;
                ThisList         = new series();
                ThisList.top     = StartIndex;
                ThisList.topCard = Cards[StartIndex];
                ThisSeries.Add(ThisList);
                StartIndex++;
                GetRemainingSEQ(StartIndex);
            }
        }
Пример #18
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);
        }
Пример #19
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));
        }
Пример #20
0
        // suits must be the same
        // pick the best series for the value of the entire series but subtract the
        // number of cards below the bottom
        public void FormSEQseries(int iFromColumn)
        {
            series ThisList, SaveSeries = null;
            int    nValue;
            int    NumToUnstack;
            int    i, j = 0, iSEQ = 0;
            int    ThisTop = top;

            ThisSeries.Clear();
            if (Cards.Count == 0)
            {
                return;
            }
            ThisList         = new series();
            ThisList.top     = ThisTop;
            ThisList.topCard = Cards[top];
            ThisSeries.Add(ThisList);
            ThisTop++;
            GetRemainingSEQ(ThisTop);

            // when unstacking, the top card is never unstacked since we are trying to get to the top
            // if only 1 series, then takes nothing to unstack (it just gets moved to the destination
            // if 2 series the bottom one takes nothing to unstack, the one above it requires that
            // the one below it be unstacked first so it is = 1 and on up 2,3,etc
            // example:  4 series, K has 3, Q has 2, (J 10) has 1 and (6 5 4 3 2 1) has 0

            for (i = 0; i < ThisSeries.Count; i++)
            {
                ThisSeries[i].iStack = iFromColumn;
                for (j = ThisSeries[i].top; j <= ThisSeries[i].bottom; j++)
                {
                    Cards[j].WhichSEQSeries = i;
                }
                ThisSeries[i].nEmptiesToUnstack = ThisSeries.Count - i - 1;
                if (i == 0)
                {
                    NumToUnstack = ThisSeries.Count - i - 1;
                }
            }

            SEQvalue = 0;
            if (ThisSeries.Count == 0)
            {
                return;
            }
            ThisList = null;
            series LastSeries = null;

            foreach (series s in ThisSeries)
            {
                if (LastSeries != null)
                {
                    LastSeries.NextSeries = s;
                }
#if USE_ALL_SERIES
                i         = utils.CalcSEQSeriesValue(s);
                SEQvalue += i;
#endif
                s.size         = s.bottom - s.top + 1;
                s.topCard.next = s.size;
                for (i = 1; i < s.size; i++)
                {
                    Cards[s.top + i].next = s.size - i;
                }

                ThisList = s;
                iSEQ++;
                LastSeries = s;
            }

            // new:  if CLUBS are suitable and a CLUB series is sequential then we must not score
            // the column high if there is a non CLUB below the series.
            // the above was not implemented
            // instead we will NOT use the SEQ value if the suit is not completable.  just use the count

#if true
            j = 0;
            for (i = ThisSeries.Count - 1; i >= 0; i--)
            {
                series s = ThisSeries[i];
                // jys the value is getting to 1000 and cannot do that
                // just use the largest value
                nValue = utils.CalcSEQSeriesValue(s, BoardState);
                if (j == 0)
                {
                    SEQvalue   = nValue;
                    SaveSeries = s;
                }
                else
                {
                    if ((nValue > SEQvalue) && !bSuitable)
                    {
                        SEQvalue   = nValue;
                        SaveSeries = s;
                    }
                }
                j++;
                if (j > NumEmptyColumns)
                {
                    break;
                }
            }
#endif
            ThisSeries.Last().NextSeries = null;
            if (SEQvalue > 1000)
            {
                SEQvalue = 1000;
            }
            if (SaveSeries != null)
            {
                int b = (1 << SaveSeries.sSuit);
                // the following works at last deal ???  17nov2012
                // if (!((b & iSuitStatus) > 0)) SEQvalue = SaveSeries.size;
                if ((b & iSuitStatus) > 0) // we need this suit
                {
                    return;
                }
                else
                {
                    // we dont need that suit, but we are not in the last deal yet
                    if (bLastDeal)
                    {
                        SEQvalue = SaveSeries.size;
                    }
                }
            }
        }
Пример #21
0
        private int UnstackOneSeries(ref board tb)
        {
            int Any = 0;

            cUnstackOrder[] cUO;
            column          cCol;
            card            CardExposed;

            PlaceHolder.Clear();
            cUO = new cUnstackOrder[tb.NumFacedownColumns()];
            int i = 0;

            tb.CopyWorkingCards(ref xBottomMost, GlobalClass.WorkingType.tBottomMost);
            tb.CopyWorkingInts(ref xEmpties, GlobalClass.WorkingType.tEmpties);
            tb.BuildPlaceholders(ref PlaceHolder);


            // get best unstack order in case we cannot unstack all of them
            i = 0;
            foreach (int e in tb.NonEmpties)
            {
                cCol = tb.ThisColumn[e];
                if (cCol.top == 0)
                {
                    continue;
                }
                int nSEQ = cCol.ThisSeries.Count;
                int nSOS = cCol.ThisSOS.Count;
                cUO[i++] = new cUnstackOrder(e, nSEQ);
            }
            Array.Sort(cUO, delegate(cUnstackOrder c1, cUnstackOrder c2)
            {
                return(c1.SizeSeries.CompareTo(c2.SizeSeries));
            });

            foreach (cUnstackOrder uo in cUO)
            {
                cCol = tb.ThisColumn[uo.e];
                for (i = uo.SizeSeries - 1; i >= 0; i--)
                {
                    series s      = cCol.ThisSeries[i];
                    int    iStack = utils.GetBestMove(s.topCard, ref tb, ref PlaceHolder);
                    if (iStack < 0)
                    {
                        if (xEmpties.Count == 0)
                        {
                            return(Any);
                        }
                        iStack = xEmpties[0];
                        xEmpties.RemoveAt(0);
                    }
                    CardExposed = tb.PerformMove(s.iStack, s.top, iStack, s.size);
                    RecoverPlaceholder(ref tb, ref CardExposed);
                    Any++;
                }
                if (Any > 0)
                {
                    return(Any);
                }
            }
            return(Any);
        }
Пример #22
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);
        }
Пример #23
0
 // use a pattern if one is available else just unstack anyway possible
 private bool UnstackBelow(ref series sKeep)
 {
     return(true);
 }
Пример #24
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));
        }