I don't know very much about chess beyond the rules but I enjoy programming and am trying to write a chess engine. I recently found this evaluation function: Simple Evaluation Function. What would be the best way to improve on what has been done there?
-
1Did you see chessprogramming.wikispaces.com/Evaluation and chessprogramming.wikispaces.com/Evaluation+function on the same website? Also you could take a look at the source code of Stockfish, which is one of the strongest (if not the strongest) chess engine out there.– user1583209Commented Jul 1, 2017 at 13:38
-
I did take a look at them but the Stockfish evaluation is obviously very detailed and I am only looking to make small improvements on the simple evaluation function that I gave a link to. Because I don't really know much about chess, I'm not sure what to prioritise in adding to my evaluation or what sort of weightings it should receive and if that means I should change other parts of the current evaluation.– Matthew BarberCommented Jul 1, 2017 at 14:05
-
@MatthewBarber Try out the common chess knowledge that even a beginner would know, like open files and semi-open files.– SmallChessCommented Jul 1, 2017 at 14:13
2 Answers
EDIT for comment
The most important by far is the material count and PST already discussed in your link. You won't go anywhere unless your engine can count materials properly. Other than that, the common knowledge such as rook behind a passed pawn, castled king, pawn majority and mobility are important. Your human knowledge to chess should be sufficient.
ORIGINAL
The best way to improve it is to study the Stockfish source code. Read the comments, and study the implementation.
Code your engine, make it work with a simple evaluation function. Gradually and slowly apply Stockfish's ideas to your own engine.
There's many possible improvements. I can only list some of those. I will give you a link to the Stockfish source code below.
- Two bishops advantage
- Interpolate between middle game and endgame scoring
- Bonus to pawn structures (the page only gives very simple PST values)
- Calibrate the values better with a statistical model
- Castled king
- Number of squares controlled
- Number of attacking squares near the enemy's king
- Asymmetric evaluation (Stockfish doesn't do that but some engines like Chess Genius does that)
- Pieces attacked by the king
- Rook behind a pawn
- Pawn on the check colour as bishop
- Mobility bonus
- Enemy checks
- Rook on semi- or open file
- Insufficient defended squares
- Passed pawn that is not blocked
- Candidate passed pawn (pawn majority)
- ......
Let's take some random examples from Stockfish. Please examine the source code yourself for details.
// RookOnFile[semiopen/open] contains bonuses for each rook when there is no
// friendly pawn on the rook file.
const Score RookOnFile[] = { S(20, 7), S(45, 20) };
and
// ThreatByMinor/ByRook[attacked PieceType] contains bonuses according to
// which piece type attacks which one. Attacks on lesser pieces which are
// pawn-defended are not considered.
const Score ThreatByMinor[PIECE_TYPE_NB] = {
S(0, 0), S(0, 33), S(45, 43), S(46, 47), S(72, 107), S(48, 118)
};
and
// Scale down bonus for candidate passers which need more than one
// pawn push to become passed or have a pawn in front of them.
if (!pos.pawn_passed(Us, s + pawn_push(Us)) || (pos.pieces(PAWN) & forward_bb(Us, s)))
mbonus /= 2, ebonus /= 2;
-
Could you give any guide as to which features would be most important as I don't want to have a function which is too complex? Also, would you recommend changing any of my current weightings? I don't know how sensible they are Commented Jul 1, 2017 at 14:07
-
I would like to add up a couple things to support the good answers you have already.
- Stockfish never applies evaluation function for positions where king of either side is in check.
- Evaluation is based on the state of your Middle Game and End Game.
- Also a smooth transition between the phases of the game using a fine
grained numerical game phase value considering type of captured
pieces so far. This is called "Tapered Eval".
Here a snippet of my own evaluation for middle gale
EvalPhase middle_game_evaluation(&pos) {
int ev = 0;
ev += piece_value_mg(pos) - piece_value_mg(colorflip(pos));
ev += psqt_mg(pos) - psqt_mg(colorflip(pos));
ev += imbalance_total(pos);
ev += pawns_mg(pos) - pawns_mg(colorflip(pos));
ev += pieces_mg(pos) - pieces_mg(colorflip(pos));
ev += mobility_mg(pos) - mobility_mg(colorflip(pos));
ev += threats_mg(pos) - threats_mg(colorflip(pos));
ev += passed_mg(pos) - passed_mg(colorflip(pos));
ev += space(pos) - space(colorflip(pos));
ev += king_mg(pos) - king_mg(colorflip(pos));
return EvalPhase(ev);
}