// 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();
            }
            // 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();
            }
        // Return true if there is some valid path from the specified source
        // position to the specified target position; otherwise return false.
        public bool IsValidPath(TzaarBoard board, int fromCol, int fromRow, int toCol, int toRow)
        {
            if (!board.IsValidPosition(fromCol, fromRow) || !board.IsValidPosition(toCol, toRow))
                // Parameters are out of range.
                return false;

            Node fromNode = paths[fromCol][fromRow];
            Node toNode = paths[toCol][toRow];

            if (fromCol == toCol)
            {
                if (fromRow == toRow)
                    // We can't move to ourselves!
                    return false;

                // The target is in the same column as the source.  So, we are
                // either going north or south.
                if (fromRow < toRow)
                    // Go north!
                    return ExplorePath(board, fromNode, toNode, "n");
                else
                    // Go south!
                    return ExplorePath(board, fromNode, toNode, "s");
            }
            else if (toCol > fromCol)
            {
                // Go east!

                // Try northeast first.
                if (ExplorePath(board, fromNode, toNode, "ne"))
                    return true;
                else
                    // Try southeast.
                    return ExplorePath(board, fromNode, toNode, "se");
            }
            else
            {
                // Go west!

                // Try northwest first.
                if (ExplorePath(board, fromNode, toNode, "nw"))
                    return true;
                else
                    // Try southwest.
                    return ExplorePath(board, fromNode, toNode, "sw");
            }
        }
            // Constructor parses a message string into a BoardState object.
            // Throws an exception if the message string does not represent a
            // valid BoardState message.
            public BoardState(string msg)
            {
                if (!GameMessage.IsBoardState(msg))
                    throw new Exception("This is not a BoardState message.");

                // Remove all whitespace characters from the message string.
                string msgString = RemoveAllWhiteSpace(msg);

                this.data = msgString;

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

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

                this.board = GetBoardStateFromString(msgString);
            }
            // 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();
            }
            // 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);
            }
예제 #7
0
        // 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;
        }
예제 #8
0
 // A game can be constructed without a parameter (empty board), with a
 // premade board, with a premade state, or with the bool value 'true'
 // for a randomly generated board.
 public TzaarLogic()
 {
     this.boardMap = new TzaarBoardMap();
     TzaarBoard board = new TzaarBoard();
     this.state = new TzaarGameState(board);
 }
            // 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;
            }
            // Constructor to instantiate a new BoardState based on the
            // specified TzaarBoard object.
            public BoardState(TzaarBoard aBoard)
            {
                this.data = GetStringFromBoardState(aBoard);

                this.board = (TzaarBoard)aBoard.Copy();
            }
            // 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);
            }
        // Start at the specified sourceNode and travel in the specified
        // direction.  Return true if there is a clear path between the two
        // specified board positions; otherwise return false.
        private static bool ExplorePath(TzaarBoard board, Node fromNode, Node toNode, string direction)
        {
            Node currentNode = fromNode;
            while (true)
            {
                // Move to the next node in the specified direction.
                FieldInfo myPropInfo = currentNode.GetType().GetField(direction);
                Node nextNode = (Node)myPropInfo.GetValue(currentNode);
                currentNode = nextNode;
                if (currentNode == null)
                    // We ran off the board.
                    break;

                if (currentNode == toNode)
                    // We have successfully reached our destination!
                    return true;

                Stack<TzaarPiece> currentPieceStack = board.Query(currentNode.col, currentNode.row);
                if (currentPieceStack.Count != 0)
                    // There are pieces on this position, stop here.
                    break;
            }

            // We can't get there.
            return false;
        }
예제 #13
0
        // 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;
                }
            }
        }
예제 #14
0
        // Scan the board and update the counts for each piece still remaining.
        private static void UpdatePieceCount(TzaarBoard board)
        {
            // The entire board is scanned for the update, so destroy the old
            // count values.
            board.blackTzaarCount = 0;
            board.blackTzarraCount = 0;
            board.blackTottCount = 0;

            board.whiteTzaarCount = 0;
            board.whiteTzarraCount = 0;
            board.whiteTottCount = 0;

            // Scan each space of the board to update.
            for (int i = 0; i < 9; i++)
                for (int j = 0; j < 9; j++)
                {
                    // If the position is not valid, we have passed the end of
                    // the column. Move to the next column.
                    if (!board.IsValidPosition(i, j))
                        break;

                    // Otherwise, find the color and number of pieces at the
                    // current position and update accordingly.
                    Stack<TzaarPiece> S = board.board[i][j].Query();
                    if (S.Count == 0)
                        continue;

                    TzaarPiece topPiece = S.Peek();
                    if (topPiece.Color == TzaarColor.WHITE)
                    {
                        if (topPiece.GetType() == typeof(TzaarPiece.Tzaar))
                            board.whiteTzaarCount++;
                        else if (topPiece.GetType() == typeof(TzaarPiece.Tzarra))
                            board.whiteTzarraCount++;
                        else
                            board.whiteTottCount++;
                    }
                    else
                    {
                        if (topPiece.GetType() == typeof(TzaarPiece.Tzaar))
                            board.blackTzaarCount++;
                        else if (topPiece.GetType() == typeof(TzaarPiece.Tzarra))
                            board.blackTzarraCount++;
                        else
                            board.blackTottCount++;
                    }
                }
        }
            // 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();
                }
            }