Пример #1
0
    IEnumerator PieceMove(GameLogic.Move move)
    {
        var     piece = m_pieces[move.pieceNr];
        Vector3 newCoords;

        if (move.toPos < GameLogic.BoardSize)
        {
            newCoords = BoardCoords.getPositionCoords(move.toPos);
        }
        else
        {
            newCoords = BoardCoords.getTargetCoords(m_gameLogic.CurrentPlayer, move.toPos % 1000);
        }

        GameObject bumpedPiece   = null;
        Vector3?   bumpTargetPos = null;

        if (move.pieceOnTargetPos.HasValue)
        {
            var bumpedPieceIdx = move.pieceOnTargetPos.Value;
            var bumpedOwner    = m_gameLogic.WhosePlayerIsPiece(bumpedPieceIdx);
            var bumpHomePos    = (-m_gameLogic.FindFreeHomePos(bumpedOwner)) - 1;
            bumpedPiece   = m_pieces[bumpedPieceIdx];
            bumpTargetPos = BoardCoords.getHomeCoords(bumpedOwner, bumpHomePos);
        }

        m_move = new MovingPiece()
        {
            piece  = piece,
            start  = piece.transform.parent.position,
            target = newCoords,
            phase  = 0f
        };

        yield return(new WaitForSeconds(m_jumpLength));

        if (bumpedPiece != null)
        {
            bumpedPiece.transform.parent.position = bumpTargetPos.Value;
        }

        var result = m_gameLogic.ExecuteMove(move);

        if (result.gameOver != null)
        {
            Debug.Log("Game over");
            GameOver();
        }
        else
        {
            StartCoroutine(NextPlayer());
        }
    }
Пример #2
0
        /**
         * Check if the move correlates to the userPiece and
         * that the destination square of the move is empty.
         */
        private Boolean CheckMoveValidity(Move selectedMove)
        {
            Boolean moveValid = false;

            if (currentPosition.getPiece(selectedMove.origin) == userPiece)
            {
                if (currentPosition.getPiece(selectedMove.destination) == PieceType.Empty)
                {
                    moveValid = true;
                }
            }

            return moveValid;
        }
Пример #3
0
    public void OnPieceSelected(GameObject pieceParent)
    {
        // The mouse raycast returns the piece parent object
        // We want to find the actual piece
        GameObject piece = null;

        if (pieceParent.transform.childCount == 1)
        {
            piece = pieceParent.transform.GetChild(0).gameObject;
        }
        else
        {
            piece = pieceParent;
        }
        // find out the index of the selected piece
        int selectedPieceIdx = -1;

        for (var i = 0; i < m_pieces.Count; i++)
        {
            if (piece == m_pieces[i])
            {
                selectedPieceIdx = i;
                break;
            }
        }
        if (selectedPieceIdx == -1)
        {
            return;
        }

        // check that the piece is playable
        GameLogic.Move selectedMove = null;
        foreach (var move in m_pendingMoves)
        {
            if (move.pieceNr == selectedPieceIdx)
            {
                selectedMove = move;
                break;
            }
        }
        if (selectedMove == null)
        {
            return;
        }

        DisablePlayerInput();
        StartCoroutine(PieceMove(selectedMove));
    }
Пример #4
0
 /*
  * Returns true if a move is valid for a given position
  */
 public static Boolean isMoveValid(Move move, Position position)
 {
     if (move == null)
     {
         return false;
     }
     ArrayList moves = new MoveGenerator().legalMoves(position);
     foreach (Move listMove in moves)
     {
         //Move is only valid if it appears in legal moves list
         if (move.Equals(listMove))
         {
             return true;
         }
     }
     return false;
 }
Пример #5
0
        public void TestUnMakeMove()
        {
            //arrange
            Move simpleMove = new Move(12, 28, PieceType.Empty);
            UnMakeInfo unMakeMove = new UnMakeInfo();
            Position startPosition = FENConverter.convertFENToPosition(FENConverter.startPosition);
            //act
            startPosition.makeMove(simpleMove, unMakeMove);
            String fenString = "rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1";
            //assert
            Assert.AreEqual(fenString, FENConverter.convertPositionToFEN(startPosition));

            //act
            startPosition.unMakeMove(simpleMove, unMakeMove);
            //assert
            Assert.AreEqual(FENConverter.startPosition, FENConverter.convertPositionToFEN(startPosition));
        }
Пример #6
0
 public void TestMakeMove()
 {
     //arrange
     Move simpleMove = new Move(12, 28, PieceType.Empty); //e2e4
     UnMakeInfo unMakeMove = new UnMakeInfo();
     Position startPosition = FENConverter.convertFENToPosition(FENConverter.startPosition);
     //act
     startPosition.makeMove(simpleMove, unMakeMove);
     /*
      * This following string is technically incorrect as in FEN it should indicate e3 as
      * the en passant square. However, our implementation does not set the en passant square
      * if it cannot be used.
      */
     String fenString = "rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1";
     //assert
     Assert.AreEqual(fenString, FENConverter.convertPositionToFEN(startPosition));
 }
Пример #7
0
        public void TestLegalMovesWithCapture()
        {
            //arrange
            String positionB = "3k4/6p1/8/8/8/8/1B6/8 w - - 0 1";
            String positionR = "3k4/6p1/8/8/8/8/6R1/8 w - - 0 1";
            Position testPositionB = FENConverter.convertPiecePlacementToPosition(positionB);
            Position testPositionR = FENConverter.convertPiecePlacementToPosition(positionR);
            //act
            ArrayList legalMovesB = MoveGenerator.mgInstance.legalMoves(testPositionB);
            ArrayList legalMovesR = MoveGenerator.mgInstance.legalMoves(testPositionR);

            Move captureB = new Move(FENConverter.getSquare("b2"), FENConverter.getSquare("g7"), PieceType.Empty);
            Move captureR = new Move(FENConverter.getSquare("g2"), FENConverter.getSquare("g7"), PieceType.Empty);
            //assert
            Assert.AreEqual(8, legalMovesB.Count);
            Assert.AreEqual(13, legalMovesR.Count);
            Assert.AreEqual(true, MoveParser.isMoveCapture(captureB, testPositionB));
            Assert.AreEqual(true, MoveParser.isMoveCapture(captureR, testPositionR));
        }
Пример #8
0
 /*
  * Returns true if a move results in a caputre for a given
  * position
  */
 public static Boolean isMoveCapture(Move move, Position position)
 {
     if (position.getPiece(move.destination) == PieceType.Empty)
     {
         //Deal with En Passant capture
         PieceType piece = position.getPiece(move.origin);
         if ((piece == (position.whiteMove ? PieceType.P : PieceType.p)) && (move.destination == position.getEpSquare()))
         {
             return true;
         }
         else
         {
             return false;
         }
     }
     else
     {
         return true;
     }
 }
Пример #9
0
        /*
         * Converts a move object into a UCI move string (long algebraic
         * notation), a move list can be supplied to search through.
         */
        public static String moveObjectToString(Move move, Position position, ArrayList moves)
        {
            if ((move == null) || move.Equals(new Move(0, 0, 0)))
            {
                return "--";
            }
            StringBuilder moveString = new StringBuilder();
            int whiteKingOrigin = Position.getSquare(4, 0);
            int blackKingOrigin = Position.getSquare(4, 7);
            if ((move.origin == whiteKingOrigin) && (position.getPiece(whiteKingOrigin) == PieceType.K))
            {
                //Check white castle
                if (move.destination == Position.getSquare(6, 0))
                {
                    moveString.Append("O-O");
                }
                else if (move.destination == Position.getSquare(2, 0))
                {
                    moveString.Append("O-O-O");
                }
            }
            else if ((move.origin == blackKingOrigin) && (position.getPiece(blackKingOrigin) == PieceType.k))
            {
                //Check black castle
                if (move.destination == Position.getSquare(6, 7))
                {
                    moveString.Append("O-O");
                }
                else if (move.destination == Position.getSquare(2, 7))
                {
                    moveString.Append("O-O-O");
                }
            }
            if (moveString.Length == 0)
            {
                PieceType piece = position.getPiece(move.origin);
                moveString.Append("" + piece);

                int originFile = Position.getRank(move.origin);
                int originRank = Position.getFile(move.origin);
                int destinationFile = Position.getRank(move.destination);
                int destinationRank = Position.getFile(move.destination);

                //Long Algebraic Notation-----
                moveString.Append((char)(originFile + 'a'));
                moveString.Append((char)(originRank + '1'));
                moveString.Append(isMoveCapture(move, position) ? 'x' : '-');
                //----------------------------
                moveString.Append((char)(destinationFile + 'a'));
                moveString.Append((char)(destinationRank + '1'));
                if (move.promoteTo != PieceType.Empty)
                {
                    moveString.Append("" + piece);
                }
            }
            UnMakeInfo unMake = new UnMakeInfo();
            position.makeMove(move, unMake);
            Boolean inCheck = MoveGenerator.inCheck(position);
            if (inCheck)
            {
                ArrayList nextMoves = MoveGenerator.mgInstance.legalMoves(position);
                if (nextMoves.Count == 0)
                {
                    moveString.Append('#');
                }
                else
                {
                    moveString.Append('+');
                }
            }
            position.unMakeMove(move, unMake);

            return moveString.ToString();
        }
Пример #10
0
 /*
  * Converts a move object into a UCI move string (long algebraic
  * notation)
  */
 public static String moveObjectToString(Move move, Position position)
 {
     return moveObjectToString(move, position, null);
 }
Пример #11
0
 /*
  * Convert a move object to UCI string format
  */
 public static String moveObjectToString(Move move)
 {
     String moveString = squareToString(move.origin);
     moveString += (squareToString(move.destination));
     switch (move.promoteTo)
     {
         case PieceType.Q:
         case PieceType.q:
             moveString += "q";
             break;
         case PieceType.R:
         case PieceType.r:
             moveString += "r";
             break;
         case PieceType.B:
         case PieceType.b:
             moveString += "b";
             break;
         case PieceType.N:
         case PieceType.n:
             moveString += "n";
             break;
         default:
             break;
     }
     return moveString;
 }
Пример #12
0
        public void StartGame()
        {
            myConsoleOut.WriteLine("Welcome, press enter to start a new game.");
            myConsoleOut.WriteLine("To quit, simply type quit and hit enter.");
            myConsoleOut.WriteLine("To undo the last move made, type undo and hit enter.");
            myConsoleOut.WriteLine("To make a move, type the move in long algebraic notation.");
            myConsoleOut.WriteLine("An example would be 'e2e4'.");
            myConsoleIn.ReadLine();

            while (!gameFinished)
            {
                myConsoleOut.WriteLine(FENConverter.asciiBoard(currentPosition));
                String userInput = myConsoleIn.ReadLine();

                switch (userInput)
                {
                    case ("quit"):
                    case ("Quit"):
                        gameFinished = true;
                        break;
                    case ("undo"):
                    case ("Undo"):
                        undoMove = true;
                        break;
                    default:
                        break;
                }

                //Continue if user has not quit
                if (!gameFinished)
                {
                    //undo previous moce
                    if (undoMove)
                    {
                        if (unMakeInfo == null)
                        {
                            myConsoleOut.WriteLine("No move to undo.");
                        }
                        else
                        {
                            currentPosition.unMakeMove(currentMove, unMakeInfo);
                        }
                    }
                    //performs valid move
                    else
                    {
                        if (ParseMove(userInput))
                        {
                            String originString = userInput.Substring(0, 2);
                            String destinationString = userInput.Substring(2, 2);

                            int origin = FENConverter.getSquare(originString);
                            int destination = FENConverter.getSquare(destinationString);

                            currentMove = new Move(origin, destination, PieceType.Empty);

                            currentPosition.makeMove(currentMove, unMakeInfo);
                        }
                    }
                }
            }
        }
Пример #13
0
 /*
  * Creates a Move object with given input
  */
 public Move(Move m)
 {
     this.origin = m.origin;
     this.destination = m.destination;
     this.promoteTo = m.promoteTo;
 }
Пример #14
0
        /*
         * Unmake a move to the current position
         */
        public void unMakeMove(Move move, UnMakeInfo moveInfo)
        {
            if (!sameActiveColor)
            {
                setWhiteMove(!whiteMove);
            }
            PieceType piece = pieceLayout[move.destination];
            setPiece(move.origin, piece);
            setPiece(move.destination, moveInfo.getCapturedPiece());
            setCastleMask(moveInfo.getCastleRights());
            setEpSquare(moveInfo.getEPSquare());
            halfMoveClock = moveInfo.getHalfMoveClock();

            Boolean whiteToMove = whiteMove;
            if (move.promoteTo != PieceType.Empty)
            {
                piece = whiteToMove ? PieceType.P : PieceType.p;
                setPiece(move.origin, piece);
            }
            if (!whiteToMove)
            {
                fullMoveCounter--;
            }

            //Handle Castling
            PieceType king = whiteToMove ? PieceType.K : PieceType.k;
            int kingOrigin = move.origin;
            if (piece == king)
            {
                if (move.destination == kingOrigin + 2)
                {
                    setPiece(kingOrigin + 3, pieceLayout[kingOrigin + 1]);
                    setPiece(kingOrigin + 1, PieceType.Empty);
                }
                else if (move.destination == kingOrigin - 2)
                {
                    setPiece(kingOrigin - 4, pieceLayout[kingOrigin - 1]);
                    setPiece(kingOrigin - 1, PieceType.Empty);
                }
            }

            //Handle En Passant
            if (move.destination == epSquare)
            {
                if (piece == PieceType.P)
                {
                    setPiece(move.destination - 8, PieceType.p);
                }
                else if (piece == PieceType.p)
                {
                    setPiece(move.destination + 8, PieceType.P);
                }
            }
        }
Пример #15
0
        //-----------------Move Methods---------------------------
        /*
         * Apply a move to the current position
         */
        public void makeMove(Move move, UnMakeInfo moveInfo)
        {
            //Store info to undo move if needed
            moveInfo.setCapturedPiece(pieceLayout[move.destination]);
            moveInfo.setCastleRights(castleMask);
            moveInfo.setEPSquare(epSquare);
            moveInfo.setHalfMoveClock(halfMoveClock);

            Boolean whiteToMove = whiteMove;

            PieceType piece = pieceLayout[move.origin];
            PieceType capturedPiece = pieceLayout[move.destination];

            Boolean nullMove = (move.origin == 0) && (move.destination == 0);

            if (nullMove || (capturedPiece != PieceType.Empty) || (piece == (whiteToMove ? PieceType.P : PieceType.p)))
            {
                halfMoveClock = 0;
            }
            else
            {
                halfMoveClock++;
            }
            if (!whiteToMove)
            {
                fullMoveCounter++;
            }

            //Handle Castling
            PieceType king = whiteToMove ? PieceType.K : PieceType.k;
            int kingOrigin = move.origin;
            if (piece == king)
            {
                if (move.destination == kingOrigin + 2)
                {
                    setPiece(kingOrigin + 1, pieceLayout[kingOrigin + 3]);
                    setPiece(kingOrigin + 3, PieceType.Empty);
                }
                else if (move.destination == kingOrigin - 2)
                {
                    setPiece(kingOrigin - 1, pieceLayout[kingOrigin - 4]);
                    setPiece(kingOrigin - 4, PieceType.Empty);
                }

                if (whiteToMove)
                {
                    setCastleMask(castleMask & ~(1 << Position.A1_CASTLE));
                    setCastleMask(castleMask & ~(1 << Position.H1_CASTLE));
                }
                else
                {
                    setCastleMask(castleMask & ~(1 << Position.A8_CASTLE));
                    setCastleMask(castleMask & ~(1 << Position.H8_CASTLE));
                }
            }

            if (!nullMove)
            {
                PieceType rook = whiteToMove ? PieceType.R : PieceType.r;
                if (piece == rook)
                {
                    removeCastleRights(move.origin);
                }
                PieceType opppositeRook = whiteToMove ? PieceType.r : PieceType.R;
                if (capturedPiece == opppositeRook)
                {
                    removeCastleRights(move.destination);
                }
            }

            //Handle En Passant
            int prevEpSquare = epSquare;
            setEpSquare(-1);
            if (piece == PieceType.P)
            {
                if (move.destination - move.origin == 2 * 8)
                {
                    int file = Position.getFile(move.destination);
                    if (((file > 0) && (pieceLayout[move.destination - 1] == PieceType.p)) ||
                        ((file < 7) && (pieceLayout[move.destination + 1] == PieceType.p)))
                    {
                        setEpSquare(move.origin + 8);
                    }
                }
                else if (move.destination == prevEpSquare)
                {
                        setPiece(move.destination - 8, PieceType.Empty);
                }
            }
            else if (piece == PieceType.p)
            {
                if (move.destination - move.origin == -2 * 8)
                {
                    int file = Position.getFile(move.destination);
                    if (((file > 0) && (pieceLayout[move.destination - 1] == PieceType.P)) ||
                        ((file < 7) && (pieceLayout[move.destination + 1] == PieceType.P)))
                    {
                        setEpSquare(move.origin - 8);
                    }
                }
                else if (move.destination == prevEpSquare)
                {
                    setPiece(move.destination + 8, PieceType.Empty);
                }
            }

            //Perform Move
            setPiece(move.origin, PieceType.Empty);
            //Handle Promotion
            if (move.promoteTo != PieceType.Empty)
            {
                setPiece(move.destination, move.promoteTo);
            }
            else
            {
                setPiece(move.destination, piece);
            }

            if (!sameActiveColor)
            {
                setWhiteMove(!whiteToMove);
            }
        }
Пример #16
0
 public void returnMove(Move move)
 {
     if (movesInCache < moveCache.Length)
     {
         moveCache[movesInCache++] = move;
     }
 }