If it works. One might guess by my signature that I'm not a fan of "if" statements. While coding a white pawn on the 5th rank I was determined to code a cep capture without using an if statement. I probably spent over two hours on it. It was only after giving up and going to the kitchen to get some food that the solution came to me. A cep square is stored as a bb and not a square value.
Since I have an e.p. bit the idea is to create a bit from the ts - 8 and and them together giving a zero or a one. Then shifting left the zero or one by 3 to get a zero or 8 and then subtracting it from the ts to get the target square. It is probably slower than just using an "if" but it is the principle of the idea!
If you are on a sidewalk and the covid goes beep beep
Just step aside or you might have a bit of heat
Covid covid runs through the town all day
Can the people ever change their ways
Sherwin the covid's after you
Sherwin if it catches you you're through
I don't understand your code, because I have no idea what t, ply[] and epbit[][] are. And it looks fishy, because you seem to subtract a bitboard from a square number. But what would be wrong with
hgm wrote: ↑Sat Apr 11, 2020 7:51 am
I don't understand your code, because I have no idea what t, ply[] and epbit[][] are. And it looks fishy, because you seem to subtract a bitboard from a square number. But what would be wrong with
sq = ts ^ 8*(epbitboard == one<<ts);
?
I should have said how the code is structured. The var t is the thread index that gets passed everywhere. And I'm using arrays instead of a structure because I spent a couple of hours searching the internet on the subject and the consensus by the more intelligent sounding posters is that arrays are faster. So when a pawn double move is made the bit bb is stored in an array indexed by half move count after ply[t]++ so it is available at the next half move. In epbit[t][ply[t] - 1], the -1 is because ply[t]++ was made earlier basically a six of one half a dozen of another situation. So what it does is and, let's say 010 with 010 to get a 1 or say 010 with 100 to get a zero therefore 1 << 3 is eight or 0 << 3 is zero and therefore sq = ts - 8 or sq = ts - 0;
Let's see if I understand your code. Does every possible ep square have bit 8 set? Okay, yes they do! What about blacks ep squares 24 - 31? Okay so yes they also do! But there is a problem, "(epbitboard == one<<ts)" is just a hidden if statement, dos it not, still requiring a conditional branch? Or does the compiler have ways around that
If you are on a sidewalk and the covid goes beep beep
Just step aside or you might have a bit of heat
Covid covid runs through the town all day
Can the people ever change their ways
Sherwin the covid's after you
Sherwin if it catches you you're through
No, statements like that do not require a branch on i386 architecture. There are instructions SETcc which copy a condition code (like the EQ flag) to the AL register. So you just do the compare, which sets the condition codes, and then SETEQ to get a 0 or 1 depending on the result.
Thanks for the explanation. The problem I have with your code is that 010 & 010 doesn't give you 1. It gives you 010 = 2. And 2<<3 = 16.
Why do you pass the bitboard with e.p. square anyway? Wouldn't it be much simpler to pass the square number?
Undoubtedly very wise. But I am not sure how it applies here. An efficient ptogramming style is not the same as optimization. I would say that intentionally writing poor code is an even deeper root of evil.
hgm wrote: ↑Sat Apr 11, 2020 5:24 pmBut I am not sure how it applies here.
Generating code so clever that not even the programmer will understand it two weeks from now, without having checked the disassembly whether ifs would even compile to branch instructions, and all of that in a part of the program that doesn't take relevant runtime - in a new project before having reached the "it works correctly" stage.
I guess it depends on what you are used to. For me this is the natural way to do things, while if-statements are cumbersome, difficult to understand and error-prone.
hgm wrote: ↑Sat Apr 11, 2020 4:29 pm
No, statements like that do not require a branch on i386 architecture. There are instructions SETcc which copy a condition code (like the EQ flag) to the AL register. So you just do the compare, which sets the condition codes, and then SETEQ to get a 0 or 1 depending on the result.
Thanks for the explanation. The problem I have with your code is that 010 & 010 doesn't give you 1. It gives you 010 = 2. And 2<<3 = 16.
Why do you pass the bitboard with e.p. square anyway? Wouldn't it be much simpler to pass the square number?
I guess that I was hallucinating. So instead of a shift to the left by 3 a shift right (epsq - 3) is needed or something like that. But that is all moot because your way satisfies the no conditional branch goal and is obviously faster. THANKS
Also it is stored as a bb because in the move generator i have this:
case RANK5:
bb = (wPawnMoves[fs] & empty) | (wPawnCapts[fs] & (bPieces | epbit[t][ply[t]]));
typ = WCEP;
break;
If you are on a sidewalk and the covid goes beep beep
Just step aside or you might have a bit of heat
Covid covid runs through the town all day
Can the people ever change their ways
Sherwin the covid's after you
Sherwin if it catches you you're through