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); }
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); }
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); }
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; }
public void StartNewRound() { this.gameState = this.gameState.StartNewRound(); }
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; }