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
        public async Task <TexasHoldemOdds> Calculate(TexasHoldemOdds odds, Action <TexasHoldemOdds> saveState)
        {
            var outcomes = new List <PokerOutcome>();

            for (var index = 0; index < Enum.GetNames(typeof(Hand.HandTypes)).Length; index++)
            {
                outcomes.Add(new PokerOutcome
                {
                    HandType  = ((Hand.HandTypes)index).ToString(),
                    WinChance = 0
                });
            }

            odds.Outcomes = outcomes;

            if (saveState != null)
            {
                saveState(odds);
            }

            return(await Task <TexasHoldemOdds> .Run(() =>
            {
                ulong playerMask = Hand.ParseHand(odds.Pocket);     // Player Pocket Cards
                ulong partialBoard = Hand.ParseHand(odds.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;

                // 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++;
                    }

                    for (var index = 0; index < playerWins.Length; index++)
                    {
                        outcomes[index].WinChance = playerWins[index] / ((double)count);
                    }

                    if (saveState != null)
                    {
                        saveState(odds);
                    }
                }

                odds.OverallWinSplitChance = odds.Outcomes.Sum(o => o.WinChance);
                odds.Completed = true;

                if (saveState != null)
                {
                    saveState(odds);
                }

                return odds;
            }));
        }
예제 #3
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");
        }
예제 #4
0
        public async Task<TexasHoldemOdds> Calculate(TexasHoldemOdds odds, Action<TexasHoldemOdds> saveState)
        {
            var outcomes = new List<PokerOutcome>();

            for (var index = 0; index < Enum.GetNames(typeof(Hand.HandTypes)).Length; index++)
            {
                outcomes.Add(new PokerOutcome
                {
                    HandType = ((Hand.HandTypes)index).ToString(),
                    WinChance = 0
                });
            }

            odds.Outcomes = outcomes;

            if (saveState != null)
            {
                saveState(odds);
            }

            return await Task<TexasHoldemOdds>.Run(() =>
            {
                ulong playerMask = Hand.ParseHand(odds.Pocket);     // Player Pocket Cards
                ulong partialBoard = Hand.ParseHand(odds.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;

                // 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++;                       
                    }

                    for (var index = 0; index < playerWins.Length; index++)
                    {
                        outcomes[index].WinChance = playerWins[index] / ((double)count);
                    }

                    if (saveState != null)
                    {
                        saveState(odds);
                    }
                }

                odds.OverallWinSplitChance = odds.Outcomes.Sum(o => o.WinChance);
                odds.Completed = true;

                if (saveState != null)
                {
                    saveState(odds);
                }

                return odds;
            });
        }
예제 #5
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);
        }