Let me give an example for why I think this doesn't matter.Chan Rasjid wrote:I think 1800 might be possible as your engine has mates+draws+Beal's mobility.bob wrote:I posted the code from Crafty a couple of times. Here is a very simplified version of what it does:AlvaroBegue wrote:A question for Bob Hyatt: If I understand correctly, your scores in this mode always indicate white is ahead. If a draw is 0, wouldn't this mean that white will always avoid draws and black will always seek them? In that sense, this is not equivalent to using random numbers centered around 0.
int Evaluate(int wtm) {
int score = Random(); // returns a value 0 <= v < 100
return ((wtm) ? score : -score);
}
I am not certain that the negation at the bottom is required.
And doing that is producing a program that is playing around 1800 on the rating lists that measure programs on this end of the rating range...
But I still don't like small one-sided numbers (might be erroneous ?) for white and black; better to comment out Evaluate() and replace with something like:
-7000 + (hash % 14001) as long as they don't invalidate mates scores.
Rasjid
Let's suppose we are going to do a simple 2 ply search + captures. Random eval (since there are not any captures in my example) of 0-99.
At the root, we have 2 moves, m1-1 and m1-2. m1-1 is a check that has only one way out. m1-2 is a normal move that leaves the opponent with 20 possible replies.
We make move m1-1 (at a max node) and reach the position at ply-2 which is a min node. We make the only possible move and get to ply 3. With no captures, we generate a random number (let's guess 50) and return this. But when it is passed back to ply-2 it is negated and gets there as a -50. We are finished with this move and back up this to the root, which via negamax now turns into a +50, the score for the first move. Now we try the second move from the root, and again reach ply 2, but here we have 20 moves. So we make each one of those, and call quiesce() which returns a random number between 0 and 99. But as it is backed up to ply2 negamax negates it. So we choose the largest of those numbers, which is actually the smallest random number we found. If we assume that the 20 random numbers are 1 thru 20, then at ply=2 we choose the largest of -1 to -20, which is -1. We return that back to the root where it becomes +1. And we choose the move with the largest score, which is max(50,1).
It doesn't matter if the numbers are centered around 0 or not. What is important is that you get a sampling distribution of the random numbers and always choose the most favorable result, but then it gets backed up thru negamax. So that at ply P you pick the largest value each time you get here and back that up, but at ply P-1 you get those values with the sign changed and pick the largest of them there, which is the smallest value from the next ply if you think about it.
These values propagate back thru the tree, although the numbers mean nothing. All you can conclude is that if you are a max node, you pick the move that leads to the largest "score" because that represents the move where you had the largest number of options further down, and your opponent had the fewest options.
A bit odd until you think about it, and then suddenly nothing matters but the random numbers. All you care about is that the more choices you have, the better your chance of being able to pick from a set that has at least one large number. And then at the previous ply, your opponent chooses from that set of scores, but negated, so that he is picking the smallest...