示例#1
0
        protected override void AfterMove()
        {
            TicTacToeMove lastMove = (TicTacToeMove)this.moves[this.moves.Length - 1];

            this.winner = this.GetWinner(lastMove);
            this.isOver = this.winner != null || !this.MovesLeft(lastMove);

            this.currentPlayerIndex = ++this.currentPlayerIndex % 2;
        }
示例#2
0
        protected GamePlayer GetWinner(TicTacToeMove state)
        {
            int[] colSums  = new int[3];
            int[] rowSums  = new int[3];
            int   diagSum1 = 0;
            int   diagSum2 = 0;

            GamePlayer winner = null;

            for (int r = 0; r < state.Board.Length; r++)
            {
                ImmutableArray <string> row = state.Board[r];
                for (int c = 0; c < row.Length; c++)
                {
                    string currentPlayerId = row[c];
                    if (String.IsNullOrWhiteSpace(currentPlayerId))
                    {
                        continue;
                    }

                    int currentPlayerNum = playerToNumberMap[currentPlayerId];

                    rowSums[r] += currentPlayerNum;
                    if ((winner = CheckScore(rowSums[r])) != null)
                    {
                        return(winner);
                    }

                    colSums[c] += currentPlayerNum;
                    if ((winner = CheckScore(colSums[c])) != null)
                    {
                        return(winner);
                    }

                    if (r == c)
                    {
                        diagSum1 += currentPlayerNum;
                        if ((winner = CheckScore(diagSum1)) != null)
                        {
                            return(winner);
                        }
                    }

                    if (r + c == row.Length - 1)
                    {
                        diagSum2 += currentPlayerNum;
                        if ((winner = CheckScore(diagSum2)) != null)
                        {
                            return(winner);
                        }
                    }
                }
            }

            return(null);
        }
示例#3
0
        protected override bool ValidateMove(IGameState game, IGameMove move)
        {
            TicTacToeMove typedMove = (TicTacToeMove)move;

            string expectedPlayerId = this.CurrentPlayer.Id;
            string actualPlayerId   = typedMove.PlayerId;

            if (actualPlayerId != expectedPlayerId)
            {
                throw new Exception($"Move was made by the wrong player. Expected {expectedPlayerId}, received {actualPlayerId}.");
            }

            return(true);

            // TODO: proper validation;
        }
示例#4
0
        protected bool MovesLeft(TicTacToeMove state)
        {
            for (int r = 0; r < state.Board.Length; r++)
            {
                ImmutableArray <string> row = state.Board[r];
                for (int c = 0; c < row.Length; c++)
                {
                    if (String.IsNullOrWhiteSpace(row[c]))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
示例#5
0
        public TicTacToeGame(GamePlayer[] players)
        {
            if (players.Length != 2)
            {
                throw new ArgumentOutOfRangeException(nameof(players), "Tic Tac Toe requires exactly 2 players");
            }
            if (players[0].Id == players[1].Id)
            {
                throw new ArgumentException(nameof(players), "Players cannot have the same Id");
            }

            this.players = players.ToImmutableArray();

            playerToNumberMap = new Dictionary <string, int> {
                { players[0].Id, -1 },
                { players[1].Id, 1 }
            }
            .ToImmutableDictionary();

            TicTacToeMove move = new TicTacToeMove();

            this.moves = ImmutableArray.Create((IGameMove)move);
        }