⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jcboardevaluator.java

📁 这是自己在学习编写下象棋时参考过的很好的程序。
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/************************************************************************* * jcBoardEvaluator - Analyzes and evaluates a chess board position * by F.D. Laramee * * History * 07.08.00 Creation * *********************************************************************/package javachess;import javachess.jcBoard;public class jcBoardEvaluator{  /**********************************************************************   * DATA MEMBERS   **********************************************************************/  // Data counters to evaluate pawn structure  int MaxPawnFileBins[];  int MaxPawnColorBins[];  int MaxTotalPawns;  int PawnRams;  int MaxMostAdvanced[];  int MaxPassedPawns[];  int MinPawnFileBins[];  int MinMostBackward[];  // The "graininess" of the evaluation.  MTD(f) works a lot faster if the  // evaluation is relatively coarse  private static final int Grain = 3;  /**********************************************************************   * PUBLIC METHODS   *********************************************************************/  // Construction  public jcBoardEvaluator()  {    MaxPawnFileBins = new int[ 8 ];    MaxPawnColorBins = new int[ 2 ];    MaxMostAdvanced = new int[ 8 ];    MaxPassedPawns = new int[ 8 ];    MinPawnFileBins = new int[ 8 ];    MinMostBackward = new int[ 8 ];  }  // int EvaluateQuickie( jcBoard theBoard, int FromWhosePerspective )  // A simple, fast evaluation based exclusively on material.  Since material  // is overwhelmingly more important than anything else, we assume that if a  // position's material value is much lower (or much higher) than another,  // then there is no need to waste time on positional factors because they  // won't be enough to tip the scales the other way, so to speak.  public int EvaluateQuickie( jcBoard theBoard, int fromWhosePerspective )  {    return ( ( theBoard.EvalMaterial( fromWhosePerspective ) >> Grain ) << Grain );  }  // int EvaluateComplete( jcBoard theBoard )  // A detailed evaluation function, taking into account several positional  // factors  public int EvaluateComplete( jcBoard theBoard, int fromWhosePerspective )  {    AnalyzePawnStructure( theBoard, fromWhosePerspective );    return(((theBoard.EvalMaterial( fromWhosePerspective ) +             EvalPawnStructure( fromWhosePerspective ) +             EvalBadBishops( theBoard, fromWhosePerspective ) +             EvalDevelopment( theBoard, fromWhosePerspective ) +             EvalRookBonus( theBoard, fromWhosePerspective ) +             EvalKingTropism( theBoard, fromWhosePerspective ) ) >> Grain ) << Grain );  }  /***************************************************************************   * PRIVATE METHODS   **************************************************************************/  // private EvalKingTropism  // All other things being equal, having your Knights, Queens and Rooks close  // to the opponent's king is a good thing  // This method is a bit slow and dirty, but it gets the job done  private int EvalKingTropism( jcBoard theBoard, int fromWhosePerspective )  {    int score = 0;    // Square coordinates    int kingRank = 0, kingFile = 0;    int pieceRank = 0, pieceFile = 0;    if ( fromWhosePerspective == jcPlayer.SIDE_WHITE )    {      // Look for enemy king first!      for( int i = 0; i < 64; i++ )      {        if ( theBoard.FindBlackPiece( i ) == jcBoard.BLACK_KING )        {          kingRank = i >> 8;          kingFile = i % 8;          break;        }      }      // Now, look for pieces which need to be evaluated      for( int i = 0; i < 64; i++ )      {        pieceRank = i >> 8;        pieceFile = i % 8;        switch( theBoard.FindWhitePiece( i ) )        {          case jcBoard.WHITE_ROOK:            score -= ( Math.min( Math.abs( kingRank - pieceRank ),                                 Math.abs( kingFile - pieceFile ) ) << 1 );            break;          case jcBoard.WHITE_KNIGHT:            score += 5 - Math.abs( kingRank - pieceRank ) -                         Math.abs( kingFile - pieceFile );            break;          case jcBoard.WHITE_QUEEN:            score -= Math.min( Math.abs( kingRank - pieceRank ),                               Math.abs( kingFile - pieceFile ) );            break;          default:            break;        }      }    }    else    {      // Look for enemy king first!      for( int i = 0; i < 64; i++ )      {        if ( theBoard.FindWhitePiece( i ) == jcBoard.WHITE_KING )        {          kingRank = i >> 8;          kingFile = i % 8;          break;        }      }      // Now, look for pieces which need to be evaluated      for( int i = 0; i < 64; i++ )      {        pieceRank = i >> 8;        pieceFile = i % 8;        switch( theBoard.FindBlackPiece( i ) )        {          case jcBoard.BLACK_ROOK:            score -= ( Math.min( Math.abs( kingRank - pieceRank ),                                 Math.abs( kingFile - pieceFile ) ) << 1 );            break;          case jcBoard.BLACK_KNIGHT:            score += 5 - Math.abs( kingRank - pieceRank ) -                         Math.abs( kingFile - pieceFile );            break;          case jcBoard.BLACK_QUEEN:            score -= Math.min( Math.abs( kingRank - pieceRank ),                               Math.abs( kingFile - pieceFile ) );            break;          default:            break;        }      }    }    return score;  }  // private EvalRookBonus  // Rooks are more effective on the seventh rank, on open files and behind  // passed pawns  private int EvalRookBonus( jcBoard theBoard, int fromWhosePerspective )  {    long rookboard = theBoard.GetBitBoard( jcBoard.ROOK + fromWhosePerspective );    if ( rookboard == 0 )      return 0;    int score = 0;    for( int square = 0; square < 64; square++ )    {      // Find a rook      if ( ( rookboard & jcBoard.SquareBits[ square ] ) != 0 )      {        // Is this rook on the seventh rank?        int rank = ( square >> 3 );        int file = ( square % 8 );        if ( ( fromWhosePerspective == jcPlayer.SIDE_WHITE ) &&             ( rank == 1 ) )          score += 22;        if ( ( fromWhosePerspective == jcPlayer.SIDE_BLACK ) &&             ( rank == 7 ) )          score += 22;        // Is this rook on a semi- or completely open file?        if ( MaxPawnFileBins[ file ] == 0 )        {          if ( MinPawnFileBins[ file ] == 0 )            score += 10;          else            score += 4;        }        // Is this rook behind a passed pawn?        if ( ( fromWhosePerspective == jcPlayer.SIDE_WHITE ) &&             ( MaxPassedPawns[ file ] < square ) )            score += 25;        if ( ( fromWhosePerspective == jcPlayer.SIDE_BLACK ) &&             ( MaxPassedPawns[ file ] > square ) )            score += 25;        // Use the bitboard erasure trick to avoid looking for additional        // rooks once they have all been seen        rookboard ^= jcBoard.SquareBits[ square ];        if ( rookboard == 0 )          break;      }    }    return score;  }  // private EvalDevelopment  // Mostly useful in the opening, this term encourages the machine to move  // its bishops and knights into play, to control the center with its queen's  // and king's pawns, and to castle if the opponent has many major pieces on  // the board  private int EvalDevelopment( jcBoard theBoard, int fromWhosePerspective )  {    int score = 0;    if ( fromWhosePerspective == jcPlayer.SIDE_WHITE )    {      // Has the machine advanced its center pawns?      if ( theBoard.FindWhitePiece( 51 ) == jcBoard.WHITE_PAWN )        score -= 15;      if ( theBoard.FindWhitePiece( 52 ) == jcBoard.WHITE_PAWN )        score -= 15;      // Penalize bishops and knights on the back rank      for( int square = 56; square < 64; square++ )      {        if ( ( theBoard.FindWhitePiece( square ) == jcBoard.WHITE_KNIGHT ) ||             ( theBoard.FindWhitePiece( square ) == jcBoard.WHITE_BISHOP ) )          score -= 10;      }      // Penalize too-early queen movement      long queenboard = theBoard.GetBitBoard( jcBoard.WHITE_QUEEN );      if ( ( queenboard != 0 ) && ( ( queenboard & jcBoard.SquareBits[ 59 ] ) == 0 ) )      {        // First, count friendly pieces on their original squares        int cnt = 0;        if ( ( theBoard.GetBitBoard( jcBoard.WHITE_BISHOP ) & jcBoard.SquareBits[ 58 ] ) != 0 )          cnt++;        if ( ( theBoard.GetBitBoard( jcBoard.WHITE_BISHOP ) & jcBoard.SquareBits[ 61 ] ) != 0 )          cnt++;        if ( ( theBoard.GetBitBoard( jcBoard.WHITE_KNIGHT ) & jcBoard.SquareBits[ 57 ] ) != 0 )          cnt++;        if ( ( theBoard.GetBitBoard( jcBoard.WHITE_KNIGHT ) & jcBoard.SquareBits[ 62 ] ) != 0 )          cnt++;        if ( ( theBoard.GetBitBoard( jcBoard.WHITE_ROOK ) & jcBoard.SquareBits[ 56 ] ) != 0 )          cnt++;        if ( ( theBoard.GetBitBoard( jcBoard.WHITE_ROOK ) & jcBoard.SquareBits[ 63 ] ) != 0 )          cnt++;        if ( ( theBoard.GetBitBoard( jcBoard.WHITE_KING ) & jcBoard.SquareBits[ 60 ] ) != 0 )          cnt++;        score -= ( cnt << 3 );      }      // And finally, incite castling when the enemy has a queen on the board      // This is a slightly simpler version of a factor used by Cray Blitz      if ( theBoard.GetBitBoard( jcBoard.BLACK_QUEEN ) != 0 )      {        // Being castled deserves a bonus        if ( theBoard.GetHasCastled( jcPlayer.SIDE_WHITE ) )          score += 10;        // small penalty if you can still castle on both sides        else if ( theBoard.GetCastlingStatus( jcPlayer.SIDE_WHITE + jcBoard.CASTLE_QUEENSIDE ) &&                  theBoard.GetCastlingStatus( jcPlayer.SIDE_WHITE + jcBoard.CASTLE_QUEENSIDE ) )          score -= 24;        // bigger penalty if you can only castle kingside        else if ( theBoard.GetCastlingStatus( jcPlayer.SIDE_WHITE + jcBoard.CASTLE_KINGSIDE ) )          score -= 40;        // bigger penalty if you can only castle queenside        else if ( theBoard.GetCastlingStatus( jcPlayer.SIDE_WHITE + jcBoard.CASTLE_QUEENSIDE ) )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -