示例#1
0
    // returns the position score for the specified color
    public static int GetPositionScore(int player)
    {
        // initialize variables
        int  white_position = 0, black_position = 0, net_position = 0;
        uint white_king_sq = MoveGen.GetNextSquare(AI.board.white_king);
        uint black_king_sq = MoveGen.GetNextSquare(AI.board.black_king);

        // loop through game AI.board squares and calculate position/distance scores for each piece
        for (int i = 0; i < 64; i++)
        {
            if (AI.board.theBoard[i] == ChessBoard.EMPTY)
            {
                continue;                                     // square is empty
            }
            if (ChessBoard.GetPieceColor(AI.board.theBoard[i]) == ChessBoard.WHITE)
            {
                switch (AI.board.theBoard[i])
                {
                case ChessBoard.W_PAWN:
                    white_position += PAWN_POSITION[i];
                    white_position += PAWN_OPPONENT_DISTANCE[Math.Min(Math.Abs((int)ChessMove.GetFile((uint)i) - (int)ChessMove.GetFile(black_king_sq)),
                                                                      Math.Abs((int)ChessMove.GetRank((uint)i) - (int)ChessMove.GetRank(black_king_sq)))];
                    white_position += PAWN_OWN_DISTANCE[Math.Min(Math.Abs((int)ChessMove.GetFile((uint)i) - (int)ChessMove.GetFile(white_king_sq)),
                                                                 Math.Abs((int)ChessMove.GetRank((uint)i) - (int)ChessMove.GetRank(white_king_sq)))];
                    break;

                case ChessBoard.W_ROOK:
                    white_position += ROOK_POSITION[i];
                    white_position += ROOK_DISTANCE[Math.Min(Math.Abs((int)ChessMove.GetFile((uint)i) - (int)ChessMove.GetFile(black_king_sq)),
                                                             Math.Abs((int)ChessMove.GetRank((uint)i) - (int)ChessMove.GetRank(black_king_sq)))];
                    break;

                case ChessBoard.W_KNIGHT:
                    white_position += KNIGHT_POSITION[i];
                    white_position += KNIGHT_DISTANCE[Math.Min(Math.Abs((int)ChessMove.GetFile((uint)i) - (int)ChessMove.GetFile(black_king_sq)),
                                                               Math.Abs((int)ChessMove.GetRank((uint)i) - (int)ChessMove.GetRank(black_king_sq)))];
                    break;

                case ChessBoard.W_BISHOP:
                    white_position += BISHOP_POSITION[i];
                    white_position += BISHOP_DISTANCE[Math.Min(Math.Abs((int)ChessMove.GetFile((uint)i) - (int)ChessMove.GetFile(black_king_sq)),
                                                               Math.Abs((int)ChessMove.GetRank((uint)i) - (int)ChessMove.GetRank(black_king_sq)))];
                    break;

                case ChessBoard.W_QUEEN:
                    white_position += QUEEN_POSITION[i];
                    white_position += QUEEN_DISTANCE[Math.Min(Math.Abs((int)ChessMove.GetFile((uint)i) - (int)ChessMove.GetFile(black_king_sq)),
                                                              Math.Abs((int)ChessMove.GetRank((uint)i) - (int)ChessMove.GetRank(black_king_sq)))];
                    break;

                case ChessBoard.W_KING:
                    if (IsEndGame(GetMaterialScore(ChessBoard.WHITE), GetMaterialScore(ChessBoard.BLACK)))
                    {
                        white_position += KING_ENDGAME_POSITION[i];
                    }
                    else
                    {
                        white_position += KING_POSITION[i];
                    }
                    break;
                }
            }
            else if (ChessBoard.GetPieceColor(AI.board.theBoard[i]) == ChessBoard.BLACK)
            {
                switch (AI.board.theBoard[i])
                {
                case ChessBoard.B_PAWN:
                    black_position += PAWN_POSITION[MIRROR[i]];
                    black_position += PAWN_OPPONENT_DISTANCE[Math.Min(Math.Abs((int)ChessMove.GetFile((uint)i) - (int)ChessMove.GetFile(white_king_sq)),
                                                                      Math.Abs((int)ChessMove.GetRank((uint)i) - (int)ChessMove.GetRank(white_king_sq)))];
                    black_position += PAWN_OWN_DISTANCE[Math.Min(Math.Abs((int)ChessMove.GetFile((uint)i) - (int)ChessMove.GetFile(black_king_sq)),
                                                                 Math.Abs((int)ChessMove.GetRank((uint)i) - (int)ChessMove.GetRank(black_king_sq)))];
                    break;

                case ChessBoard.B_ROOK:
                    black_position += ROOK_POSITION[MIRROR[i]];
                    black_position += ROOK_DISTANCE[Math.Min(Math.Abs((int)ChessMove.GetFile((uint)i) - (int)ChessMove.GetFile(white_king_sq)),
                                                             Math.Abs((int)ChessMove.GetRank((uint)i) - (int)ChessMove.GetRank(white_king_sq)))];
                    break;

                case ChessBoard.B_KNIGHT:
                    black_position += KNIGHT_POSITION[MIRROR[i]];
                    black_position += KNIGHT_DISTANCE[Math.Min(Math.Abs((int)ChessMove.GetFile((uint)i) - (int)ChessMove.GetFile(white_king_sq)),
                                                               Math.Abs((int)ChessMove.GetRank((uint)i) - (int)ChessMove.GetRank(white_king_sq)))];
                    break;

                case ChessBoard.B_BISHOP:
                    black_position += BISHOP_POSITION[MIRROR[i]];
                    black_position += BISHOP_DISTANCE[Math.Min(Math.Abs((int)ChessMove.GetFile((uint)i) - (int)ChessMove.GetFile(white_king_sq)),
                                                               Math.Abs((int)ChessMove.GetRank((uint)i) - (int)ChessMove.GetRank(white_king_sq)))];
                    break;

                case ChessBoard.B_QUEEN:
                    black_position += QUEEN_POSITION[MIRROR[i]];
                    black_position += QUEEN_DISTANCE[Math.Min(Math.Abs((int)ChessMove.GetFile((uint)i) - (int)ChessMove.GetFile(white_king_sq)),
                                                              Math.Abs((int)ChessMove.GetRank((uint)i) - (int)ChessMove.GetRank(white_king_sq)))];
                    break;

                case ChessBoard.B_KING:
                    if (IsEndGame(GetMaterialScore(ChessBoard.WHITE), GetMaterialScore(ChessBoard.BLACK)))
                    {
                        black_position += KING_ENDGAME_POSITION[MIRROR[i]];
                    }
                    else
                    {
                        black_position += KING_POSITION[MIRROR[i]];
                    }
                    break;
                }
            }
        }

        // calculate net position score
        if (player == ChessBoard.WHITE)
        {
            net_position += white_position - black_position;
        }
        else if (player == ChessBoard.BLACK)
        {
            net_position += black_position - white_position;
        }

        // return position score
        return(net_position);
    }
示例#2
0
    // initializes non-constant scoring arrays
    public static void InitializeScoringArrays()
    {
        // initialize scoring arrays and set values to 0
        W_PASSED_PAWN       = new UInt64[64];
        B_PASSED_PAWN       = new UInt64[64];
        W_ISOLATED_PAWN     = new UInt64[64];
        B_ISOLATED_PAWN     = new UInt64[64];
        W_BACKWARD_PAWN     = new UInt64[64];
        B_BACKWARD_PAWN     = new UInt64[64];
        W_KINGSAFETY_STRONG = new UInt64[64];
        B_KINGSAFETY_STRONG = new UInt64[64];
        W_KINGSAFETY_WEAK   = new UInt64[64];
        B_KINGSAFETY_WEAK   = new UInt64[64];
        for (int i = 0; i < 64; i++)
        {
            W_PASSED_PAWN[i]       = 0;
            B_PASSED_PAWN[i]       = 0;
            W_ISOLATED_PAWN[i]     = 0;
            B_ISOLATED_PAWN[i]     = 0;
            W_BACKWARD_PAWN[i]     = 0;
            B_BACKWARD_PAWN[i]     = 0;
            W_KINGSAFETY_STRONG[i] = 0;
            B_KINGSAFETY_STRONG[i] = 0;
            W_KINGSAFETY_WEAK[i]   = 0;
            B_KINGSAFETY_WEAK[i]   = 0;
        }

        // set values for pawn structure position arrays
        for (int i = 0; i < 64; i++)
        {
            // set values for passed pawn position arrays
            for (int rank = (int)ChessMove.GetRank((uint)i) + 1; rank < 8; rank++)
            {
                // white passed pawns
                if (ChessMove.GetFile((uint)i) > 0)
                {
                    W_PASSED_PAWN[i] ^= ChessBoard.SQUARES[((rank - 1) * 8) + (int)ChessMove.GetFile((uint)i)];
                }
                W_PASSED_PAWN[i] ^= ChessBoard.SQUARES[((rank - 1) * 8) + (int)ChessMove.GetFile((uint)i)];
                if (ChessMove.GetFile((uint)i) < 7)
                {
                    W_PASSED_PAWN[i] ^= ChessBoard.SQUARES[((rank - 1) * 8) + (int)ChessMove.GetFile((uint)i)];
                }
            }

            // set values for isolated pawn position arrays
            for (int rank = 2; rank < 8; rank++)
            {
                // white isolated pawns
                if (ChessMove.GetFile((uint)i) > 0)
                {
                    W_ISOLATED_PAWN[i] ^= ChessBoard.SQUARES[((rank - 1) * 8) + (int)ChessMove.GetFile((uint)i)];
                }
                if (ChessMove.GetFile((uint)i) < 7)
                {
                    W_ISOLATED_PAWN[i] ^= ChessBoard.SQUARES[((rank - 1) * 8) + (int)ChessMove.GetFile((uint)i)];
                }
            }

            // set values for backward pawn position array
            for (int rank = 2; rank <= (int)ChessMove.GetRank((uint)i) + 1; rank++)
            {
                // white backward pawns
                if (ChessMove.GetFile((uint)i) > 0)
                {
                    W_BACKWARD_PAWN[i] ^= ChessBoard.SQUARES[((rank - 1) * 8) + (int)ChessMove.GetFile((uint)i)];
                }
                if (ChessMove.GetFile((uint)i) < 7)
                {
                    W_BACKWARD_PAWN[i] ^= ChessBoard.SQUARES[((rank - 1) * 8) + (int)ChessMove.GetFile((uint)i)];
                }
            }
        }

        // set values for king safety position arrays
        for (int i = 0; i < 24; i++)
        {
            // white king safety strong/weak
            W_KINGSAFETY_STRONG[i] ^= ChessBoard.SQUARES[i + 8];
            W_KINGSAFETY_WEAK[i]   ^= ChessBoard.SQUARES[i + 16];
            if (ChessMove.GetFile((uint)i) > 0)
            {
                W_KINGSAFETY_STRONG[i] ^= ChessBoard.SQUARES[i + 7];
                W_KINGSAFETY_WEAK[i]   ^= ChessBoard.SQUARES[i + 15];
            }
            if (ChessMove.GetFile((uint)i) < 7)
            {
                W_KINGSAFETY_STRONG[i] ^= ChessBoard.SQUARES[i + 9];
                W_KINGSAFETY_WEAK[i]   ^= ChessBoard.SQUARES[i + 17];
            }
            if (ChessMove.GetFile((uint)i) == 0)
            {
                W_KINGSAFETY_STRONG[i] ^= ChessBoard.SQUARES[i + 10];
                W_KINGSAFETY_WEAK[i]   ^= ChessBoard.SQUARES[i + 18];
            }
            if (ChessMove.GetFile((uint)i) == 7)
            {
                W_KINGSAFETY_STRONG[i] ^= ChessBoard.SQUARES[i + 6];
                W_KINGSAFETY_WEAK[i]   ^= ChessBoard.SQUARES[i + 14];
            }
        }

        // set values for black position arrays
        for (int i = 0; i < 64; i++)
        {
            for (int square = 0; square < 64; square++)
            {
                // black passed pawns (mirror of white passed pawns)
                if ((W_PASSED_PAWN[i] & ChessBoard.SQUARES[square]) != 0)
                {
                    B_PASSED_PAWN[MIRROR[i]] |= ChessBoard.SQUARES[MIRROR[square]];
                }

                // black isolated pawns (mirror of white isolated pawns)
                if ((W_ISOLATED_PAWN[i] & ChessBoard.SQUARES[square]) != 0)
                {
                    B_ISOLATED_PAWN[MIRROR[i]] |= ChessBoard.SQUARES[MIRROR[square]];
                }

                // black backward pawns (mirror of white backward pawns)
                if ((W_BACKWARD_PAWN[i] & ChessBoard.SQUARES[square]) != 0)
                {
                    B_BACKWARD_PAWN[MIRROR[i]] |= ChessBoard.SQUARES[MIRROR[square]];
                }

                // black king safety strong (mirror of white king safety strong)
                if ((W_KINGSAFETY_STRONG[i] & ChessBoard.SQUARES[square]) != 0)
                {
                    B_KINGSAFETY_STRONG[MIRROR[i]] |= ChessBoard.SQUARES[MIRROR[square]];
                }

                // black king safety weak (mirror of white king safety weak)
                if ((W_KINGSAFETY_WEAK[i] & ChessBoard.SQUARES[square]) != 0)
                {
                    B_KINGSAFETY_WEAK[MIRROR[i]] |= ChessBoard.SQUARES[MIRROR[square]];
                }
            }
        }
    }
示例#3
0
文件: AI.CS 项目: mhs294/Csharp
    //This function is called each time it is your turn
    //Return true to end your turn, return false to ask the server for updated information
    public override bool run()
    {
        // Print out the current board state
        Console.WriteLine("+---+---+---+---+---+---+---+---+");
        for (int rank = 8; rank > 0; rank--)
        {
            Console.Write("|");
            for (int file = 1; file <= 8; file++)
            {
                bool found = false;
                // Loops through all of the pieces
                for (int p = 0; !found && p < pieces.Length; p++)
                {
                    // determines if that piece is at the current rank and file
                    if (pieces[p].getRank() == rank && pieces[p].getFile() == file)
                    {
                        found = true;
                        // Checks if the piece is black
                        if (pieces[p].getOwner() == 1)
                        {
                            Console.Write("*");
                        }
                        else
                        {
                            Console.Write(" ");
                        }
                        // prints the piece's type
                        Console.Write((char)pieces[p].getType() + " ");
                    }
                }
                if (!found)
                {
                    Console.Write("   ");
                }
                Console.Write("|");
            }
            Console.WriteLine("\n+---+---+---+---+---+---+---+---+");
        }

        // Looks through information about the players
        for (int p = 0; p < players.Length; p++)
        {
            Console.Write(players[p].getPlayerName());
            // if playerID is 0, you're white, if its 1, you're black
            if (players[p].getId() == myID)
            {
                Console.Write(" (ME)");

                // update timeRemaining
                timeRemaining = players[p].getTime();
            }
            Console.WriteLine(" time remaining: " + players[p].getTime());
        }

        // if there has been a move, print the most recent move
        if (moves.Length > 0)
        {
            Console.Write("Last Move Was: ");
            Console.WriteLine(files[moves[0].getFromFile() - 1] + "" + moves[0].getFromRank() + "-" + files[moves[0].getToFile() - 1] + "" + moves[0].getToRank());
        }

        /////////////////////////////////////
        // <-- END OF STOCK AI.cs CODE --> //
        /////////////////////////////////////

        // print current move number
        Console.WriteLine("\nMove " + turnNumber().ToString("D3") + "\n========\n");

        // add to GameState List and update ChessBoard
        if (moves.Length <= 1)
        {
            board = new ChessBoard(ref pieces, myID);
            states.Add(new GameState(null, null));
        }
        else
        {
            ChessMove lastMove = ChessMove.GetChessMove(moves[0].getFromFile(), moves[0].getToFile(), moves[0].getFromRank(), moves[0].getToRank(),
                                                        moves[0].getPromoteType(), states[states.Count - 1].enPassant);
            board = new ChessBoard(ref pieces, myID);
            states.Add(new GameState(states[states.Count - 1], lastMove));
        }

        // display current score information for player
        Console.Write("Score for ");
        if (myID == ChessBoard.WHITE)
        {
            Console.WriteLine("WHITE:\n");
        }
        else if (myID == ChessBoard.BLACK)
        {
            Console.WriteLine("BLACK:\n");
        }
        int material = Score.GetMaterialScore(myID);
        int position = Score.GetPositionScore(myID);
        // int mobility = Score.GetPositionScore(myID);
        int pawn_structure = Score.GetPawnStructureScore(myID);
        int king_safety    = Score.GetKingSafetyScore(myID);

        Console.WriteLine("Net Material = " + material);
        Console.WriteLine("Net Position = " + position);
        //Console.WriteLine("Net Mobility = " + mobility);
        Console.WriteLine("Net Pawn Structure = " + pawn_structure);
        Console.WriteLine("Net King Safety = " + king_safety + "\n");
        Console.WriteLine("Overall Score = " + (material + position + /*mobility +*/ pawn_structure + king_safety) + "\n");

        // if playing as human, get move from console prompt
        while (HUMAN_PLAYER)
        {
            // get legal moves for this position
            List <ChessMove> legalMoves = MoveGen.GenerateMoves(myID, false);

            // prompt user for move
            Console.Write("Enter a move ([from] [to] <promotion type>): ");
            string[] humanMove = Console.ReadLine().Split(' ');

            // get origin square
            int humanFromFile = 0, humanFromRank = 0;
            for (int i = 0; i < 8; i++)
            {
                if (humanMove[0][0] == files[i])
                {
                    humanFromFile = i + 1;
                    break;
                }
            }
            humanFromRank = (int)Char.GetNumericValue(humanMove[0][1]);

            // get destination square
            int humanToFile = 0, humanToRank = 0;
            for (int i = 0; i < 8; i++)
            {
                if (humanMove[1][0] == files[i])
                {
                    humanToFile = i + 1;
                    break;
                }
            }
            humanToRank = (int)Char.GetNumericValue(humanMove[1][1]);

            // if promotion type is specified, get the promotion piece from move
            int humanPromote = 0;
            if (humanMove.Length > 2)
            {
                humanPromote = (int)humanMove[2][0];
            }

            // check for legality of human move
            bool isLegal = false;
            for (int i = 0; i < legalMoves.Count; i++)
            {
                ChessMove m = legalMoves[i];
                if ((ChessMove.GetFile(m.GetFromSq()) + 1) == (uint)humanFromFile &&
                    (ChessMove.GetRank(m.GetFromSq()) + 1) == (uint)humanFromRank &&
                    (ChessMove.GetFile(m.GetToSq()) + 1) == (uint)humanToFile &&
                    (ChessMove.GetRank(m.GetToSq()) + 1) == (uint)humanToRank)
                {
                    isLegal = true;
                    break;
                }
            }

            // if move is legal, make move
            if (isLegal)
            {
                // get Piece associated with move
                Piece humanPiece = pieces[FindPiece(humanFromFile, humanFromRank)];

                // make move
                humanPiece.move(humanToFile, humanToRank, humanPromote);
                return(true);
            }
            else if (!isLegal)
            {
                Console.WriteLine("ILLEGAL MOVE. Please input a legal move.\n");
            }
        }

        // reset TIME_EXPIRED and timer
        TIME_EXPIRED = false;
        timer.Reset();

        // reset history table
        history = new HistoryTable();

        // run ABMiniMax
        int  moveScore = 0, n = 0, toFile = -1, toRank = -1;
        uint fromSq = 0, toSq = 0, thePiece = 0;

        depth = 0;
        List <ChessMove> completeBestMoves = new List <ChessMove>(0);

        Search.UpdateTimePerMove(moves.Length);
        timer.Start();
        while (!TIME_EXPIRED)
        {
            depth                  += 1;
            nodes                   = 0;
            Search.MAX_DEPTH        = depth;
            Search.NULLMOVE_ALLOWED = true;
            Search.FOLLOW_PV        = true;
            Search.PV               = new List <ChessMove>(0);
            int score = Search.PVABMiniMax(0, Search.SMALL_NUM, Search.LARGE_NUM);
            if (score != Score.TIME_EXPIRED_SCORE)
            {
                moveScore         = score;
                completeBestMoves = new List <ChessMove>(Search.PV);
            }

            // select random move from bestMoves List
            if (completeBestMoves.Count > 0)
            {
                n = generator.Next(0, completeBestMoves.Count - 1);

                // get bestMove info
                fromSq   = completeBestMoves[n].GetFromSq();
                thePiece = completeBestMoves[n].GetPiece();
                toSq     = completeBestMoves[n].GetToSq();
                toFile   = (int)((toSq % 8) + 1);
                toRank   = (int)((toSq / 8) + 1);

                // print bestMove info
                Console.WriteLine("Best Move: " + completeBestMoves[n].GetMoveString() + ", Score: " + moveScore + ", Depth: " + depth + " (t = " +
                                  (timer.ElapsedMilliseconds / 1000.0).ToString("F3") + "s, nodes = " + nodes + ")");
            }

            // if checkmate is found, stop searching
            if (score == Score.CHECKMATE_WIN_SCORE)
            {
                break;
            }
        }
        timer.Stop();

        // output number of best moves
        Console.WriteLine("completeBestMoves = " + completeBestMoves.Count);

        // make bestMove
        pieces[FindPiece(fromSq, thePiece)].move(toFile, toRank, completeBestMoves[n].GetPromoteType());

        // update ChessBoard and GameState List
        completeBestMoves[n].DoMove(Search.MAKE);

        return(true);
    }