public async Task HandleRequest(IOwinContext context) { var pocket = context.Request.Query["pocket"]; var board = context.Request.Query["board"]; var callback = context.Request.Query["callback"]; if (string.IsNullOrWhiteSpace(board)) { board = string.Empty; } var odds = new TexasHoldemOdds { Pocket = HoldemOddsCalculator.SortCards(pocket), Board = HoldemOddsCalculator.SortCards(board) }; var cacheOdds = Cache.Get(odds.GetCacheKey()) as TexasHoldemOdds; if (cacheOdds == null) { Cache.Add(odds.GetCacheKey(), odds, _policy); var calculator = new HoldemOddsCalculator(); cacheOdds = await calculator.Calculate(odds, o => Cache.Set(odds.GetCacheKey(), odds, _policy)); } //check If-None-Match header etag to see if it matches our data hash else if (context.Request.Headers["If-None-Match"] == cacheOdds.GetETag()) { //if it does return 304 Not Modified context.Response.StatusCode = 304; return; } var jsonData = await Task.Factory.StartNew(() => JsonConvert.SerializeObject(cacheOdds)); var result = string.Empty; if (string.IsNullOrWhiteSpace(callback)) { context.Response.ContentType = "application/json"; result = jsonData; } else { context.Response.ContentType = "application/javascript"; result = callback + "(" + jsonData + ");"; } //set the response as cached for cache duration context.Response.Headers["Cache-Control"] = string.Format("max-age={0}", CACHE_DURATION_SECS); //set etag context.Response.ETag = cacheOdds.GetETag(); //Just in case, handle CORS context.Response.Headers["Access-Control-Allow-Origin"] = "*"; await context.Response.WriteAsync(result); }
private static void SaveOdds(TexasHoldemOdds odds) { Console.WriteLine("Saving generated odds for pocket {0}", odds.Pocket); var json = JsonConvert.SerializeObject(odds); File.WriteAllText(Path.Combine(_outputPath, string.Format("{0}.json", odds.GetCacheKey())), json); }
public TexasHoldemOdds Get(string pocket, string board) { if (pocket == null) { throw new ArgumentNullException("pocket"); } if (board == null || board.Equals("undefined", StringComparison.InvariantCultureIgnoreCase)) { board = string.Empty; } ulong playerMask = Hand.ParseHand(pocket); // Player Pocket Cards ulong partialBoard = Hand.ParseHand(board); // Partial Board // Calculate values for each hand type double[] playerWins = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; double[] opponentWins = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; // Count of total hands examined. long count = 0; var stopWatch = new Stopwatch(); stopWatch.Start(); // Iterate through all possible opponent hands foreach (ulong opponentMask in Hand.Hands(0UL, partialBoard | playerMask, 2).AsParallel()) { // Iterate through all possible boards foreach (ulong boardMask in Hand.Hands(partialBoard, opponentMask | playerMask, 5).AsParallel()) { // Create a hand value for each player uint playerHandValue = Hand.Evaluate(boardMask | playerMask, 7); uint opponentHandValue = Hand.Evaluate(boardMask | opponentMask, 7); // Calculate Winners if (playerHandValue > opponentHandValue) { // Player Win playerWins[Hand.HandType(playerHandValue)] += 1.0; } else if (playerHandValue < opponentHandValue) { // Opponent Win opponentWins[Hand.HandType(opponentHandValue)] += 1.0; } else if (playerHandValue == opponentHandValue) { // Give half credit for ties. playerWins[Hand.HandType(playerHandValue)] += 0.5; opponentWins[Hand.HandType(opponentHandValue)] += 0.5; } count++; if (stopWatch.Elapsed > TimeSpan.FromSeconds(10)) { break; } } if (stopWatch.Elapsed > TimeSpan.FromSeconds(10)) { break; } } stopWatch.Stop(); var outcomes = new List <PokerOutcome>(); for (var index = 0; index < playerWins.Length; index++) { outcomes.Add(new PokerOutcome { HandType = (Hand.HandTypes)index, HandTypeName = ((Hand.HandTypes)index).ToString(), WinPercentage = playerWins[index] / ((double)count) * 100.0 }); } var results = new TexasHoldemOdds { Pocket = pocket, Board = board, Outcomes = outcomes.ToArray(), OverallWinSplitPercentage = outcomes.Sum(o => o.WinPercentage), CalculationTimeMS = stopWatch.ElapsedMilliseconds, Completed = stopWatch.Elapsed <= TimeSpan.FromSeconds(10) }; return(results); }
static void Main(string[] args) { Console.WriteLine(Assembly.GetExecutingAssembly().GetName().FullName); Console.WriteLine(); if (args.Length < 1) { Console.WriteLine("Please specifiy output folder path"); return; } _outputPath = args[0]; Directory.CreateDirectory(_outputPath); bool overwrite = false; if (args.Length > 1) { if (args[1].Equals("/overwrite", StringComparison.InvariantCultureIgnoreCase)) { overwrite = true; } } var deck = GenerateDeck(); var calculator = new HoldemOddsCalculator(); var tasks = new List <Task>(); for (int i = 0; i < deck.Count; i++) { for (int j = 0; j < deck.Count; j++) { //must be different cards if (i != j) { var odds = new TexasHoldemOdds { Pocket = HoldemOddsCalculator.SortCards(string.Format("{0} {1}", deck[i], deck[j])), Board = String.Empty }; //if the file exists, and we are not overwriting, skip these cards if (!overwrite && File.Exists(Path.Combine(_outputPath, string.Format("{0}.json", odds.GetCacheKey())))) { Console.WriteLine("Skipping odds for pocket {0}", odds.Pocket); continue; } Console.WriteLine("Generating odds for pocket {0}", odds.Pocket); var calculateTask = calculator.Calculate(odds, o => Console.WriteLine("Updated odds for pocket {0}", o.Pocket)); calculateTask.ContinueWith(t => SaveOdds(t.Result)); tasks.Add(calculateTask); //if we've got enough tasks to keep the processors busy if (tasks.Count >= Environment.ProcessorCount) { //wait for any of them to finish Task.WaitAny(tasks.ToArray(), Timeout.Infinite); //remove any completed tasks int k = 0; while (k < tasks.Count) { if (tasks[k].IsCompleted) { tasks.RemoveAt(k); } else { k++; } } } } } } if (tasks.Count > 0) { //wait for the remainder to complete Task.WaitAll(tasks.ToArray(), Timeout.Infinite); } var outPath = Path.Combine(_outputPath, "PrimeCache.json"); if (File.Exists(outPath)) { File.Delete(outPath); } using (var outputArchive = new StreamWriter(outPath)) { bool firstItem = true; Directory.GetFiles(_outputPath, "*.json") .Where(filePath => !filePath.Equals(outPath, StringComparison.InvariantCultureIgnoreCase)) .ToList().ForEach(filePath => { if (firstItem) { outputArchive.Write("["); firstItem = false; } else { outputArchive.WriteLine(","); } using (var inputStream = new StreamReader(filePath)) { outputArchive.Write(inputStream.ReadToEnd()); } }); outputArchive.WriteLine("]"); } Console.WriteLine("Job Done"); }