Example #1
0
        /// <summary>
        /// Get a list of positions where a pawn has to be flipped, given the position where a new pawn is to be placed.
        /// This is basically the effect of a new move on the board.
        /// NB: the list does not contain the new pawn.
        /// </summary>
        /// <param name="pawnPosition">Pawn position</param>
        /// <returns>List of positions where to flip pawns</returns>
        public List <IntPosition> GetPawnsToFlip(IntPosition pawnPosition)
        {
            List <IntPosition> pawnsToFlip    = new List <IntPosition>();
            List <IntPosition> directionsList = GetNeighborsDirections(pawnPosition);

            foreach (IntPosition direction in directionsList)
            {
                List <IntPosition> currentPath = new List <IntPosition>();

                Player currentPlayer  = playerTurn;
                Player oppositePlayer = GetOppositePlayer(currentPlayer);

                IntPosition currentPosition = pawnPosition;
                currentPosition += direction;
                while (IsPositionValid(currentPosition) && gameBoard[currentPosition.Column, currentPosition.Row] == (int)oppositePlayer)
                {
                    currentPath.Add(currentPosition);
                    currentPosition += direction;
                }

                if (IsPositionValid(currentPosition) && gameBoard[currentPosition.Column, currentPosition.Row] == (int)currentPlayer)
                {
                    pawnsToFlip.AddRange(currentPath);
                }
            }

            return(pawnsToFlip);
        }
Example #2
0
        /// <summary>
        /// Get directions where there's a playable move
        /// </summary>
        /// <param name="position">Position to check</param>
        /// <returns>List of directions</returns>
        public List <IntPosition> GetNeighborsDirections(IntPosition position)
        {
            List <IntPosition> directionsList = new List <IntPosition>();
            Player             currentPlayer  = playerTurn;
            Player             oppositePlayer = GetOppositePlayer(currentPlayer);

            for (int rowDelta = -1; rowDelta <= 1; rowDelta++)
            {
                for (int columnDelta = -1; columnDelta <= 1; columnDelta++)
                {
                    IntPosition nextPosition = new IntPosition(position.Column + columnDelta, position.Row + rowDelta);

                    if (IsPositionValid(nextPosition))
                    {
                        int slotContentId = gameBoard[nextPosition.Column, nextPosition.Row];

                        if ((position.Row != nextPosition.Row || position.Column != nextPosition.Column) &&
                            slotContentId == (int)oppositePlayer &&
                            IsPositionValid(nextPosition))
                        {
                            directionsList.Add(new IntPosition(columnDelta, rowDelta));
                        }
                    }
                }
            }

            return(directionsList);
        }
Example #3
0
        /// <summary>
        /// Initialize all the data of the game
        /// </summary>
        /// <param name="gridSize">Size of the board</param>
        /// <param name="initialPawnsPosition">Initial position of the pawns (top left corner)</param>
        public void InitAll(IntPosition gridSize, IntPosition initialPawnsPosition)
        {
            playerTurn = Player.Black;

            InitPlayersData();
            InitGameBoard(gridSize, initialPawnsPosition);
            InitTimer();
            moveHistory = new List <Tuple <List <IntPosition>, Player> >();
        }
Example #4
0
        /// <summary>
        /// Gets the most recent move stored and plays it backwards.
        /// </summary>
        /// <returns>
        /// A tuple containing the coordinates of the affected slots, which
        /// player the move belongs to and the coordinates of the pawn that
        /// was added to the board (which now has to be removed).
        /// </returns>
        public Tuple <List <IntPosition>, Player, IntPosition> UndoMove()
        {
            var lastMove = moveHistory.Last();
            List <IntPosition> slotsToUndo      = lastMove.Item1;
            Player             moveAuthor       = lastMove.Item2;
            IntPosition        lastPawnPosition = slotsToUndo.Last();

            slotsToUndo.RemoveAt(slotsToUndo.Count - 1);
            foreach (var position in slotsToUndo)
            {
                GameBoard[position.Column, position.Row] = (int)GetOppositePlayer(moveAuthor);
            }
            GameBoard[lastPawnPosition.Column, lastPawnPosition.Row] = (int)SlotContent.Nothing;
            moveHistory.RemoveAt(moveHistory.Count - 1);
            return(Tuple.Create(slotsToUndo, moveAuthor, lastPawnPosition));
        }
Example #5
0
        /// <summary>
        /// Init. the game board
        /// </summary>
        /// <param name="gridSize">Size of the board</param>
        /// <param name="initialPawnsPosition">Initial position of the pawns (top left corner)</param>
        public void InitGameBoard(IntPosition gridSize, IntPosition initialPawnsPosition)
        {
            gameBoard = new int[gridSize.Column, gridSize.Row];

            for (int row = 0; row < Rows; row++)
            {
                for (int column = 0; column < Columns; column++)
                {
                    gameBoard[column, row] = (int)SlotContent.Nothing;
                }
            }

            gameBoard[initialPawnsPosition.Column, initialPawnsPosition.Row]         = (int)SlotContent.White;
            gameBoard[initialPawnsPosition.Column + 1, initialPawnsPosition.Row]     = (int)SlotContent.Black;
            gameBoard[initialPawnsPosition.Column, initialPawnsPosition.Row + 1]     = (int)SlotContent.Black;
            gameBoard[initialPawnsPosition.Column + 1, initialPawnsPosition.Row + 1] = (int)SlotContent.White;
        }
Example #6
0
        /// <summary>
        /// Walk the game board to get all possible moves for the current player.
        /// </summary>
        /// <returns>
        /// A list containing the position of each playable slot.
        /// </returns>
        public List <IntPosition> GetAllPossibleMoves()
        {
            List <IntPosition> possibleMovesList = new List <IntPosition>();

            for (int rowIndex = 0; rowIndex < Rows; rowIndex++)
            {
                for (int columnIndex = 0; columnIndex < Columns; columnIndex++)
                {
                    IntPosition currentSlot   = new IntPosition(columnIndex, rowIndex);
                    int         slotContentId = gameBoard[currentSlot.Column, currentSlot.Row];
                    if (slotContentId == (int)playerTurn)
                    {
                        List <IntPosition> currentSlotPossibleMovesList = GetNeighborsDirections(currentSlot);
                        List <IntPosition> movements = new List <IntPosition>();
                        foreach (IntPosition direction in currentSlotPossibleMovesList)
                        {
                            if (IsPossibleMove(currentSlot, direction, movements))
                            {
                                IntPosition possibleMove = movements[movements.Count - 1];
                                possibleMovesList.Add(possibleMove);
                            }
                            movements.Clear();
                        }
                    }
                }
            }

            if (possibleMovesList.Count == 0)
            {
                SkipCurrentPlayerTurn();
            }
            else
            {
                CurrentPlayerData.HasSkippedLastTurn = false;
            }

            return(possibleMovesList);
        }
Example #7
0
        /// <summary>
        /// Check if there's a valid move in the given direction, if true, the "positions" list is filled with all the positions of the valid move
        /// </summary>
        /// <param name="pawnPosition">Position to check</param>
        /// <param name="direction">Direction to check</param>
        /// <param name="positions">Empty list given by the user, filled with severals position if there's a valid move</param>
        /// <returns></returns>
        public bool IsPossibleMove(IntPosition pawnPosition, IntPosition direction, List <IntPosition> positions)
        {
            IntPosition currentPosition = pawnPosition;
            bool        result          = false;

            Player currentPlayer  = playerTurn;
            Player oppositePlayer = GetOppositePlayer(currentPlayer);

            positions.Add(pawnPosition);

            currentPosition += direction;
            while (IsPositionValid(currentPosition) && gameBoard[currentPosition.Column, currentPosition.Row] == (int)oppositePlayer)
            {
                positions.Add(currentPosition);
                currentPosition += direction;
            }

            if (result = IsPositionValid(currentPosition) && (gameBoard[currentPosition.Column, currentPosition.Row] == (int)SlotContent.Nothing))
            {
                positions.Add(currentPosition);
            }

            return(result);
        }
Example #8
0
 /// <summary>
 /// Overloaded constructor: can define the size of the board and the initial position of the pawns (top left corner)
 /// </summary>
 /// <param name="gridSize">Size of the board</param>
 /// <param name="initialPawnsPosition">Initial position of the pawns (top left corner)</param>
 public OthelloLogic(IntPosition gridSize, IntPosition initialPawnsPosition)
 {
     InitAll(gridSize, initialPawnsPosition);
 }
Example #9
0
 /// <summary>
 /// Check if the position is inside the board
 /// </summary>
 /// <param name="position">Position to check</param>
 /// <returns>True if the position is inside board, false otherwise</returns>
 public bool IsPositionValid(IntPosition position)
 {
     return(position.Row >= 0 && position.Row < Rows && position.Column >= 0 && position.Column < Columns);
 }