// Test the protocol components related to the 'board state' message
            // type. Throws Exception if a 'board state' message is generated
            // which is inconsistent with the physical board state, or if a
            // board state defined by a 'board state' message is physically
            // inconsistent with the desired state.
            private static void TestBoardStateMessage()
            {
                // Create a new empty game board.
                TzaarBoard board = new TzaarBoard(true);

                // Create some game pieces of various types.
                TzaarPiece p1 = new TzaarPiece.Tzaar(TzaarColor.BLACK);
                TzaarPiece p2 = new TzaarPiece.Tzarra(TzaarColor.BLACK);
                TzaarPiece p3 = new TzaarPiece.Tott(TzaarColor.BLACK);

                // Add the pieces we created to the board at the target
                // position.
                board.Add(p1, 0, 0);
                board.Add(p2, 1, 0);
                board.Add(p3, 2, 0);

                TzaarMessage.BoardState message = new TzaarMessage.BoardState(board);

                // Check that the generated 'board state' message matches the
                // physical state of the board defined above.
                if (((string)message).CompareTo("BoardState{{BLACK,Tzaar},{},{},{},{},{BLACK,Tzarra},{},{},{},{},{},{BLACK,Tott},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}}") != 0)
                    throw new Exception();

                message = new TzaarMessage.BoardState("BoardState{{BLACK,Tzaar},{},{},{},{},{BLACK,Tzarra},{},{},{},{},{},{BLACK,Tott},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}}");

                // Check that a board state generated from a 'board state'
                // message is consistent with the desired state.
                Stack<TzaarPiece> S = ((TzaarBoard)message.Board).Query(0, 0);
                if (S == null || S.Count == 0 || S.Peek().GetType() != typeof(TzaarPiece.Tzaar))
                    throw new Exception();
            }
            // Check that stacking pieces works properly. Additionally, it
            // should be possible to add a piece to an invalid position on the
            // board without error. Throws Exception if the determined stack
            // size is not equal to the size of the stack placed at the
            // specified position.
            private static void TestAdd()
            {
                // Create a new empty game board.
                TzaarBoard board = new TzaarBoard(true);

                // Create some game pieces of various types.
                TzaarPiece p1 = new TzaarPiece.Tzaar(TzaarColor.BLACK);
                TzaarPiece p2 = new TzaarPiece.Tzarra(TzaarColor.BLACK);
                TzaarPiece p3 = new TzaarPiece.Tott(TzaarColor.BLACK);

                board.Add(p1, 0, 0);
                board.Add(p2, 0, 0);
                board.Add(p3, 0, 0);

                Stack<TzaarPiece> S = board.Query(0, 0);
                if (S.Count != 3)
                    throw new Exception();
                if (S.Peek() != p3)
                    throw new Exception();

                // Try to add to a spot that doesn't exist.
                board.Add((TzaarPiece)null, 8, 8);
            }
            // The goal is to test various representative valid and invalid
            // moves for correctness. Throws Exception if a validly specified
            // path is determined to be invalid, or if an invalidly specified
            // path is determined to be valid.
            private static void TestBoardMapPathing()
            {
                // Create a new empty game board.
                TzaarBoardMap boardMap = new TzaarBoardMap();
                TzaarBoard board = new TzaarBoard(true);

                // Create some game pieces of various types.
                TzaarPiece p1 = new TzaarPiece.Tzaar(TzaarColor.BLACK);
                TzaarPiece p2 = new TzaarPiece.Tzarra(TzaarColor.BLACK);
                TzaarPiece p3 = new TzaarPiece.Tott(TzaarColor.BLACK);

                // Operate on this specific position.
                int col = 8;
                int row = 0;

                // Add the pieces we created to the board at the target
                // position.
                board.Add(p1, col, row);
                board.Add(p2, col, row);
                board.Add(p3, col, row);

                // Check that a valid move is reported as valid.
                if (!boardMap.IsValidPath(board, 0, 0, 0, 1))
                    throw new Exception();

                // Check that an invalid move is reported as invalid.
                if (boardMap.IsValidPath(board, 4, 3, 4, 4))
                    throw new Exception();

                board.Add(p1, 2, 2);
                board.Add(p2, 2, 3);

                // Check that an invalid move is reported as invalid.
                if (!boardMap.IsValidPath(board, 2, 2, 2, 3))
                    throw new Exception();

                // Check that passing through another piece is reported as
                // invalid.
                board.Add(p1, 1, 1);
                if (boardMap.IsValidPath(board, 0, 0, 2, 2))
                    throw new Exception();

                // Remove the obstructing piece and verify that (0, 0) and
                // (2, 2) are now connected.
                board.Take(1, 1);
                if (!boardMap.IsValidPath(board, 0, 0, 2, 2))
                    throw new Exception();
            }
            // Parse a message string into a TzaarBoard object.
            private TzaarBoard GetBoardStateFromString(string msg)
            {
                TzaarBoard board = new TzaarBoard(true);

                // Strip packet wrapper.
                string boardString = TzaarMessage.GetMessageData(msg);

                boardString = boardString.Substring(1, boardString.Length - 2);

                // Split into individual stacks.
                string[] stacks = Regex.Split(boardString, "},{");

                int[] offsets = new int[] { 0, 5, 11, 18, 26, 34, 42, 49, 55 };
                string[] aStack;
                for (int i = 0; i < 9; i++)
                {
                    for (int j = 0; j < 9; j++)
                    {
                        Stack<TzaarPiece> S = board.Query(i, j);
                        if (S == null)
                            break;

                        // Split stack into color (aStack[0]) and individual
                        // pieces.
                        aStack = stacks[j + offsets[i]].Split(',');

                        TzaarColor color = (aStack[0].Equals(TzaarColor.BLACK.ToString())) ? TzaarColor.BLACK : TzaarColor.WHITE;

                        // Add each piece to the board.
                        for (int k = aStack.Length - 1; k >= 0; k--)
                        {
                            String s = aStack[k];
                            if (s.Equals(typeof(TzaarPiece.Tzaar).Name.ToString()))
                                board.Add(new TzaarPiece.Tzaar(color), i, j);
                            else if (s.Equals(typeof(TzaarPiece.Tzarra).Name.ToString()))
                                board.Add(new TzaarPiece.Tzarra(color), i, j);
                            else if (s.Equals(typeof(TzaarPiece.Tott).Name.ToString()))
                                board.Add(new TzaarPiece.Tott(color), i, j);
                        }
                    }
                }

                return board;
            }
            // The goal is to test the board-querying functionality. Throws
            // Exception if the piece(s) returned from the specified position
            // do not match those placed at that position.
            private static void TestQuery()
            {
                // Create a new empty game board.
                TzaarBoard board = new TzaarBoard(true);

                // Create some game pieces of various types.
                TzaarPiece p1 = new TzaarPiece.Tzaar(TzaarColor.BLACK);
                TzaarPiece p2 = new TzaarPiece.Tzarra(TzaarColor.BLACK);
                TzaarPiece p3 = new TzaarPiece.Tott(TzaarColor.BLACK);

                // Add the pieces we created to the board at the target
                // position.
                board.Add(p1, 0, 0);
                board.Add(p2, 0, 0);
                board.Add(p3, 0, 0);

                // Check that there are 3 pieces on the target position.
                Stack<TzaarPiece> pieces = board.Query(0, 0);
                if (pieces.Count != 3)
                    throw new Exception();
            }
            // Test the functionality related to 'taking' a piece, or stack of
            // pieces, from a position on the game board. Additionally, it
            // should be possible to attempt to 'take' a piece from an invalid
            // position on the game board without error. Throws Exception if
            // 'taking' the pieces from the board does not result in the
            // specified position being empty.
            private static void TestTake()
            {
                // Create a new empty game board.
                TzaarBoard board = new TzaarBoard(true);

                // Create some game pieces of various types.
                TzaarPiece p1 = new TzaarPiece.Tzaar(TzaarColor.BLACK);
                TzaarPiece p2 = new TzaarPiece.Tzarra(TzaarColor.BLACK);
                TzaarPiece p3 = new TzaarPiece.Tott(TzaarColor.BLACK);

                // Add the pieces we created to the board at the target
                // position.
                board.Add(p1, 0, 0);
                board.Add(p2, 0, 0);
                board.Add(p3, 0, 0);

                // Check that there are 3 pieces on the target position.
                if (board.Query(0, 0).Count != 3)
                    throw new Exception();

                // Take the pieces.
                if (board.Take(0, 0).Count != 3)
                    throw new Exception();

                // Check that there are now 0 pieces on the target position.
                if (board.Query(0, 0).Count != 0)
                    throw new Exception();

                // Try to Take from a spot that doesn't exist.
                board.Take(-1, 8);
            }
            // The goal is to verify that a change to the board state in the
            // form of a 'capture' or 'stack' operation results in a correct
            // update to the counts for each piece remaining on the board.
            // Throws Exception if a piece count is inconsistent with the actual
            // game state following the specified operation.
            private static void TestUpdatePieceCount()
            {
                TzaarBoard board = new TzaarBoard(true);
                board.Add(new TzaarPiece.Tzaar(TzaarColor.WHITE), 2, 2);
                board.Add(new TzaarPiece.Tzaar(TzaarColor.BLACK), 2, 3);
                board.Add(new TzaarPiece.Tzaar(TzaarColor.BLACK), 3, 4);
                TzaarGameState state = new TzaarGameState(board);
                TzaarLogic game = new TzaarLogic(state);
                int BlackTzaarCount = ((TzaarBoard)game.GetGameState().Board).BlackTzaarCount;

                game.Move(2, 2, 2, 3);

                // A Black Tzaar was 'captured', so the piece count should be
                // decremented by 1.
                if (BlackTzaarCount - ((TzaarBoard)game.GetGameState().Board).BlackTzaarCount != 1)
                    throw new Exception();
            }
            // Test the components which control functionality to 'stack' pieces
            // on one another. Throws Exception if an attempt to 'stack' pieces
            // results in a stack size not equal to the total number of pieces
            // being 'stacked'.
            private static void TestStack()
            {
                TzaarBoard board = new TzaarBoard(true);
                board.Add(new TzaarPiece.Tzaar(TzaarColor.WHITE), 2, 2);
                board.Add(new TzaarPiece.Tzaar(TzaarColor.WHITE), 2, 3);
                TzaarGameState state = new TzaarGameState(board, 4);
                TzaarLogic game = new TzaarLogic(state);

                game.Move(2, 2, 2, 3);

                Stack<TzaarPiece> S = board.Query(2, 3);

                // Stacked a total of 2 pieces, so stack size should be 2.
                if (S.Count() != 2)
                    throw new Exception();

                // Stacked a Tzaar on top of another Tzaar, so the top piece
                // should be a Tzaar.
                if (S.Peek().GetType() != typeof(TzaarPiece.Tzaar))
                    throw new Exception();

                // Stacked a white piece on top of another white piece, so the
                // top piece should be white.
                if (S.Peek().Color != TzaarColor.WHITE)
                    throw new Exception();
            }
            // Test the components which determine an end-game state. Throws
            // Exception if the actual game state is an end-game state and the
            // game is not determined to be over.
            private static void TestGameOver()
            {
                // Black has no Totts; black loses.
                TzaarBoard board = new TzaarBoard(true);
                board.Add(new TzaarPiece.Tzaar(TzaarColor.WHITE), 0, 0);
                board.Add(new TzaarPiece.Tzarra(TzaarColor.WHITE), 0, 1);
                board.Add(new TzaarPiece.Tott(TzaarColor.WHITE), 0, 2);
                board.Add(new TzaarPiece.Tzaar(TzaarColor.BLACK), 1, 1);
                board.Add(new TzaarPiece.Tzarra(TzaarColor.BLACK), 1, 2);
                TzaarLogic game = new TzaarLogic(board);
                if (!game.WhiteCanCapture())
                    throw new Exception();
                if (!game.BlackCanCapture())
                    throw new Exception();
                if (game.WhiteIsOutOfPieces())
                    throw new Exception();
                if (!game.BlackIsOutOfPieces())
                    throw new Exception();
                if (!game.IsGameOver())
                    throw new Exception();

                // Black and White have enough pieces to play, but white can't
                // make any more moves.
                board = new TzaarBoard(true);
                board.Add(new TzaarPiece.Tzaar(TzaarColor.WHITE), 0, 0);
                board.Add(new TzaarPiece.Tzarra(TzaarColor.WHITE), 0, 1);
                board.Add(new TzaarPiece.Tott(TzaarColor.WHITE), 0, 2);
                board.Add(new TzaarPiece.Tzaar(TzaarColor.BLACK), 1, 0);
                board.Add(new TzaarPiece.Tzaar(TzaarColor.BLACK), 1, 0);
                board.Add(new TzaarPiece.Tzarra(TzaarColor.BLACK), 8, 0);
                board.Add(new TzaarPiece.Tott(TzaarColor.BLACK), 8, 1);
                game = new TzaarLogic(board);
                if (game.WhiteCanCapture())
                    throw new Exception();
                if (!game.BlackCanCapture())
                    throw new Exception();
                if (game.WhiteIsOutOfPieces())
                    throw new Exception();
                if (game.BlackIsOutOfPieces())
                    throw new Exception();
                if (!game.IsGameOver())
                    throw new Exception();

                // Neither player can make a move, so we don't know who won;
                // this is ok, because we can handle this case in the server
                // based on who made the final move, and which turn of theirs it
                // was. As far as the game logic is concerned, the game is over,
                // but neither player won.
                board = new TzaarBoard(true);
                board.Add(new TzaarPiece.Tzaar(TzaarColor.WHITE), 0, 0);
                board.Add(new TzaarPiece.Tzarra(TzaarColor.WHITE), 0, 1);
                board.Add(new TzaarPiece.Tott(TzaarColor.WHITE), 0, 2);
                board.Add(new TzaarPiece.Tzaar(TzaarColor.BLACK), 8, 0);
                board.Add(new TzaarPiece.Tzarra(TzaarColor.BLACK), 8, 1);
                board.Add(new TzaarPiece.Tott(TzaarColor.BLACK), 8, 2);
                game = new TzaarLogic(board);
                if (game.WhiteCanCapture())
                    throw new Exception();
                if (game.BlackCanCapture())
                    throw new Exception();
                if (game.WhiteIsOutOfPieces())
                    throw new Exception();
                if (game.BlackIsOutOfPieces())
                    throw new Exception();
                if (!game.IsGameOver())
                    throw new Exception();
            }
            // Test components controlling the logic for one player to 'capture'
            // the piece of another player. Throws Exception if a valid
            // 'capture' results in an inconsistent game state, if an invalid
            // capture is allowed, or if a player is allowed to move the
            // opposite player's game pieces.
            private static void TestCapture()
            {
                // Test a simple, valid capture.
                TzaarBoard board = new TzaarBoard(true);
                TzaarPiece whitePiece = new TzaarPiece.Tzaar(TzaarColor.WHITE);
                board.Add(whitePiece, 2, 2);
                board.Add(new TzaarPiece.Tzaar(TzaarColor.BLACK), 2, 3);
                TzaarGameState state = new TzaarGameState(board);
                TzaarLogic game = new TzaarLogic(state);

                game.Move(2, 2, 2, 3);

                // The destination position should now contain the white piece
                // which captured the black piece.
                if (board.Query(2, 3).Peek() != whitePiece)
                    throw new Exception();

                // The origin position should no longer contain any pieces.
                if (board.Query(2, 2).Count() != 0)
                    throw new Exception();

                // Test an illegal capture.  The capture is illegal because the
                // stack in the target position is more powerful than the stack
                // at the source.
                board = new TzaarBoard(true);
                board.Add(new TzaarPiece.Tzaar(TzaarColor.WHITE), 2, 2);
                board.Add(new TzaarPiece.Tzaar(TzaarColor.BLACK), 2, 3);
                board.Add(new TzaarPiece.Tzaar(TzaarColor.BLACK), 2, 3);
                state = new TzaarGameState(board);
                game = new TzaarLogic(state);

                bool passedTest = false;
                try
                {
                    game.Move(2, 2, 2, 3);
                }
                catch
                {
                    passedTest = true;
                }
                if (!passedTest)
                {
                    throw new Exception();
                }

                // Now try controlling some of the opponent's pieces. The game
                // should not allow it!
                board = new TzaarBoard(true);
                board.Add(new TzaarPiece.Tzaar(TzaarColor.WHITE), 2, 2);
                board.Add(new TzaarPiece.Tzaar(TzaarColor.BLACK), 2, 3);
                board.Add(new TzaarPiece.Tzaar(TzaarColor.BLACK), 2, 3);
                state = new TzaarGameState(board);
                game = new TzaarLogic(state);

                passedTest = false;
                try
                {
                    game.Move(2, 3, 2, 2);
                }
                catch
                {
                    passedTest = true;
                }
                if (!passedTest)
                {
                    throw new Exception();
                }
            }
        // Randomize the board state.
        private static void RandomizeBoardState(TzaarBoard board)
        {
            // Store the counts in a 2D array for easy access.
            int[][] actual = new int[2][];
            actual[0] = new int[] { 6, 9, 15 };
            actual[1] = new int[] { 6, 9, 15 };

            // Keep track of the number of pieces placed so far.
            int[,] pieces = new int[2, 3];

            // Column lengths of the board.
            int[] colLengths = new int[] { 5, 6, 7, 8, 8, 8, 7, 6, 5 };

            Random rand = new Random();
            int player, type;
            bool valid = false;
            TzaarColor color;

            // Now cycle through each space of the board and choose a random
            // piece to place.
            for (int i = 0; i < colLengths.Length; i++)
            {
                for (int j = 0; j < colLengths[i]; j++)
                {
                    // While a valid piece has not been chosen...
                    while (!valid)
                    {
                        // Randomly choose 0 - black or 1 - white.
                        player = rand.Next(0, 2);
                        // Randomly choose between 0 and 2. This will be one of
                        // the three types of pieces.
                        type = rand.Next(0, 3);
                        // Check that this particular color and type can still
                        // be placed.
                        if (pieces[player, type] < actual[player][type])
                        {
                            Stack<TzaarPiece> s = new Stack<TzaarPiece>();
                            if (player == 0)
                                color = TzaarColor.BLACK;
                            else
                                color = TzaarColor.WHITE;

                            switch (type)
                            {
                                case 0:
                                    s.Push(new TzaarPiece.Tzaar(color));
                                    break;
                                case 1:
                                    s.Push(new TzaarPiece.Tzarra(color));
                                    break;
                                case 2:
                                    s.Push(new TzaarPiece.Tott(color));
                                    break;
                            }
                            board.Add(s, i, j);
                            valid = true;
                            pieces[player, type]++;
                        }
                    }
                    valid = false;
                }
            }
        }
        // Return a full copy.
        public override GameBoard Copy()
        {
            TzaarBoard b = new TzaarBoard(true);

            for (int i = 0; i < this.board.Length; i++)
            {
                TzaarBoardPosition[] col = this.board[i];
                for (int j = 0; j < col.Length; j++)
                {
                    TzaarBoardPosition n = col[j];

                    if (n == null)
                        continue;

                    b.Add(n.Query(), i, j);
                }
            }
            return b;
        }