Пример #1
0
        // same as above JSS but does not consume any empty columns
        // the ranks must be in order (rankable under the series) and the gap above both top cards must be 1
        // this routine can be called at any time after building a sorted sequence (BuildSEQ) of any number of suits
        public bool JoinSuitedWhenRankable(ref board tb)
        {
            if (cSC.bTrigger)
            {
                Console.WriteLine(MethodBase.GetCurrentMethod().Name);
            }
            series sDes, sSrc;
            series uDes;    // the unstacked part of the destination
            int    PossibleCostReduction;
            int    RankWanted, LowestRank, RankWantedLoc;

            PsuedoMoveList.Clear();
            tb.BuildPlaceholders(ref PlaceHolder);
            //foreach (series s1 in tb.SortedSEQ)
            for (int i = 0; i < tb.SortedSEQ.Count - 1; i++)
            {
                sDes = tb.SortedSEQ[i]; // biggest is first in sorted order of ranks
                if (sDes.topCard.GapAbove != 1 || sDes.pattern == "")
                {
                    continue;
                }
                // only want reversible moves for swapping purposes
                // and there must be a pattern of else the series is not rankable
                PossibleCostReduction = sDes.bRankable ? utils.hasPlaceholder(ref sDes.topCard, ref tb, ref PlaceHolder) : 0;

                //foreach (series s2 in tb.SortedSEQ)
                for (int j = i + 1; j < tb.SortedSEQ.Count; j++)
                {
                    sSrc = tb.SortedSEQ[j];
                    if (sSrc.topCard.GapAbove != 1 || sSrc.pattern == "")
                    {
                        continue;
                    }
                    if (sSrc.sSuit != sDes.sSuit)
                    {
                        continue;                           // in event more then one suit is in the sorted list
                    }
                    PossibleCostReduction +=
                        sSrc.bRankable ? utils.hasPlaceholder(ref sSrc.topCard, ref tb, ref PlaceHolder) : 0;

                    utils.FreeExcludedPlaceholders(ref PlaceHolder);    // done with our PossibleCostReduction

                    // the 0 below represents possibly a single available placeholder ie; we assume NONE here
                    if (sDes.nEmptiesToUnstack + sSrc.nEmptiesToUnstack > (tb.NumEmptyColumns + PossibleCostReduction + 0))
                    {
                        return(false);
                    }
                    if (sDes.iStack == sSrc.iStack)
                    {
                        continue;
                    }
                    // make s1 (bottom) the destination and s2 (top) the source (ranks must be different)
                    if (sDes.topCard.rank == sSrc.topCard.rank)
                    {
                        continue;                                           // nothing to join
                    }
                    // 9..6 could join to 6..3 by moveing only the 5..3 if it exists
                    RankWanted = sDes.bottomCard.rank - 1;  // find a card in source to be mvoed that is this rank
                    LowestRank = sSrc.bottomCard.rank;
                    if (!(RankWanted > LowestRank && sSrc.topCard.rank >= RankWanted))
                    {
                        continue;
                    }
                    // figure out where that card is in the source to be moved
                    RankWantedLoc = sSrc.top + (1 + sSrc.topCard.rank - sDes.bottomCard.rank);
                    card cSrc = tb.ThisColumn[sSrc.iStack].Cards[RankWantedLoc];
                    Debug.Assert(RankWanted == cSrc.rank);
                    sSrc.size   -= (1 + sSrc.topCard.rank - sDes.bottomCard.rank);
                    sSrc.topCard = cSrc;
                    sSrc.top     = cSrc.iCard;
                    if (sSrc.nEmptiesToUnstack == 0 && sDes.nEmptiesToUnstack == 0)
                    {
                        tb.moveto(cSrc.iStack, cSrc.iCard, sDes.bottomCard.iStack);
                        return(true);
                    }
                    //pseudoCard pCard = new pseudoCard(sDes.topCard.ID, sSrc.bottomCard.ID, true);
                    //PsuedoMoveList.Insert(0, pCard);
                    uDes = null;
                    if (sDes.nEmptiesToUnstack > 0)
                    {
                        uDes     = sDes.NextSeries;
                        uDes.tag = sSrc.iStack;    // after moveing sSrc put the unstack from Des where Src came from
                        // the above works because the algorithm only moves rankables that are in order
                        // so as to not consume a stack. the tag is not updated by any move card operation
                        if (!MoveSeriesBelow(ref tb, ref sDes))
                        {
                            return(false);
                        }
                        uDes.iStack = tb.tag;   // series locations are NOT updated by any cards that are moved
                        // uDes.iStack is where the unstacked stuff was stashed
                        tb.tag = uDes.tag;      // cannot use sSrc.iStack since Src was moved
                    }
                    tb.tag = sDes.iStack;
                    bool bAny = cSC.Suitable.Disassemble.MoveCollapsible(ref sSrc, ref tb);
                    if (!bAny)
                    {
                        return(false);
                    }
                    if (uDes == null)
                    {
                        return(true);
                    }
                    tb.tag = uDes.tag;
                    bAny   = cSC.Suitable.Disassemble.MoveCollapsible(ref uDes, ref tb);
                    return(bAny);
                }
            }
            return(false);
        }
Пример #2
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);
        }