If anyone is interested I've written this up as a post on ChessProgramming.net:
Writing Color Blind Chess Code
Steve
How to Shift Left a Negative Number??
Moderator: Ras
-
Steve Maughan
- Posts: 1307
- Joined: Wed Mar 08, 2006 8:28 pm
- Location: Florida, USA
-
Daniel Shawul
- Posts: 4186
- Joined: Tue Mar 14, 2006 11:34 am
- Location: Ethiopia
Re: How to Shift Left a Negative Number??
I find that you find this twisted pawn generation code clearer than straight forward color dependent code. The fact that you are happy about the existences of this trick for pawns and are now looking for similar tricks for castling and en-passant should tell which is simpler. A beginner will definately like to see black pawns shifted down, black short castling on the top rank etc. It sounds like you have a certain hammer (one sub-routine criteria) and are finding the nails now...So in Maverick I’m attempting to make the code as clear as possible. To this end, one of the aims is to write color-blind code i.e. wherever possible try to have one routine
-
Steve Maughan
- Posts: 1307
- Joined: Wed Mar 08, 2006 8:28 pm
- Location: Florida, USA
Re: How to Shift Left a Negative Number??
Hi Daniel,
My only (weak) defense is once you use magic move generation simplicity, from a beginners perspective, has gone anyway. But I take your point.
Steve
You make a fair point!Daniel Shawul wrote:I find that you find this twisted pawn generation code clearer than straight forward color dependent code. The fact that you are happy about the existences of this trick for pawns and are now looking for similar tricks for castling and en-passant should tell which is simpler. A beginner will definately like to see black pawns shifted down, black short castling on the top rank etc. It sounds like you have a certain hammer (one sub-routine criteria) and are finding the nails now...
My only (weak) defense is once you use magic move generation simplicity, from a beginners perspective, has gone anyway. But I take your point.
Steve
-
hgm
- Posts: 28425
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: How to Shift Left a Negative Number??
Indeed I do castling and such also always with color-independent code. E.g. in Spartacus it is table drive, the table listing the square range that has to be tested for emptiness, the range that has to be tested for in-check, the from- and to-square of the Rook, a mask for the rights bits that have to be tested, etc. The table index is encoded in the to-square of the move representation (any off-board square number is used directly as a table index). The move generator creates the table indexes as KCASTLE+stm and QCASTLE+stm, and then uses those to access the table to test if all conditions are met, while MakeMove accesses the table to know how to move the Rook.
Also very useful (especially on 8x8 boards) is the XOR operator, because it can map one square on another in a symmetry-invariant way. E.g. to get the capture square for e.p. micro-Max uses toSqr^16, which works for both colors.
To test if a Rook is in a corner in Joker's eval I use
(rookSqr-1 & 0xF) >= 6 && (rookSqr-16 & 0xF0) >= 0x60
(Joker uses 0x88 board), which detects all corners at once. I then use rookSqr^1 and rookSqr^2 to get the two squares next to it, to check if a King locks the Rook into the corner, etc. Not only color-independent, but even left-right invariant.
Also very useful (especially on 8x8 boards) is the XOR operator, because it can map one square on another in a symmetry-invariant way. E.g. to get the capture square for e.p. micro-Max uses toSqr^16, which works for both colors.
To test if a Rook is in a corner in Joker's eval I use
(rookSqr-1 & 0xF) >= 6 && (rookSqr-16 & 0xF0) >= 0x60
(Joker uses 0x88 board), which detects all corners at once. I then use rookSqr^1 and rookSqr^2 to get the two squares next to it, to check if a King locks the Rook into the corner, etc. Not only color-independent, but even left-right invariant.
-
Daniel Shawul
- Posts: 4186
- Joined: Tue Mar 14, 2006 11:34 am
- Location: Ethiopia
Re: How to Shift Left a Negative Number??
Hi Steve,Steve Maughan wrote:Hi Daniel,You make a fair point!Daniel Shawul wrote:I find that you find this twisted pawn generation code clearer than straight forward color dependent code. The fact that you are happy about the existences of this trick for pawns and are now looking for similar tricks for castling and en-passant should tell which is simpler. A beginner will definately like to see black pawns shifted down, black short castling on the top rank etc. It sounds like you have a certain hammer (one sub-routine criteria) and are finding the nails now...
My only (weak) defense is once you use magic move generation simplicity, from a beginners perspective, has gone anyway. But I take your point.
Steve
Have you thought about what you are going to do in the evaluation? It may be very complicated to have color-independent code for pawns due to many patterns. That is usually where programmers tend to introduce bugs. I just think that having one sub-routine adds to the problems that it advocates to solve i.e. concerning clarity. I will follow your blog and give comments there in the future.
Cheers
-
lucasart
- Posts: 3243
- Joined: Mon May 31, 2010 1:29 pm
- Full name: lucasart
Re: How to Shift Left a Negative Number??
I remember exactly that problem. Some people duplicate code (<< 8 for white and >> 8 for black). I find that dreadful and error prone. So I simply do this:Steve Maughan wrote: What do others do?
Code: Select all
inline Bitboard shift_bit(Bitboard b, int i)
{ assert(std::abs(i) < 64); return i > 0 ? b << i : b >> -i; }Theory and practice sometimes clash. And when that happens, theory loses. Every single time.
-
Steve Maughan
- Posts: 1307
- Joined: Wed Mar 08, 2006 8:28 pm
- Location: Florida, USA
Re: How to Shift Left a Negative Number??
Hi Daniel,
While the aim is to write color blind code, I view it as a guiding principle and not something I'm going to be obsessive about (although you could argue starting this thread is a solid sign of obsessive behavior!).
So for the evaluation function I'll cross each bridge as it comes along. Pawn patterns may well be something I cannot do in a colorblind way.
One element of color blind coding which I will apply is symmetrical evaluation. So I'll have a test routine which evaluates a position then flips it over and checks to make sure it evaluates to the same value from the opponents perspective.
Steve
While the aim is to write color blind code, I view it as a guiding principle and not something I'm going to be obsessive about (although you could argue starting this thread is a solid sign of obsessive behavior!).
So for the evaluation function I'll cross each bridge as it comes along. Pawn patterns may well be something I cannot do in a colorblind way.
One element of color blind coding which I will apply is symmetrical evaluation. So I'll have a test routine which evaluates a position then flips it over and checks to make sure it evaluates to the same value from the opponents perspective.
Steve
-
Daniel Shawul
- Posts: 4186
- Joined: Tue Mar 14, 2006 11:34 am
- Location: Ethiopia
Re: How to Shift Left a Negative Number??
That is a good idea. Code from white's perspective and then flip the pawn bitboards when evaluating black's. It may be difficult for other pieces since you will have to flip all of the bitboards in that case.Steve Maughan wrote: One element of color blind coding which I will apply is symmetrical evaluation. So I'll have a test routine which evaluates a position then flips it over and checks to make sure it evaluates to the same value from the opponents perspective.
Btw the one/multiple subroutine debate goes for search as well. For example Fruit had separate full_root, full_search ,full_null even though eval follows the other approach. Then rybka added PV,CUT and ALL node distinction on top resulting in a ton of duplicate code. Well i definitely would not do that for search but found move generation/eval clearer with duplicate code. For search I merged my root_search with the rest just recently to allows for root splitting, but the code became uglier and also found a bug with repetitions after a day! The morale every one will say what he does is the best but I guess in the end what matters is if you are comfortable with what you do.
-
bob
- Posts: 20943
- Joined: Mon Feb 27, 2006 7:30 pm
- Location: Birmingham, AL
Re: How to Shift Left a Negative Number??
Shift right, instead.Steve Maughan wrote:One of the aims of Maverick is to have minimal (almost zero?) color dependent code. I'm not sure how practical this will be - but it's a starting point.
I thought I had a nice neat way of generating pawn moves:This relies on forward being +8 for white and -8 for black. The resulting shift for black would be a negative left shift - which didn't work.Code: Select all
int forward = 8 - 16 * to_move; moves = ((board->piecelist[piece] << forward) & ~(board->all_pieces));
I realize it's not the end of the world to add a bit of color dependent code but before I do so I thought I'd ask if there were any tricks I'm missing.
What do others do?
Thanks,
Steve
-
Don
- Posts: 5106
- Joined: Tue Apr 29, 2008 4:27 pm
Re: How to Shift Left a Negative Number??
You can hind the gory details using macro's or templates. So a pawn forward macro, for example, can appear to be color blind where it's used even though it fact it isn't.Steve Maughan wrote:If anyone is interested I've written this up as a post on ChessProgramming.net:
Writing Color Blind Chess Code
Steve
I would go for code clarity and not try anything too clever - you can add that later unless the decision just has to be made immediately because the choice of data structure depends on it.
Capital punishment would be more effective as a preventive measure if it were administered prior to the crime.