Moderator: Andres Valverde
#include <stdio.h>
typedef unsigned long long bitboard_t;
enum {HORIZ_DIR, VERT_DIR, DIAG_DIR, XDIAG_DIR};
bitboard_t SlidingAttackBBArray[4][64][64];
int bit_is_set(bitboard_t b, int bit) {
return b & (1ULL << bit);
}
int slide(int x, int v, int d) {
x += d;
if(x < 0 || x > 7) return 0;
if(v & (1<<x)) return 1<<x;
return (1<<x) | slide(x, v, d);
}
int fill(int x, int v) {
return slide(x, v, 1) | slide(x, v, -1);
}
bitboard_t place_bitvector(int bitvector, int square, int direction) {
int i, r=square>>3, f=square&7, d=(r-f)&7, x=(r+f)&7;
bitboard_t result = 0ULL;
int d_mask[16] = {255, 127, 63, 31, 15, 7, 3, 1,
0, 128, 192, 224, 240, 248, 252, 254};
int xd_mask[16] = {1, 3, 7, 15, 31, 63, 127, 255,
254, 252, 248, 240, 224, 192, 128, 0};
if(direction == DIAG_DIR) bitvector &= d_mask[(r-f)&15];
else if(direction == XDIAG_DIR) bitvector &= xd_mask[(r+f)&15];
for(i=0; i<8; i++) {
if(bitvector&(1<<i))
switch(direction) {
case HORIZ_DIR: result |= (1ULL<<(r*8+i)); break;
case VERT_DIR: result |= (1ULL<<(i*8+f)); break;
case DIAG_DIR: result |= (1ULL<<(i+8*((d+i)&7))); break;
case XDIAG_DIR: result |= (1ULL<<(i+8*((x-i)&7))); break;
}
}
return result;
}
void init_attacks(void) {
int i, j, k;
for(i = 0; i < 64; i++)
for(j = 0; j < 256; j++)
for(k = HORIZ_DIR; k <= XDIAG_DIR; k++)
SlidingAttackBBArray[k][i][(j >> 1) & 63] =
place_bitvector(fill((k == 1)? (i>>3) : (i&7), j), i, k);
}
int main(void) {
FILE *f;
int i, j, k, l;
init_attacks();
f = fopen("tables.c", "w");
fprintf(f, "const bitboard_t LineMask[4][64][64] = \n{\n");
for(i = 0; i < 4; i++) {
fprintf(f, " {\n");
for(j = 0; j < 64; j++) {
fprintf(f, " {\n");
for(k = 0; k < 16; k++) {
fprintf(f, " ");
for(l = 0; l < 4; l++)
fprintf(f, "0x%llxULL%s", SlidingAttackBBArray[i][j][k*4+l],
(k == 15 && l == 3)? "" : ", ");
fprintf(f, "\n");
}
fprintf(f, " }%s", (j < 63)? ",\n" : "\n");
}
fprintf(f, " }%s", (i < 3)? ",\n" : "\n");
}
fprintf(f, "};\n");
fclose(f);
return 0;
}
unsigned __int64 LineMaskxxx[4][64][64];
int max_possible_7(int i,int j,int h)
{
int score=h;
int k=0;
h=h-7;
while (h>i)
{
if (j&(1<<k))
{
//there is a piece in h
score=h;
}
k++;
h=h-7;
}
return score;
////example i=E4 h=A8 l=A1
//j&1 mean not A8 score=B7
//j&2 mean not B7 score=C6
//j&4 mean not C6 score=D5
//otherwise everything is possible in the diagnol
//j&16 mean square=F3
}
int min_possible_7(int i,int j,int h,int l)
{
int score=l;
int k=rank0(h)-rank0(l)-2;
l+=7;
while (l<i)
{
if (j&(1<<k))
score=l;
k--;
l+=7;
}
return score;
//example i=E4 h=A8 l=A1
//k=
}
int min_possible_9(int i,int j,int l)
{
int score=l;
int k=0;
l+=9;
while (l<i)
{
if (j&(1<<k))
score=l;
k++;
l+=9;
}
return score;
}
int max_possible_9(int i,int j,int h,int l)
{
int score=h;
int k=rank0(h)-rank0(l)-2;
h-=9;
while (h>i)
{
if (j&(1<<k))
score=h;
k--;
h-=9;
}
return score;
}
int min_possible_1(int i,int j)
{
int score=rank0(i)*8;
int k=0;
int l=score+1;
while (l<i)
{
if (j&(1<<k))
score=l;
k++;
l++;
}
return score;
}
int max_possible_1(int i,int j)
{
int score=rank0(i)*8+7;
int h=score-1;
int k=5;
while (h>i)
{
if (j&(1<<k))
score=h;
h--;
k--;
}
return score;
}
int min_possible_8(int i,int j)
{
int score=fil0(i);
int k=5;
int l=score+8;
while (l<i)
{
if (j&(1<<k))
score=l;
k--;
l+=8;
}
return score;
}
int max_possible_8(int i,int j)
{
int score=fil0(i)+56;
int h=score-8;
int k=0;
while (h>i)
{
if (j&(1<<k))
score=h;
h-=8;
k++;
}
return score;
}
void calculate_line_mask()
{
int i,j,l,h,k;
for (i=0;i<64;i++)
for(j=0;j<64;j++)
{
LineMaskxxx[0][i][j]=0;
l=fil0(i)+rank0(i);
if (l>=8)
l+=7*(l-7);
h=fil0(l)*8+rank0(l);
if (h>l)
for (k=min_possible_7(i,j,h,l);k<=max_possible_7(i,j,h);k+=7)
{
if (k!=i)
LineMaskxxx[0][i][j]|=setmask[k];
}
LineMaskxxx[1][i][j]=0;
if (rank0(i)>fil0(i))
{
l=i-9*fil0(i);
h=l+9*(7-rank0(l));
}
else
{
l=i-9*rank0(i);
h=l+9*(7-fil0(l));
}
for (k=min_possible_9(i,j,l);k<=max_possible_9(i,j,h,l);k+=9)
{
if (k!=i)
LineMaskxxx[1][i][j]|=setmask[k];
}
LineMaskxxx[2][i][j]=0;
for (k=min_possible_1(i,j);k<=max_possible_1(i,j);k++)
{
if (k!=i)
LineMaskxxx[2][i][j]|=setmask[k];
}
LineMaskxxx[3][i][j]=0;
for (k=min_possible_8(i,j);k<=max_possible_8(i,j);k+=8)
{
if (k!=i)
LineMaskxxx[3][i][j]|=setmask[k];
}
}
}
Onno Garms wrote:What do the arrays LineMask (or SlidingAttackBBArray) do?
Is the Strelka source publically available?
Uri Blass wrote:The disadvantage of your code is that there are no comments to explain
what you do but I learned from your code and changed my code to be shorter.
Note that part of the reason that your code is shorter is the fact that you simply has some tricks that make is shorter instead of easier to understand and I find if then else easier to understand then ?
My opinion about it is that it is better to have a short code but not code that is too short.
Onno Garms wrote:What do the arrays LineMask (or SlidingAttackBBArray) do?
Is the Strelka source publically available?
Uri Blass wrote:
My opinion about it is that it is better to have a short code but not code that is too short.
Uri
Tord Romstad wrote:Onno Garms wrote:What do the arrays LineMask (or SlidingAttackBBArray) do?
It's a technique for computing attack bitboards for sliding pieces, known as "rotated bitboards". It was originally invented by Bob Hyatt (I think), and described in this paper. For some reason I have never been able to figure out, Bob uses four different arrays (rook_attacks_r0, rook_attacks_rl90, bishop_attacks_rl45 and bishop_attacks_rr45) instead of a single array for all directions.
Rotated bitboards were very popular until a year or two ago, but don't seem to be very fashionable at the moment. I currently don't use them in chess, but I use a similar technique in shogi.
Is the Strelka source publically available?
No, it is not.
Tord
Uri Blass wrote:Onno Garms wrote:What do the arrays LineMask (or SlidingAttackBBArray) do?
Is the Strelka source publically available?
These array simply have 64 bit numbers that represent set of squares that piece can go in a line based on 3 parameters:
parameter 1 is the line of the piece(0,1,2,3 for every line based on the direction)
when 2 numbers are for lines of the rook (same file or same rank) and 2 numbers are for lines of the bishop.
parameter 2 is the square that the piece start from (0-63)
parameter 3 is the vector of enemy pieces in the same line when you ignore the minimal and the maximal square(again 0-63)
An example:
suppose that you have a bishop at E4 and the line that you look is H1-A8
This mean direction=0 based on strelka definition and square=36
suppose that there are pieces at B7 C6 H1 and there are no pieces in other squares
This means that the relevant vector of pieces is
B7-1 *2^0
C6-1 *2^1
D5-0 *2^2
E4-0 *2^3
F3-0 *2^4
G2-0 *2^5
and this means that the vector of pieces is 2+4=6
The bishop At E4 can goto D5 F3 G2 and capture C6 and H1.
This give 64 bit number that is setmask[D5]+setmask[F3]+setmask[G2]+
setmask[C6]+setmask[H1] when setmask is an array of powers of 2 and
D5 F3 G2 C6 H1 are numbers 0-63 (every square is translated to a number).
For your second question strelka is not free source code(I was lucky to get it) but Tord told me that this idea is also used in Crafty so I decided that I can post about this specific array.
Uri
I disagree, Michael. Strelka's author says and does strange things before, and free to continue to do strange things further for his own strange reasons. Uri got his Strelka source copy by occasion but without any doubt legally. I know that Strelka's evaluation (and successor program named Belka, http://en.wikipedia.org/wiki/Soviet_space_dogs) is discussing now in Russian computer chess forum, so probably suspicious Uri's forum postings about Strelka's internals are also ok. Just my personal opinion.Michael Sherwin wrote:Thanks for being honest and admitting that you posses the sources, but you should realize that it would be morally wrong to benifit from them if others can not.
Sorry, I do not mean to cause you any trouble. For fairness the author of Strelka should now release the source code under the GPL so all can benifit.
Uri Blass wrote:Note that it is possible to say that everything that I do is unfair.
In case of deciding to refuse to look at strelka the author of smarthink could have the advantage of having strelka.
I simply see the code as a gift that I got.
I do not know how much it is going to help me to have a better program later and it may even be counter productive because it is possible that without looking at the code I could get better progress in movei.
Uri
Uri Blass wrote:Note that I never accused strelka of being a fruit clone and I was asked to give opinion about that.
I had the opinion that it has parts of rybka based on comparing analysis of positions and not based on other things.
This opinion is unchanged.
Uri
Michael Sherwin wrote:Uri Blass wrote:Note that I never accused strelka of being a fruit clone and I was asked to give opinion about that.
I had the opinion that it has parts of rybka based on comparing analysis of positions and not based on other things.
This opinion is unchanged.
Uri
So if B steals from A it is okay for C to steal from B what B stole from A?
Thanks, I did not realize this.
Things are much better now!
Do not sweat it, as I am not going to let it bother me anymore or give it any more thought.
Return to Programming and Technical Discussions
Users browsing this forum: No registered users and 4 guests