Re: I'm not very happy with the do {} while() statement in C
Posted: Sun Feb 18, 2018 11:21 am
I would not recommend the for() solution, though
Computer Chess Club
https://talkchess.com/
syzygy wrote:I would not recommend the for() solution, though
It isn't. You could eliminate it because the whole initialisation only takes place for the 64 centre squares of the board, which is checked via the initboard.Michael Sherwin wrote:The initBoard variable is absolutely needed
Ras wrote:It isn't. You could eliminate it because the whole initialisation only takes place for the 64 centre squares of the board, which is checked via the initboard.Michael Sherwin wrote:The initBoard variable is absolutely needed
So why not using eight dedicated loops? The first runs from 21 to 28, the second from 31 to 38, the third from 41 to 48 and so on. You would even eliminate the superfluous initboard checks when i is 29 or 30, or 39 or 40.
If you put each of these row-wise loops in a parametrised macro, you'd eliminate the code duplication that directly rolling out these 8 loops would bring.
Michael Sherwin wrote:Ras wrote:It isn't. You could eliminate it because the whole initialisation only takes place for the 64 centre squares of the board, which is checked via the initboard.Michael Sherwin wrote:The initBoard variable is absolutely needed
So why not using eight dedicated loops? The first runs from 21 to 28, the second from 31 to 38, the third from 41 to 48 and so on. You would even eliminate the superfluous initboard checks when i is 29 or 30, or 39 or 40.
If you put each of these row-wise loops in a parametrised macro, you'd eliminate the code duplication that directly rolling out these 8 loops would bring.
Okay, now I follow!
Code: Select all
for(sq = 0, sq < 64, sq++) {
y = sq / 8; x = sq - y * 8;
k = y * 10 + x + 1;
...
}
That's even nicer because it's clearer. And you could make the loop count down instead of counting up. AndMichael Sherwin wrote:Or better just changing the direction!
Code: Select all
#define RANK64(x) (x >> 3)
#define FILE64(x) (x & 0x07)
...
y = RANK64(sq);
x = FILE64(sq);
Consider it done! All this stuff I used to know but forgot because I have not programmed anything new for a long time. Thank youRas wrote:That's even nicer because it's clearer. And you could make the loop count down instead of counting up. AndMichael Sherwin wrote:Or better just changing the direction!
y = sq / 8; x = sq - y * 8;
could be replaced by
y = sq >> 3; x = sq & 0x07;
though the compiler will likely do the first replacement automatically.
Or, and that would be even more readable:Code: Select all
#define RANK64(x) (x >> 3) #define FILE64(x) (x & 0x07) ... y = RANK64(sq); x = FILE64(sq);
Subtle oppurtunities for bugs upon a second glance. If the x that is handed over isn't a variable, but e.g. a sum, then this will go wrong. Should be:Ras wrote:Code: Select all
#define RANK64(x) (x >> 3) #define FILE64(x) (x & 0x07)
Code: Select all
#define RANK64(x) ((x) >> 3)
#define FILE64(x) ((x) & 0x07)
Ras wrote:Subtle oppurtunities for bugs upon a second glance. If the x that is handed over isn't a variable, but e.g. a sum, then this will go wrong. Should be:Ras wrote:Code: Select all
#define RANK64(x) (x >> 3) #define FILE64(x) (x & 0x07)
Code: Select all
#define RANK64(x) ((x) >> 3) #define FILE64(x) ((x) & 0x07)
Code: Select all
#define SQUARE120(x) (((x) >> 3 * 10) + (((x) & 7) + 1))
Multiplication has operator precedence over shifting, so the shift would be evaluated to ">> 30" at compile time.Michael Sherwin wrote:Code: Select all
#define SQUARE120(x) (((x) >> 3 * 10) + (((x) & 7) + 1))
Code: Select all
#define SQUARE120(x) ((((x) >> 3) * 10) + ((x) & 7) + 1)