Woaw, that real C++ wizardry !Aleks Peshkov wrote:Code: Select all
template <> Bb attack<Knight>(Square sq) { return sq(-2, -1) + sq(-2, +1) + sq(-1, -2) + sq(-1, +2) + sq(+2, +1) + sq(+2, -1) + sq(+1, +2) + sq(+1, -2); }
Code: Select all
Bb Square::operator() (signed fileOffset, signed rankOffset) const { signed x88 = *this + (*this & 070) + fileOffset + 16*rankOffset; if (x88 & 0x88) { return Bb::empty(); //offside } else { Square sq = static_cast<square_t>((x88 + (x88 & 7)) >> 1); return Bb(sq); } }
Problem with bitboard knight attack generator
Moderators: hgm, Rebel, chrisw
-
- Posts: 3232
- Joined: Mon May 31, 2010 1:29 pm
- Full name: lucasart
Re: Problem with bitboard knight attack generator
-
- Posts: 1334
- Joined: Sun Jul 17, 2011 11:14 am
Re: Problem with bitboard knight attack generator
I take your point.
I just use C++ for STL and stuff like that (the <algorithm> header has come in handy). But even I use C++ better than a certain author of Fruit. (From reading the code in Fruit 2.1 he doesn't seem to have heard of classes or templates, *makes a mental note to upgrade Fruit 2.1 so it uses modern features*).
I use a (probably) strange method of determining pawn captures.
I just take 5 and right shift it by the square + (for white) or - (for black) 8.
Matthew:out
I just use C++ for STL and stuff like that (the <algorithm> header has come in handy). But even I use C++ better than a certain author of Fruit. (From reading the code in Fruit 2.1 he doesn't seem to have heard of classes or templates, *makes a mental note to upgrade Fruit 2.1 so it uses modern features*).
I use a (probably) strange method of determining pawn captures.
Code: Select all
void InitPawnAttacks()
{
const Bitboard a = 0x5ULL;
for (int i = a2; i < h7; i++) {
PawnAttacks[0][i] = a << i + 8;
for (int i = a2; i < h7; i++) {
PawnAttacks[1][i] = a << i - 8;
}
Matthew:out
Some believe in the almighty dollar.
I believe in the almighty printf statement.
I believe in the almighty printf statement.
-
- Posts: 3232
- Joined: Mon May 31, 2010 1:29 pm
- Full name: lucasart
Re: Problem with bitboard knight attack generator
It was always unclear to my why Fabien wrote Fruit in C++ and not in C. His code would probably compile (with a few trivial modifications) with any ISO C99 compiler. He doesn't use any C++ feature, but just called his source files *.cpp and compiled with g++ i/o gcc.ZirconiumX wrote: But even I use C++ better than a certain author of Fruit. (From reading the code in Fruit 2.1 he doesn't seem to have heard of classes or templates, *makes a mental note to upgrade Fruit 2.1 so it uses modern features*).
But I really like his code, and I think that Fruit 2.1's source code has been the greatest contribution to the computer chess community of all times! Second on "my list" is of course Glaurung/StockFish. The point is that these programs are very well constructed, and their code is cristal clear. Everything is nicely separated and testable separately.
The (first) key to a good chess program is probably to eliminate bugs, and an easy way to achieve it is by making the code as banal as possible, and program very defensively (put assert everywhere for example, never make dubious assumptions). And that was the lesson that Fabien gave to everyone when he published his code, and spanked almost all other programs, even though those programs had a lot more "features" than Fruit, which had a relatively simple eval and straight forward search algorithm.
Ippolit however, as strong as it may be, is one the most obfuscated and illegible code ever written. A good candidate for the famous IOCCC
-
- Posts: 1334
- Joined: Sun Jul 17, 2011 11:14 am
Re: Problem with bitboard knight attack generator
Yup Fruit 2.1 is great , and yup, Fruit 2.1 compiles with GCC without any modifications... It makes you wonder, doesn't it?
What makes me laugh is the IPPOLIT wiki always calls us "capitalists" (not all the countries are capitalist over here, some are royal capitalist)
Matthew:out
What makes me laugh is the IPPOLIT wiki always calls us "capitalists" (not all the countries are capitalist over here, some are royal capitalist)
Matthew:out
Some believe in the almighty dollar.
I believe in the almighty printf statement.
I believe in the almighty printf statement.
-
- Posts: 3232
- Joined: Mon May 31, 2010 1:29 pm
- Full name: lucasart
Re: Problem with bitboard knight attack generator
I like your pawn attack code. It's very elegant !ZirconiumX wrote:Code: Select all
void InitPawnAttacks() { const Bitboard a = 0x5ULL; for (int i = a2; i < h7; i++) { PawnAttacks[0][i] = a << i + 8; for (int i = a2; i < h7; i++) { PawnAttacks[1][i] = a << i - 8; }
-
- Posts: 3232
- Joined: Mon May 31, 2010 1:29 pm
- Full name: lucasart
Re: Problem with bitboard knight attack generator
I think the IPPOLIT wiki is just a big joke. The developpers of IPPOLIT are probably people like you and me, just having fun and disguising their names under ridiculous peudonyms (taken from Dostoievsky's litterature). I think the capitalist that they flame are the developpers of proprietary and/or commercial engines. Of course, this capitalist / socialist stuff is a big joke, but I do agree that proprietary software is the devil's inventions.ZirconiumX wrote:Yup Fruit 2.1 is great , and yup, Fruit 2.1 compiles with GCC without any modifications... It makes you wonder, doesn't it?
What makes me laugh is the IPPOLIT wiki always calls us "capitalists" (not all the countries are capitalist over here, some are royal capitalist)
Matthew:out
-
- Posts: 3232
- Joined: Mon May 31, 2010 1:29 pm
- Full name: lucasart
Re: Problem with bitboard knight attack generator
Unfortunately it's incorrect. Have you tested it ?lucasart wrote:I like your pawn attack code. It's very elegant !ZirconiumX wrote:Code: Select all
void InitPawnAttacks() { const Bitboard a = 0x5ULL; for (int i = a2; i < h7; i++) { PawnAttacks[0][i] = a << i + 8; for (int i = a2; i < h7; i++) { PawnAttacks[1][i] = a << i - 8; }
For example 5ULL << A2 + 8 is actually the value that you should get for B2 not for A2.
And when i = H2, can you guess what happens ?
Also the compiler generates a warning and invites you to clarify operator associativity. And I agree with the compiler that
Code: Select all
PawnAttacks[0][i] = a << (i + 8);
-
- Posts: 1334
- Joined: Sun Jul 17, 2011 11:14 am
Re: Problem with bitboard knight attack generator
Yes, it was an attempt by a noob to try and get a decent attack generator with as few lines as possible...
Matthew:out
Matthew:out
Some believe in the almighty dollar.
I believe in the almighty printf statement.
I believe in the almighty printf statement.
-
- Posts: 4675
- Joined: Mon Mar 13, 2006 7:43 pm
CookieCat's advance and onboard arrays
CookieCat's advance and onboard arrays:
Code: Select all
var
advance: array [sqtype, dirtype] of sqxtype; { Next square along any direction }
onboard: array [sqtype, dirtype] of Boolean; { True if next square is on the board }
function CalcAdvance(sq: sqtype; dir: dirtype): sqxtype;
var
fval, rval: si8type;
begin
fval := Ord(MapSqToBfile(sq)) + dirtobfiledelta[dir];
rval := Ord(MapSqToBrank(sq)) + dirtobrankdelta[dir];
if (fval < 0) or (fval > bfilemax) or (rval < 0) or (rval > brankmax) then
CalcAdvance := sqnil
else
CalcAdvance := MapBfileBrankToSq(bfiletype(fval), branktype(rval))
end; { CalcAdvance }
procedure InitializeAdvance;
var
sq: sqtype;
dir: dirtype;
begin
for sq := 0 to sqmax do
for dir := 0 to dirmax do
advance[sq, dir] := CalcAdvance(sq, dir)
end; { InitializeAdvance }
procedure InitializeOnBoard;
var
sq: sqtype;
dir: dirtype;
flag: Boolean; { Needed for compiler bug work-around }
begin
for sq := 0 to sqmax do
for dir := 0 to dirmax do
begin
flag := advance[sq, dir] <> sqnil;
onboard[sq, dir] := flag
end
end; { InitializeAdvance }
-
- Posts: 1334
- Joined: Sun Jul 17, 2011 11:14 am
Re: Problem with bitboard knight attack generator
In theory, it would have worked. In practice however...
The error for being ahead of the square should be fixed by replacing 8 with 7, and wraparound by ANDing with the file ahead. So we get this:
Which is somewhat less elegant...
Matthew:out
The error for being ahead of the square should be fixed by replacing 8 with 7, and wraparound by ANDing with the file ahead. So we get this:
Code: Select all
void InitPawnAttacks()
{
const Bitboard a = 0x5ULL;
for (int i = a2; i < h7; i++) {
PawnAttacks[0][i] = (a << (i + 7)) bitand (FileMaskForSquare(i) + 1);
for (int i = a2; i < h7; i++) {
PawnAttacks[1][i] = (a << (i - 7)) bitand (FileMaskForSquare(i) - 1);
}
Matthew:out
Some believe in the almighty dollar.
I believe in the almighty printf statement.
I believe in the almighty printf statement.