예제 #1
0
        public override SimPlayerAction GetTurn(SimPlayerTurnContext context)
        {
            var validCardsToPlay = this.PlayerActionValidator.GetPossibleCardsToPlay(context, this.Cards);
            var randomCard       = validCardsToPlay.Shuffle().First();

            return(this.PlayCard(randomCard));
        }
예제 #2
0
        public override SimPlayerAction GetTurn(SimPlayerTurnContext context)
        {
            var validCardsToPlay = this.PlayerActionValidator.GetPossibleCardsToPlay(context, this.Cards);
            var randomCard = validCardsToPlay.Shuffle().First();

            return this.PlayCard(randomCard);
        }
예제 #3
0
        public float GetProbability(SimPlayerTurnContext context, Card card, HashSet <Card> cardsNotInDeck, ICollection <Card> cards)
        {
            float value = 0;

            for (int play = 0; play < NumberOfPlayouts; ++play)
            {
                var currentContext = context.DeepClone();

                this.Cards = new List <Card>(cards);
                var currentDeck = new SimDeck(cardsNotInDeck, currentContext.TrumpCard);

                var firstAction  = (currentContext.FirstPlayedCard != null) ? SimPlayerAction.PlayCard(currentContext.FirstPlayedCard) : null;
                var secondAction = (card == null) ? SimPlayerAction.CloseGame() : SimPlayerAction.PlayCard(card);

                var playAction = (card == null) ? this.CloseGame() : this.PlayCard(card);

                var firstPlayer = new SimDummyPlayer();

                var opponentCardsNumber = (currentContext.FirstPlayedCard == null) ? this.Cards.Count + 1 : this.Cards.Count;

                for (int i = 0; i < opponentCardsNumber; i++)
                {
                    if (currentDeck.CardsLeft == 0)
                    {
                        break;
                    }

                    firstPlayer.AddCard(currentDeck.GetNextCard());
                }

                var stateManager = new SimStateManager();
                stateManager.SetState(currentContext.State);
                var round = new SimRound(firstPlayer, this, GameRulesProvider.Santase, currentDeck, stateManager);


                var result = round.PlaySimulation(
                    currentContext.FirstPlayerRoundPoints,
                    currentContext.SecondPlayerRoundPoints,
                    firstAction,
                    secondAction,
                    firstPlayer.Cards,
                    this.Cards);

                value += this.Expand(result);
            }

            value = value / NumberOfPlayouts;

            return(value);
        }
예제 #4
0
        public SimRoundPlayerInfo Play()
        {
            var context = new SimPlayerTurnContext(
                this.stateManager.State,
                this.deck.TrumpCard,
                this.deck.CardsLeft,
                this.firstToPlay.RoundPoints,
                this.secondToPlay.RoundPoints);

            // First player
            var firstPlayerAction = this.GetFirstPlayerAction(this.firstToPlay, context);
            context.FirstPlayedCard = firstPlayerAction.Card;
            context.FirstPlayerAnnounce = firstPlayerAction.Announce;
            context.FirstPlayerRoundPoints = this.firstToPlay.RoundPoints;

            this.firstToPlay.Cards.Remove(firstPlayerAction.Card);

            // When player announces something he may immediately become round winner
            if (this.firstToPlay.RoundPoints >= this.gameRules.RoundPointsForGoingOut)
            {
                // Inform players for end turn
                this.firstToPlay.Player.EndTurn(context);
                this.secondToPlay.Player.EndTurn(context);
                return this.firstToPlay;
            }

            // Second player
            var secondPlayerAction = GetPlayerAction(this.secondToPlay, context);
            context.SecondPlayedCard = secondPlayerAction.Card;
            this.secondToPlay.Cards.Remove(secondPlayerAction.Card);

            // Determine winner
            ICardWinnerLogic cardWinnerLogic = new CardWinnerLogic();
            var winnerPosition = cardWinnerLogic.Winner(
                firstPlayerAction.Card,
                secondPlayerAction.Card,
                this.deck.TrumpCard.Suit);

            var winner = winnerPosition == PlayerPosition.FirstPlayer ? this.firstToPlay : this.secondToPlay;
            winner.TrickCards.Add(firstPlayerAction.Card);
            winner.TrickCards.Add(secondPlayerAction.Card);

            // Inform players for end turn
            context.FirstPlayerRoundPoints = this.firstToPlay.RoundPoints;
            context.SecondPlayerRoundPoints = this.secondToPlay.RoundPoints;
            this.firstToPlay.Player.EndTurn(context);
            this.secondToPlay.Player.EndTurn(context);

            return winner;
        }
예제 #5
0
        public float GetProbability(SimPlayerTurnContext context, Card card, HashSet<Card> cardsNotInDeck, ICollection<Card> cards)
        {
            float value = 0;
            for (int play = 0; play < NumberOfPlayouts; ++play)
            {
                var currentContext = context.DeepClone();

                this.Cards = new List<Card>(cards);
                var currentDeck = new SimDeck(cardsNotInDeck, currentContext.TrumpCard);

                var firstAction = (currentContext.FirstPlayedCard != null) ? SimPlayerAction.PlayCard(currentContext.FirstPlayedCard) : null;
                var secondAction = (card == null) ? SimPlayerAction.CloseGame() : SimPlayerAction.PlayCard(card);

                var playAction = (card == null) ? this.CloseGame() : this.PlayCard(card);

                var firstPlayer = new SimDummyPlayer();

                var opponentCardsNumber = (currentContext.FirstPlayedCard == null) ? this.Cards.Count + 1 : this.Cards.Count;

                for (int i = 0; i < opponentCardsNumber; i++)
                {
                    if (currentDeck.CardsLeft == 0)
                    {
                        break;
                    }

                    firstPlayer.AddCard(currentDeck.GetNextCard());
                }

                var stateManager = new SimStateManager();
                stateManager.SetState(currentContext.State);
                var round = new SimRound(firstPlayer, this, GameRulesProvider.Santase, currentDeck, stateManager);

                var result = round.PlaySimulation(
                                                    currentContext.FirstPlayerRoundPoints,
                                                    currentContext.SecondPlayerRoundPoints,
                                                    firstAction,
                                                    secondAction,
                                                    firstPlayer.Cards,
                                                    this.Cards);

                value += this.Expand(result);
            }

            value = value / NumberOfPlayouts;

            return value;
        }
예제 #6
0
        public bool IsValid(SimPlayerAction action, SimPlayerTurnContext context, ICollection<Card> playerCards)
        {
            if (context.State.CanAnnounce20Or40)
            {
                action.Announce = this.announceValidator.GetPossibleAnnounce(
                    playerCards,
                    action.Card,
                    context.TrumpCard,
                    context.IsFirstPlayerTurn);
            }

            if (action == null)
            {
                return false;
            }

            if (action.Type == PlayerActionType.PlayCard)
            {
                var canPlayCard = SimPlayCardActionValidator.CanPlayCard(
                    context.IsFirstPlayerTurn,
                    action.Card,
                    context.FirstPlayedCard,
                    context.TrumpCard,
                    playerCards,
                    context.State.ShouldObserveRules);
                return canPlayCard;
            }

            if (action.Type == PlayerActionType.ChangeTrump)
            {
                var canChangeTrump = SimChangeTrumpActionValidator.CanChangeTrump(
                    context.IsFirstPlayerTurn,
                    context.State,
                    context.TrumpCard,
                    playerCards);
                return canChangeTrump;
            }

            // action.Type == PlayerActionType.CloseGame
            var canCloseGame = SimCloseGameActionValidator.CanCloseGame(context.IsFirstPlayerTurn, context.State);
            return canCloseGame;
        }
예제 #7
0
        public ICollection<Card> GetPossibleCardsToPlay(SimPlayerTurnContext context, ICollection<Card> playerCards)
        {
            var possibleCardsToPlay = new List<Card>(playerCards.Count);

            // ReSharper disable once LoopCanBeConvertedToQuery (performance)
            foreach (var card in playerCards)
            {
                if (SimPlayCardActionValidator.CanPlayCard(
                    context.IsFirstPlayerTurn,
                    card,
                    context.FirstPlayedCard,
                    context.TrumpCard,
                    playerCards,
                    context.State.ShouldObserveRules))
                {
                    possibleCardsToPlay.Add(card);
                }
            }

            return possibleCardsToPlay;
        }
예제 #8
0
        private static SimPlayerTurnContext GetCurrentContext(PlayerTurnContext context)
        {
            SimPlayerTurnContext currentContext = null;

            var stateManager = new SimStateManager();

            if (context.State.GetType().Name == "StartRoundState")
            {
                var state = new SimStartRoundState(stateManager);

                currentContext = new SimPlayerTurnContext(state, context.TrumpCard, context.CardsLeftInDeck, context.FirstPlayerRoundPoints, context.SecondPlayerRoundPoints);
            }
            else if (context.State.GetType().Name == "TwoCardsLeftRoundState")
            {
                var state = new SimTwoCardsLeftRoundState(stateManager);

                currentContext = new SimPlayerTurnContext(state, context.TrumpCard, context.CardsLeftInDeck, context.FirstPlayerRoundPoints, context.SecondPlayerRoundPoints);
            }
            else if (context.State.GetType().Name == "MoreThanTwoCardsLeftRoundState")
            {
                var state = new SimMoreThanTwoCardsLeftRoundState(stateManager);

                currentContext = new SimPlayerTurnContext(state, context.TrumpCard, context.CardsLeftInDeck, context.FirstPlayerRoundPoints, context.SecondPlayerRoundPoints);
            }
            else if (context.State.GetType().Name == "FinalRoundState")
            {
                var state = new SimFinalRoundState(stateManager);

                currentContext = new SimPlayerTurnContext(state, context.TrumpCard, context.CardsLeftInDeck, context.FirstPlayerRoundPoints, context.SecondPlayerRoundPoints);
            }

            currentContext.FirstPlayedCard     = context.FirstPlayedCard;
            currentContext.SecondPlayedCard    = context.SecondPlayedCard;
            currentContext.FirstPlayerAnnounce = context.FirstPlayerAnnounce;

            return(currentContext);
        }
예제 #9
0
        private static SimPlayerTurnContext GetCurrentContext(PlayerTurnContext context)
        {
            SimPlayerTurnContext currentContext = null;

            var stateManager = new SimStateManager();

            if (context.State.GetType().Name == "StartRoundState")
            {
                var state = new SimStartRoundState(stateManager);

                currentContext = new SimPlayerTurnContext(state, context.TrumpCard, context.CardsLeftInDeck, context.FirstPlayerRoundPoints, context.SecondPlayerRoundPoints);
            }
            else if (context.State.GetType().Name == "TwoCardsLeftRoundState")
            {
                var state = new SimTwoCardsLeftRoundState(stateManager);

                currentContext = new SimPlayerTurnContext(state, context.TrumpCard, context.CardsLeftInDeck, context.FirstPlayerRoundPoints, context.SecondPlayerRoundPoints);
            }
            else if (context.State.GetType().Name == "MoreThanTwoCardsLeftRoundState")
            {
                var state = new SimMoreThanTwoCardsLeftRoundState(stateManager);

                currentContext = new SimPlayerTurnContext(state, context.TrumpCard, context.CardsLeftInDeck, context.FirstPlayerRoundPoints, context.SecondPlayerRoundPoints);
            }
            else if (context.State.GetType().Name == "FinalRoundState")
            {
                var state = new SimFinalRoundState(stateManager);

                currentContext = new SimPlayerTurnContext(state, context.TrumpCard, context.CardsLeftInDeck, context.FirstPlayerRoundPoints, context.SecondPlayerRoundPoints);
            }

            currentContext.FirstPlayedCard = context.FirstPlayedCard;
            currentContext.SecondPlayedCard = context.SecondPlayedCard;
            currentContext.FirstPlayerAnnounce = context.FirstPlayerAnnounce;

            return currentContext;
        }
예제 #10
0
 public abstract SimPlayerAction GetTurn(SimPlayerTurnContext context);
예제 #11
0
 public virtual void EndTurn(SimPlayerTurnContext context)
 {
 }
예제 #12
0
        private SimPlayerAction GetFirstPlayerAction(SimRoundPlayerInfo playerInfo, SimPlayerTurnContext context)
        {
            while (true)
            {
                var action = GetPlayerAction(playerInfo, context);
                switch (action.Type)
                {
                    case PlayerActionType.ChangeTrump:
                        {
                            var oldTrumpCard = this.deck.TrumpCard;
                            var nineOfTrump = new Card(oldTrumpCard.Suit, CardType.Nine);

                            this.deck.ChangeTrumpCard(nineOfTrump);
                            context.TrumpCard = nineOfTrump;

                            // Only swap cards from the local cards list (player should swap its own cards)
                            playerInfo.Cards.Remove(nineOfTrump);
                            playerInfo.Cards.Add(oldTrumpCard);
                            continue;
                        }

                    case PlayerActionType.CloseGame:
                        {
                            this.stateManager.State.Close();
                            context.State = this.stateManager.State;
                            playerInfo.GameCloser = true;
                            continue;
                        }

                    case PlayerActionType.PlayCard:
                        {
                            if (action.Announce != Announce.None)
                            {
                                playerInfo.Announces.Add(action.Announce);
                            }

                            return action;
                        }
                }
            }
        }
예제 #13
0
        private static SimPlayerAction GetPlayerAction(SimRoundPlayerInfo playerInfo, SimPlayerTurnContext context)
        {
            var action = playerInfo.Player.GetTurn(context.DeepClone());
            var isActionValid = SimPlayerActionValidator.Instance.IsValid(action, context, playerInfo.Cards);
            if (!isActionValid)
            {
                throw new InternalGameException($"Invalid action played from {playerInfo.Player.Name}");
            }

            return action;
        }