Is it safe? (C/C++)
Posted: Fri Sep 24, 2010 8:14 am
I've decided to continue my chess programming efforts from scratch. No deadline or anything. Taking it slow as part of a learning process.
So I was thinking about the problem of shifting a pattern around on a bitboard. Fx, if you shift a patter left, if you shift it too far, which you sometimes need to do, the part of the patter which is shifted over the "edge" will usually appear at the opposite side of the board, which is not what is needed.
The solution I've come up with, not saying it haven't been done before, though I haven't seen it anywhere, is actually rather simple, but rather than trying to explain it, I'll simply post the code. It should be pretty self explanatory.
Question number one is if this is a safe approach. At first I used regular signed variable, which had some weird side effects that I don't quite understand. didn't think that the sign bit was an issue when shifting, but in any case if seems to work well now.
Question number two is of course if there's any obvious improvements I've missed. fx. I was thinking if it would be possible to drop the rank pointer all together like:
I am aware that the obvious solution involves a union, but I seem to recall having had some trouble with that approach in the past.
It was my original plan to do it in C, oddly as it may sound, but unless you tell me otherwise, I'll assume that there's no pretty way to do it.
Also, should it not be possible to leave the pointer out of the equation, I'd really like it to be const, but am not sure how exactly to achieve that effect.
Anyway, looking forward to your input on the issue.
Best regards.
edit:
obviously I'll need to ensure that the types are safe, but for now it only need work on my own machine.
So I was thinking about the problem of shifting a pattern around on a bitboard. Fx, if you shift a patter left, if you shift it too far, which you sometimes need to do, the part of the patter which is shifted over the "edge" will usually appear at the opposite side of the board, which is not what is needed.
The solution I've come up with, not saying it haven't been done before, though I haven't seen it anywhere, is actually rather simple, but rather than trying to explain it, I'll simply post the code. It should be pretty self explanatory.
Code: Select all
class Board {
unsigned char* rank;
public:
unsigned long long board;
Board() {
rank = (unsigned char*)&board;
board = (some_pattern)LL;
}
void shiftRight(int n) {
for(int i = 0; i < 8; i++)
*(rank+i) = *(rank+i) << n;
}
void shiftLeft(int n) {
for(int i = 0; i < 8; i++)
*(rank+i) = *(rank+i) >> n;
}
void shiftUp(int n) {
board = board << (n * 8);
}
void shiftDown(int n) {
board = board >> (n * 8);
}
};
Question number two is of course if there's any obvious improvements I've missed. fx. I was thinking if it would be possible to drop the rank pointer all together like:
Code: Select all
void shiftRight(int n) {
for(int i = 0; i < 8; i++)
*((unsigned char*)&board+i) = *((unsigned char*)&board+i) << n;
}
It was my original plan to do it in C, oddly as it may sound, but unless you tell me otherwise, I'll assume that there's no pretty way to do it.
Also, should it not be possible to leave the pointer out of the equation, I'd really like it to be const, but am not sure how exactly to achieve that effect.
Anyway, looking forward to your input on the issue.
Best regards.
edit:
obviously I'll need to ensure that the types are safe, but for now it only need work on my own machine.