Answers.Body: <p>A simple board material evaluation using <a href="https://github.com/niklasf/python-chess" rel="nofollow noreferrer">python-chess</a>.</p>
  <h4>Code</h4>
  <pre><code>import chess
  
  
  PV = {
      'pawn': 100,
      'knight': 320,
      'bishop': 330,
      'rook': 500,
      'queen': 950
  }
  
  DRAW_VALUE = 0
  
  
  def evaluation(board):
      if board.is_insufficient_material():
          return DRAW_VALUE
  
      wp = len(board.pieces(chess.PAWN, chess.WHITE))
      bp = len(board.pieces(chess.PAWN, chess.BLACK))
  
      wn = len(board.pieces(chess.KNIGHT, chess.WHITE))
      bn = len(board.pieces(chess.KNIGHT, chess.BLACK))
  
      wb = len(board.pieces(chess.BISHOP, chess.WHITE))
      bb = len(board.pieces(chess.BISHOP, chess.BLACK))
  
      wr = len(board.pieces(chess.ROOK, chess.WHITE))
      br = len(board.pieces(chess.ROOK, chess.BLACK))
  
      wq = len(board.pieces(chess.QUEEN, chess.WHITE))
      bq = len(board.pieces(chess.QUEEN, chess.BLACK))
  
      value = (
          PV['pawn'] * (wp - bp) +
          PV['knight'] * (wn - bn) +
          PV['bishop'] * (wb - bb) +
          PV['rook'] * (wr - br) +
          PV['queen'] * (wq - bq)
      )
  
      if board.turn == chess.WHITE:
          return value
      return -value
  
  
  # Start
  fen = 'rnbqkbnr/ppp1pppp/8/3P4/8/8/PPPP1PPP/RNBQKBNR b KQkq - 0 2'
  board = chess.Board(fen)
  print(board)
  
  value = evaluation(board)
  print(f'board evaluation: {value}')
  </code></pre>
  <h4>Output</h4>
  <pre><code>r n b q k b n r
  p p p . p p p p
  . . . . . . . .
  . . . P . . . .
  . . . . . . . .
  . . . . . . . .
  P P P P . P P P
  R N B Q K B N R
  board evaluation: -100
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-01-19T14:53:19.727Z
Answers.LastActivityDate: 2022-01-19T14:53:19.727Z
Answers.UserDisplayName: ferdy
Answers.Body: <p>The usually basic evaluation people will start off with consistent material balance and piece-square tables. The material balance makes sure the engine understands basic ideas of trading and tactics, while the piece-square tables make sure the engine plays reasonable chess and encourages ideas like pushing pawns in the endgame or centralizing knights.</p>
  <p>It honestly shouldn't be too hard to role your own code. For example, <a href="https://github.com/algerbrex/blunder/blob/a5e1f1bfe1958f87023e62d9e04a6e54fc7df5b2/engine/evaluation.go" rel="nofollow noreferrer">here's what my evaluation function looked like</a> for a while, in Golang.</p>
  <p>Another example of a simple implementation is <a href="https://www.chessprogramming.org/PeSTO%27s_Evaluation_Function" rel="nofollow noreferrer">PeSTO</a>, which does include one more feature known as tapered evaluation, which sounds like a fancy idea but is really just based on the intuition that different things become important going from the middle to endgame. In the middlegame the king should hide away to avoid getting mated, but in the endgame the centralization of the king is crucial to winning.</p>
  <p>Once you come back to the evaluation, then you can focus on adding other important terms like mobility, king safety, and pawn structure (passed pawns, doubled pawns, isolated pawns, etc.)</p>
  <p>If your program does use the above-linked PeSTO code verbatim and you make it public (which I hope you would eventually), just make sure you give a little shoutout to where you got it from.</p>
  <p>As for the move ordering, that also shouldn't be super hard either. Start with some basic scheme like sorting captures, and then eventually using a transposition table to put the hash move first. This is what <a href="https://github.com/algerbrex/blunder/blob/main/engine/search.go#L687" rel="nofollow noreferrer">Something like that</a>, though a tad more complicated, is what I've done for my engine. See <code>scoreMoves</code> and <code>orderMoves</code>.</p>
  <p>Best of luck.</p>
  <p>P.S: <a href="http://talkchess.com/forum3/index.php" rel="nofollow noreferrer">http://talkchess.com/forum3/index.php</a> is a great resource for interacting with people who are very knowledgeable and helpful when it comes to building an engine. Consider making an account some time.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-01-19T13:52:23.480Z
Answers.LastActivityDate: 2022-01-19T13:52:23.480Z
Answers.UserDisplayName: Chris
Body: <p>I'm building a chess engine in Python. I'd like to find a board evaluation function that would be easy to put into my engine as a placeholder while I work on other aspects of the engine first.</p>
  <p>I would love to use some iteration of StockFish's board evaluation. But there's no way I can see to do this without interacting with the normal StockFish engine in some way that has obscene overhead.</p>
  <p>So, basically, I'm wondering if there are any evaluation functions someone else has already made that I can use. I would like for it to be easy to get working, not <em>extremely</em> slow, and not that bad at scoring boards.</p>
  <p>Bonus points if possible:</p>
  <ul>
  <li>The board representation it expects is a Python-Chess <code>Board</code> object (or uses similar bitboards)</li>
  <li>You also know of a placeholder I can use for move ordering as well (would have the same criteria as the evaluation function)</li>
  <li>It's actually written fully in Python, so JIT compilation may be possible (so NumPy works but not much else)</li>
  </ul>
  
Tags: <engines><stockfish><evaluation><python>
Title: Python Efficient Board Scoring Function To Use As Placeholder
ThreadText: # Python Efficient Board Scoring Function To Use As Placeholder
  
  (Asked by: username_0 on 2022-01-19)
  
  I'm building a chess engine in Python. I'd like to find a board evaluation function that would be easy to put into my engine as a placeholder while I work on other aspects of the engine first.
  
  I would love to use some iteration of StockFish's board evaluation. But there's no way I can see to do this without interacting with the normal StockFish engine in some way that has obscene overhead.
  
  So, basically, I'm wondering if there are any evaluation functions someone else has already made that I can use. I would like for it to be easy to get working, not *extremely* slow, and not that bad at scoring boards.
  
  Bonus points if possible:
  
  * The board representation it expects is a Python-Chess `Board` object (or uses similar bitboards)
  * You also know of a placeholder I can use for move ordering as well (would have the same criteria as the evaluation function)
  * It's actually written fully in Python, so JIT compilation may be possible (so NumPy works but not much else)
  
  **Tags:** engines, stockfish, evaluation, python
  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_1 on 2022-01-19. Score: 2
  
  A simple board material evaluation using python-chess.
  Code
  import chess
  
  
  PV = {
      'pawn': 100,
      'knight': 320,
      'bishop': 330,
      'rook': 500,
      'queen': 950
  }
  
  DRAW_VALUE = 0
  
  
  def evaluation(board):
      if board.is_insufficient_material():
          return DRAW_VALUE
  
      wp = len(board.pieces(chess.PAWN, chess.WHITE))
      bp = len(board.pieces(chess.PAWN, chess.BLACK))
  
      wn = len(board.pieces(chess.KNIGHT, chess.WHITE))
      bn = len(board.pieces(chess.KNIGHT, chess.BLACK))
  
      wb = len(board.pieces(chess.BISHOP, chess.WHITE))
      bb = len(board.pieces(chess.BISHOP, chess.BLACK))
  
      wr = len(board.pieces(chess.ROOK, chess.WHITE))
      br = len(board.pieces(chess.ROOK, chess.BLACK))
  
      wq = len(board.pieces(chess.QUEEN, chess.WHITE))
      bq = len(board.pieces(chess.QUEEN, chess.BLACK))
  
      value = (
          PV['pawn'] * (wp - bp) +
          PV['knight'] * (wn - bn) +
          PV['bishop'] * (wb - bb) +
          PV['rook'] * (wr - br) +
          PV['queen'] * (wq - bq)
      )
  
      if board.turn == chess.WHITE:
          return value
      return -value
  
  
  # Start
  fen = 'rnbqkbnr/ppp1pppp/8/3P4/8/8/PPPP1PPP/RNBQKBNR b KQkq - 0 2'
  board = chess.Board(fen)
  print(board)
  
  value = evaluation(board)
  print(f'board evaluation: {value}')
  
  Output
  r n b q k b n r
  p p p . p p p p
  . . . . . . . .
  . . . P . . . .
  . . . . . . . .
  . . . . . . . .
  P P P P . P P P
  R N B Q K B N R
  board evaluation: -100
  
  
  ---
  
  ### Answer by username_2 on 2022-01-19. Score: 0
  
  The usually basic evaluation people will start off with consistent material balance and piece-square tables. The material balance makes sure the engine understands basic ideas of trading and tactics, while the piece-square tables make sure the engine plays reasonable chess and encourages ideas like pushing pawns in the endgame or centralizing knights.
  
  It honestly shouldn't be too hard to role your own code. For example, [here's what my evaluation function looked like](https://github.com/algerbrex/blunder/blob/a5e1f1bfe1958f87023e62d9e04a6e54fc7df5b2/engine/evaluation.go) for a while, in Golang.
  
  Another example of a simple implementation is [PeSTO](https://www.chessprogramming.org/PeSTO%27s_Evaluation_Function), which does include one more feature known as tapered evaluation, which sounds like a fancy idea but is really just based on the intuition that different things become important going from the middle to endgame. In the middlegame the king should hide away to avoid getting mated, but in the endgame the centralization of the king is crucial to winning.
  
  Once you come back to the evaluation, then you can focus on adding other important terms like mobility, king safety, and pawn structure (passed pawns, doubled pawns, isolated pawns, etc.)
  
  If your program does use the above-linked PeSTO code verbatim and you make it public (which I hope you would eventually), just make sure you give a little shoutout to where you got it from.
  
  As for the move ordering, that also shouldn't be super hard either. Start with some basic scheme like sorting captures, and then eventually using a transposition table to put the hash move first. This is what [Something like that](https://github.com/algerbrex/blunder/blob/main/engine/search.go#L687), though a tad more complicated, is what I've done for my engine. See `scoreMoves` and `orderMoves`.
  
  Best of luck.
  
  P.S: <http://talkchess.com/forum3/index.php> is a great resource for interacting with people who are very knowledgeable and helpful when it comes to building an engine. Consider making an account some time.
  
  
  ---
  
  