static void OnPrecalculateBoard(ref CardSet board, PrecalculationContext d) { NormSuit sei = new NormSuit(d.pocketSei); CardSet seBoard = sei.Convert(board); Entry keyEntry = new Entry(d.pocketKind, seBoard); // Actually there is no BinarySearch necessary, because a key will be either present in the table // or go to the end (greater than the rest). // It's left here just to verify the algorithm. int idx = d.list.BinarySearch(keyEntry); if (idx < 0) { if (d.list.Count > 0 && d.list[d.list.Count - 1].key >= keyEntry.key) { throw new ApplicationException( "Algorithm error, new value must be greater than all existing values."); } List <int> pocketIdxs = StdDeck.Descriptor.GetIndexesAscending(d.pocket); List <int> boardIdxs = StdDeck.Descriptor.GetIndexesAscending(seBoard); int[] hand = new int[pocketIdxs.Count + boardIdxs.Count]; int h = 0; for (int i = 0; i < pocketIdxs.Count; ++i) { hand[h++] = pocketIdxs[i]; } for (int i = 0; i < boardIdxs.Count; ++i) { hand[h++] = boardIdxs[i]; } keyEntry.value = Calculate(hand); d.list.Add(keyEntry); } d.count++; }
/// <summary> /// Precalculate and store tables. If the output already exists, will not overwrite. /// <remarks>Long-running. </remarks> /// </summary> /// <param name="round">Round (0, 1 or 2).</param> public static void Precalculate(int round) { DateTime startTime = DateTime.Now; string lutPath = GetLutPath(round); if (File.Exists(lutPath)) { // Do not ovewriting an existing file to save time. Console.WriteLine("LUT file {0} already exist, exiting. Delete the file to recalculate.", lutPath); return; } int POCKETS_COUNT = (int)HePocketKind.__Count; //POCKETS_COUNT = 1; // Test PrecalculationContext context = new PrecalculationContext { Round = round }; int[] listSize = new int[] { 169, 1361802, 15111642 }; context.list = round < 2 ? (object)new List <Entry01>(listSize[round]) : (object)new List <Entry2>(listSize[round]); Console.WriteLine("Calculating for round {0}: ", round); int boardSize = HeHelper.RoundToHandSize[round] - 2; for (int p = 0; p < POCKETS_COUNT; ++p) { context.pocketKind = (HePocketKind)p; context.pocket = HePocket.KindToCardSet((HePocketKind)p); context.pocketSei.Reset(); context.pocketSei.Convert(context.pocket); Console.Write("{0} ", HePocket.KindToString((HePocketKind)p)); CardEnum.Combin(StdDeck.Descriptor, boardSize, CardSet.Empty, context.pocket, OnPrecalculateBoard, context); } Console.WriteLine(); Debug.Assert(EnumAlgos.CountCombin(50, boardSize) * POCKETS_COUNT == context.count); if (round < 2) { WriteTable((List <Entry01>)context.list, lutPath); } else { WriteTable((List <Entry2>)context.list, lutPath); } Console.WriteLine("LUT file {0} written, calculated in {1:0.0} s", lutPath, (DateTime.Now - startTime).TotalSeconds); }
static List <Entry> Precalculate(int boardSize) { int POCKETS_COUNT = (int)HePocketKind.__Count; //POCKETS_COUNT = 1; // Test PrecalculationContext context = new PrecalculationContext(); int[] listSize = new int[] { 169, -1, -1, 1361802, 15111642 }; context.list = new List <Entry>(listSize[boardSize]); for (int p = 0; p < POCKETS_COUNT; ++p) { context.pocketKind = (HePocketKind)p; context.pocket = HePocket.KindToCardSet((HePocketKind)p); context.pocketSei.Reset(); context.pocketSei.Convert(context.pocket); Console.WriteLine("Calculating for board size {0}, pocket {1}", boardSize, context.pocket); CardEnum.Combin(StdDeck.Descriptor, boardSize, CardSet.Empty, context.pocket, OnPrecalculateBoard, context); } Debug.Assert(EnumAlgos.CountCombin(50, boardSize) * POCKETS_COUNT == context.count); return(context.list); }
static void OnPrecalculateBoard(ref CardSet board, PrecalculationContext d) { NormSuit sei = new NormSuit(d.pocketSei); CardSet seBoard = sei.Convert(board); List <Entry01> list01 = null; List <Entry2> list2 = null; UInt32 key = GetKey((int)d.pocketKind, seBoard); bool addNew = false; // A key will be either present in the table or go to the end (greater than the rest). // This is due to the order of dealt boards in CardEnum if (d.Round < 2) { list01 = (List <Entry01>)d.list; addNew = list01.Count == 0 || list01[list01.Count - 1].Key < key; } else { list2 = (List <Entry2>)d.list; addNew = list2.Count == 0 || list2[list2.Count - 1].Key < key; } if (addNew) { List <int> pocketIdxs = StdDeck.Descriptor.GetIndexesAscending(d.pocket); List <int> boardIdxs = StdDeck.Descriptor.GetIndexesAscending(seBoard); int[] hand = new int[pocketIdxs.Count + boardIdxs.Count]; int h = 0; for (int i = 0; i < pocketIdxs.Count; ++i) { hand[h++] = pocketIdxs[i]; } for (int i = 0; i < boardIdxs.Count; ++i) { hand[h++] = boardIdxs[i]; } float[] sdhs; if (d.Round < 2) { Entry01 newEntry = new Entry01 { Key = key }; sdhs = Calculate(hand, d.Round + 1); newEntry.Hs = sdhs[0]; newEntry.SdPlus1 = sdhs[1]; sdhs = Calculate(hand, 3); newEntry.Sd3 = sdhs[1]; list01.Add(newEntry); } else { Entry2 newEntry = new Entry2 { Key = key }; sdhs = Calculate(hand, d.Round + 1); newEntry.Hs = sdhs[0]; newEntry.SdPlus1 = sdhs[1]; list2.Add(newEntry); } } d.count++; }