public bool SpinOff(ref board tb)
        {
            int i, j;

            if (cSC.bTrigger)
            {
                Console.WriteLine(MethodBase.GetCurrentMethod().Name);
            }
            int n = tb.ThisColumn[10].Cards.Count;

            for (i = 0; i < 10; i++)
            {
                j = i; // cCO[i].ptr;
                if (tb.ThisColumn[j].Cards.Count == 0)
                {
                    continue;               // column is empty: nothing to spin
                }
                if (tb.NumEmptyColumns > 2) // || tb.bOnLastDeal ||(n==10 && tb.NumEmptyColumns == 1 ))
                {
                    strSpinType = "Spin by suit!";
                    if (SpinThisSuitedColumn(ref tb, j))
                    {
                        continue;
                    }
                    return(false);
                }
                else
                {
                    if (SpinThisColumn(ref tb, j))
                    {
                        continue;
                    }
                    return(false);
                }
            }
            return(true);
        }
Example #2
0
        public int FirstStrategy(ref board oldb)
        {
            int   TotalAny = 0, Any = 0;
            int   NumSOS;
            board tb;

            OurLastBest = oldb.LastBest;
            if (oldb.NumEmptyColumns >= 1)
            {
                do
                {
                    Any       = ExposeTop(ref oldb);
                    TotalAny += Any;
                } while (Any > 0);
            }

            if (!(oldb.RunEndgame()))
            {
                return(0);
            }

            Any       = SOSExposeTop(ref oldb);
            TotalAny += Any;
            NumSOS    = NewBoards.Count; // SOSexpose added this many
            if (oldb.bIsCompletable)
            {
                Any += RunJoinables(ref oldb, false); // process the original board
                for (int i = 0; i < NumSOS; i++)      // process any that SOSexpose created
                {
                    tb = NewBoards[i];
                    board nb = new board(ref tb);
                    Any      += RunJoinables(ref nb, false);
                    TotalAny += Any;
                }
            }
            return(TotalAny);
        }
Example #3
0
        // this looks for available spots to stuff a card and if it cannot find one it suggests an empty stack
        // this is different than the one in strategy because it can use the default BottomMost. This is true
        // because we are leaving the list unchanged.
        private int GetBestMove(card c, ref board tb)
        {
            int i, n;
            int iSameSuit = -1;
            int iAnySuit  = -1;
            int ToStack   = -1;

            n = tb.BottomMost.Count;
            for (i = 0; i < n; i++)
            {
                if (tb.BottomMost[i].ExcludePlaceholder)
                {
                    continue;                                         // cannot use this
                }
                if (tb.BottomMost[i].rank - 1 == c.rank)
                {
                    if (tb.BottomMost[i].suit == c.suit)
                    {
                        iSameSuit = i;
                        ToStack   = tb.BottomMost[i].iStack;
                        break;
                    }
                    iAnySuit = i;
                }
            }
            if (iAnySuit < 0 && iSameSuit < 0)
            {
                return(-1);                                 // signal to use an empty column
            }
            if (iSameSuit >= 0)
            {
                return(ToStack);
            }
            ToStack = tb.BottomMost[iAnySuit].iStack;
            return(ToStack);
        }
Example #4
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);
        }
Example #5
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);
        }
Example #6
0
        public bool ReAssembleStackables(ref List <series> Unstackables, ref board tb, string strPattern)
        {
            int    i, j, n = strPattern.Length;
            string strPossibles = "ABCDEFG".Substring(0, n);

            dictLookup.Clear();
            j = n;
            for (i = 0; i < n; i++)
            {
                dictLookup.Add(strPossibles.Substring(--j, 1), Unstackables[i].topCard);
            }
            tb.CopyWorkingInts(ref xEmpties, GlobalClass.WorkingType.tEmpties);

            /*
             * the following was to go there, but we are doing a type of expose top and there is no SCard
             * as SCard is the breakup column, not another column. use the FILLDS type tools
             *             SCard = new card(ref sCollapse.bottomCard, sCollapse.bottomCard.iStack, sCollapse.bottomCard.iCard);
             * dictLookup.Add("S", SCard);
             *
             * // 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.Collapsible != null || strPattern != cds.Pattern) continue;  // only want to use empties
             *      sosUnstackE(ref tb, ref cds);
             *      return true;
             *  }
             * }
             *
             * */


            return(false);
        }
Example #7
0
        //complete starts off with  x 110 y 380  then x goes to 140 (increments by 30

        private void MakeXmlFile(string strFullPathName, ref board tb, ref cSpinControl cSC)
        {
            bool bFaceUp;       // deck:  all are false except the last enabled
            bool bEnabled;      // complete: all are faceup and all enabled are false

            sbXML = new StringBuilder(16384);
            XmlWriterSettings settings = new XmlWriterSettings();

            settings.Indent             = true;
            settings.IndentChars        = ("    ");
            settings.NewLineChars       = "\n";
            settings.OmitXmlDeclaration = true;

            using (XmlWriter writer = XmlWriter.Create(sbXML, settings)) //(strFullPathName + "_bin.xml", settings))

//            using (XmlWriter writer = XmlWriter.Create(strFullPathName + "_bin.xml", settings))
            {
                // Write XML data.
                writer.WriteStartElement("Root");
                writer.WriteStartElement("GameState");
                writer.WriteElementString("Version", "7");
                writer.WriteElementString("GameSeed", cSC.GameSeed.ToString());
                writer.WriteElementString("Score", tb.score.ToString());             // 2018 tb.score.ToString());
                writer.WriteElementString("Moves", (1 + tb.DealCounter).ToString()); // (tb.NumMoves + tb.MyMoves.TheseMoves.Count).ToString());
                writer.WriteEndElement();                                            // gamestate
                writer.WriteStartElement("CardTable");
                writer.WriteStartElement("CardStacks");
                cCardStack ccsPtr;
                int        nCardStack = 0;
                int        nDirection = 1;

                foreach (column col in tb.ThisColumn)
                {
                    ccsPtr = col.CardStack;
                    int    ccsPtrX = ccsPtr.X;
                    int    ccsPtrY = ccsPtr.Y;
                    int    j = 0; // count cards as only last one is enabled
                    int    dX = 0, dY = 0;
                    string stackName = "";
                    switch (nDirection)
                    {
                    case 1: stackName = "Stack" + (col.CardStack.stackid).ToString();
                        dY            = 7;
                        dX            = -7;
                        break;

                    case 2: stackName = "Deck";
                        dX            = -6;
                        break;

                    case 3: stackName = "Complete";
                        dX            = 30; // origin of X was 110
                        dY            = 0;  // origin of Y was 380
                        break;
                    }
                    writer.WriteStartElement("CardStack");
                    writer.WriteElementString("NumEndCardsSpaced", ccsPtr.NumEndCardsSpaced.ToString());
                    writer.WriteElementString("X", ccsPtr.X.ToString());
                    writer.WriteElementString("Y", ccsPtr.Y.ToString());
                    writer.WriteElementString("Name", stackName);
                    writer.WriteElementString("Direction", nDirection.ToString());
                    writer.WriteStartElement("Cards");
                    foreach (card crd in col.Cards)
                    {
                        writer.WriteStartElement("Card");
                        writer.WriteElementString("X", ccsPtrX.ToString());
                        writer.WriteElementString("Y", ccsPtrY.ToString());
                        bFaceUp  = crd.bFaceUp;
                        bEnabled = bFaceUp;

                        if (nDirection == 3)
                        {
                            bFaceUp  = true;
                            bEnabled = false;
                        }
                        else if (nDirection == 2)
                        {
                            bFaceUp  = false;
                            bEnabled = (j == (col.Cards.Count - 1));
                        }

                        if (nDirection == 1)
                        {
                            ccsPtrY += dY;
                        }
                        writer.WriteElementString("Name", GlobalClass.ProperName(crd));
                        writer.WriteElementString("Type", crd.type.ToString());
                        writer.WriteElementString("FaceUp", bFaceUp.ToString().ToLower());
                        writer.WriteElementString("Enabled", bEnabled.ToString());

                        if (bFaceUp && nDirection < 3)
                        {
                            dY = 23;
                        }

                        if (((1 + j) % 13) == 0)
                        {
                            ccsPtrX += dX;
                            if (nDirection != 1)
                            {
                                ccsPtrY += dY;
                            }
                        }

                        j++;
                        writer.WriteEndElement(); // card
                    }
                    writer.WriteEndElement();     // cards
                    writer.WriteEndElement();     //CardStack
                    nCardStack++;
                    if (nCardStack == 10)
                    {
                        nDirection = 2;
                    }
                    if (nCardStack == 11)
                    {
                        nDirection = 3;
                    }
                    // need to write out the completed stack eventually!!
                }
                writer.WriteEndElement();   // cardstacks
                writer.WriteEndElement();   // cardtable
                writer.WriteEndElement();   // root
                writer.Flush();
                if (strFullPathName.Contains("SUIT"))
                {
                    Console.WriteLine(" Wrote out a binary suit file: " + strFullPathName);
                }
                else if (strFullPathName.Contains("DEAL"))
                {
                    Console.WriteLine(" Wrote out a binary deal file: " + strFullPathName);
                }
                else
                {
                    Console.WriteLine(" replaced with a new binary deal file: " + strFullPathName);
                }
                foreach (cSuitedStatus cSS in tb.SuitStatus)
                {
                    for (int i = 0; i < cSS.NumCompletedAndRemoved; i++)
                    {
                        Console.WriteLine("Removed suit:" + GlobalClass.SuitNames[cSS.index]);
                    }
                }
            }
        }
Example #8
0
        static void SolveBoard(ref cSpinControl cSC, string strSpiderBin)
        {
            int m = GlobalClass.MAX_FILTERED_BOARDS;

            GlobalClass.StrategyType gcst = GlobalClass.StrategyType.CONTINUE_SPINNING;
            board InitialBoard            = new board();

            cSC.Deck             = new cBuildDeck(strSpiderBin, XMLtoRead, ref cSC);
            MakeAllPossibleMoves = new cSpinAllMoves(ref cSC);
            cSC.Deck.GetBoardFromSpiderSave(ref InitialBoard);
            if (InitialBoard.NumEmptyColumns > 0)
            {
                GlobalClass.bFoundFirstColunn = false;  // started with an empty column, no need to display it.
            }
            InitialBoard.ShowBoard();

            cSC.cMXF = new cMergeXmlFile();

            if (cSC.bJustReadXML)
            {
                Console.WriteLine(" Did you mean to read a pre-existing XML file?\n - close window to abort\n - or press N to delete the XML file and abort\n - or press Y to continue");
                if (cSC.EventList.Count > 0)
                {
                    Console.WriteLine(" There are " + cSC.EventList.Count + " events in the event list");
                    Console.WriteLine(cSC.Deck.strEventInfoPrompt);
                }
                ConsoleKeyInfo cki = Console.ReadKey();
                Console.WriteLine("");
                if (cki.Key.ToString().ToLower() == "n")
                {
                    File.Delete(cSC.XML_Diag_filename);
                    Environment.Exit(0);
                }
                else
                {
                    string strA = cki.KeyChar.ToString();
                    int    A    = -1;
                    int.TryParse(strA, out A);

                    if (A >= 1 && A < 7)
                    {
                        int    RequiredOffset = 0;
                        int    RequiredDeal   = A;
                        string strCmd         = Console.ReadLine().ToLower();
                        strA         = strCmd.Substring(0, 1);
                        InitialBoard = null;
                        if (strA == "m")  //Format is 2m34 or 3M45
                        {
                            strCmd         = strCmd.Substring(1);
                            RequiredOffset = Convert.ToInt32(strCmd);
                            bool bResult = cSC.Deck.AdvanceToPosition(RequiredDeal, RequiredOffset, out InitialBoard);
                            CallExit();
                        }
                        else
                        {
                            if (strA == "s") // format is 2s 3S , etc ..   show all best scores
                            {
                                bool bResult = cSC.Deck.ShowAllBestScores(RequiredDeal, out InitialBoard);
                                CallExit();
                            }
                            else if (strA == "t") // format is 2t45 3t9 , etc .. trace using stlookup
                            {                     // deals 2, 3, and set breakpoint in debugger at the callout for the 45, 9, etc
                                RequiredOffset = Convert.ToInt32(strCmd.Substring(1));
                                bool bResult = cSC.Deck.AddBoardsToLookup(RequiredDeal, RequiredOffset);
                                CallExit();
                            }
                            else
                            {
                                Console.WriteLine("Unknown key code.  One of M,S,m,s only");
                                CallExit();
                            }
                        }
                    }
                    else
                    {
                        bool bResult = cSC.Deck.AdvanceSaveBoard(cki.Key.ToString().ToLower(), out InitialBoard);
                        Debug.Assert(false);
                    }
                }
            }



            //Suitable.CheckSuitability(ref InitialBoard);
            // the above is not critical to the program as yet, just good info about unexposed cards

            //cSC.Suitable.CombineLikeSuits(ref InitialBoard);

            MakeAllPossibleMoves.AddInitialBoard(ref InitialBoard, GlobalClass.FIRST_CARD, ref Suitable);


            //cSC.JoinSuited.SpinSuitedJoinables(ref cSC.ThisBoardSeries);


            //if (InitialBoard.bIsCompletable)                PerformReduceSuits(ref cSC, 20);

            //Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e)
            //{
            //    e.Cancel = true;
            //    Program.keepRunning = false;
            //};

            while (true) // (Program.keepRunning)
            {
                RunAway--;
                if (RunAway < 0)
                {
                    Console.WriteLine("hit any key except x: TBS:" + cSC.ThisBoardSeries.Count + "  NBS:" + cSC.NextBoardSeries.Count);
                    ConsoleKeyInfo cki = Console.ReadKey();
                    if (cki.KeyChar == 'x')
                    {
                        Environment.Exit(0);
                    }
                }

                bool b1 = MakeAllPossibleMoves.RunFilter(m);    // m is max to allow after applying filter

                bool bSameSeed = cSC.PrevSeed.bSameSeed(ref cSC.ThisSeed);
                if (cSC.bOutOfSpaceInSTLOOKUP)
                {
                    Console.WriteLine("ran out of space and had to clear stlookup");
                    cSC.stlookup.Clear();
                    cSC.bOutOfSpaceInSTLOOKUP = false;
                }
                if (cSC.bSpinDidAllBoards)
                {
                    int iAny = 0;
                    for (int i = 0; i < cSC.ThisBoardSeries.Count; i++)
                    {
                        board nb = cSC.ThisBoardSeries[i];
                        if (cSC.Suitable.CombineLikeSuits(ref nb))
                        {
                            iAny++;
                        }
                    }
                    if (iAny > 0)
                    {
                        cSC.bSpinDidAllBoards = false;
                        m = cSC.ThisBoardSeries.Count;
                        Console.WriteLine("Cannot deal but found " + iAny.ToString() + "  new boards using join suited" + cSC.bSpinDidAllBoards);
                    }
                }
                if (cSC.bSpinDidAllBoards || bSameSeed || cSC.bStopThisRun)
                {
                    m = HandleDeal(ref cSC, false);
                    Console.WriteLine("Handled deal with m:" + m.ToString() + "  bSpin:" + cSC.bSpinDidAllBoards + " SameSeed:" + bSameSeed, " StopRun:" + cSC.bStopThisRun);
                    Console.WriteLine("TBS: " + cSC.ThisBoardSeries.Count + " NBS: " + cSC.NextBoardSeries.Count);
                    cSC.bTrace = true;
                }
                else
                {
                    // unable to finish all boards -or- didnt generate any boards other then the same seeds
                    if (cSC.SortedScores.Count == 0)
                    {
                        // no larger scores were found during the last run:  use ThisSeed
                        m = HandleDeal(ref cSC, true);
                        Console.WriteLine("Handled deal from SortedScores.count=0 m:" + m.ToString());
                    }
                    else
                    {
                        gcst = utils.UseThisManyBoards(ref cSC, ref m);
                        Console.WriteLine("HNS: " + m + "  type " + gcst.ToString());
                        if (gcst != GlobalClass.StrategyType.CONTINUE_SPINNING)
                        {
                            Console.WriteLine("Seem we are to reduce:" + m);
                            HandleNewStrategy(gcst, ref cSC, ref m);
                        }
                    }
                }
            }
            //if (!Program.keepRunning)
            //{
            //    cSC.BestBoard.ShowBoard();  // 11nov2012 added this ctrl-c stuff
            //}
        }
Example #9
0
        public static int HandleDeal(ref cSpinControl cSC, bool bDealThruSeed)
        {
            int           m, n = cSC.ThisBoardSeries.Count; // utils.UseThisManyBoards(ref cSC);
            cDealStrategy DealStrategy = new cDealStrategy(ref cSC);
            board         tb = null;
            int           j, nNewBoards = 0;

            if (cSC.BestBoard != null)
            {
                SaveBestBoard(ref cSC);
            }

            if (bDealThruSeed)
            {
                n = cSC.ThisSeed.Seeds.Count;
            }
            if (n > GlobalClass.MAX_FILTERED_BOARDS)
            {
                n = GlobalClass.MAX_FILTERED_BOARDS;
            }
            cSC.BestBoard = null;   // only want the one for the current deal
            for (int i = 0; i < n; i++)
            {
                if (bDealThruSeed)
                {
                    if (i >= cSC.ThisSeed.SeedIndex.Count)
                    {
                        break;
                    }
                    j = cSC.ThisSeed.SeedIndex[i];
                }
                else
                {
                    j = i;
                }
                tb         = cSC.ThisBoardSeries[j];
                nNewBoards = DealStrategy.DealToBoard(ref tb, DateTime.Now, n);
                // nNewBoards mistakenly includes dead boards so dont check for n==m anymore
                cSC.LocalDealCounter++;
                tb.DealCountIndex = cSC.LocalDealCounter;
                // save only the first 12 boards of the deal.  the deal is against the previous deck
                if (i < GlobalClass.MaxDealsToShow)
                {
                    bool bOnLast = ((i == (n - 1)) || (i == (GlobalClass.MaxDealsToShow - 1)));
                    cSC.Deck.SaveBoardAtDeal(bOnLast ? GlobalClass.eSBAD.eAllGathered : GlobalClass.eSBAD.eContinue, ref tb, i);
                    if (tb.MyMoves.TheseMoves.Count() < 6)
                    {
                        int kk = 0;
                    }
                }
                if (nNewBoards > GlobalClass.MinInserts)
                {
                    break;
                }
            }
            m = DealStrategy.GetBoards(ref cSC);
            if (m <= 0)
            {
                if (tb.DealCounter < 5)
                {
                    Debug.Assert(m > 0);
                    Console.WriteLine("problem with handleing deal! m:" + m + " nNewBoards:" + nNewBoards);
                }
                else
                {
                    Console.WriteLine("Game over\n");
                }
                Environment.Exit(0);
            }
            tb = cSC.ThisBoardSeries[0];
            utils.SetSuitableValues(ref cSC, ref tb);
            if (m > GlobalClass.MAX_FILTERED_BOARDS)
            {
                m = GlobalClass.MAX_FILTERED_BOARDS;
            }
            // all will be processed, just want at most 500 results after RunFilter
            if (m < GlobalClass.MIN_FILTERED_BOARDS)
            {
                m = GlobalClass.MIN_FILTERED_BOARDS;
            }
            // want to have at least this many from the filter if possible
            cSC.BestScore = 0;      // this may get new boards into SortedScores at least on the next filter run
            cSC.stlookup.Clear();
            //GlobalClass.bLookForFirstColumn = true;  // ONLY WANT TO DO THIS ONCE FOR VERY FIRST TIME.
            //GlobalClass.bFoundFirstColunn = false;
            return(m);
        }
Example #10
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);
        }
Example #11
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);
        }
        public bool ShrinkThisBoardSeries(int nToUse)
        {
            int   tbsNum = cSC.ThisBoardSeries.Count;
            board tb;
            int   nEmpties = 0;
            int   i, j, n = GetBestScores(nToUse, ref nEmpties);


            if (n == 0)
            {
                return(false);
            }

            cSC.NextBoardSeries.Clear();

            if (nEmpties < 3 || true)   // jys !!!!
            {
                for (i = 0; i < n; i++)
                {
                    tb = cSC.ThisBoardSeries[cSC.BestScoreIndex[i]];
                    //int beforeJSS = tb.score;
                    //cSC.JoinSuited.JoinAllSuitedWhenRankable(ref tb);
                    //cSC.BestScore = tb.score;
                    //Debug.Assert(beforeJSS <= tb.score);
                    cSC.NextBoardSeries.Add(tb);
                    if ((GlobalClass.TraceBits & 1) > 0)
                    {
                        tb.ShowBoard();
                    }
                }
            }
            else
            {
                // get the one(s) with the fewest moves when the boards are about the same
                j  = 0; // count "n" may be different
                tb = cSC.ThisBoardSeries[cSC.BestScoreIndex[0]];
                cSC.NextBoardSeries.Add(tb);
                j++;
                for (i = 1; i < n; i++)
                {
                    board nb = cSC.ThisBoardSeries[cSC.BestScoreIndex[i]];
                    if (tb.Comparable(ref nb) && nb.MyMoves.TheseMoves.Count < tb.MyMoves.TheseMoves.Count)
                    {
                        cSC.NextBoardSeries.RemoveAt(cSC.NextBoardSeries.Count - 1);
                        cSC.NextBoardSeries.Add(nb);
                        tb = nb;
                    }
                    else
                    {
                        cSC.NextBoardSeries.Add(nb);
                        j++;
                        tb = nb;
                    }
                }
                n = j;
            }



            if ((GlobalClass.TraceBits & 2) > 0)
            {
                Console.WriteLine("++++++++Shrank from " + tbsNum + " to " + n + "  and here is the best one...");
                DumpSorted(1);  // very little difference between any, no need to show "n"
                cSC.stlookup.ShowBufferStats();
            }
            cSC.ThisBoardSeries.Clear();
            cSC.CountLimit = 0;
            cSC.PrevSeed.CopySeeds(ref cSC.ThisSeed);
            cSC.ThisSeed.Clear();
            for (i = 0; i < n; i++)
            {
                tb = cSC.NextBoardSeries[i];
                tb.MyMoves.AddShrinkCode(ref cSC, n);
                tb.from = tb.ID;
                tb.ID   = cSC.ThisBoardSeries.Count;
                cSC.ThisSeed.Add(ref tb);
                cSC.ThisBoardSeries.Add(tb);
                Debug.Assert(tb.ID == (cSC.ThisBoardSeries.Count - 1));
                //if (i == 0)
                //{
                //    cBestScore cBS = new cBestScore(0, tb.score, tb.NumEmptyColumns, tb.NumCompletedSuits);
                //    cSC.SortedScores.Add(cBS);
                //}
            }
            cSC.NextBoardSeries.Clear();
            cSC.BestScore = cSC.ThisBoardSeries[0].score;
            cSC.stlookup.ShrinkPerformed();

            return(true);
        }
Example #13
0
 public void Add(ref board tb)
 {
     Seeds.Add(tb.UniqueID);
     SeedIndex.Add(tb.ID);
 }
Example #14
0
        public void ReCreateBinFile(ref board tb, ref cSpinControl cSC, string strPrefix)
        {
            long   nLen1, nLen = 1048576;
            int    i, j, n;
            int    DealID          = cSC.LocalDealCounter; // this is the deals that are done to the "working deal" which is the board deal counter.
            string strFullpathname = "";

            if (strPrefix == "")
            {
                strFullpathname = GlobalClass.strSpiderOutputBinary;
            }
            else
            {
                strFullpathname = GlobalClass.strSpiderDir + strPrefix + ".SpiderSolitaireSave-ms";
            }


            //FileStream inStream = File.OpenRead(strFullpathname + ".hdr");
            //BinaryReader br = new BinaryReader(inStream);
            //nLen = inStream.Length;
            //Debug.Assert(nLen == 0x2028);



            if (File.Exists(strFullpathname))
            {
                Debug.Assert(false);
            }

            FileStream   outStream = File.Create(strFullpathname);
            BinaryWriter bw        = new BinaryWriter(outStream);


            // get the hdr
            byte[] outbuf = new byte[256000];
            for (j = 0; j < 0x2028; j++)
            {
                outbuf[j] = cSC.Hdr[j];
            }


            nLen = cSC.PngArray.Length;
            // get the png file
#if SAVE_PNG
            inStream = File.OpenRead(strFullpathname + ".png");
            nLen     = inStream.Length;
            br       = new BinaryReader(inStream);
            br.Read(outbuf, 0x2028, (int)nLen);
            nLen1 = nLen + 0x2028;
#endif
            nLen1 = 0x2028;
            for (i = 0; i < nLen; i++)
            {
                outbuf[nLen1] = cSC.PngArray[i];
                nLen1++;
            }

            MakeXmlFile(strFullpathname, ref tb, ref cSC);
            n = sbXML.Length;
            string sbTemp = sbXML.ToString();
            j = (int)nLen1;
            // convert n into bytes and append ff fe so one could get "c6 18 01 00 ff fe"
            byte[] b6 = new byte[8];
            GetUnk6(ref b6, 6 + n * 2); // added 2 to fix problem and added another 2 for two more nulls but 0xa is missing

            for (i = 0; i < 6; i++)
            {
                outbuf[j] = b6[i];
                j++;
            }
            for (i = 0; i < n; i++)
            {
                outbuf[j] = (byte)sbTemp[i];
                j++;
                outbuf[j] = 0;
                j++;
            }
            outbuf[j] = 0;
            j++;
            outbuf[j] = 0x0a;
            j++;
            bw.Write(outbuf, 0, j + 2);
            bw.Close();
        }
        public bool RunFilter(int BoardsToSave)
        {
            bool bCanSpinMore = true;
            int  LastCount;

            cSC.CountLimit   = 0;
            BoardBeingWorked = 0;
            board tb, OldBoard;
            bool  bOnlyNotifyOnce = true;

            cSC.bSignalSpinDone        = false;
            cSC.bExceededCountLimit    = false;
            cSC.bExceededONEcolLimit   = false;
            cSC.bExceededTWOcolLimit   = false;
            cSC.bExceededThreecolLimit = false;
            cSC.bOutOfSpaceInSTLOOKUP  = false;
            cSC.bGotOneSuitAtLeast     = false;
            dtFirstBoard = DateTime.Now;
            cSC.SortedScores.Clear();
            cSC.BestScoreIndex.Clear();
            cSC.TimeDealStarted = TimeLastBest;
            NumOne             = 0;
            NumTwo             = 0;
            NumThreeOrBetter   = 0;
            Num3000            = 0;
            TimeLastBest       = DateTime.Now; // in event we never get a "best"
            TimeSinceFilterRan = TimeLastBest;
            OriginalCount      = cSC.ThisBoardSeries.Count;
            bool bAnyInShrink;

            //bool bAbleToReduce = false;
            ClearNumSuitedInSeries();
            while (BoardBeingWorked < cSC.ThisBoardSeries.Count)
            {
                OldBoard = cSC.ThisBoardSeries[BoardBeingWorked];
                tb       = new board(ref OldBoard);
                tb.from  = OldBoard.ID;
                //cSC.Strategy.ExposeOneTop(ref tb);
                tb.RunCounter = cSC.RunCounter++;

                if (tb.NotifySuitJustCompleted && bOnlyNotifyOnce)
                {
                    tb.NotifySuitJustCompleted = false;
                    bOnlyNotifyOnce            = tb.bIsCompletable; // once all are done then no need for hi values
                    utils.SetSuitableValues(ref cSC, ref tb);
                }

                // cSC.JoinSuited.JoinAllSuitedWhenRankable(ref tb);
                // 12november2012 had to comment out the above because makeing wrong moves
                int any = cSC.Strategy.FirstStrategy(ref tb);

                //if (BoardBeingWorked < OriginalCount)
                //{
                //    int any = cSC.Strategy.FirstStrategy(ref tb);
                //    bAbleToReduce = (any > 0);
                //    if (bAbleToReduce)
                //    {
                //        cSC.Strategy.GetBoards();
                //    }
                //}
                //else
                //{
                //    int any = cSC.Strategy.RunJoinables(ref tb, true);
                //    bAbleToReduce = (any > 0);
                //}



                LastCount    = cSC.ThisBoardSeries.Count;
                bCanSpinMore = SpinOff(ref tb);
                if (GlobalClass.bFoundFirstColunn)
                {
                    string strName = cSC.FormName(tb.DealCounter, eSavedType.eFIRST);
                    GlobalClass.bFoundFirstColunn = false;
                    cSC.cBD.SetCS(ref GlobalClass.FirstEmptyColumn);
                    cXmlFromBoard xtest = new cXmlFromBoard();
                    xtest.ReCreateBinFile(ref GlobalClass.FirstEmptyColumn, ref cSC, strName);
                    cSC.Deck.SaveBoardMoves(ref GlobalClass.FirstEmptyColumn, strName);
                }
                OldBoard.nchild = cSC.ThisBoardSeries.Count - LastCount;
                BoardBeingWorked++;
                if (cSC.bSignalSpinDone)
                {
                    Console.WriteLine("Spin Done");
                    break;
                }
            }
            if (LastDuplicateBoard != null)
            {
                int        LDB_ID = LastDuplicateBoard.ID;
                cBestScore cBS    = new cBestScore(LDB_ID,
                                                   LastDuplicateBoard.score,
                                                   LastDuplicateBoard.NumEmptyColumns,
                                                   LastDuplicateBoard.NumCompletedSuits,
                                                   LastDuplicateBoard.bOnLastDeal);
                cSC.SortedScores.Add(cBS);
                Debug.Assert(LastDuplicateBoard.score == cSC.ThisBoardSeries[LDB_ID].score);
                LastDuplicateBoard = null;
            }

            cSC.bSpinDidAllBoards = (BoardBeingWorked == cSC.ThisBoardSeries.Count);
            //if (cSC.bExceededONEcolLimit) cSC.bSpinDidAllBoards = true;
            cSC.bStopThisRun = cSC.Strategy.ConsiderStopRunning(ref RepeatDepth);
            if ((GlobalClass.TraceBits & 2) > 0)
            {
                Console.WriteLine("DidAllBoards:" + cSC.bSpinDidAllBoards + " SpinDone:" + cSC.bSignalSpinDone + " ScoresSaved:" + cSC.SortedScores.Count + " NumSeeds:" + cSC.ThisSeed.SeedIndex.Count);
            }
            bAnyInShrink = ShrinkThisBoardSeries(BoardsToSave);
            if (!bAnyInShrink)
            {
                int n = cSC.ThisSeed.SeedIndex.Count;
                Console.WriteLine("None in shrink but seed was:" + n.ToString());
                for (int i = 0; i < n; i++)
                {
                    cSC.ThisBoardSeries[cSC.ThisSeed.SeedIndex[i]].MyMoves.AddShrinkCode(ref cSC, n);
                }
            }
            return(bAnyInShrink);
        }
Example #16
0
        public static GlobalClass.StrategyType  UseThisManyBoards(ref cSpinControl cSC, ref int NumToUse)
        {
            int i, n = cSC.ThisBoardSeries.Count;
            int iBiggest = 0;

            int[] tsbEmptyDistribution = new int[11] {
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            };
            int[] sedEmptyDistribution = new int[11] {
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            };
            Debug.Assert(cSC.ThisBoardSeries.Count > 0);
            Debug.Assert(cSC.ThisSeed.SeedIndex.Count > 0);



            foreach (board tb in cSC.ThisBoardSeries)
            {
                tsbEmptyDistribution[tb.Empties.Count]++;
            }
            for (i = 0; i < cSC.ThisSeed.SeedIndex.Count; i++)
            {
                board tb = cSC.ThisBoardSeries[cSC.ThisSeed.SeedIndex[i]];
                sedEmptyDistribution[tb.Empties.Count]++;
            }

            for (i = 10; i >= 1; i--)
            {
                if (sedEmptyDistribution[i] > 0)
                {
                    iBiggest = i;
                    break;
                }
            }

            if (iBiggest == 0)
            {
                NumToUse = GlobalClass.MAX_FILTERED_BOARDS;    // if no empty columns run thru all boards
                return(GlobalClass.StrategyType.CONTINUE_SPINNING);
            }
            if (iBiggest <= 3)
            {
                NumToUse = GlobalClass.MIN_FILTERED_BOARDS;
                return(GlobalClass.StrategyType.CONTINUE_SPINNING);
            }


            if (iBiggest > 3 && cSC.ThisBoardSeries[0].bIsCompletable)
            {
                NumToUse = 0;
                return(GlobalClass.StrategyType.REDUCE_SUITS); // stop the spinning - switch to end game
            }

            // UNTIL I FIX JOINSUITS
            //if (iBiggest == 3)
            //{
            //    NumToUse = 10;
            //    return GlobalClass.StrategyType.SPIN_JOINSUITS;
            //}
            //if (iBiggest == 2)
            //{
            //    NumToUse = GlobalClass.MIN_FILTERED_BOARDS;
            //    return GlobalClass.StrategyType.RUN_JOINSUITS_INPLACE;
            //}

            //foreach (board tb in cSC.ThisBoardSeries)
            //{
            //    if (tb.NumEmptyColumns == 2)
            //        Console.WriteLine(tb.ID + " " + tb.score + " ");
            //}

            NumToUse = GlobalClass.MIN_FILTERED_BOARDS;
            return(GlobalClass.StrategyType.CONTINUE_SPINNING);
        }
Example #17
0
        static void Main(string[] args)
        {
            bool         bIsThere = false;
            string       stExt = ".SpiderSolitaireSave-ms";
            string       stTemp, strSpiderBin0;
            string       PathToDirectory;
            string       stSrc = "", stDef = "Spider Solitaire.SpiderSolitaireSave-ms";
            cSpinControl cSC;
            board        InitialBoard;

            stTemp = System.Reflection.Assembly.GetEntryAssembly().Location; // path to executable
            if (args.Count() > 0)
            {
                stSrc = "\\" + args[0];
            }
            else //stSrc = "\\" + stDef;  - not searching for save file anymore
            {
                GiveHelp();
                Environment.Exit(0);
            }
            strSpiderBin0 = System.IO.Path.GetDirectoryName(stTemp) + stSrc;
            bIsThere      = File.Exists(strSpiderBin0);
            if (bIsThere)
            {
                PathToDirectory           = Path.GetDirectoryName(strSpiderBin0) + "\\";
                GlobalClass.strSpiderBin  = strSpiderBin0;
                GlobalClass.strSpiderDir  = PathToDirectory;
                GlobalClass.strSpiderName = PathToDirectory + Path.GetFileNameWithoutExtension(strSpiderBin0);
                GlobalClass.strSpiderExt  = Path.GetExtension(strSpiderBin0);
                cSC          = new cSpinControl(); // this created the default xml "filename"
                InitialBoard = new board();
                cSC.Deck     = new cBuildDeck(strSpiderBin0, XMLtoRead, ref cSC);
                if (args.Count() < 2) // just want to look at the xml
                {
                    cSC.Deck.GetBoardFromSpiderSave(ref InitialBoard);
                }
                else
                {
                    string stDes = stDef;
                    if (args.Count() == 3)
                    {
                        stDes = args[2];
                    }
                    if (!stDes.Contains(stExt))
                    {
                        stDes += stExt;
                    }
                    if (args[0] == stDes)
                    {
                        Console.WriteLine("cannot have same output file name as the input saved game\n");
                        Environment.Exit(0);
                    }
                    stTemp = PathToDirectory + Path.GetFileNameWithoutExtension(args[1]);
                    if (GlobalClass.strSpiderName == stTemp)
                    {
                        Console.WriteLine("should not have same input saved game name as the input xml filename\n");
                        Console.WriteLine("or input xml file will be over written as that filename used for temp storage\n");
                        Environment.Exit(0);
                    }
                    GlobalClass.strSpiderOutputBinary = cSC.BIN_Diag_filename = PathToDirectory + "\\" + stDes;
                    cSC.Deck.GetBoardFromSpiderSave(ref InitialBoard);  // read in the saved game and also create the matching xml
                    cSC.XML_Diag_filename = PathToDirectory + args[1];
                    cSC.Deck.WriteBoardMergingXML();
                }
            }
        }
        public bool TrySpinOneCard(ref board tb, int SrcCol, int SrcCard, int DesCol, int DesCard)
        {
            if (cSC.bTrigger)
            {
                Console.WriteLine(MethodBase.GetCurrentMethod().Name);
            }
            board nb = null;

            int[] des = new int[112];
            Int64 ChkWord = 0;
            int   WouldGoHere = cSC.ThisBoardSeries.Count;
            bool  bInsertFailed = false, bResult = false;

#if AINT
            int[] des1 = new int[112];
            Int64 ChkWord1 = 0, ChkWord2 = 0;
            int   desptr1;
            bool  bVerify = true;
#endif
            int desptr = tb.FormDupList(SrcCol, SrcCard, DesCol, DesCard, ref des, ref ChkWord);
            // check for a duplicate move before creating a new board
            // note that the number of actual moves is 1 less since we have not yet moved anything

            if (cSC.stlookup.bIsNewBoard(ChkWord, desptr, ref des, tb.MyMoves.TheseMoves.Count + 1, ref WouldGoHere, ref bInsertFailed))
            {
                if (bInsertFailed)
                {
                    cSC.bSignalSpinDone       = true;
                    cSC.bOutOfSpaceInSTLOOKUP = true;
                    return(false);
                }
                if (WouldGoHere != cSC.ThisBoardSeries.Count)
                {
                    // this indicates the lookup program found an identical board that had more moves
                    // replace that board with the moves from this one.

                    //ThisBoardSeries[WouldGoHere].DoNotUse = true;
                    cSC.ThisBoardSeries.RemoveAt(WouldGoHere);
                    nb      = new board(ref tb);
                    bResult = SpinOneCard(ref nb, SrcCol, SrcCard, DesCol, DesCard);
                    cSC.ThisBoardSeries.Insert(WouldGoHere, nb);
                    cSC.ThisBoardSeries.RemoveAt(cSC.ThisBoardSeries.Count - 1);
                    return(bResult);
                }

                // either it was not found or it was found but we cannot update the queue
                // because the pointer WouldGoHere is invalid (board was shrunk)
                nb      = new board(ref tb);
                bResult = SpinOneCard(ref nb, SrcCol, SrcCard, DesCol, DesCard);

#if AINT
                //bVerify = tbsCompare1(0, 12);
                //tbsDump(WouldGoHere, desptr, ref des);
                //if ((WouldGoHere == 12 && RunCounter == 2) || WouldGoHere == 0)
                //{
                //    tbsDump(WouldGoHere, desptr, ref des);
                //}
                //if (WouldGoHere == 13 || WouldGoHere == 102)
                //{
                //    tbsDump(WouldGoHere, desptr, ref des);
                //    desptr = tb.FormDupList(SrcCol, SrcCard, DesCol, DesCard, ref des, ref ChkWord2);
                //    desptr1 = nb.FormVerify(ref des1, ref ChkWord1);
                //    Console.WriteLine("WGH: " + WouldGoHere + " " + ChkWord.ToString("x16") + " " + ChkWord1.ToString("x16") + " " + ChkWord2.ToString("x16"));
                //}
                if ((iTrace & 0x10) > 0)
                {
                    ChkWord1 = 0;
                    //desptr = tb.FormDupList(SrcCol, SrcCard, DesCol, DesCard, ref des, ref ChkWord);
                    desptr1  = nb.FormVerify(ref des1, ref ChkWord1);
                    bVerify  = (desptr == desptr1);
                    bVerify |= (ChkWord == ChkWord1);
                    for (int ii = 0; ii < desptr; ii++)
                    {
                        bVerify |= (des[ii] == des1[ii]);
                    }
                    Debug.Assert(bVerify);
                }
#endif
                return(bResult);
            }
            else
            {
                cSC.NumberDuplicates++;
            }
            return(true);
        }
Example #19
0
        /*
         * THIS DOES NOT WORK EXCEPT FOR VERY SIMPLE SEQ SERIES JYS !!!! need UnStack and to use patterns
         * This joins one SEQ series under another so as to concatanate the two series
         * */



        /*
         * this just exposes the top card and check to see if it can be recovered
         * jys this needs to be able to expose all cards that are exposable
         * (8s,6h,7D) expose to 8S,7D,6H
         *
         * right now, the series underneath must be SEQ, use the SOS one for that, but it does not use placeholders
         *
         * */
        public int ExposeOneTop(ref board tb)
        {
            int  e, n;
            int  LocAbove;  // location of card just above the top card
            card CardAbove;
            int  Any = 0;
            int  OriginalSource;

            foreach (card cT in tb.TopMost)
            {
                LocAbove = cT.iCard - 1;
                if (LocAbove <= 0)
                {
                    continue;                   // nothing to expose
                }
                CardAbove = tb.ThisColumn[cT.iStack].Cards[LocAbove];
                if (CardAbove.bFaceUp)
                {
                    continue;                       // already exposed
                }
                // we want only unexposed cards and the series underneath must be SEQ

                // we can expose this card by moving the one below it (our card cT)
                if (CardAbove.rank - 1 != cT.rank)
                {
                    continue;                                        // nope, wrong rank, we want to move it back
                }
                n = tb.ThisColumn[cT.iStack].Cards.Count - cT.iCard; // number of cards to move
                // the below does no error checking nor any statistics computation


                if (tb.NumEmptyColumns > 0)
                {
                    e = tb.Empties[0];
                    OriginalSource = cT.iStack;
                    tb.PerformMove(cT.iStack, cT.iCard, e, n);
                    tb.PerformMove(e, 0, OriginalSource, n);
                    Any++;
                }
                else
                {
                    // we will have to find a card that can hold it temporarily
                    foreach (card bC in tb.BottomMost)
                    {
                        if (bC.iStack == cT.iStack)
                        {
                            continue;
                        }
                        if (bC.rank - 1 == cT.rank)
                        {
                            OriginalSource = cT.iStack;
                            n = tb.ThisColumn[cT.iStack].Cards.Count - cT.iCard;
                            tb.PerformMove(cT.iStack, cT.iCard, bC.iStack, n);
                            tb.PerformMove(bC.iStack, bC.iCard + 1, OriginalSource, n);
                            Any++;
                        }
                    }
                }
                if (Any > 0)
                {
                    tb.ThisColumn[cT.iStack].CalculateColumnValue(cT.iStack, tb.NumEmptyColumns, tb.BoardState());
                }
            }

            if (Any > 0)
            {
                tb.ReScoreBoard(); // alternately CalcBoardScore and then GetSortedTops
                return(ExposeOneTop(ref tb));
            }
            return(Any);
        }
Example #20
0
 public bool JoinSuitedJoinables(ref board tb)
 {
     return(false);
 }
Example #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);
        }
Example #22
0
        public int SOSExposeTop(ref board tb)
        {
            bool                  bAnySameSuit = false;
            List <series>         TopSeries    = new List <series>();
            List <cPossibleMoves> ActualMoves  = new List <cPossibleMoves>();

            NewBoards.Clear();
            TryUnstackAll(ref tb);

            tb.CopyWorkingCards(ref xBottomMost, GlobalClass.WorkingType.tBottomMost);
            foreach (column cCol in tb.ThisColumn)
            {
                if (cCol.iStack > 9)
                {
                    break;
                }
                if (cCol.ThisSOS.Count == 1)
                {
                    TopSeries.Add(cCol.ThisSOS[0]);
                }
            }
            foreach (card bm in xBottomMost)
            {
                foreach (series s in TopSeries)
                {
                    card tm = s.topCard;
                    if ((tm.rank + 1) == bm.rank)
                    {
                        card           bbm = bm;
                        cPossibleMoves cpm = new cPossibleMoves(ref tm, ref bbm);
                        ActualMoves.Add(cpm);
                    }
                }
            }

            foreach (cPossibleMoves cpm in ActualMoves)
            {
                if (cpm.bSameSuit)
                {
                    bAnySameSuit = true;
                    break;
                }
            }

            foreach (cPossibleMoves cpm in ActualMoves)
            {
                column        cCol;
                card          cCrd;
                board         nb;
                series        SOS;
                bool          bCan;
                List <series> ListSEQ;
                List <int>    yEmpties    = new List <int>();
                List <card>   yBottomMost = new List <card>();
                if (bAnySameSuit && !cpm.bSameSuit)
                {
                    continue;
                }
                nb = new board(ref tb);
                nb.AssignCompletedID(GlobalClass.TypeCompletedBy.ID_SOSET);
                CardsToMove.Clear();
                cCol    = nb.ThisColumn[cpm.From.iStack];
                SOS     = cCol.ThisSOS[0];
                ListSEQ = cCol.ThisSeries;    // the top cards in the SEQ are the ones to move in the SOS
                for (int i = 0; i < SOS.NumSubSeries; i++)
                {
                    cCrd = ListSEQ[i].topCard;
                    CardsToMove.Add(cCrd);
                }
                nb.tag = cpm.To.iStack;
                nb.CopyWorkingInts(ref yEmpties, GlobalClass.WorkingType.tEmpties);
                nb.CopyWorkingCards(ref yBottomMost, GlobalClass.WorkingType.tBottomMost);
                bCan = DisAssemble.bCanDisassembleSOS(SOS.NumSubSeries, ref nb, ref yEmpties, ref yBottomMost, ref CardsToMove);
                if (bCan)
                {
                    NewBoards.Add(nb);
                    nb.AssignCompletedID();
                }
            }
            return(NewBoards.Count);
        }
Example #23
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);
        }
 public void AddNewBoard(ref board ThisBoard)
 {
     ThisBoard.ReScoreBoard();
     ThisBoard.ID = cSC.ThisBoardSeries.Count;
     cSC.ThisBoardSeries.Add(ThisBoard);
 }
Example #25
0
        // 20nov2012 need to prevent too many boards from being created
        // problem arises when there are more then 1 empty column
        // Do not return more than NumWanted boards total
        // spread those number across the number of empty columns using decimation
        // by multipling by NumEmptys and then using only every 1 out of NumEmptys

        public int DealToBoard(ref board tb, DateTime TimeOfLastDeal, int NumBoardsTotal)
        {
            int  i, n, NumEmpties, NonEmpties, nbPtr = NewBoards.Count;
            bool bMore        = true;
            int  lBest        = tb.score;
            int  NumWantedMax = 32;
            int  NumWantedMin = 16;
            int  NumWanted    = tb.NumEmptyColumns * NumWantedMax * NumBoardsTotal;

            if (NumWanted < NumWantedMin)
            {
                NumWanted = NumWantedMin;
            }
            int NumGenerated  = 0;
            int DecimationCnt = tb.NumEmptyColumns * NumBoardsTotal;

            int[] NumDealtTo;
            if (DecimationCnt == 0)
            {
                DecimationCnt = 1;
            }
            tb.bWasDealtTo = false;

            if (OutOfCardsOrDone(ref tb))
            {
                return(0);
            }
            StartOfDealPtr = nbPtr;
            tb.CopyWorkingInts(ref OEmpties, GlobalClass.WorkingType.tEmpties);
            tb.score = lBest;

            NumGenerated += AddBoard(ref tb, TimeOfLastDeal);
            bMore         = (NumGenerated < NumWanted);
            // we reduced this board to a series that have 1 column less (if it has an empty column)
            while (bMore)
            {
                while (nbPtr < NewBoards.Count)
                {
                    if (!NewBoards[nbPtr].bWasDealtTo)
                    {
                        board nb = NewBoards[nbPtr];
                        nb.score      = lBest;
                        NumGenerated += AddBoard(ref nb, TimeOfLastDeal);
                    }
                    nbPtr++;
                    if (NumGenerated >= NumWanted)
                    {
                        bMore = false;
                        break;
                    }
                }
                bMore = false;
                //NonEmpties = 0;
                //for (i = StartOfDealPtr; i < NewBoards.Count; i++)
                //{
                //    if (NewBoards[i].NumEmptyColumns == 0)
                //    {
                //        NonEmpties++;
                //    }
                //}
                //bMore = bMore && (NonEmpties < NumWanted);
                //nbPtr = StartOfDealPtr;
            }
            NumDealtTo = new int[NumGenerated];
            n          = 0;
            for (i = StartOfDealPtr; i < NewBoards.Count; i++)
            {
                if (NewBoards[i].bWasDealtTo)
                {
                    NumDealtTo[n]            = i;
                    NewBoards[i].bWasDealtTo = false;
                    n++;
                }
            }
            for (i = 0; i < n; i += DecimationCnt)
            {
                NewBoards[NumDealtTo[i]].bWasDealtTo = true;
                NumCreated++;
            }
            //for(i=StartOfDealPtr;i<NewBoards.Count;i++)
            //{
            //    board nb = NewBoards[i];
            //    if (nb.NumEmptyColumns == 0)
            //    {
            //        //nb.dead = true;  // finished with this one also
            //        // deal does not add a board so it needs to be marked dead ...but...
            //        // the check for empty columns is the same as check for dead
            //        NumCreated++;
            //        //GetBetterMoves(ref nb);
            //        // 11nov2012 somehow we are dealing a 2nd time so dont deal to a dead board
            //        if(!nb.bWasDealtTo)
            //        {
            //            Debug.Assert(false);    // dead is not used anymore ???
            //            nb.deal(lBest, TimeOfLastDeal);
            //            nb.bWasDealtTo = true;
            //        }
            //    }
            //}

            //Console.WriteLine("NW:" + NumWanted + "  DC:" + DecimationCnt + "  NC:" + NumCreated + "  NG:" + NumGenerated + "  ====\n");

            return(NumCreated);
        }
Example #26
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);
        }
Example #27
0
        public bool PerformSuitabiltyStudy(ref board tb, int isuit)
        {
            column     tCol;
            card       tCrd;
            List <int> DupList = new List <int>();
            int        cRankBits = ALL_AVAILABLE;
            int        i, j, k, rBit;
            int        DealCnt = 0;

            tb.BuildingThisSuit = 0;

            if (!tb.SuitStatus[isuit].bSuitsCompletable)
            {
                // calculate all missing ranks, keep a copy (dMissing)
                for (j = 1; j < 14; j++)
                {
                    rBit = 1 << j;
                    if ((rBit & tb.SuitStatus[isuit].SuitedRankBits) == 0)
                    {
                        eMissingRanks.Add(j);
                        dMissingRanks.Add(j);
                    }
                }
                // see if we can expose some cards so as to reduce the number of required (eMissing)
                for (i = 0; i < 10; i++)
                {
                    tCol = tb.ThisColumn[i];
                    if (tCol.Cards.Count < 2)
                    {
                        continue;                       // there are no cards to expose
                    }
                    for (j = tCol.top - 1; j >= 0; j--)
                    {
                        tCrd = tCol.Cards[j];
                        if (isuit != tCrd.suit)
                        {
                            continue;
                        }
                        if (DupList.Contains(tCrd.rank)) // must have put it in earlier
                        {
                            for (k = j + 1; k < tCol.Cards.Count; k++)
                            {
                                if (tCol.Cards[k].rank == 13)
                                {
                                    continue;
                                }
                            }
                            int nUncover = tCol.NumUnstacksReq(tCrd);
                            foreach (cExposeStack cES in ExposesRequired)
                            {
                                if (cES.Rank != tCrd.rank)
                                {
                                    continue;
                                }
                                if (cES.NumToRemove > nUncover)
                                {
                                    cES.NumToRemove = nUncover;
                                    cES.Stack       = i;
                                }
                            }
                        }
                        if (eMissingRanks.Contains(tCrd.rank))
                        {
                            eMissingRanks.Remove(tCrd.rank);
                            DupList.Add(tCrd.rank);
                            // if a king is below this face down card then assume it cannot be exposed
                            for (k = j + 1; k < tCol.Cards.Count; k++)
                            {
                                if (tCol.Cards[k].rank == 13)
                                {
                                    continue;
                                }
                            }
                            cExposeStack ces = new cExposeStack(i, tCol.NumUnstacksReq(tCrd), tCrd.rank);
                            ExposesRequired.Add(ces);
                        }
                    }
                }


                if (eMissingRanks.Count > 0) // seems cannot get a suit unless we deal
                {
                    tCol = tb.ThisColumn[10];

                    // for each deal, go thru the available deck and see if we can form a complete suit
                    // if a card from the deck duplicates one that is facedown then remove the facedown one
                    // from the exposes required list
                    for (i = 0; i < tCol.Cards.Count; i++)
                    {
                        tCrd = tCol.Cards[i];
                        if (0 == (i % 10))
                        {
                            DealCnt++;
                            if (eMissingRanks.Count > 0)
                            {
                                DealsRequired++;
                            }
                            if (eMissingRanks.Count > 0)
                            {
                                CardsReqAfterDeal.Add(eMissingRanks.Count);
                            }
                        }

                        if (tCrd.suit != isuit)
                        {
                            continue;
                        }
                        if (eMissingRanks.Contains(tCrd.rank))
                        {
                            eMissingRanks.Remove(tCrd.rank);
                            // no need to expose any cards if they will be in the deal
                            for (j = 0; j < ExposesRequired.Count; j++)
                            {
                                ces = ExposesRequired[j];
                                if (dMissingRanks.Contains(ces.Rank))
                                {
                                    //ExposesRequired.RemoveAt(j);
                                    ExposesRequired[j].AtDeal = DealCnt;
                                }
                            }
                        }
                        //if (eMissingRanks.Count == 0) break;
                    }
                    if (eMissingRanks.Count > 0)
                    {
                        CardsReqAfterDeal.Add(eMissingRanks.Count);
                    }
                }
            }

            if (tb.SuitStatus[isuit].bSuitsCompletable)
            {
                NumberCompletable++;
            }
            return(tb.SuitStatus[isuit].bSuitsCompletable);
        }
Example #28
0
        public board(ref board nb)
        {
            int    i, j;
            column cCol;

            init();
            // jys !!! need to copy the suitability stuff
            NumCompletedSuits = nb.NumCompletedSuits;
            bitJustCompleted  = nb.bitJustCompleted; // fixs problem with suits missing from deck?
            for (i = 0; i < nb.UnexposedTypes.Count; i++)
            {
                UnexposedTypes.Add(nb.UnexposedTypes[i]);
            }
            strSuitsRemoved = nb.strSuitsRemoved;
            DealString      = nb.DealString;
            for (i = 0; i < 12; i++)    //2018 should have copied the completed ones also
            {
                cCol = nb.ThisColumn[i];
                for (j = 0; j < cCol.Cards.Count; j++)
                {
                    card nc = new card();
                    nc.bFaceUp = cCol.Cards[j].bFaceUp;
                    nc.ID      = cCol.Cards[j].ID;
                    ThisColumn[i].Cards.Add(nc);
                }
            }

            foreach (cSuitedStatus cSS in SuitStatus)
            {
                int ii = cSS.index;
                cSS.bSuitsCompletable      = nb.SuitStatus[ii].bSuitsCompletable;
                cSS.bExposesRequired       = nb.SuitStatus[ii].bExposesRequired;
                cSS.UnexposedRankBits      = nb.SuitStatus[ii].UnexposedRankBits;
                cSS.SuitedRankBits         = nb.SuitStatus[ii].SuitedRankBits;
                cSS.NumCompletedAndRemoved = nb.SuitStatus[ii].NumCompletedAndRemoved;
            }
            ExtraPoints     = nb.ExtraPoints;
            bOnLastDeal     = nb.bOnLastDeal;
            score           = nb.score;
            dead            = nb.dead;
            nchild          = nb.nchild;
            from            = nb.ID;
            NumEmptyColumns = nb.NumEmptyColumns;
            DealCounter     = nb.DealCounter;
            bIsCompletable  = nb.bIsCompletable;
            MyMoves.CopyMoves(ref nb.MyMoves);
            BuildingThisSuit = nb.BuildingThisSuit;
            for (i = 0; i < nb.SuitedSEQ.Count; i++)
            {
                SuitedSEQ.Add(nb.SuitedSEQ[i]);
            }
            TimeOfLastDeal = nb.TimeOfLastDeal;
            foreach (cSuitedStatus css in SuitStatus)
            {
                for (i = 0; i < nb.SuitStatus[css.index].BonusExposes.Count; i++)
                {
                    css.BonusExposes.Add(nb.SuitStatus[css.index].BonusExposes[i]);
                }
            }

            ReScoreBoard();
        }
Example #29
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);
        }
        // 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);
        }