I'm not positive, but I think the final fix to your code is to set bestScore not to -INF but to the the current evaluation OR the bestScore from 2 levels previously, whichever is better.Don wrote:I also see that if all captures are losing, you have not choice but to return a losing score which is also wrong.Don wrote:What score is returned if there are no captures? It looks like you only return -INF in that case unless it happens to reach the maximum level. That is wrong too.mike_bike_kite wrote:This is a better description of my main search function and I hope it describes what I mean by the best score at the level below. It shows what variables I have to play with ie score and BestScore. It doesn't include the stand pat score as we're trying to decide if my alpha beta stuff is ok - I think it is but this should explain it.hgm wrote:It all depends on what 'level_below_best' is, and how you update it. As I pointed out, the very deep line you showed is definitely searching a branch that is totally irrelevant for the root score, and thus should have been pruned by alpha-beta. So either your alpha-beta is not correctly implemeted (e.g. alpha and beta wrongly updated), or your eval scores must be very wrong (which I don't expect). Normally gaining Knight for Pawn should be sufficient to cause a beta cutoff, but it obviously doesn't.
As long as you don't fix that, none of the refinements suggested in the above posts will have much impact. Move ordering is only helpful when alpha-beta works properly...Does this look right?Code: Select all
findBestMove( level, max_level ) { bestScore[level] = whites_turn ? -2000000 : 2000000 get moves in MVV/LVA order ie captures first // leaf node if level > max_level and no_captures_available return evaluateBoard(); // try each move for each move if level <= max_level or capture_move // try move putOnMove() swapSides() score = findBestMove( level+1, max_level ) swapSides() takeOffMove() // minmax if whites_turn and score>bestScore[level] or blacks_turn and score<bestScore[level] bestScore[level] = score bestMove[level] = move // alpha beta cut if whites_turn and score>=bestScore[level -1] or blacks_turn and score<=bestScore[level -1] return score return bestScore[level]
You can correct some of this by first setting the bestScore at the new level to the same score as the evaluation, not -INF. So if all captures are losing this would become the default score (which is how all modern programs do it) and if there are NO captures this would be returned.
This does not apply to the main search however which is no doubt also wrong. In the main search set the bestScore for this level to the -INF or the best from level-2 which is the same as the best score from level-2 i.e. :
bestScore[level] = bestScore[level-2]
Watch out for level < 0, in which case you should use -INF (-200000 for you.)
Don


