Пример #1
0
        private static GameRecord PlayOneGame(
            long gameId,
            decimal initalBet,
            decimal initalWinAmount,
            GameContext gameContext,
            Func <HandCards, PlayerHandCards, int, GameContext, PlayerAction> getPlayerAction)
        {
            GameRecord newGame = new GameRecord(gameId);

            // Player place initial bet, game starts
            decimal totalWinThisGame = 0;

            newGame.AddGameStartedEvent(initalBet);

            // Initial round of card dealing
            PlayerHandCards playerCards = new PlayerHandCards(initalBet);

            playerCards.AddCard(gameContext.GetCardWithReshuffle());                   // player first card
            int dealerFaceDownCard = gameContext.GetCardWithReshuffle();               // dealer first card, face-down

            playerCards.AddCard(gameContext.GetCardWithReshuffle());                   // player second card
            HandCards dealerCards = new HandCards(gameContext.GetCardWithReshuffle()); // dealer second card, face-up

            LinkedList <PlayerHandCards> playerHands = new LinkedList <PlayerHandCards>();

            playerHands.AddFirst(playerCards);
            newGame.AddOpenHandEvent(playerHands.Count, dealerCards, playerHands.First());

            // Handle player hands until all of them either stand or be busted.
            int playerId = 1;

            for (LinkedListNode <PlayerHandCards> node = playerHands.First; node != null;)
            {
                PlayerHandCards currentHand   = node.Value;
                PlayerAction    currentAction = getPlayerAction(dealerCards, currentHand, playerHands.Count, gameContext);
                PlayerHandCards newHand       = null;

                switch (currentAction)
                {
                case PlayerAction.Double:
                    currentHand.BetAmount *= 2;
                    currentHand.AddCard(gameContext.GetCardWithReshuffle());
                    break;

                case PlayerAction.Hit:
                    currentHand.AddCard(gameContext.GetCardWithReshuffle());
                    break;

                case PlayerAction.Split:
                    newHand = currentHand.SplitAndGetNewHandCards(
                        gameContext.GetCardWithReshuffle(),
                        gameContext.GetCardWithReshuffle(),
                        gameContext);
                    break;

                case PlayerAction.Surrender:
                    currentHand.HasSurrendered = true;
                    break;
                }

                newGame.AddEventByPlayerAction(currentAction, playerId, dealerCards, currentHand, gameContext);

                if (newHand != null)
                {
                    playerHands.AddLast(newHand);
                    newGame.AddOpenHandEvent(playerHands.Count, dealerCards, newHand);
                }

                // Conditions to move to next hand
                LinkedListNode <PlayerHandCards> nodeToRemove;
                if (currentHand.HasSurrendered)
                {
                    decimal lostAmount = currentHand.BetAmount / 2;
                    totalWinThisGame -= lostAmount;
                    newGame.AddCloseHandEvent(playerId, dealerCards, currentHand, lostAmount, "Surrender");
                    nodeToRemove = node;
                    playerHands.Remove(nodeToRemove);

                    node = node.Next;
                    playerId++;
                }
                else if (currentHand.IsBusted)
                {
                    totalWinThisGame -= currentHand.BetAmount;
                    newGame.AddCloseHandEvent(playerId, dealerCards, currentHand, -currentHand.BetAmount, "Busted");
                    nodeToRemove = node;
                    playerHands.Remove(nodeToRemove);

                    node = node.Next;
                    playerId++;
                }
                else if (currentAction == PlayerAction.Stand)
                {
                    node = node.Next;
                    playerId++;
                }
            }

            // Dealer dealing for himself until he is busted, or over 17
            if (playerHands.Count > 0)
            {
                bool isSoftValue;

                dealerCards.AddCard(dealerFaceDownCard);
                string initialCards = dealerCards.ToString();
                int    currentValue = dealerCards.GetHandValue(out isSoftValue);

                while (!dealerCards.IsBusted && !dealerCards.IsBlackJack)
                {
                    if (currentValue >= 17)
                    {
                        if (!isSoftValue || !gameContext.DealerHitsOnSoft17)
                        {
                            break;
                        }
                    }

                    int newCard = gameContext.GetCardWithReshuffle();
                    dealerCards.AddCard(newCard);
                    currentValue = dealerCards.GetHandValue(out isSoftValue);
                }

                newGame.AddDealerEvent(initialCards, dealerCards.ToString(), currentValue);

                // Check game result by comparing dealer with each player hand
                playerId = 1;
                for (LinkedListNode <PlayerHandCards> node = playerHands.First; node != null; node = node.Next, playerId++)
                {
                    if (!node.Value.HasSurrendered && !node.Value.IsBusted)
                    {
                        decimal winAmount;
                        if (CheckGameStatus(dealerCards, node.Value, gameContext, out winAmount) != GameStatus.NotComplete)
                        {
                            totalWinThisGame += winAmount;
                            newGame.AddCloseHandEvent(playerId, dealerCards, node.Value, winAmount);
                        }
                    }
                }
            }

            newGame.AddGameCompletedEvent(totalWinThisGame, initalWinAmount + totalWinThisGame);
            return(newGame);
        }