/// <summary>
 /// Write move to log.
 /// </summary>
 /// <param name="move"></param>
 private void _writeLog(cgSimpleMove move)
 {
     if (moveLog != null)
     {
         if (NotationType == cgNotation.NotationType.Coordinate)
         {
             if (_loggedMoves % 2 == 0)
             {
                 moveLog.text += "\n";
             }
             else
             {
                 moveLog.text += " | ";
             }
             moveLog.text += _abstractBoard.SquareNames[move.from] + "-" + _abstractBoard.SquareNames[move.to];
         }
         else if (NotationType == cgNotation.NotationType.Algebraic)
         {
             moveLog.text = "Moves:\n";
             cgNotation note = new cgNotation(_abstractBoard.duplicate());
             moveLog.text = note.getLogFriendlyNotation();
         }
         _loggedMoves++;
     }
 }
示例#2
0
    public void OnPieceMove(cgSimpleMove _move)
    {
        isChanged        = true;
        Btn_Save.enabled = true;

        if (curMove < moveList.Count)
        {
            moveList.RemoveRange(curMove, moveList.Count - curMove);
        }

        moveList.Add(_move);
        board.move(_move);

        if (board.isChecked(board.whiteTurnToMove))
        {
            AudioSource.PlayClipAtPoint(Check_Sound, Vector3.zero, 1.0f);
        }
        else
        {
            AudioSource.PlayClipAtPoint(MovePiece_Sound, Vector3.zero, 1.0f);
        }

        curMove++;

        UpdateInfos();
        Wnd_Board.UpdateBoard();
    }
    /// <summary>
    /// The engine returns with its prefered move.
    /// </summary>
    /// <param name="move">The prefered move.</param>
    private void _engineCallback(List <cgSimpleMove> moves)
    {
        if (!playerCanMove)
        {
            cgSimpleMove move = moves[0];
            if (this._abstractBoard.moves.Count < 10 && randomizeEarlyEngineMoves)  //We are in the very early game and we should randomize the engine moves early, so we will make a random-ish choice here instad of the prefered choice.
                                                                                    //random-ish in the sense, that we will take a random move of one of the moves that are in the better half of all possible moves.

            {
                List <cgSimpleMove> candidates = _findAllMovesNear(moves, 24);
                UnityEngine.Debug.Log("Candidates: " + candidates.Count);
                int choice = UnityEngine.Random.Range(0, candidates.Count);

                move = moves[choice];
            }
            if (_abstractBoard.verifyLegality(move))
            {
                _makeMove(move);
            }
            else
            {
                moves.Remove(move);
                if (_engine.moves.Count > 0)
                {
                    _engineCallback(moves);
                }
                else
                {
                    _checkGameOver();
                }
            }
        }
    }
示例#4
0
    public void OnPieceMove(cgSimpleMove _move)
    {
        if (isRightMove(_move))
        {
            if (!m_MissedThisLine)
            {
                m_Score++;
                m_TotalScore++;
            }

            moveNextMove();
        }
        else
        {
            m_MissedThisLine = true;

            if (m_Missed)
            {
                WndManager.Singleton.OpenMsgBox("Incorrect move. The Right move is " + cgNotation.NotationFromMove(m_Board, m_CurLine.moveList[m_CurMoveIdx]) /*, CallBackIncorrectMove*/);
            }
            else
            {
                WndManager.Singleton.OpenMsgBox("Incorrect move.");
                //revertMove();
                m_Missed = true;
            }
        }

        UpdateInfos();
    }
示例#5
0
 /// <summary>
 /// Final verification, checks if the kings is attempting to perform a capture that leads to the king being taken next, which is the only illegal move findLegalMoves does not check.
 /// </summary>
 /// <param name="testMove">The move to be verified</param>
 /// <returns>Is this an illegal king capture?</returns>
 public bool verifyLegality(cgSimpleMove testMove)
 {
     if (testMove.to == 65)
     {
         return(false);
     }
     else if (Mathf.Abs(squares[testMove.from]) != 6)
     {
         return(true);
     }
     else
     {
         move(testMove);
         foreach (cgSimpleMove mov in findLegalMoves(_whiteTurnToMove))
         {
             if (mov.to == testMove.to)
             {
                 revert();
                 return(false);
             }
         }
         revert();
         return(true);
     }
 }
示例#6
0
    private void _testBoard()
    {
        bool asWhite  = true;
        int  tryMoves = 200;

        UnityEngine.Debug.Log("testing board..");
        for (int i = 0; i < tryMoves; i++)
        {
            List <cgSimpleMove> moves = _board.findLegalMoves(asWhite);
            cgSimpleMove        move  = moves[UnityEngine.Random.Range(0, moves.Count)];
            UnityEngine.Debug.Log("trying move:" + cgGlobal.MoveToString(move));
            if (moves.Count < 2)
            {
                break;
            }
            _board.move(move);
            asWhite = !asWhite;
            _debugReadBoard();
        }
        _debugReadBoard();
        UnityEngine.Debug.Log("^^pre reversion.");
        for (int u = tryMoves; u > 0; u--)
        {
            _board.revert();
        }

        _debugReadBoard();

        UnityEngine.Debug.Log("moves:" + _board.moveCount + " reverts:" + _board.revertCount);
    }
示例#7
0
    public void OnSquareSelected(int _pos)
    {
        if (m_SelectedPiece == -1)
        {
            return;
        }

        List <cgSimpleMove> moveSet = m_Board.findStrictLegalMoves(m_Board.whiteTurnToMove);

        foreach (cgSimpleMove move in moveSet)
        {
            if (move.from == m_SelectedPiece && move.to == _pos)
            {
                if (IsPromotionMove(move))
                {
                    m_CurMove = move;
                    WndManager.Singleton.OpenPromotionSelectWnd(m_Board.whiteTurnToMove, CallbackPromotionSelect);
                }
                else
                {
                    OnMovePiece(move);
                }

                break;
            }
        }

        UnselectAllSquare();
        m_SelectedPiece = -1;
    }
示例#8
0
    /// <summary>
    /// Add a move based on a notation type.
    /// </summary>
    /// <param name="move">the string representation of the move(e4, bxd3 or e2-e4 etc.)</param>
    /// <param name="notationType"></param>
    public void AddMove(string move, NotationType notationType)
    {
        if (notationType == NotationType.Coordinate)
        {
            if (move == "0-0")
            {
                //cgSimpleMove smove = new cgCastlingMove(0,0,0,0,0);
            }
            else if (move == "0-0-0")
            {
            }
            else
            {
                byte start = 0;
                byte end   = 0;
                for (byte i = 0; i < board.SquareNames.Length; i++)
                {
                    string str = board.SquareNames[i];

                    if (str == move.Substring(0, 2))
                    {
                        start = i;
                    }
                    if (str == move.Substring(3, 2))
                    {
                        end = i;
                    }
                }

                cgSimpleMove smove = new cgSimpleMove(start, end);
                moves.Add(smove);
            }
        }
    }
示例#9
0
    /**
     * 0  1  2  3  4  5  6  7
     *  8  9  10 11 12 13 14 15
     *  16 17 18 19 20 21 22 23
     *  24 25 26 27 28 29 30 31
     *  32 33 34 35 36 37 38 39
     *  40 41 42 43 44 45 46 47
     *  48 49 50 51 52 53 54 55
     *  56 57 58 59 60 61 62 63
     * */


    public static string MoveToString(cgSimpleMove move)
    {
        if (move == null)
        {
            return("");
        }
        return(SquareNames[move.from] + "->" + SquareNames[move.to]);
    }
示例#10
0
    private void _suggestMove(cgSimpleMove move)
    {
        cgSquareScript departingSquare = _getSquare(cgGlobal.SquareNames[move.from]);
        cgSquareScript arrivalSquare   = _getSquare(cgGlobal.SquareNames[move.to]);

        departingSquare.highlightTemporarily(new Color(0, .5f, 0));
        arrivalSquare.highlightTemporarily(new Color(0, .5f, 0));
    }
示例#11
0
    void OnMovePiece(cgSimpleMove _move)
    {
        m_PieceMoveHandler(_move);
//         if (m_Board.isChecked(m_Board.whiteTurnToMove))
//             AudioSource.PlayClipAtPoint(m_CheckSound, Vector3.zero, 1.0f);
//         else
//             AudioSource.PlayClipAtPoint(m_MoveSound, Vector3.zero, 1.0f);
    }
    /// <summary>
    /// Duplicate this move. Used when duplicating a board which has had moves performed on it, said moves are also duplicated.
    /// </summary>
    /// <returns></returns>
    public virtual cgSimpleMove duplicate()
    {
        cgSimpleMove dup = new cgSimpleMove(this.from, this.to, this.positionalVal);

        dup.capturedType = this.capturedType;
        dup.val          = this.val;
        dup.bestResponse = bestResponse;
        dup.queened      = this.queened;
        return(dup);
    }
示例#13
0
    /// <summary>
    /// The user has released a dragged piece. Verify that its a legal move, if so perform the move and perform the next move if appropriate mode.
    /// </summary>
    /// <param name="piece"></param>
    private void _pieceUp(cgChessPieceScript piece)
    {
        if (_downPiece != null)
        {
            if (playerCanMove || Mode == BoardMode.PlayerVsPlayer)
            {
                cgSimpleMove        legalMove     = null;
                cgSquareScript      closestSquare = _findSquareAt(_downPiece.transform.position);
                List <cgSimpleMove> legalMoves    = _abstractBoard.findLegalMoves(whiteTurnToMove);
                foreach (cgSimpleMove move in legalMoves)
                {
                    if (cgGlobal.SquareNames[move.from] == _downPiece.square.uniqueName && cgGlobal.SquareNames[move.to] == closestSquare.uniqueName)
                    {
                        legalMove = move;
                    }
                }
                //test legality of move here.

                if (legalMove != null && _abstractBoard.verifyLegality(legalMove))
                {
                    //piece.moveToSquare(closestSquare);
                    _makeMove(legalMove);
                    if (Mode == BoardMode.PlayerVsEngine)
                    {
                        _engine.MakeMove(_abstractBoard, false, _engineCallback);
                    }
                    else if (Mode == BoardMode.EngineVsPlayer)
                    {
                        _engine.MakeMove(_abstractBoard, true, _engineCallback);
                    }
                }
                else
                {
                    piece.moveToSquare(piece.square);
                }
            }
            else
            {
                piece.moveToSquare(piece.square);
            }
            _downPiece = null;
        }
        else
        {
            piece.moveToSquare(piece.square);
            _downPiece = null;
        }
        if (highlightLastMove)
        {//revert colors if highlighting is active
            foreach (cgSquareScript square in _squares)
            {
                square.changeColor(square.startColor);
            }
        }
    }
示例#14
0
    bool isRightMove(cgSimpleMove _move)
    {
        cgSimpleMove curMove = m_CurLine.moveList[m_CurMoveIdx];

        if (curMove.from == _move.from && curMove.to == _move.to)
        {
            return(true);
        }

        return(false);
    }
示例#15
0
    /// <summary>
    /// Returns all squares the block the provided move.
    /// </summary>
    /// <param name="forMove">The move that should be blocked</param>
    /// <returns>The squares that block the move.</returns>
    private List <byte> _getBlockAttackSquares(cgSimpleMove forMove)
    {
        List <byte> returns = new List <byte>();

        returns.Add(forMove.from);
        int type = Mathf.Abs(squares[forMove.from]);

        if (type == 2 || type == 4 || type == 5)
        {
            returns.AddRange(_getRayIn(_findMoveSetFor(type, forMove.from), forMove.to));
        }
        return(returns);
    }
    /// <summary>
    /// Utilizing an AlphaBeta searching algorithm, we generate moves evaluate them, prune and decide which is best.
    /// https://en.wikipedia.org/wiki/Alpha%E2%80%93beta_pruning
    /// </summary>
    /// <param name="node">the move to analyze</param>
    /// <param name="depth">The max depth to search to, execution time increases exponentially the higher the depth</param>
    /// <param name="alpha"></param>
    /// <param name="beta"></param>
    /// <param name="maximizing"></param>
    /// <returns>The value of the provided node</returns>


    private int _alfaBeta(cgSimpleMove node, int depth, int alpha = int.MinValue, int beta = int.MaxValue, bool maximizing = true)
    {
        _board.move(node);

        if (depth == 0)
        {
            int val = _board.Evaluate();
            _board.revert();
            return(val);
        }

        if (maximizing)
        {
            int v = int.MinValue;
            List <cgSimpleMove> replies = _board.findLegalMoves(true);
            foreach (cgSimpleMove reply in replies)
            {
                int candidate = _alfaBeta(reply, depth - 1, alpha, beta, false);
                v = candidate > v ? candidate : v;

                alpha = alpha > v ? alpha : v;
                if (beta < alpha)
                {
                    break;
                }
            }
            _board.revert();
            return(v);
        }
        else
        {
            int v = int.MaxValue;
            List <cgSimpleMove> replies = _board.findLegalMoves(false);
            foreach (cgSimpleMove reply in replies)
            {
                int candidate = _alfaBeta(reply, depth - 1, alpha, beta, true);
                v = candidate < v ? candidate : v;
                if (beta > v)
                {
                    beta = v;
                    //node.bestResponse = reply;
                }
                if (beta < alpha)
                {
                    break;
                }
            }
            _board.revert();
            return(v);
        }
    }
    /// <summary>
    /// Peform the provided move on the visual board and the abstract board, with no legality checks - thus should be performed prior to calling this.
    /// </summary>
    /// <param name="move"></param>
    private void _makeMove(cgSimpleMove move)
    {
        UnityEngine.Debug.Log("White: " + _abstractBoard.whiteTurnToMove);
        movesMade++;
        playSound(moveSound);
        _abstractBoard.move(move);
        _writeLog(move);
        //_abstractBoard.debugReadBoard();
        if (_getPieceOn(_abstractBoard.SquareNames[move.to]) != null && !(move is cgCastlingMove))
        {
            _setDeadPiece(_getPieceOn(_abstractBoard.SquareNames[move.to]));
        }
        cgChessPieceScript piece = _getPieceOn(_abstractBoard.SquareNames[move.from]);

        if (move.queened)
        {
            piece.SetType(_abstractBoard.squares[move.to] > 0 ? cgChessPieceScript.Type.WhiteQueen : cgChessPieceScript.Type.BlackQueen);
        }
        if (move is cgCastlingMove)
        {
            cgChessPieceScript piece2 = _getPieceOn(_abstractBoard.SquareNames[(move as cgCastlingMove).secondFrom]);
            if (piece2)
            {
                piece2.moveToSquare(_getSquare(_abstractBoard.SquareNames[(move as cgCastlingMove).secondTo]));
            }
        }
        else if (move is cgEnPassantMove)
        {
            cgChessPieceScript piece2 = _getPieceOn(_abstractBoard.SquareNames[(move as cgEnPassantMove).attackingSquare]);
            piece2.dead = true;
        }
        piece.moveToSquare(_getSquare(_abstractBoard.SquareNames[move.to]));

        whiteTurnToMove = _abstractBoard.whiteTurnToMove;
        _checkGameOver();
        if (highlightLastMove)
        {
            //Color copyFrom = _getSquare(cgGlobal.SquareNames[move.to]).startColor;
            Color color = _getSquare(_abstractBoard.SquareNames[move.to]).recentMoveColor;

            _getSquare(_abstractBoard.SquareNames[move.to]).highlightTemporarily(color);
        }

        //Debug.Log("making move. " + _abstractBoard.whiteTurnToMove+" moves "+_abstractBoard.moves.Count);
        //UnityEngine.Debug.Log("Time elapsed: " + stopwatch.Elapsed);

        if (Mode == BoardMode.EngineVsEngine)
        {
            MakeEngineMove(_abstractBoard.duplicate(), _abstractBoard.whiteTurnToMove, _engineCallback);
        }
    }
示例#18
0
    public void OnPieceSelected(int _pos)
    {
        bool canMove = false;

        Debug.Log("source pos = " + m_SelectedPiece.ToString() + ", target pos = " + _pos.ToString());

        if ((m_SelectedPiece != -1) && (m_SelectedPiece != _pos))
        {
            List <cgSimpleMove> moveSet = m_Board.findStrictLegalMoves(m_Board.whiteTurnToMove);
            foreach (cgSimpleMove move in moveSet)
            {
                if (move.from == m_SelectedPiece && move.to == _pos)
                {
                    if (IsPromotionMove(move))
                    {
                        m_CurMove = move;
                        WndManager.Singleton.OpenPromotionSelectWnd(m_Board.whiteTurnToMove, CallbackPromotionSelect);
                    }
                    else
                    {
                        OnMovePiece(move);
                        canMove = true;
                    }
                    break;
                }
            }

            UnselectAllSquare();
            m_SelectedPiece = -1;
        }

        if (m_SelectedPiece == -1 || !canMove)
        {
            UnselectAllSquare();
//             List<cgSimpleMove> moveSet = m_Board.findStrictLegalMoves(m_Board.whiteTurnToMove);
//             foreach (cgSimpleMove move in moveSet)
//                 if (move.from == _pos)
//                     SelectSquare(move.to);
            if (m_Board.squares[_pos] != 0 &&
                ((m_Board.squares[_pos] > 0 && m_Board.whiteTurnToMove && (m_CanMove == CanMove.All || (m_CanMove == CanMove.White))) ||
                 (m_Board.squares[_pos] < 0 && !m_Board.whiteTurnToMove && (m_CanMove == CanMove.All || (m_CanMove == CanMove.Black)))))
            {
                SelectSquare(_pos);
                m_SelectedPiece = _pos;
            }
            else
            {
                m_SelectedPiece = -1;
            }
        }
    }
示例#19
0
    void UnselectAllSquare()
    {
        for (int i = 0; i < m_SquarePoses.Length; i++)
        {
            Image img = m_SquarePoses[i].GetComponent <Image>();
            img.color = Col_None;
        }

        if (m_Board.moves.Count > 0)
        {
            cgSimpleMove lastMove = m_Board.moves[m_Board.moves.Count - 1];
            Image        img      = m_SquarePoses[lastMove.to].GetComponent <Image>();
            img.color = Col_LastMove;
        }
    }
示例#20
0
 private void _engineSuggestion(cgSimpleMove move)
 {
     if (playerCanMove)
     {
         if (_abstractBoard.verifyLegality(move))
         {
             _suggestMove(move);
         }
         else
         {
             _engine.Moves.Remove(move);
             if (_engine.Moves.Count > 0)
             {
                 _engineSuggestion(_engine.Moves[0]);
             }
         }
     }
 }
示例#21
0
 /// <summary>
 /// Add a move based on a notation type.
 /// </summary>
 /// <param name="move">the string representation of the move(e4, bxd3 or e2-e4 etc.)</param>
 /// <param name="notationType"></param>
 public void AddMove(string move, NotationType notationType)
 {
     if (notationType == NotationType.Coordinate)
     {
         if (move == "0-0")
         {
             //cgSimpleMove smove = new cgCastlingMove(0,0,0,0,0);
         }
         else if (move == "0-0-0")
         {
         }
         else
         {
             cgSimpleMove smove = new cgSimpleMove(cgGlobal.IndexFromCellName(move.Substring(0, 2)), cgGlobal.IndexFromCellName(move.Substring(3, 2)));
             moves.Add(smove);
         }
     }
 }
示例#22
0
    /// <summary>
    /// Peform the provided move on the visual board and the abstract board, with no legality checks - thus should be performed prior to calling this.
    /// </summary>
    /// <param name="move"></param>
    private void _makeMove(cgSimpleMove move)
    {
        //Debug.Log("making move:" + cgGlobal.MoveToString(move));

        movesMade++;
        playSound(moveSound);
        _abstractBoard.move(move);
        _writeLog(move);
        //_abstractBoard.debugReadBoard();
        if (_getPieceOn(cgGlobal.SquareNames[move.to]) != null)
        {
            _setDeadPiece(_getPieceOn(cgGlobal.SquareNames[move.to]));
        }
        cgChessPieceScript piece = _getPieceOn(cgGlobal.SquareNames[move.from]);

        piece.moveToSquare(_getSquare(cgGlobal.SquareNames[move.to]));
        if (move.promoted)
        {
            piece.SetType(_abstractBoard.squares[move.to] > 0 ? cgChessPieceScript.Type.WhiteQueen : cgChessPieceScript.Type.BlackQueen);
        }
        if (move is cgCastlingMove)
        {
            cgChessPieceScript piece2 = _getPieceOn(cgGlobal.SquareNames[(move as cgCastlingMove).secondFrom]);
            if (piece2)
            {
                piece2.moveToSquare(_getSquare(cgGlobal.SquareNames[(move as cgCastlingMove).secondTo]));
            }
        }
        else if (move is cgEnPassantMove)
        {
            cgChessPieceScript piece2 = _getPieceOn(cgGlobal.SquareNames[(move as cgEnPassantMove).attackingSquare]);
            piece2.dead = true;
        }

        whiteTurnToMove = _abstractBoard.whiteTurnToMove;
        _checkGameOver();
        if (highlightLastMove)
        {
            //Color copyFrom = _getSquare(cgGlobal.SquareNames[move.to]).startColor;
            Color color = _getSquare(cgGlobal.SquareNames[move.to]).recentMoveColor;

            _getSquare(cgGlobal.SquareNames[move.to]).highlightTemporarily(color);
        }
    }
    /// <summary>
    /// Called when the analysis starts.
    /// </summary>
    /// <returns></returns>
    private IEnumerator _startAnalysis(Action <float> progressCallback = null)
    {
        yield return(null);

        //Console.WriteLine("Starting analysis.");
        finished = false;
        moves    = _board.findStrictLegalMoves(moveAsWhite);
        if (moves.Count > 1)
        {
            movesLeftToAnalyze  = moves.Count;
            totalMovesToAnalyze = moves.Count;
            int alpha = int.MinValue;
            int beta  = int.MaxValue;
            for (int i = 0; i < moves.Count; i++)
            {
                cgSimpleMove possibleMove = moves[i];
                byte         depth        = (cgValueModifiers.AlphaBeta_Strong_Delineation < possibleMove.positionalVal ? searchDepthStrong : searchDepthWeak);
                if (moves.Count < 10)
                {
                    depth = searchDepthEndGame;
                }
                //determining whether move looks weak or strong based on positional value, if its strong we use strong depth otherwise we use weak depth.
                possibleMove.val = _alfaBeta(possibleMove, depth, alpha, beta, !moveAsWhite);
                movesLeftToAnalyze--;
                yield return(null);

                if (progressCallback != null)
                {
                    float progress = (float)((float)totalMovesToAnalyze - (float)movesLeftToAnalyze) / (float)totalMovesToAnalyze;
                    progressCallback(progress);
                }
                //UnityEngine.Debug.Log("Moves left: " + MovesLeftToAnalyze + " total: " + TotalMovesToAnalyze);
            }
            _sortMovesOnBoardValue(moves, moveAsWhite);
        }

        yield return(null);

        _analysisComplete();
    }
示例#24
0
 /// <summary>
 /// The engine returns with its prefered move.
 /// </summary>
 /// <param name="move">The prefered move.</param>
 private void _engineCallback(cgSimpleMove move)
 {
     //Debug.Log("move:" + move.from.name + " to:" + move.to.name);
     if (!playerCanMove)
     {
         if (_abstractBoard.verifyLegality(move))
         {
             _makeMove(move);
         }
         else
         {
             _engine.Moves.Remove(move);
             if (_engine.Moves.Count > 0)
             {
                 _engineCallback(_engine.Moves[0]);
             }
             else
             {
                 _checkGameOver();
             }
         }
     }
 }
示例#25
0
    /// <summary>
    /// Called when the analysis starts.
    /// </summary>
    /// <returns></returns>
    IEnumerator _startAnalysis()
    {
        yield return(null);

        Finished = false;
        Moves    = _board.findStrictLegalMoves(MoveAsWhite);
        if (Moves.Count > 1)
        {
            MovesLeftToAnalyze  = Moves.Count;
            TotalMovesToAnalyze = Moves.Count;
            if (LoadBar != null)
            {
                LoadBar.transform.localScale = new Vector3(0, LoadBar.transform.localScale.y, 1);
            }
            int alpha = int.MinValue;
            int beta  = int.MaxValue;
            for (int i = 0; i < Moves.Count; i++)
            {
                cgSimpleMove possibleMove = Moves[i];
                byte         depth        = (cgValueModifiers.AlphaBeta_Strong_Delineation < possibleMove.positionalVal ? SearchDepthStrong : SearchDepthWeak);
                if (Moves.Count < 10)
                {
                    depth = SearchDepthEndGame;
                }
                //determining whether move looks weak or strong based on positional value, if its strong we use strong depth otherwise we use weak depth.
                possibleMove.val = _alfaBeta(possibleMove, depth, alpha, beta, !MoveAsWhite);
                MovesLeftToAnalyze--;
                yield return(null);
            }
            _sortMovesOnBoardValue(Moves, MoveAsWhite);
        }

        yield return(null);

        _analysisComplete();
    }
    // Update is called once per frame
    void Update()
    {
        lock (_engineCallbackParams) {
            if (_engineCallbackParams.Count > 0)
            {
                UnityEngine.Debug.Log(": " + _engineCallbackFunctions);
                _engineCallbackFunctions[0](_engineCallbackParams[0]);
                _engineCallbackParams.RemoveAt(0);
                _engineCallbackFunctions.RemoveAt(0);
                //threadListener.Stop();
            }
        }
        lock (_engineProgress) {
            if (_engineProgress.Count > 0 && engineProgressBar != null)
            {
                float progress = _engineProgress[0];
                _engineProgress.RemoveAt(0);
                Vector3 nscale = engineProgressBar.transform.localScale;
                nscale.x = progress;
                engineProgressBar.transform.localScale = nscale;
            }
        }
        foreach (cgChessPieceScript cp in _livePieces)
        {
            if (cp.dead && !_deadPieces.Contains(cp))
            {
                _setDeadPiece(cp);
            }
        }

        for (int i = _deadPieces.Count; i > 0; i--)
        {
            if (_livePieces.Contains(_deadPieces[i - 1]))
            {
                _livePieces.Remove(_deadPieces[i - 1]);
            }
        }
        if (_downPiece != null)
        {
            Vector3    cursorPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, Input.mousePosition.z);
            Ray        cursorRay   = Camera.main.ScreenPointToRay(cursorPoint);
            RaycastHit hit;
            if (Physics.Raycast(cursorRay, out hit, 100.0f))
            {
                _downPiece.transform.position = hit.point;
            }
        }

        if (Input.GetKey(KeyCode.C) && Input.GetKeyDown(KeyCode.LeftControl))
        {
            _copyGameToClipboard();
        }
        else if (Input.GetKey(KeyCode.LeftControl) && Input.GetKeyDown(KeyCode.C))
        {
            _copyGameToClipboard();
        }


        if (Input.GetKey(KeyCode.V) && Input.GetKeyDown(KeyCode.LeftControl))
        {
            _pasteGameFromClipboard();
        }
        else if (Input.GetKey(KeyCode.LeftControl) && Input.GetKeyDown(KeyCode.V))
        {
            _pasteGameFromClipboard();
        }

        if (Input.GetKey(KeyCode.F1))
        {
            UnityEngine.Debug.Break();
        }
        if (Input.GetKey(KeyCode.A))
        {
            //_abstractBoard.boardToString()
            UnityEngine.Debug.Log(_abstractBoard.boardToString());
            //UnityEngine.Debug.Log(_abstractBoard._blackKingStart);
        }
        if (Input.GetKey(KeyCode.U))
        {
            _abstractBoard.revert();
            UnityEngine.Debug.Log(_abstractBoard.boardToString());
        }
        if (Input.GetKey(KeyCode.V))  //Perform long castling move.
        {
            List <cgSimpleMove> moves = _abstractBoard.findStrictLegalMoves(_abstractBoard.whiteTurnToMove);
            cgSimpleMove        move  = null;
            foreach (cgSimpleMove mv in moves)
            {
                if (mv is cgCastlingMove)
                {
                    if (move == null)
                    {
                        move = mv;
                    }
                    else if (Math.Abs(move.to - move.from) < Math.Abs(mv.to - mv.to))
                    {
                        move = mv;
                    }
                }
            }
            _makeMove(move);
        }
    }
示例#27
0
 /// <summary>
 /// Add a move to the list of moves.
 /// </summary>
 /// <param name="move"></param>
 public void AddMove(cgSimpleMove move)
 {
     moves.Add(move);
 }
示例#28
0
    /// <summary>
    /// Perform the provided move, capturing if necessary.
    /// </summary>
    /// <param name="move">The move to perform.</param>
    public void move(cgSimpleMove move)
    {
        moves.Add(move);
        moveCount++;
        if (move.to == 65)
        {
            return;
        }
        move.capturedType  = squares[move.to];
        squares[move.to]   = squares[move.from];
        squares[move.from] = 0;
        //_enPassantSquare = 0;
        //Pawn auto-promote to queen
//         if (move.to < 8 && squares[move.to] == 1)
//         {
//             move.promoted = true;
//
//             squares[move.to] = (sbyte)move.promotionType;
//         }
//         else if (move.to > 55 && squares[move.to] == -1)
//         {
//             move.promoted = true;
//             squares[move.to] = (sbyte)move.promotionType;
//         }

        if (move.promoted)
        {
            bool isWhite = (squares[move.to] == 1);
            switch (move.promotionType)
            {
            case 2:
                squares[move.to] = (sbyte)(isWhite ? 2 : -2);
                break;

            case 3:
                squares[move.to] = (sbyte)(isWhite ? 3 : -3);
                break;

            case 4:
                squares[move.to] = (sbyte)(isWhite ? 4 : -4);
                break;

            case 5:
                squares[move.to] = (sbyte)(isWhite ? 5 : -5);
                break;
            }
        }

        if (move is cgCastlingMove)
        {
            //if move is castling there is a secondary move to also perform.
            squares[(move as cgCastlingMove).secondTo]   = squares[(move as cgCastlingMove).secondFrom];
            squares[(move as cgCastlingMove).secondFrom] = 0;
            if (_whiteTurnToMove)
            {
                whiteHasCastled = true;
            }
            else
            {
                blackHasCastled = true;
            }
        }
        else if (move is cgEnPassantMove)
        {
            move.capturedType = squares[(move as cgEnPassantMove).attackingSquare];
            squares[(move as cgEnPassantMove).attackingSquare] = 0;
        }
        if (squares[move.to] == -2 && move.from == 0)
        {
            _blackARookMoves++;
        }
        else if (squares[move.to] == -2 && move.from == 7)
        {
            _blackHRookMoves++;
        }
        else if (squares[move.to] == 2 && move.from == 56)
        {
            _whiteARookMoves++;
        }
        else if (squares[move.to] == 2 && move.from == 63)
        {
            _whiteHRookMoves++;
        }
        //if(squares[move.to]==1)
        if (squares[move.to] == 6)
        {
            _whiteKingMoves++;
        }
        else if (squares[move.to] == -6)
        {
            _blackKingMoves++;
        }

        _whiteTurnToMove = !_whiteTurnToMove;
    }
示例#29
0
    public static string NotationFromMove(cgBoard _board, cgSimpleMove _move)
    {
        string str = "";

        if (_board.moves.Count % 2 == 0)
        {
            str += (Math.Floor(_board.moves.Count / 2f) + 1).ToString() + ". ";
        }

        int typ = Mathf.Abs(_board.squares[_move.from]);
        List <cgSimpleMove> othermoves     = _board.findLegalMoves(_board.whiteTurnToMove);
        List <cgSimpleMove> ambiguousMoves = new List <cgSimpleMove>();

        foreach (cgSimpleMove othermove in othermoves)
        {
            if (othermove.to == _move.to && othermove.from != _move.from && Mathf.Abs(_board.squares[othermove.from]) == typ)
            {
                ambiguousMoves.Add(othermove);
            }
        }
        if (typ == 1 && _move.capturedType != 0)
        {
            str += cgGlobal.SquareNames[_move.from].Substring(0, 1);
        }
        if (typ == 2)
        {
            str += "R";
        }
        if (typ == 3)
        {
            str += "N";
        }
        if (typ == 4)
        {
            str += "B";
        }
        if (typ == 5)
        {
            str += "Q";
        }
        if (typ == 6 && !(_move is cgCastlingMove))
        {
            str += "K";
        }
        //if (typ == 6) str += "K";

        if (ambiguousMoves.Count > 0 && typ != 1)
        {
            bool fileMatch = false;
            bool rankMatch = false;
            foreach (cgSimpleMove ambiguousMove in ambiguousMoves)
            {
                if (cgGlobal.SquareNames[ambiguousMove.from].Substring(0, 1) == cgGlobal.SquareNames[_move.from].Substring(0, 1))
                {
                    fileMatch = true;
                }
                if (cgGlobal.SquareNames[ambiguousMove.from].Substring(1, 1) == cgGlobal.SquareNames[_move.from].Substring(1, 1))
                {
                    rankMatch = true;
                }
            }
            if (!fileMatch)
            {
                str += cgGlobal.SquareNames[_move.from].Substring(0, 1);
            }
            else if (fileMatch && !rankMatch)
            {
                str += cgGlobal.SquareNames[_move.from].Substring(1, 1);
            }
            else if (fileMatch && rankMatch)
            {
                str += cgGlobal.SquareNames[_move.from];
            }
        }
        if (_move.capturedType != 0)
        {
            str += "x";
        }
        if (_move is cgCastlingMove)
        {
            if (_move.to == 2 || _move.to == 58)
            {
                str += "O-O-O";
            }
            else
            {
                str += "O-O";
            }
        }
        else
        {
            str += cgGlobal.SquareNames[_move.to];
        }
        if (_move.promoted)
        {
            switch (_move.promotionType)
            {
            case 2:
                str += "=R";
                break;

            case 3:
                str += "=N";
                break;

            case 4:
                str += "=B";
                break;

            case 5:
                str += "=Q";
                break;

            default:
                break;
            }
        }

        return(str);
    }
示例#30
0
    /// <summary>
    /// Perform the provided move, capturing if necessary.
    /// </summary>
    /// <param name="move">The move to perform.</param>
    public void move(cgSimpleMove move)
    {
        moves.Add(move);
        moveCount++;
        if (move.to == 65)
        {
            return;
        }
        move.capturedType  = squares[move.to];
        squares[move.to]   = squares[move.from];
        squares[move.from] = 0;
        //_enPassantSquare = 0;
        //Pawn auto-promote to queen
        if (move.to < 8 && squares[move.to] == 1)
        {
            move.queened     = true;
            squares[move.to] = 5;
        }
        else if (move.to > 55 && squares[move.to] == -1)
        {
            move.queened     = true;
            squares[move.to] = -5;
        }
        if (move is cgCastlingMove)
        {
            //if move is castling there is a secondary move to also perform.
            squares[(move as cgCastlingMove).secondTo]   = squares[(move as cgCastlingMove).secondFrom];
            squares[(move as cgCastlingMove).secondFrom] = 0;
            if (_whiteTurnToMove)
            {
                whiteHasCastled = true;
            }
            else
            {
                blackHasCastled = true;
            }
        }
        else if (move is cgEnPassantMove)
        {
            move.capturedType = squares[(move as cgEnPassantMove).attackingSquare];
            squares[(move as cgEnPassantMove).attackingSquare] = 0;
        }
        if (squares[move.to] == -2 && move.from == 0)
        {
            _blackARookMoves++;
        }
        else if (squares[move.to] == -2 && move.from == 7)
        {
            _blackHRookMoves++;
        }
        else if (squares[move.to] == 2 && move.from == 56)
        {
            _whiteARookMoves++;
        }
        else if (squares[move.to] == 2 && move.from == 63)
        {
            _whiteHRookMoves++;
        }
        //if(squares[move.to]==1)
        if (squares[move.to] == 6)
        {
            _whiteKingMoves++;
        }
        else if (squares[move.to] == -6)
        {
            _blackKingMoves++;
        }

        _whiteTurnToMove = !_whiteTurnToMove;
    }