You can give evaluateknight a pointer to array xxx and it solves the problem but I still do not think that it is simpler than having:bob wrote:Almost right. Since EvaluateKnights() is defined in the same source file as Evaluate() where it is called, the two calls get inlined and there is no function call overhead. But it makes it easier to read...Uri Blass wrote:This mean that you call EvaluateKnight twice in your code and the same for some other functions.bob wrote:I decided to go this way:Uri Blass wrote:I wonder how you write your evaluation without special code for white/black.
The original code of strelka has code like the following
endgame += cnt * mobility_knight_endgame;//black minus
opening += cnt * mobility_knight_opening;//black minus
I can simply have array of 2 numbers 1 and -1 and have
endgame += cnt * mobility_knight_endgame*mult[side]
opening += cnt * mobility_knight_opening*mult[side]//black minus
Second alternative is to have special arrays and have
endgame[side]+=cnt*mobility_knight_endgame
In this case you need in the end to substract in order to find the score.
Third alternative is to have
I wonder which alternative is better.Code: Select all
#define eval(a,side) ((side)==White)?(a):(0-(a))) endgame[side]+=cnt*eval(mobility_knight_endgame,side)
1. a procedure that evaluates the pieces for just one side, and returns a score +=good for that side, -=bad for that side...
then
value += EvaluateKnight(white) - EvaluateKnight(black)
does the trick. Somewhere you obviously have to have special-case code, since white and black are different, the above minimizes the differences pretty nicely and now you never have to look at the above line, you just modify EvaluateKnights() and you are done...
I wonder what is the advantage relative to value+=Evaluate(white)-Evaluate(black) when Evaluate(side) calls only to Evaluateknight(side)
In the case of Strelka the program has no EvaluateKnight function but
even if I change it and add EvaluateKnight function then
value += EvaluateKnight(white) - EvaluateKnight(black) is not a solution
The problem is that EvaluateKnight not only change the evaluation by calculating mobility but also updates some variables at the same time(controling squares near the king) and these variables are used later in the evaluation.
Uri
As far as the latter problem, I deal with that in Crafty. You just have a variable such as xxx[2] where xxx[0] is the stuff black knights do, and xxx[1] is the stuff white knights do (I have those for mobility, and any sort of other information that needs to be passed around (white candidate pawns, black candidates becomes candidates[2] for example...)
value += Evaluate(White)-Evaluate(Black) when Evaluate(side) calculates Evaluateknights(side)
If you do it in this way then you still have the same evaluation but you have only in one case of your program White or Black and if you use
Evaluateknights(White)-Evaluateknights(Black) then you may also use EvaluateRooks(White)-EvaluateRooks(Black) and
EvaluateQueens(White)-EvaluateQueens(Black) so you have more code to write.
It may be the same from speed point of view but I think that a solution
with smaller code is more elegant.
I am also not sure if it is the same from speed point of view.
If you have EvaluateKnight(white)-EvaluateKnight(Black) then
EvaluateKnight(white) updates xxx[White] when
EvaluateKnight(black) updates xxx[Black]
It mean that practically EvaluateKnight get an array of 2 numbers and not pointer to a single variable.
If you have Evaluate(white)-Evaluate(Black) for independent parts of the evaluation then you do not need to give array xxx to your functions and you can give them only a pointer to variable.
Note that Evaluate(White)-Evaluate(Black) is not the final evaluation but only most of it.
It clearly include more than one function like EvaluateKnights but you still need to do steps like changing the score to be closer to draw for opposite color bishops endgame.
Uri