I think that I understand the file colour.h of Fruit but I do not understand the reasons for the complex definitions in it.
#define COLOUR_IS_OK(colour) (((colour)&~1)==0)
I wonder what is the reason for that definition.
It seems to me simpler to write
#define COLOUR_IS_OK(colour)
(((colour)==0)||((colour)==1))
Later:
#define COLOUR_IS_WHITE(colour) ((colour)==White)
#define COLOUR_IS_BLACK(colour) ((colour)!=White)
I do not understand why colour!=White and not colour==Black in the second definition.
Later:
#define COLOUR_IS(piece,colour) (FLAG_IS((piece),COLOUR_FLAG(colour)))
#define FLAG_IS(piece,flag) (((piece)&(flag))!=0)
#define COLOUR_OPP(colour) ((colour)^(White^Black))
#define COLOUR_FLAG(colour) ((colour)+1)
Note that I never use definitions inside definitions in Movei and I did not know that it is correct code but
I do not understand the order of definitions and it seems that COLOUR_IS use definitions that are only defined later.
I also do not understand the reason for
#define COLOUR_OPP(colour) ((colour)^(White^Black))
Fruit has
const int White = 0;
const int Black = 1;
so I think that it is more simple to write
#define COLOUR_OPP(colour) ((colour)^1)
Also it is more clear to write
#define COLOUR_FLAG(colour) (1<<(colour))
and not
#define COLOUR_FLAG(colour) ((colour)+1)
These definitions are equal for colour=0 and colour=1 and I wonder what is the reason for prefering (colour)+1(speed optimization?)
I also understand that
COLOUR_IS(piece,colour) gives me 1 only if some piece has specific colour and piece is probably some information about some square that include the colour in 2 bits(piece&1 only if it is white when piece&2 only if it is black when neither of them if it is empty)
Uri