private static GameStatus CheckGameStatus(HandCards dealerHandCards, PlayerHandCards playerHandCards, GameContext gameContext, out decimal winAmount)
        {
            bool       isSoftValue;
            int        playerValue      = playerHandCards.GetHandValue(out isSoftValue);
            int        dealerValue      = dealerHandCards.GetHandValue(out isSoftValue);
            GameStatus gameStatusResult = GameStatus.NotComplete;

            if (playerValue > 21 || playerHandCards.HasSurrendered)
            {
                gameStatusResult = GameStatus.DealerWins; // player is busted or has surrendered
            }
            else if (dealerValue >= 17)
            {
                if (!isSoftValue || !gameContext.DealerHitsOnSoft17)
                {
                    if (dealerValue > 21)
                    {
                        gameStatusResult = GameStatus.PlayerWins; // dealer is busted
                    }
                    else if (dealerValue == 21 && playerValue == 21)
                    {
                        if (dealerHandCards.IsBlackJack)
                        {
                            gameStatusResult = playerHandCards.IsBlackJack ? GameStatus.DrawGame : GameStatus.DealerWins;
                        }
                        else
                        {
                            gameStatusResult = playerHandCards.IsBlackJack ? GameStatus.PlayerWins : GameStatus.DrawGame;
                        }
                    }
                    else if (dealerValue == playerValue)
                    {
                        gameStatusResult = GameStatus.DrawGame;
                    }
                    else
                    {
                        gameStatusResult = playerValue > dealerValue ? GameStatus.PlayerWins : GameStatus.DealerWins;
                    }
                }
            }

            switch (gameStatusResult)
            {
            case GameStatus.DealerWins:
                winAmount = -playerHandCards.BetAmount;
                break;

            case GameStatus.PlayerWins:
                winAmount = playerHandCards.BetAmount * (playerHandCards.IsBlackJack ? gameContext.BlackJackPayRate : 1);
                break;

            default:
                winAmount = 0m;
                break;
            }

            return(gameStatusResult);
        }
        /// <summary>
        /// Get the next move suggestion by Wizard's Strategy: http://wizardofodds.com/games/blackjack/basics/
        /// </summary>
        /// <param name="dealerHandCards">Dealer's Hand</param>
        /// <param name="playerHandCards">Player's Hand</param>
        /// <param name="playerHands">Current hand count the player has</param>
        /// <param name="gameContext">Game Context</param>
        /// <returns></returns>
        public static PlayerAction GetActionByWizardStrategy(HandCards dealerHandCards, PlayerHandCards playerHandCards, int playerHands, GameContext gameContext)
        {
            bool isSoftValue;
            int  dealerValue = dealerHandCards.GetHandValue(out isSoftValue);
            int  playerValue = playerHandCards.GetHandValue(out isSoftValue);

            if (playerValue == 16 && dealerValue == 10 && playerHandCards.EligibleToSurrender(gameContext))
            {
                return(PlayerAction.Surrender);
            }

            if (dealerValue >= 2 && dealerValue <= 6)
            {
                if (playerHandCards.EligibleToSplit(playerHands, gameContext))
                {
                    if (playerValue != 8 && playerValue != 10 && playerValue != 20)
                    {
                        return(PlayerAction.Split);
                    }
                }

                if (isSoftValue)
                {
                    if (playerValue >= 12 && playerValue <= 15)
                    {
                        return(PlayerAction.Hit);
                    }
                    else if (playerValue >= 16 && playerValue <= 18)
                    {
                        return(playerHandCards.EligibleToDouble(gameContext) ? PlayerAction.Double : (playerValue == 18 ? PlayerAction.Stand : PlayerAction.Hit));
                    }
                    else if (playerValue >= 19 && playerValue <= 21)
                    {
                        return(PlayerAction.Stand);
                    }
                }
                else
                {
                    if (playerValue >= 4 && playerValue <= 8)
                    {
                        return(PlayerAction.Hit);
                    }
                    else if (playerValue >= 9 && playerValue <= 11)
                    {
                        return(playerHandCards.EligibleToDouble(gameContext) ? PlayerAction.Double : PlayerAction.Hit);
                    }
                    else if (playerValue >= 12 && playerValue <= 21)
                    {
                        return(PlayerAction.Stand);
                    }
                }
            }
            else if (dealerValue >= 7 && dealerValue <= 11)
            {
                if (playerHandCards.EligibleToSplit(playerHands, gameContext))
                {
                    if (playerValue == 16 || playerHandCards.ToString().Equals("AA"))
                    {
                        return(PlayerAction.Split);
                    }
                }

                if (isSoftValue)
                {
                    if (playerValue >= 12 && playerValue <= 18)
                    {
                        return(PlayerAction.Hit);
                    }
                    else if (playerValue >= 19 && playerValue <= 21)
                    {
                        return(PlayerAction.Stand);
                    }
                }
                else
                {
                    if (playerValue >= 4 && playerValue <= 16)
                    {
                        if (playerValue == 10 || playerValue == 11)
                        {
                            if (playerValue > dealerValue)
                            {
                                return(playerHandCards.EligibleToDouble(gameContext) ? PlayerAction.Double : PlayerAction.Hit);
                            }
                        }

                        return(PlayerAction.Hit);
                    }
                    else if (playerValue >= 12 && playerValue <= 21)
                    {
                        return(PlayerAction.Stand);
                    }
                }
            }
            else
            {
                throw new ArgumentException(string.Format("Dealer value is invalid: {0}", dealerValue), "dealerHandCards");
            }

            throw new ArgumentException(string.Format("Player value is invalid: {0} IsSoftValue: {1}", playerValue, isSoftValue), "playerHandCards");
        }