Example #1
0
        public GameState Execute(GameState gameState)
        {
            // Enforce rules
            Validate(gameState);

            var nextAvailableTokens = gameState.Bank.CreateCopy();
            var nextPlayerTokens    = gameState.CurrentPlayer.Purse.CreateCopy();

            // Perform transaction
            foreach (var colour in TokensToTake.Colours().Union(TokensToReturn.Colours()).ToArray())
            {
                // Take coins
                nextAvailableTokens[colour] -= TokensToTake[colour];
                nextPlayerTokens[colour]    += TokensToTake[colour];

                // Return coins
                nextAvailableTokens[colour] += TokensToReturn[colour];
                nextPlayerTokens[colour]    -= TokensToReturn[colour];
            }

            var player = gameState.CurrentPlayer with {
                Purse = nextPlayerTokens
            };

            return(gameState.WithUpdatedPlayerByName(player) with {
                Bank = nextAvailableTokens
            });
Example #2
0
        public override string ToString()
        {
            var things     = TokensToTake.Colours().Select(col => (TokensToTake[col] == 1 ? "" : $"{TokensToTake[col]} ") + $"{col}");
            var thingsBack = TokensToReturn.Colours().Select(col => (TokensToReturn[col] == 1 ? "" : $"{TokensToReturn[col]} ") + $"{col}");
            var returning  = TokensToReturn.Sum == 0 ? "" : $", returning {string.Join(", ", thingsBack)}";

            return($"Taking {string.Join(", ", things)}{returning}");
        }
Example #3
0
        private void Validate(GameState gameState)
        {
            var player = gameState.CurrentPlayer;

            if (TokensToTake.Sum > 3)
            {
                throw new RulesViolationException("You can only take up to three different tokens, or two of the same if there are four of that type available.");
            }
            else if (TokensToTake.Colours().Any(col => TokensToTake[col] > 2))
            {
                throw new RulesViolationException("You can only take up to two tokens of any one colour.");
            }

            if (TokensToTake[TokenColour.Gold] > 0)
            {
                throw new RulesViolationException("You can't take gold tokens, except when reserving cards.");
            }

            if (TokensToTake.Colours().Any(col => TokensToTake[col] == 2)) // If two taken
            {
                if (TokensToTake.Colours().Count() > 1)
                {
                    throw new RulesViolationException("You can only take two tokens of the same colour if you take no other tokens.");
                }

                var doubleCoinColour = TokensToTake.Colours().Single();

                if (gameState.Bank[doubleCoinColour] < 4)
                {
                    throw new RulesViolationException("You can only take two tokens of the same colour if there are four or more available of that colour.");
                }
            }

            var totalCoinsAfterTransaction = player.Purse.Sum + TokensToTake.Sum - TokensToReturn.Sum;

            if (totalCoinsAfterTransaction > 10)
            {
                throw new RulesViolationException("A player cannot end a turn with more than 10 tokens.");
            }

            foreach (var colour in TokensToTake.Colours())
            {
                if (gameState.Bank[colour] < TokensToTake[colour])
                {
                    throw new RulesViolationException($"There aren't enough {colour} tokens to take.");
                }
            }

            foreach (var colour in TokensToReturn.Colours())
            {
                if (player.Purse[colour] + TokensToTake[colour] < TokensToReturn[colour])
                {
                    throw new RulesViolationException($"The player doesn't have enough {colour} tokens to give back.");
                }
            }
        }
Example #4
0
        public GameState Execute(GameState gameState)
        {
            // Enforce rules
            Validate(gameState);

            var nextAvailableTokens = gameState.Bank.CreateCopy();
            var nextPlayerTokens    = gameState.CurrentPlayer.Purse.CreateCopy();

            // Perform transaction
            foreach (var colour in TokensToTake.Colours().Union(TokensToReturn.Colours()).ToArray())
            {
                // Take coins
                nextAvailableTokens[colour] -= TokensToTake[colour];
                nextPlayerTokens[colour]    += TokensToTake[colour];

                // Return coins
                nextAvailableTokens[colour] += TokensToReturn[colour];
                nextPlayerTokens[colour]    -= TokensToReturn[colour];
            }

            var player = gameState.CurrentPlayer.Clone(withPurse: nextPlayerTokens);

            return(gameState.Clone(withTokensAvailable: nextAvailableTokens).CloneWithPlayerReplacedByName(player));
        }