//PsudoMoveList must have moves inserted in the "front" to keep the move order correct // board tag contains destination of series to be moved to public bool MoveCollapsible(ref series sCollapse, ref board tb) { List <card> BackupOfCardsToMove = new List <card>(); if (cSC.bTrigger) { Console.WriteLine(MethodBase.GetCurrentMethod().Name); } column cCol = tb.ThisColumn[sCollapse.iStack]; int n = sCollapse.pattern.Length; if (n > 7) { return(false); } tb.CopyWorkingInts(ref xEmpties, GlobalClass.WorkingType.tEmpties); if (tb.tag < 0) { tb.tag = xEmpties[0]; xEmpties.RemoveAt(0); } CollapsibleSEQCardsToMove.Clear(); series s = sCollapse; for (int i = 0; i < sCollapse.pattern.Length; i++) { string a = sCollapse.pattern.Substring(i, 1); CollapsibleSEQCardsToMove.Add(s.topCard); BackupOfCardsToMove.Add(s.topCard); s = s.NextSeries; } for (int i = DisStrategy.Count - 1; i >= 0; i--) { // going backwards we see the max empty columns before the ones requiring help if (DisStrategy[i].NumSeqSeries == n) { if (xEmpties.Count >= DisStrategy[i].nEmptyColumns) { if (DisStrategy[i].Ranks.Count > 0) { continue; // must use empty stack for now JYS !!! } // if a placeholder was available, it would have been assigned to tab.tag // since all series are rankable, they can all go under the top card // JYS !!! we could possibly have looked for another placeholder or two to make // complicated moves bool bAny = FormCollapsibleMoves(i, ref tb); return(bAny); } } } return(false); }
// 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); } }
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); }
// 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); }
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); }
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); }