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);
        }
Пример #2
0
        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);
        }
Пример #4
0
        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");
        }