hgm wrote:Well, if c6-e7 increased alpha to -110 (which is reasonable) then it becomes best move at that point. If Qxa2 later scores also -110 it is a fail low, and thus an upper bound only. (And indeed its true score should be somewhere around -900.) It should never have been able to replace c6-e7 as best move in the root,and get played.
So the root, the code around search() should only update the score if new_score > alpha?
The score at the root is the score for the best move. This should be an exact score, not a bound.
So it depends a bit on how your search is ordered. If you don't iterate over root moves in your root search, then the result of search() is just the score for the node. If that is not within bounds, you need to research with a wider window.
That I understand. And that is also what happens: the second time depth 9 is searched, beta is set to infinite (alpha -160, beta 10000). So if it returns -110 then that is in bounds.
So I don't follow what is going wrong then. We went through the whole search but what to conclude from it is, I don't see.
flok wrote:So the root, the code around search() should only update the score if new_score > alpha?
Searching the root is not different from searching any other node: every move that scores <= alpha is completely ignored, and every move that scores > alpha leads to increasing alpha correspondingly.
flok wrote:So the root, the code around search() should only update the score if new_score > alpha?
Searching the root is not different from searching any other node: every move that scores <= alpha is completely ignored, and every move that scores > alpha leads to increasing alpha correspondingly.
With the root I don't mean the routine where it goes through the moves of the root, I mean the function that calls that. The function performing the aspiration windowing.
Well, none of my engines has such a function, (i.e. Search() is called directly from main(), if the command-processing loop there sees it is the engine's turn), so I have no idea how it would look.
Where it goes wrong is in the function that loops over moves, where at some point the move Qxa2 is promoted to 'best move' (and subsequently played) despite the fact that it failed low (i.e. scored equal to alpha, which was raised to -110 by c6e7). It should have been ignored, as any low-failing move, and have left c6e7 as best move, so that that would have been played.
That contradicts what you said before, namely that c6e7 was tried first, and increased alpha.
Either c6e7 is tried first, raises alpha to -110, which then causes Qxa2 to fail low later at -110, or Qxa2 was tried first, while alpha was still at -160. In the latter case it is completely unexplained where the 110 came from against which the null move after Qxa2 Rxa2 b5b4 could fail high.
which then causes Qxa2 to fail low later at -110, or Qxa2 was tried first, while alpha was still at -160. In the latter case it is completely unexplained where the 110 came from against which the null move after Qxa2 Rxa2 b5b4 could fail high.
If the window for the second d=9 search was set at {-160, 10000}, how did beta after Qxa2 Rxa2 b5b4 get to be 110, so that the null move from there could refute b5b4 with a -110 score? Nothing was searched before Qxa2 that could have raised alpha from-160 to -110. So it must have happened at ply 3. What move was searched in the node after Qxa2 Rxa2 before b5b4 that would have raised alpha from -160 to -110?