My first try was using the MVV/LVA method. This didn?t work out too well because it had many problems with it like a move where the pawn would be hanging to be taken by a queen. This move would not even be considered.
Then I tried something that checks whether the piece would be taken with the capture
- Code: Select all
int score=PieceVal[board.piece[square]];
if(isAttacked(square,attackingpiecesq))
score-=PieceVal[attackingpiece];
return score;
This doesn?t work well either because of problems like the following position:
Witz_a17 ? Witz_a16
[diag]Q1bk2r1/p3pp1p/3p4/1P6/1P1P4/Pq3NP1/3K1P1P/R6R[/diag]
Q1bk2r1/p3pp1p/3p4/1P6/1P1P4/Pq3NP1/3K1P1P/R6R w - - 1 21
Witz a17 set at depth 5 search played a8c8 and went on to lose the game.
Here was its PV line in the position:
a8c8 d8c8 a1c1 c8b7 c1c3
[diag]6r1/pk2pp1p/3p4/1P6/1P1P4/PqR2NP1/3K1P1P/7R[/diag]
Here the previous SEE thought that the black queen takes the pawn and nothing is attacking it. But of course the Rook attacks it after that, and the quiescence search sees this and the program thinks that queens will be traded. (I?ve tried extending the attacking line which worked for this position but had problems in other positions)
So even this didn?t work and I went off into another round of thinking and came up with this.
Say you had a position like the following:
[diag]3r4/3r4/2n1n3/8/3p4/2PR4/1B1Q4/3R4[/diag]
White?s turn.
I came up with a very complex SEE for solving this.
Keep two arrays, one with black pieces attacking the square in question and one with white pieces attacking the square in question and keep them ordered from lowest piece score to highest piece score.
So the initial arrays would be:
White[ P , R ]
Black[ N , N , R ]
Since its whites move White plays the lowest piece that takes the piece and then generates the first piece along the diagonal starting from the position of the pawn
Score=P
White[ B, R ]
Black[ N, N, R]
Black Plays N
Score=P-P
White [B, R]
Black [N, R]
And so on to get a score. But one side is not compelled to play a capture. So if a later score is less than an earlier score for a certain side, the earlier score is returned.
Implementing this would have a lot of overhead compared to simple (but bad) algorithms like the MVV/LVA algorithms. My question is does anyone have a good SEE algorithm that is as accurate as my last one but not as slow as it?