Пример #1
0
        // free up a column by joining any SEQ that are joinable
        // or moves one suited sequence under another of proper rank
        // this only looks at the bottom card and tries to find an SEQ that can fit under it
        // of same suit
        public bool FreeSuitedSuits(ref board tb, ref List <card> LastSEQ)
        {
            bool   bFound = false;
            column cCol;
            card   Src = null;
            card   Des = null;

            tb.AssignCompletedID(GlobalClass.TypeCompletedBy.ID_FSS);
            do
            {
                bFound = false;
                LastSEQ.Clear();
                foreach (int e in tb.NonEmpties)
                {
                    cCol = tb.ThisColumn[e];
                    LastSEQ.Add(cCol.ThisSeries.Last().topCard);
                }
                //LastSEQ.Sort(delegate(series s1, series s2)
                //{
                //    return Comparer<int>.Default.Compare(s1.topCard.rank, s2.topCard.rank);
                //});

                // see if any suits can be combined
                foreach (card tm in tb.BottomMost)
                {
                    foreach (card bm in LastSEQ)
                    {
                        if (tm.iStack == bm.iStack || tm.rank == 1)
                        {
                            continue;
                        }
                        if ((bm.rank + 1) == tm.rank && bm.suit == tm.suit)
                        {
                            bFound = true;
                            Des    = tm;
                            Src    = bm;
                            break;
                        }
                    }
                    if (bFound)
                    {
                        break;
                    }
                }
                if (bFound)
                {
                    tb.moveto(Src.iStack, Src.iCard, Des.iStack);
                    tb.ReScoreBoard();
                    if (tb.NotifySuitJustCompleted)
                    {
                        tb.ExplainNoRescoreBoard("Free Suited Suits succeeded");
                        tb.NotifySuitJustCompleted = false;
                    }
                }
            } while (bFound);
            tb.AssignCompletedID();
            return(false);
        }
Пример #2
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);
        }
Пример #3
0
        // this moves empties an "S" only
        // we want to leave S fixed !!!

        public void sosUnstackE(ref board tb, ref csosDisStrategy cds)
        {
            int    i, PosLastLetter, n = cds.UnstackMoves.Count;
            card   c;
            string srcLetter;   // from the pattern
            string desLetter = cds.Pattern.Substring(0, 1);
            string strPattern = cds.Pattern.Substring(1);
            string strSrc, strDes;
            int    FromStack = -1, ToStack = -1, FromCard = -1;
            int    e;

            tb.CopyWorkingInts(ref xEmpties, GlobalClass.WorkingType.tEmpties);
            for (i = 0; i < 3; i++)
            {
                xDepth[i] = 0;
            }


            for (i = 0; i < n; i++)
            {
                strSrc = cds.UnstackMoves[i].id_src;
                if (strSrc == "S")
                {
                    PosLastLetter = strPattern.Length - 1;
                    srcLetter     = strPattern.Substring(PosLastLetter, 1);
                    strPattern    = strPattern.Substring(0, PosLastLetter);
                    c             = dictLookup[srcLetter];
                    FromStack     = c.iStack;
                    FromCard      = c.iCard;
                }
                else
                {
                    e         = Convert.ToInt32(strSrc);
                    FromStack = xEmpties[e];
                    xDepth[e]--;
                    FromCard = xDepth[e];
                }
                strDes = cds.UnstackMoves[i].id_des;
                if (strDes == "S")
                {
                    c       = dictLookup[desLetter];
                    ToStack = c.iStack;
                }
                else
                {
                    e       = Convert.ToInt32(strDes);
                    ToStack = xEmpties[e];
                    xDepth[e]++;
                }
                tb.moveto(FromStack, FromCard, ToStack);
            }
        }
Пример #4
0
        // this spins only a series of cards of same suit
        private bool SpinCardInto(ref board tb, int ColumnToFill)
        {
            int    i;
            series s;

            Debug.Assert(tb.ThisColumn[ColumnToFill].Cards.Count == 0);
            // do not move a card into a column that contains something

            for (i = 0; i < 10; i++)
            {
                if (OEmpties.Contains(i))
                {
                    continue;
                }
                // do not move from empty column because it is either empty
                // or we just put something in it so as to make it not empty

                if (tb.ThisColumn[i].ThisSeries.Count == 1 && tb.ThisColumn[i].ThisSeries.Last().top == 0)
                {
                    continue;
                }
                // do not create an empty column just to fill another one

                nb      = new board(ref tb);
                nb.dead = false;
                s       = nb.ThisColumn[i].ThisSeries.Last();
                //stats[i]++;

                nb.moveto(i, s.top, ColumnToFill);
                //nb.ThisColumn[i].CalculateColumnValue(i);
                //nb.ThisColumn[ColumnToFill].CalculateColumnValue(ColumnToFill);
                nb.ReScoreBoard();
                NewBoards.Add(nb);
            }
            return(false);
        }
Пример #5
0
        public bool FormMovesFromRules(int fptr, ref board tb, ref List <int> Empties, ref List <card> CardsToMove)
        {
            int           i, j, n;
            int           r1, r2;
            int           FromStack = 0, FromLoc = 0, ToStack = 0;
            string        strOper1, strOper2;
            card          TopCardToMove = CardsToMove[0];
            int           TopCardsDestination = tb.tag;
            int           SrcColumn = TopCardToMove.iStack;
            string        strSrc, strDes;
            List <cMoves> Moves = DisStrategy[fptr].Moves;

            n = Moves.Count;
            Debug.Assert(n % 2 == 0);   // must be an even number
            tb.ClearStacks();
            for (i = 0; i < n; i += 2)
            {
                strSrc = Moves[i].MoveID;
                r1     = GetOperands(strSrc, out strOper1);
                if (strOper1 == "SC")
                {
                    FromStack = SrcColumn;
                    FromLoc   = CardsToMove.Last().iCard;
                    CardsToMove.RemoveAt(CardsToMove.Count - 1);
                }
                else if (strOper1 == "E")
                {
                    FromStack = Empties[r1];
                    FromLoc   = tb.ThisColumn[FromStack].HoldMoves.Pop();
                }
                else if (strOper1 == "C")
                {
                    for (j = 0; j < WhereStored.Count; j++)
                    {
                        if (WhereStored[j].SeriesID == r1)
                        {
                            FromStack = WhereStored[j].StackNumber;
                            FromLoc   = tb.ThisColumn[FromStack].HoldMoves.Pop();
                        }
                    }
                }
                else
                {
                    Debug.Assert(false);
                    return(false);
                }


                strDes = Moves[i + 1].MoveID;
                r2     = GetOperands(strDes, out strOper2);

                if (strOper2 == "DC")
                {
                    ToStack = TopCardsDestination;
                }
                else if (strOper2 == "E")
                {
                    ToStack = Empties[r2];
                    tb.ThisColumn[ToStack].HoldMoves.Push(tb.ThisColumn[ToStack].Cards.Count);
                }
                else if (strOper2 == "C")
                {
                    for (j = 0; j < WhereStored.Count; j++)
                    {
                        if (WhereStored[j].SeriesID == r2)
                        {
                            ToStack = WhereStored[j].StackNumber;
                            tb.ThisColumn[ToStack].HoldMoves.Push(tb.ThisColumn[ToStack].Cards.Count);
                        }
                    }
                }
                else
                {
                    Debug.Assert(false);
                    return(false);
                }
                tb.moveto(FromStack, FromLoc, ToStack);
            }
            return(true);
        }
Пример #6
0
        public bool ReduceSuits(ref board oldtb)
        {
            bool  bSuccess = true;
            card  cNext = null;
            card  ExposedCard = null;
            int   e, CardID, LastID;
            card  CardExposed;
            board tb = new board(ref oldtb);

            tb.AssignCompletedID(GlobalClass.TypeCompletedBy.ID_RSI);
            OnCounter++;
            InitializeReduction(ref tb, ref cNext);
            Debug.Assert(cNext.rank == 13);
            GetPlaceholders(ref tb, cNext.iStack);

            if (bStackablesAbove(ref tb, ref cNext))
            {
                bSuccess = UnstackSeriesBelow(ref tb, ref cNext);
                if (bSuccess)
                {
                    e = tb.Empties[0];
                    tb.Empties.RemoveAt(0);
                    CardExposed = tb.moveto(cNext.iStack, cNext.iCard, e);    // have to move the king
                    RecoverPlaceholder(ref tb, ref CardExposed);
                    tb.tag = e;
                    InitializeReduction(ref tb, ref cNext);
                }
                else
                {
                    tb.AssignCompletedID();
                    return(false);  // jys !!! may want to try a second or lower ranked card
                }
            }
            else
            {
                tb.tag = cNext.iStack;
                GetPlaceholders(ref tb, tb.tag);
            }

            // unstack below the last card (cNext) and the next card

            while (bSuccess)
            {
                bSuccess = UnstackSeriesBelow(ref tb, ref cNext);
                if (bSuccess)
                {
                    if (StackableIDs.Count > 0)
                    {
                        CardID = StackableIDs[0];   // next card to gather in
                        StackableIDs.RemoveAt(0);
                        LastID   = cNext.ID;
                        cNext    = utils.FindCardFromID(ref tb, CardID);
                        bSuccess = UnstackSeriesBelow(ref tb, ref cNext);
                        if (bSuccess)
                        {
                            ExposedCard = tb.moveto(cNext.iStack, cNext.iCard, tb.tag);
                            RecoverPlaceholder(ref tb, ref ExposedCard);
                        }
                        else
                        {
                            tb.AssignCompletedID();
                            return(false);
                        }
                    }
                    else
                    {
                        tb.ReScoreBoard();
                        cSC.Suitable.PerformSuitabilityScreening(ref tb);
                        if (tb.bIsCompletable)
                        {
                            cSC.NextBoardSeries.Add(tb);
                        }
                        else
                        {
                            cSC.ThisBoardSeries.Add(tb);
                        }
                        tb.AssignCompletedID();
                        return(true);
                    }
                }
                else
                {
                    tb.AssignCompletedID();
                    return(false);
                }
            }
            tb.AssignCompletedID();
            return(false);
        }
Пример #7
0
        // dont call this unless it was sorted by rank
        // this does not handle card subsets that are in the same column
        public bool JoinAnyLikeSuits(ref board tb)
        {
            if (cSC.bTrigger)
            {
                Console.WriteLine(MethodBase.GetCurrentMethod().Name);
            }
            series sDes, sSrc;
            int    PossibleCostReduction;
            int    RankWanted, LowestRank, RankWantedLoc;

            PsuedoMoveList.Clear();
            //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
                PossibleCostReduction = sDes.bRankable ? 1 : 0;

                //foreach (series s2 in tb.SortedSEQ)
                for (int j = i + 1; j < tb.SortedSEQ.Count; j++)
                {
                    sSrc = tb.SortedSEQ[j];
                    if (sSrc.sSuit != sDes.sSuit)
                    {
                        continue;                           // in event more then one suit is in the sorted list
                    }
                    PossibleCostReduction += sSrc.bRankable ? 1 : 0;
                    // the 1 below represents possibly a single available placeholder
                    if (sDes.nEmptiesToUnstack + sSrc.nEmptiesToUnstack > (tb.NumEmptyColumns + 1 + PossibleCostReduction))
                    {
                        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, sSrc.bottomCard.iStack);
                        return(true);
                    }
                    pseudoCard pCard = new pseudoCard(sDes.topCard.ID, sSrc.bottomCard.ID, true);
                    PsuedoMoveList.Insert(0, pCard);
                    if (sSrc.nEmptiesToUnstack > 0)
                    {
                        if (!UnstackBelow(ref sSrc))
                        {
                            return(false);
                        }
                    }
                    if (sDes.nEmptiesToUnstack > 0)
                    {
                        if (!UnstackBelow(ref sDes))
                        {
                            return(false);
                        }
                    }
                    return(JoinPsudos());
                }
            }
            return(false);
        }
Пример #8
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);
        }
Пример #9
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);
        }
Пример #10
0
        // return true if was able to create a new board
        public bool SpinOneCard(ref board tb, int SrcCol, int SrcCard, int DesCol, int DesCard)
        {
            if (cSC.bTrigger)
            {
                Console.WriteLine(MethodBase.GetCurrentMethod().Name);
            }
            int      iSecs = 0;
            TimeSpan TimeSinceLastBest;

            tb.AssignCompletedID(GlobalClass.TypeCompletedBy.ID_BS);
            tb.moveto(SrcCol, SrcCard, DesCol);

            tb.ReScoreBoard();
            if (tb.NotifySuitJustCompleted)
            {
                NumSuitsWritten++;
                bool   WriteOnce        = true;
                string strJustCompleted = "_";
                int    j = 1;
                for (int i = 0; i < 4; i++)
                {
                    if ((j & tb.bitJustCompleted) > 0)
                    {
                        strJustCompleted += GlobalClass.cSuits[i] + "_";
                        SuitsCompleted[i]++;
                        if (SuitsCompleted[i] > 1)
                        {
                            WriteOnce = false;
                        }
                    }
                    j = j << 1;
                }

                if (WriteOnce)
                {
                    string strName = cSC.Deck.SaveBoardAsBin(ref tb, eSavedType.eSUIT);
                    cSC.Deck.SaveBoardMoves(ref tb, strName);
                }
            }
            if (tb.score >= cSC.BestScore)
            {
                if (tb.score == cSC.BestScore)
                {
                    LastDuplicateBoard = tb;
                }
                else
                {
                    cSC.BestScore = tb.score;
                    cBestScore cBS = new cBestScore(cSC.ThisBoardSeries.Count, tb.score, tb.NumEmptyColumns, tb.NumCompletedSuits, tb.bOnLastDeal);
                    if (tb.NotifySuitJustCompleted)
                    {
                        cBS.SuitJustCompleted |= tb.bitJustCompleted;
                    }
                    cSC.SortedScores.Add(cBS);
                    cSC.BestBoard      = tb;
                    LastDuplicateBoard = null;
                }
            }
            else
            {
                if (tb.bOnLastDeal && false)
                {
                    cBestScore cBS = new cBestScore(cSC.ThisBoardSeries.Count, tb.score, tb.NumEmptyColumns, tb.NumCompletedSuits, tb.bOnLastDeal);
                    if (tb.NotifySuitJustCompleted)
                    {
                        cBS.SuitJustCompleted |= tb.bitJustCompleted;
                    }
                    cSC.SortedScores.Add(cBS);
                }
            }

            tb.NotifySuitJustCompleted = false;
            //tb.from = tb.ID;  // board was not spun off here
            tb.ID = cSC.ThisBoardSeries.Count;
            tb.AssignCompletedID();

            if ((GlobalClass.TraceBits & 8) > 0 || cSC.bTrigger)
            {
                tb.ShowRawBoard();
            }
            cSC.ThisBoardSeries.Add(tb);

            cSC.CountLimit++;
            TimeSinceLastBest = DateTime.Now.Subtract(TimeLastBest);
            if (cSC.bSignalSpinDone)
            {
                return(false);
            }
            if (TimeSinceLastBest.TotalSeconds > cSC.MaxValues.TimeOutBest)
            {
                Console.WriteLine("Aborting due to timeing out");
                if ((GlobalClass.TraceBits & 2) > 0)
                {
                    Console.WriteLine("Best1: " + cSC.BestScore + " dups:" + cSC.NumberDuplicates + " BoardsScored:" + cSC.CountLimit + " LastBoardSpun:" + BoardBeingWorked);
                    Console.WriteLine("Suits made (dchs) " + SuitsCompleted[0].ToString() + " " +
                                      SuitsCompleted[1].ToString() + " " +
                                      SuitsCompleted[2].ToString() + " " +
                                      SuitsCompleted[3].ToString() + " StringSuits:" + tb.strSuitsRemoved);
                    if (OriginalCount > BoardBeingWorked)
                    {
                        Console.WriteLine("Did not visit " + (OriginalCount - BoardBeingWorked) + " boards from last deal");
                    }
                }
                cSC.bSpinTimedOut   = true;
                cSC.bSignalSpinDone = true;
                return(false);
            }
            if (tb.score > GlobalClass.SUIT_WEIGHT)
            {
                Num3000++;
                if (tb.NotifySuitJustCompleted)
                {
                    tb.NotifySuitJustCompleted = false;
                    utils.SetSuitableValues(ref cSC, ref tb);
                    //cSC.bSignalSpinDone = true;
                    cSC.bGotOneSuitAtLeast = true;
                    //Console.WriteLine("Completed Suit");
                    //return true;
                }
            }
            else if (tb.NumEmptyColumns > 2)
            {
                NumThreeOrBetter++;
                if (NumThreeOrBetter > 100 && Num3000 == 0)
                {
                    cSC.bSignalSpinDone        = true;
                    cSC.bExceededThreecolLimit = true;
                    Console.WriteLine("ABORT:  Too many Three Column events: " + NumThreeOrBetter);
                    return(false);
                }
            }
            else if (tb.NumEmptyColumns > 1)
            {
                NumTwo++;
//                if (NumTwo > (cSC.MaxValues.MaxInserts / (1000 - 198 * tb.DealCounter)) && NumThreeOrBetter == 0)
                if (NumTwo > (1 + tb.DealCounter) * 200 && NumThreeOrBetter == 0)
                {
                    cSC.bSignalSpinDone      = true;
                    cSC.bExceededTWOcolLimit = true;
                    Console.WriteLine("ABORT:  Too many Two Column events: " + NumTwo);
                    return(false);
                }
            }
            else if (tb.NumEmptyColumns > 0)
            {
                NumOne++;
                //if (NumOne > ((1 + tb.DealCounter) * 1000) && NumTwo == 0)
                if (NumTwo == 0)
                {
                    if (NumOne > (tb.DealCounter < 2 ? GlobalClass.SUIT_WEIGHT : (2 * GlobalClass.SUIT_WEIGHT)))
                    {
                        cSC.bSignalSpinDone      = true;
                        cSC.bExceededONEcolLimit = true;
                        Console.WriteLine("ABORT:  Too many One Column events: " + NumOne);
                        return(false);
                    }
                }
            }

            if (0 == (cSC.CountLimit % 5000) && ((GlobalClass.TraceBits & 4) > 0))
            {
                dtNow = DateTime.Now;
                TimeSpan tc         = dtNow.Subtract(tb.TimeOfLastDeal);
                string   strSinceLD = "";
                if (tc.TotalSeconds < 60)
                {
                    strSinceLD = Convert.ToInt32(tc.TotalSeconds).ToString("0") + "s";
                }
                else
                {
                    strSinceLD = Convert.ToInt32(tc.TotalMinutes).ToString("0") + "m";
                }

                dtDiff = dtNow.Subtract(dtLast);
                dtLast = dtNow;
                iSecs  = Convert.ToInt32(dtDiff.TotalSeconds);
                tb.ShowBoard();
                Console.WriteLine("Q(" + cSC.SortedScores.Count + ") " + cSC.BestScore + " dups:" + cSC.NumberDuplicates + " limit:" + cSC.CountLimit / 1000 + "k i:" + BoardBeingWorked + " et:" + strSinceLD + " dif:" + (cSC.CountLimit - BoardBeingWorked) + " 1c:" + NumOne + " 2c:" + NumTwo + " 3+" + NumThreeOrBetter + " " + strSpinType);
                cSC.stlookup.ShowBufferStats();
            }


            // if (MoveValue == board.DEALT_A_CARD) return bCreatedBoard;
            // no need to check timouts, etc as we just want to get this board into the system

            if (cSC.CountLimit >= cSC.MaxValues.MaxInserts)
            {
                cSC.bSignalSpinDone     = true;
                cSC.bExceededCountLimit = true;
                Console.WriteLine("Aborting!  Exceeded limit when counting");
            }

            if (cSC.bSignalSpinDone && (GlobalClass.TraceBits & 2) > 0)
            {
                dtNow  = DateTime.Now;
                dtDiff = dtNow.Subtract(dtLast);
                dtLast = dtNow;
                iSecs  = Convert.ToInt32(dtDiff.TotalSeconds);
                tb.ShowBoard();
                Console.WriteLine("SpinDone - Best: " + cSC.BestScore + " dups:" + cSC.NumberDuplicates + " limit:" + cSC.CountLimit / 1000 + "k i:" + BoardBeingWorked + " et:" + iSecs + " dif:" + (cSC.CountLimit - BoardBeingWorked) + " 1c:" + NumOne + " 2c:" + NumTwo + " 3+" + NumThreeOrBetter);
                return(false);
            }

            if (cSC.bSignalSpinDone)
            {
                return(false);
            }

            LastCount = cSC.ThisBoardSeries.Count;
            if (cSC.BestScore > GlobalClass.COL_WEIGHT)
            {
                if (cSC.BestScore > LastBest)
                {
                    if ((GlobalClass.TraceBits & 2) > 0)
                    {
                        Console.WriteLine(TraceBoard(LastCount - 1));
                        dtDiff = DateTime.Now.Subtract(dtFirstBoard);
                        tb.ShowBoard();
                        TimeSinceFilter = DateTime.Now.Subtract(TimeSinceFilterRan);
                        Console.WriteLine("Extra:(" + tb.ExtraPoints + ") " + cSC.BestScore + " dups:" + cSC.NumberDuplicates + " limit:" + cSC.CountLimit + " i:" + BoardBeingWorked + " TO: " + cSC.MaxValues.TimeOutBest + " (Sec) MaxIter:" + cSC.MaxValues.MaxInserts + " TimeSinceFilterRan(sec):" + TimeSinceFilter.TotalSeconds.ToString("0"));
                    }
                }
                LastBest = cSC.BestScore;
            }
            return(true); // bSignalSpinDone;
        }