public HeapGround GetMoves(bool capturesOnly, bool pseudolegal, bool autoSetMoveColour = true)       // autoset move colour means move colour will be taken from current position. Otherwise can be custom set using SetMoveColour method
    {
        pseudolegalMode = pseudolegal;
        moves           = new HeapGround(128); // I imagine that most positions will yield less than 128 psuedolegal moves. (The greatest known number of legal moves available in a position is 218)

        if (autoSetMoveColour)
        {
            moveColour = BoardGround.currentGamestate & 1;
        }

        opponentColour    = 1 - moveColour;
        friendlyKingIndex = (moveColour == 1)?BoardGround.whiteKingIndex:BoardGround.blackKingIndex;
        inCheck           = SquareAttackedByEnemy(friendlyKingIndex);


        if (capturesOnly)
        {
            GenerateCaptureMoves();
        }
        else
        {
            GenerateAllMoves();
        }

        return(moves);
    }
    /// <summary>
    /// Makes the move after confirming that it is legal
    /// </summary>
    public void TryMakeMove(string algebraicMove)
    {
        if (isWhite == BoardGround.IsWhiteToPlay())
        {
            legalMoves = moveGenerator.GetMoves(false, false);
            for (int i = 0; i < legalMoves.Count; i++)
            {
                int moveFromIndex = legalMoves.GetMove(i) & 127;
                int moveToIndex   = (legalMoves.GetMove(i) >> 7) & 127;

                int moveFromX = BoardGround.Convert128to64(moveFromIndex) % 8;
                int moveFromY = BoardGround.Convert128to64(moveFromIndex) / 8;
                int moveToX   = BoardGround.Convert128to64(moveToIndex) % 8;
                int moveToY   = BoardGround.Convert128to64(moveToIndex) / 8;


                string fromAlgebraic = DefinitionsGround.fileNames[moveFromX].ToString() + DefinitionsGround.rankNames[moveFromY].ToString();
                string toAlgebraic   = DefinitionsGround.fileNames[moveToX].ToString() + DefinitionsGround.rankNames[moveToY].ToString();


                string moveCoords = fromAlgebraic + toAlgebraic;
                if (moveCoords == algebraicMove)                   // move confirmed as legal
                //Debug.Log(algebraicMove);
                {
                    MakeMove(legalMoves.GetMove(i));
                    break;
                }
            }
        }
    }
 public override void RequestMove()
 {
     base.RequestMove();
     legalMoves = moveGenerator.GetMoves(false, false);
 }
    int AlphaBetaSearch(int plyRemaining, int alpha, int beta, bool isWhite)
    {
        HeapGround moveHeap = moveGenerator.GetMoves(false, false);
        int        count    = moveHeap.Count;

        if (moveHeap.Count == 0)
        {
            return(((isWhite)?-1:1) * (10000000 + plyRemaining));          // if no moves available, side has been checkmated. Return best score for opponent. Checkmating sooner (higher depth) is rewarded.
        }


        if (plyRemaining == 0)
        {
            nodesSearched++;
            return(Evaluate());
            //QuiescenceSearch(int.MinValue,int.MaxValue,!isWhite,true);
            //return quiescenceScore;
        }
        if (isWhite)           // white is trying to attain the highest evaluation possible

        {
            for (int i = 0; i < count; i++)
            {
                ushort move = moveHeap.RemoveFirst();
                BoardGround.MakeMove(move);
                alpha = Math.Max(alpha, AlphaBetaSearch(plyRemaining - 1, alpha, beta, false));
                BoardGround.UnmakeMove(move);

                if (plyRemaining == searchDepth)                   // has searched full depth and is now looking at top layer of moves to select the best
                {
                    if (alpha > bestScoreThisIteration)
                    {
                        bestScoreThisIteration = alpha;
                        bestMoveThisIteration  = move;
                    }
                }

                if (beta <= alpha)                   // break
                {
                    breakCount++;
                    break;
                }
            }
            return(alpha);
        }
        else
        {
            // black is trying to obtain the lowest evaluation possible
            for (int i = 0; i < count; i++)
            {
                ushort move = moveHeap.RemoveFirst();
                BoardGround.MakeMove(move);
                beta = Math.Min(beta, AlphaBetaSearch(plyRemaining - 1, alpha, beta, true));
                BoardGround.UnmakeMove(move);

                if (plyRemaining == searchDepth)                   // has searched full depth and is now looking at top layer of moves to select the best
                {
                    if (beta < bestScoreThisIteration)
                    {
                        bestScoreThisIteration = beta;
                        bestMoveThisIteration  = move;
                    }
                }

                if (beta <= alpha)                   // break
                {
                    breakCount++;
                    break;
                }
            }

            return(beta);
        }

        return(0);
    }
Beispiel #5
0
    void Update()
    {
        if (!active)
        { // input is active if one or more players have been assigned to it (or game is over)
            return;
        }

        Vector3 endPointerPosition = GvrPointerInputModule.CurrentRaycastResult.worldPosition;

        // Vector2 mousePosition = (Vector2)viewCamera.ScreenToWorldPoint (Input.mousePosition);

        // Pick up piece
        // If not holding any Piece and clicked anywhere
        if (!holdingPiece && Input.GetMouseButtonDown(0))
        // if (/*Input.GetKeyDown(KeyCode.Mouse0)*/ Input.GetMouseButtonDown(0) && !holdingPiece)
        {
            ChessUIGround.instance.ResetHighlights();
            // isPlayerMove just checks if any HumanPlayerGround has his chance
            // If so then we will highlight the regions
            bool isPlayerMove = false;
            for (int i = 0; i < players.Count; i++)
            {
                if (players[i].isMyMove)
                {
                    isPlayerMove = true;
                    break;
                }
            }

            holdingPiece = TryGetPieceUIAtPoint(endPointerPosition, out pieceHeld);
            // This line improves efficiency
            if (!isThereAPiece)
            {
                holdingPiece = false;
            }
            // Debug.Log("holding piece: " + holdingPiece + " isPlayerMove: " + isP);
            if (holdingPiece && isPlayerMove)
            {
                // highlight legal moves for held piece
                HeapGround legalMoveHeap = HumanPlayerGround.legalMoves;
                for (int i = 0; i < legalMoveHeap.Count; i++)
                {
                    HighlightSquare(legalMoveHeap.GetMove(i), pieceHeld.algebraicCoordinate);
                }
            }
        }
        // Let go of piece
        // If holding anything and clicked somewhere
        else if (Input.GetMouseButtonDown(0) && holdingPiece)
        // else if (/*Input.GetKeyUp(KeyCode.Mouse0)*/Input.GetMouseButtonUp(0) && holdingPiece)
        {
            PieceUIGround dropSquare;
            ChessUIGround.instance.ResetHighlights();
            if (TryGetPieceUIAtPoint(endPointerPosition, out dropSquare))
            {
                string algebraicMove = pieceHeld.algebraicCoordinate + dropSquare.algebraicCoordinate;
                for (int i = 0; i < players.Count; i++)
                {
                    players[i].TryMakeMove(algebraicMove);
                }
            }
            pieceHeld.Release();
            holdingPiece = false;
        }
        // Drag piece
        // else if (/*Input.GetKey(KeyCode.Mouse0)*/ Input.GetMouseButton(0) && holdingPiece)
        // {
        //    pieceHeld.Move(endPointerPosition);
        // }
    }
Beispiel #6
0
    public static string NotationFromMove(ushort move)
    {
        BoardGround.UnmakeMove(move);          // unmake move on board

        MoveGeneratorGround moveGen = new MoveGeneratorGround();
        int moveFromIndex           = move & 127;
        int moveToIndex             = (move >> 7) & 127;
        int promotionPieceIndex     = (move >> 14) & 3;     // 0 = queen, 1 = rook, 2 = knight, 3 = bishop
        int colourToMove            = BoardGround.boardColourArray[moveFromIndex];

        int movePieceCode     = BoardGround.boardArray [moveFromIndex]; // get move piece code
        int movePieceType     = movePieceCode & ~1;                     // get move piece type code (no colour info)
        int capturedPieceCode = BoardGround.boardArray [moveToIndex];   // get capture piece code

        int promotionPieceType = BoardGround.pieceCodeArray [promotionPieceIndex];

        if (movePieceType == BoardGround.kingCode)
        {
            if (moveToIndex - moveFromIndex == 2)
            {
                BoardGround.MakeMove(move);                  // remake move
                return("O-O");
            }
            else if (moveToIndex - moveFromIndex == -2)
            {
                BoardGround.MakeMove(move);                  // remake move
                return("O-O-O");
            }
        }

        string moveNotation = GetSymbolFromPieceType(movePieceType);

        // check if any ambiguity exists in notation (e.g if e2 can be reached via Nfe2 and Nbe2)
        if (movePieceType != BoardGround.pawnCode && movePieceType != BoardGround.kingCode)
        {
            HeapGround allMoves = moveGen.GetMoves(false, false);

            for (int i = 0; i < allMoves.Count; i++)
            {
                int alternateMoveFromIndex = allMoves.moves[i] & 127;
                int alternateMoveToIndex   = (allMoves.moves[i] >> 7) & 127;
                int alternateMovePieceCode = BoardGround.boardArray [alternateMoveFromIndex];

                if (alternateMoveFromIndex != moveFromIndex && alternateMoveToIndex == moveToIndex) // if moving to same square from different square
                {
                    if (alternateMovePieceCode == movePieceCode)                                    // same piece type
                    {
                        int fromFileIndex          = BoardGround.FileFrom128(moveFromIndex) - 1;
                        int alternateFromFileIndex = BoardGround.FileFrom128(alternateMoveFromIndex) - 1;
                        int fromRankIndex          = BoardGround.RankFrom128(moveFromIndex) - 1;
                        int alternateFromRankIndex = BoardGround.RankFrom128(alternateMoveFromIndex) - 1;

                        if (fromFileIndex != alternateFromFileIndex)                           // pieces on different files, thus ambiguity can be resolved by specifying file
                        {
                            moveNotation += DefinitionsGround.fileNames[fromFileIndex];
                            break;                             // ambiguity resolved
                        }
                        else if (fromRankIndex != alternateFromRankIndex)
                        {
                            moveNotation += DefinitionsGround.rankNames[fromRankIndex];
                            break;                             // ambiguity resolved
                        }
                    }
                }
            }
        }

        if (capturedPieceCode != 0)           // add 'x' to indicate capture
        {
            if (movePieceType == BoardGround.pawnCode)
            {
                moveNotation += DefinitionsGround.fileNames[BoardGround.FileFrom128(moveFromIndex) - 1];
            }
            moveNotation += "x";
        }
        else             // check if capturing ep
        {
            if (movePieceType == BoardGround.pawnCode)
            {
                if (System.Math.Abs(moveToIndex - moveFromIndex) != 16 && System.Math.Abs(moveToIndex - moveFromIndex) != 32)
                {
                    moveNotation += DefinitionsGround.fileNames[BoardGround.FileFrom128(moveFromIndex) - 1] + "x";
                }
            }
        }

        moveNotation += DefinitionsGround.fileNames [BoardGround.FileFrom128(moveToIndex) - 1];
        moveNotation += DefinitionsGround.rankNames [BoardGround.RankFrom128(moveToIndex) - 1];

        // add = piece type if promotion
        if (movePieceType == BoardGround.pawnCode)
        {
            if (moveToIndex >= 112 || moveToIndex <= 7)               // pawn has reached first/eighth rank
            {
                moveNotation += "=" + GetSymbolFromPieceType(promotionPieceType);
            }
        }

        // add check/mate symbol if applicable
        BoardGround.MakeMove(move);          // remake move
        if (moveGen.PositionIsMate())
        {
            moveNotation += "#";
        }
        else if (moveGen.PositionIsCheck())
        {
            moveNotation += "+";
        }
        return(moveNotation);
    }