예제 #1
0
파일: Game.cs 프로젝트: otac0n/Therefore
        public Game(IList<string> playerIds, GameOptions gameOptions = null)
        {
            if (playerIds == null)
            {
                throw new ArgumentNullException("playerIds");
            }

            if (gameOptions == null || gameOptions.ScoringSystem == null)
            {
                this.scoringSystem = new AverageCardsScoringSystem();
            }
            else
            {
                scoringSystem = gameOptions.ScoringSystem;
            }

            this.parser = new Parser(gameOptions == null ? null : gameOptions.ParserOptions);
            this.compiler = new Compiler(gameOptions == null ? null : gameOptions.CompilerOptions);

            this.gameState = new GameState(this, playerIds);
        }
예제 #2
0
        private static GameState ScoreGame(GameState gameState)
        {
            var newScores = gameState.game.ScoringSystem.Score(gameState);
            var scores = gameState.scores.ToDictionary(e => e.Key, e => e.Value);

            foreach (var playerId in newScores.Keys)
            {
                scores[playerId] += newScores[playerId];
            }

            return new GameState(
                gameState.game,
                gameState.playerIds,
                gameState.deck,
                scores.AsReadOnly(),
                gameState.hands,
                gameState.dealer,
                gameState.turn,
                gameState.proof,
                gameState.isRoundOver);
        }
예제 #3
0
        public GameState EndRound()
        {
            if (this.isRoundOver)
            {
                throw new InvalidOperationException("The round is already over.");
            }

            if (!this.IsValid)
            {
                throw new InvalidOperationException("The round cannot end because the current game state is invalid.");
            }

            var newState = new GameState(
                this.game,
                this.playerIds,
                this.deck,
                this.scores,
                this.hands,
                this.dealer,
                this.turn,
                this.proof,
                true);

            return ScoreGame(newState);
        }
예제 #4
0
        public GameState DrawCards(string playerId)
        {
            if (this.isRoundOver)
            {
                throw new InvalidOperationException("The round is over.");
            }

            var deck = new Stack<Card>(this.deck);
            var hands = this.hands.ToDictionary(h => h.Key, h => h.Value.ToList());

            var hand = hands[playerId];
            while (hand.Count < 7 && deck.Count > 0)
            {
                hand.Add(deck.Pop());
            }

            var isRoundOver = this.isRoundOver;
            if (hand.Count < 7)
            {
                isRoundOver = true;
            }

            var newState = new GameState(
                this.game,
                this.playerIds,
                deck.ToList().AsReadOnly(),
                this.scores,
                hands.ToDictionary(h => h.Key, h => h.Value.AsReadOnly()).AsReadOnly(),
                this.dealer,
                this.turn,
                this.proof,
                isRoundOver);

            if (isRoundOver)
            {
                newState = ScoreGame(newState);
            }

            return newState;
        }
예제 #5
0
파일: Game.cs 프로젝트: otac0n/Therefore
 public void StartNewRound()
 {
     this.gameState = this.gameState.StartNewRound();
 }
예제 #6
0
파일: Game.cs 프로젝트: otac0n/Therefore
        public void PlayCards(string playerId, IList<CardAction> actions)
        {
            if (playerId != this.gameState.CurrentPlayerId)
            {
                throw new InvalidOperationException("It is not your turn.");
            }

            if (actions.Count > 2)
            {
                throw new InvalidOperationException("Cannot play more than 2 cards per turn.");
            }

            var distinctCards = new HashSet<Card>();
            foreach (var action in actions)
            {
                if (!this.gameState.Hands[playerId].Contains(action.Card))
                {
                    throw new InvalidOperationException("This is not your card.");
                }

                if (distinctCards.Contains(action.Card))
                {
                    throw new InvalidOperationException("You cannot play the same card twice.");
                }

                distinctCards.Add(action.Card);
            }

            var intermediaryState = this.gameState;
            foreach (var action in actions)
            {
                intermediaryState = action.ApplyTo(intermediaryState, playerId);
            }

            intermediaryState = intermediaryState.DrawCards(playerId).AdvanceTurn();

            if (!intermediaryState.IsValid)
            {
                throw new InvalidOperationException("The play you have attempted puts the game in an invalid state.");
            }

            this.gameState = intermediaryState;
        }