1/* 2 Sjeng - a chess variants playing program 3 Copyright (C) 2001 Gian-Carlo Pascutto and Nubie 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, write to the Free Software 17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 19 File: segtb.c 20 Purpose: suicide endgame tablebases 21 22*/ 23 24#include <limits.h> 25#include "sjeng.h" 26#include "extvars.h" 27#include "protos.h" 28#include "squares.h" 29 30#define FILE(x) ((x) & 7) 31#define RANK(x) ((x) >> 3) 32 33#define TWO_PIECE_SIZE 4096 34#define TWO_PIECE_HASH(x,y,z) (((((x) << 5) | (y)) << 6) | (z)) 35#define TWO_PIECE_FILE "stb/2pieces.bin" 36 37#define THREE_PIECE_SIZE (64*TWO_PIECE_SIZE) 38#define THREE_PIECE_HASH(x,y,z,w) (((((((x) << 5) | (y)) << 6) | (z)) << 6) | (w)) 39#define THREE_PIECE_FILE "stb/xxx.bin" 40 41#define TABLE_KEY(x,y,z) (((((x) << 3) | (y)) << 3) | (z)) 42 43#define IO_BUFSIZE 4096 44#define CACHE_SIZE 8 45 46int upscale[64] = { 47 A1,B1,C1,D1,E1,F1,G1,H1, 48 A2,B2,C2,D2,E2,F2,G2,H2, 49 A3,B3,C3,D3,E3,F3,G3,H3, 50 A4,B4,C4,D4,E4,F4,G4,H4, 51 A5,B5,C5,D5,E5,F5,G5,H5, 52 A6,B6,C6,D6,E6,F6,G6,H6, 53 A7,B7,C7,D7,E7,F7,G7,H7, 54 A8,B8,C8,D8,E8,F8,G8,H8 55}; 56 57int vertical_flip[64] = { 58 7, 6, 5, 4, 3, 2, 1, 0, 59 15, 14, 13, 12, 11, 10, 9, 8, 60 23, 22, 21, 20, 19, 18, 17, 16, 61 31, 30, 29, 28, 27, 26, 25, 24, 62 39, 38, 37, 36, 35, 34, 33, 32, 63 47, 46, 45, 44, 43, 42, 41, 40, 64 55, 54, 53, 52, 51, 50, 49, 48, 65 63, 62, 61, 60, 59, 58, 57, 56 66}; 67 68/* angrim : this is 63-x, no need to lookup */ 69 70int rotate[64] = { 71 63, 62, 61, 60, 59, 58, 57, 56, 72 55, 54, 53, 52, 51, 50, 49, 48, 73 47, 46, 45, 44, 43, 42, 41, 40, 74 39, 38, 37, 36, 35, 34, 33, 32, 75 31, 30, 29, 28, 27, 26, 25, 24, 76 23, 22, 21, 20, 19, 18, 17, 16, 77 15, 14, 13, 12, 11, 10, 9, 8, 78 7, 6, 5, 4, 3, 2, 1, 0 79}; 80 81int white_addr[64] = { 82 0, 1, 2, 3, -1, -1, -1, -1, 83 4, 5, 6, 7, -1, -1, -1, -1, 84 8, 9, 10, 11, -1, -1, -1, -1, 85 12, 13, 14, 15, -1, -1, -1, -1, 86 16, 17, 18, 19, -1, -1, -1, -1, 87 20, 21, 22, 23, -1, -1, -1, -1, 88 24, 25, 26, 27, -1, -1, -1, -1, 89 28, 29, 30, 31, -1, -1, -1, -1 90}; 91 92int section_map[6][6] = { 93 { 0, 1, 2, 3, 4, 5 }, 94 { -1, 6, 7, 8, 9, 10 }, 95 { -1, -1, 11, 12, 13, 14 }, 96 { -1, -1, -1, 15, 16, 17 }, 97 { -1, -1, -1, -1, 18, 19 }, 98 { -1, -1, -1, -1, -1, 20 } 99}; 100 101 102int section_trans[] = {666, 0, 0, 1, 1, 5, 5, 3, 3, 4, 4, 2, 2, 6}; 103char xpiece_char[] = {'F','P','P','N','N','K','K','R','R','Q','Q','B','B','E' }; 104 105typedef struct 106{ 107 int table_key; 108 int last_access; 109} cache_data; 110 111signed char *two_piece_data; 112signed char *three_piece_data; 113signed char *temp_table; /* used when generating new tables */ 114 115int cache_counter; 116cache_data table_cache[CACHE_SIZE]; 117int temp_key; 118 119int SEGTB; 120 121int valid_2piece(int w, int b, int w_man, int b_man) 122{ 123 /* white piece on the wrong half-board? */ 124 125 if(white_addr[w] == -1) 126 return 0; 127 128 /* pieces on the same square? */ 129 if(w == b) 130 return 0; 131 132 if(w_man == wpawn || w_man == bpawn) 133 if(w < 8 || w > 55) 134 return 0; 135 136 if(b_man == bpawn || b_man == wpawn) 137 if(b < 8 || b > 55) 138 return 0; 139 140 return 1; 141} 142 143 144int valid_3piece(int w, int b1, int b2, int w_man, int b1_man, int b2_man) 145{ 146 /* white piece on the wrong half-board? */ 147 if(white_addr[w] == -1) 148 return 0; 149 150 /* pieces on the same square? */ 151 if(w == b1) 152 return 0; 153 154 if(w == b2) 155 return 0; 156 157 if(b1 == b2) 158 return 0; 159 160 /* pawn on a bad rank? */ 161 if(w_man == wpawn || w_man == bpawn) 162 if(w < 8 || w > 55) 163 return 0; 164 165 if(b1_man == bpawn || b1_man == wpawn) 166 if(b1 < 8 || b1 > 55) 167 return 0; 168 169 if(b2_man == bpawn || b2_man == wpawn) 170 if(b2 < 8 || b2 > 55) 171 return 0; 172 173 return 1; 174} 175 176int check_result() 177{ 178 int p, xp, res; 179 int wp = 0, bp = 0; 180 int a, j, i; 181 move_s moves[MOVE_BUFF]; 182 int num_moves; 183 184 for (j = 1, a = 1; (a <= piece_count); j++) 185 { 186 i = pieces[j]; 187 188 if (!i) 189 continue; 190 else 191 a++; 192 193 switch (board[i]) 194 { 195 case wpawn: 196 case wbishop: 197 case wrook: 198 case wking: 199 case wqueen: 200 case wknight: wp++; break; 201 case bpawn: 202 case bbishop: 203 case brook: 204 case bking: 205 case bqueen: 206 case bknight: bp++; break; 207 } 208 } 209 210 if (!(wp) && (bp)) 211 { 212 if (white_to_move) 213 { 214 return -127; 215 } 216 else 217 { 218 return 126; 219 } 220 } 221 else if ((!bp) && (wp)) 222 { 223 if (white_to_move) 224 { 225 return 126; 226 } 227 else 228 { 229 return -127; 230 } 231 } 232 233 234 gen(&moves[0]); 235 num_moves = numb_moves; 236 237 if(!num_moves) 238 { 239 if (white_to_move) 240 { 241 p = wp; 242 xp = bp; 243 } 244 else 245 { 246 p = bp; 247 xp = wp; 248 } 249 250 if(p < xp) return -127; 251 else if(xp < p) return 126; /* can't really happen */ 252 else return 0; 253 254 } 255 256 res = egtb(white_to_move); 257 258 if(res > -10 && res < 10 && res) 259 printf("Warning: near zero values!\n"); 260 261 if(res > 0) 262 return -res+1; 263 else if(res < 0 && res > -128) 264 return -res-1; 265 266 return res; 267} 268 269void gen_2piece(int w_man, int b_man, signed char *table) 270{ 271 int i, w, b, t, addr; 272 signed char best, res; 273 int f, unknown; 274 move_s moves[MOVE_BUFF]; 275 int num_moves; 276 277 ply = 1; 278 reset_board(); 279 280 /* initialise the table */ 281 memset(table, -128, TWO_PIECE_SIZE); 282 283 if (!(w_man & 1)) w_man--; 284 if (b_man & 1) b_man++; 285 286 do 287 { 288 f = FALSE; 289 290 for(t = 0; t < 2; t++) 291 { 292 white_to_move = t; 293 294 for(w = 0; w < 64; w++) 295 { 296 for(b = 0; b < 64; b++) 297 { 298 if(!valid_2piece(w, b, w_man, b_man)) continue; 299 300 addr = TWO_PIECE_HASH(t, white_addr[w], b); 301 if(table[addr] != -128) continue; 302 303 board[upscale[w]] = w_man; 304 board[upscale[b]] = b_man; 305 pieces[1] = upscale[w]; 306 pieces[2] = upscale[b]; 307 squares[upscale[w]] = 1; 308 squares[upscale[b]] = 2; 309 piece_count = 2; 310 ep_square = 0; 311 312 gen(&moves[0]); 313 num_moves = numb_moves; 314 315 if(num_moves == 0) 316 { 317 if (table[addr] != 0) f = TRUE; 318 table[addr] = 0; 319 } 320 else 321 { 322 best = -128; 323 unknown = FALSE; 324 325 for(i = 0; i < num_moves; i++) 326 { 327 make(&moves[0], i); 328 res = (signed char) check_result(); 329 unmake(&moves[0], i); 330 331 332 if(res == -128) 333 { 334 unknown = TRUE; 335 continue; 336 } 337 338 if(res > best) best = res; 339 } 340 341 if(best > 0 || (best < 0 && !unknown)) 342 { 343 if (table[addr] != best) f = TRUE; 344 table[addr] = best; 345 } 346 } 347 348 board[upscale[w]] = npiece; 349 board[upscale[b]] = npiece; 350 squares[upscale[w]] = 0; 351 squares[upscale[b]] = 0; 352 pieces[1] = 0; 353 pieces[2] = 0; 354 355 } 356 } 357 } 358 printf("."); 359 } 360 while(f); 361 362 printf("\n"); 363 364 for(i = 0; i < TWO_PIECE_SIZE; i++) 365 if(table[i] == -128) table[i] = 0; 366 367} 368 369 370void gen_3piece(int w_man, int b1_man, int b2_man, signed char *table) 371{ 372 int i, w, b1, b2, t, addr; 373 signed char best, res; 374 int f, unknown; 375 move_s moves[MOVE_BUFF]; 376 int num_moves; 377 378 ply = 1; 379 reset_board(); 380 381 /* initialise the table */ 382 memset(table, -128, THREE_PIECE_SIZE); 383 384 /* normalize colors if needed */ 385 if (!(w_man & 1)) w_man--; 386 if (b1_man & 1) b1_man++; 387 if (b2_man & 1) b2_man++; 388 389 do 390 { 391 f = FALSE; 392 393 for(t = 0; t < 2; t++) 394 { 395 white_to_move = t; 396 397 for(w = 0; w < 64; w++) 398 { 399 for(b1 = 0; b1 < 64; b1++) 400 { 401 for(b2 = 0; b2 < 64; b2++) 402 { 403 404 if(!valid_3piece(w, b1, b2, w_man, b1_man, b2_man)) continue; 405 406 addr = THREE_PIECE_HASH(t, white_addr[w], b1, b2); 407 // if(table[addr] != -128) continue; 408 409 board[upscale[w]] = w_man; 410 board[upscale[b1]] = b1_man; 411 board[upscale[b2]] = b2_man; 412 piece_count = 3; 413 pieces[1] = upscale[w]; 414 pieces[2] = upscale[b1]; 415 pieces[3] = upscale[b2]; 416 squares[upscale[w]] = 1; 417 squares[upscale[b1]] = 2; 418 squares[upscale[b2]] = 3; 419 ep_square = 0; 420 421 gen(&moves[0]); 422 num_moves = numb_moves; 423 424 if(!num_moves) 425 { 426 if (table[addr] != (white_to_move ? 126 : -127)) 427 f = TRUE; 428 table[addr] = (white_to_move ? 126 : -127); 429 } 430 else 431 { 432 best = -128; 433 unknown = FALSE; 434 435 for(i = 0; i < num_moves; i++) 436 { 437 make(&moves[0], i); 438 res = (signed char) check_result(); 439 unmake(&moves[0], i); 440 441 if(res == -128) 442 { 443 unknown = TRUE; 444 continue; 445 } 446 447 if(res > best) best = res; 448 } 449 450 if(best > 0 || (best < 0 && !unknown)) 451 { 452 if (table[addr] != best) f = TRUE; 453 table[addr] = best; 454 } 455 } 456 457 board[upscale[w]] = npiece; 458 board[upscale[b1]] = npiece; 459 board[upscale[b2]] = npiece; 460 squares[upscale[w]] = 0; 461 squares[upscale[b1]] = 0; 462 squares[upscale[b2]] = 0; 463 pieces[1] = 0; 464 pieces[2] = 0; 465 pieces[3] = 0; 466 } 467 } 468 } 469 } 470 printf("."); 471 } 472 while(f); 473 474 printf("\n"); 475 476 for(i = 0; i < THREE_PIECE_SIZE; i++) 477 if(table[i] == -128) table[i] = 0; 478 479} 480 481int save_2piece() 482{ 483 int i, j; 484 FILE *f; 485 signed char *table; 486 487 if(!(f = fopen(TWO_PIECE_FILE, "w"))) return 0; 488 489 for(i = 0; i < 21; i++) 490 { 491 table = two_piece_data + i * TWO_PIECE_SIZE; 492 for(j = 0 ; j < TWO_PIECE_SIZE; j++) 493 { 494 fputc(table[j], f); 495 } 496 } 497 498 fclose(f); 499 return 1; 500} 501 502 503int save_3piece(int w1_man, int b1_man, int b2_man, signed char *t) 504{ 505 FILE *f; 506 signed char fname[13]; 507 signed char *buf; 508 int i; 509 510 /* generate the filename */ 511 512 strcpy(fname, THREE_PIECE_FILE); 513 fname[4] = xpiece_char[w1_man]; 514 fname[5] = xpiece_char[b1_man]; 515 fname[6] = xpiece_char[b2_man]; 516 517 if(!(f = fopen(fname,"w"))) return 0; 518 519 for(i = 0; i < THREE_PIECE_SIZE; i += IO_BUFSIZE) 520 { 521 buf = t + i; 522 523 if(!fwrite(buf, IO_BUFSIZE, 1, f)) 524 { 525 printf("Error writing %s\n",fname); 526 fclose(f); 527 return 0; 528 } 529 } 530 531 fclose(f); 532 return 1; 533} 534 535 536void gen_all_tables() 537{ 538 int w_man, b1_man, b2_man; 539 signed char *base_addr; 540 541 printf("Two-piece tables:\n"); 542 543 /* first generate pawnless tables */ 544 for(w_man = wknight; w_man <= wbishop; w_man += 2) 545 { 546 for(b1_man = bknight; b1_man <= bbishop; b1_man += 2) 547 { 548 if(section_map[section_trans[w_man]][section_trans[b1_man]] == -1) continue; 549 550 printf("Generating %c vs %c ", 551 xpiece_char[w_man], xpiece_char[b1_man]); 552 553 base_addr = two_piece_data 554 + (section_map[section_trans[w_man]][section_trans[b1_man]] * TWO_PIECE_SIZE); 555 556 gen_2piece(w_man, b1_man, base_addr); 557 } 558 } 559 560 /* pawns are the tricky ones that can be promoted, 561 that's why we need the other tables to exist */ 562 w_man = wpawn; 563 for(b1_man = bknight; b1_man <= bbishop; b1_man += 2) 564 { 565 if(section_map[section_trans[w_man]][section_trans[b1_man]] == -1) continue; 566 printf("Generating %c vs %c ", 567 xpiece_char[w_man], xpiece_char[b1_man]); 568 569 base_addr = two_piece_data 570 + (section_map[section_trans[w_man]][section_trans[b1_man]] * TWO_PIECE_SIZE); 571 572 gen_2piece(w_man, b1_man, base_addr); 573 } 574 575 /* finally, pawn vs pawn */ 576 printf("Generating %c vs %c ", 577 xpiece_char[wpawn], xpiece_char[bpawn]); 578 579 base_addr = two_piece_data 580 + (section_map[section_trans[wpawn]][section_trans[bpawn]]*TWO_PIECE_SIZE); 581 582 gen_2piece(wpawn, bpawn, base_addr); 583 584 if(save_2piece()) 585 printf("Saved two-piece tables in %s\n", TWO_PIECE_FILE); 586 587 /* now, start doing pawnless three-piece tables */ 588 589 temp_table = malloc(THREE_PIECE_SIZE); 590 591 if(!temp_table) return; 592 593 for(w_man = wknight; w_man <= wbishop; w_man += 2) 594 for(b1_man = bknight; b1_man <= bbishop ; b1_man += 2) 595 for(b2_man = bknight; b2_man <= bbishop; b2_man += 2) 596 { 597 if(section_map[section_trans[b1_man]][section_trans[b2_man]] == -1) continue; 598 599 printf("Generating %c vs %c+%c ", xpiece_char[w_man], 600 xpiece_char[b1_man], xpiece_char[b2_man]); 601 602 temp_key = TABLE_KEY(section_trans[w_man], 603 section_trans[b1_man], 604 section_trans[b2_man]); 605 gen_3piece(w_man, b1_man, b2_man, temp_table); 606 save_3piece(w_man, b1_man, b2_man, temp_table); 607 } 608 609 610 /* white piece is a pawn */ 611 612 w_man = wpawn; 613 for(b1_man = bknight; b1_man <= bbishop; b1_man += 2) 614 for(b2_man = bknight; b2_man <= bbishop; b2_man += 2) 615 { 616 if(section_map[section_trans[b1_man]][section_trans[b2_man]] == -1) continue; 617 618 printf("Generating %c vs %c+%c ", xpiece_char[w_man], 619 xpiece_char[b1_man], xpiece_char[b2_man]); 620 621 temp_key = TABLE_KEY(section_trans[w_man], 622 section_trans[b1_man], 623 section_trans[b2_man]); 624 gen_3piece(w_man, b1_man, b2_man, temp_table); 625 save_3piece(w_man, b1_man, b2_man, temp_table); 626 } 627 628 /* one black piece is a pawn */ 629 630 for(w_man = wknight; w_man <= wbishop; w_man += 2) 631 { 632 b1_man = bpawn; 633 634 for(b2_man = wknight; b2_man <= bbishop; b2_man += 2) 635 { 636 printf("Generating %c vs %c+%c ", xpiece_char[w_man], 637 xpiece_char[b1_man], xpiece_char[b2_man]); 638 639 temp_key = TABLE_KEY(section_trans[w_man], 640 section_trans[b1_man], 641 section_trans[b2_man]); 642 gen_3piece(w_man, b1_man, b2_man, temp_table); 643 save_3piece(w_man, b1_man, b2_man, temp_table); 644 } 645 } 646 647 w_man = wpawn; 648 b1_man = bpawn; 649 for(b2_man = bknight; b2_man <= bbishop; b2_man += 2) 650 { 651 printf("Generating %c vs %c+%c ", xpiece_char[w_man], 652 xpiece_char[b1_man], xpiece_char[b2_man]); 653 654 temp_key = TABLE_KEY(section_trans[w_man], 655 section_trans[b1_man], 656 section_trans[b2_man]); 657 gen_3piece(w_man, b1_man, b2_man, temp_table); 658 save_3piece(w_man, b1_man, b2_man, temp_table); 659 } 660 661 /* both black pieces are pawns */ 662 663 for(w_man = wknight; w_man <= wbishop; w_man += 2) 664 { 665 b1_man = bpawn; 666 b2_man = bpawn; 667 668 printf("Generating %c vs %c+%c ", xpiece_char[w_man], 669 xpiece_char[b1_man], xpiece_char[b2_man]); 670 671 temp_key = TABLE_KEY(section_trans[w_man], 672 section_trans[b1_man], 673 section_trans[b2_man]); 674 gen_3piece(w_man, b1_man, b2_man, temp_table); 675 save_3piece(w_man, b1_man, b2_man, temp_table); 676 } 677 678 /* three pawns */ 679 680 w_man = wpawn; 681 b1_man = bpawn; 682 b2_man = bpawn; 683 684 printf("Generating %c vs %c+%c ", xpiece_char[w_man], 685 xpiece_char[b1_man], xpiece_char[b2_man]); 686 687 temp_key = TABLE_KEY(section_trans[w_man], 688 section_trans[b1_man], 689 section_trans[b2_man]); 690 gen_3piece(w_man, b1_man, b2_man, temp_table); 691 save_3piece(w_man, b1_man, b2_man, temp_table); 692 693 694 printf("\nAll done.\n"); 695 free(temp_table); 696 697 reset_board(); 698} 699 700 701void free_egtb() 702{ 703 free(two_piece_data); 704 free(three_piece_data); 705} 706 707 708int init_segtb() 709{ 710 int i; 711 712 two_piece_data = malloc(21 * TWO_PIECE_SIZE); 713 three_piece_data = malloc(CACHE_SIZE * THREE_PIECE_SIZE); 714 715 if(!two_piece_data || !three_piece_data) 716 { 717 return FALSE; 718 } 719 720 if(!load_2piece()) 721 { 722 return FALSE; 723 } 724 725 for(i = 0; i < CACHE_SIZE; i++) 726 { 727 table_cache[i].table_key = -1; 728 table_cache[i].last_access = 0; 729 } 730 731 cache_counter = 0; 732 temp_key = -1; 733 734 printf("Two-piece suicide endgame tables preloaded (using %d kB of memory)\n", 735 (21 * TWO_PIECE_SIZE) / 1024); 736 printf("Three-piece suicide endgame table cache %d kB\n", 737 (CACHE_SIZE * THREE_PIECE_SIZE) / 1024); 738 739 return TRUE; 740} 741 742 743int egtb(int s) 744{ 745 int w1_man, w2_man, b1_man, b2_man; 746 int w1, w2, b1, b2; 747 int w_count = 0, b_count = 0; 748 int i, t, temp, junk, bpc; 749 signed char *table; 750 751 /* first figure out what kind of position we have */ 752 753 for(i = 0; i < 64; i++) 754 { 755 bpc = board[upscale[i]]; 756 757 if (bpc == npiece) continue; 758 759 if(bpc & 1) 760 { 761 if(!w_count) 762 { 763 w1_man = bpc; 764 w1 = i; 765 } 766 else 767 { 768 w2_man = bpc; 769 w2 = i; 770 } 771 w_count++; 772 } 773 else 774 { 775 if(!b_count) 776 { 777 b1_man = bpc; 778 b1 = i; 779 } 780 else 781 { 782 b2_man = bpc; 783 b2 = i; 784 } 785 b_count++; 786 } 787 } 788 789 /* two pieces? */ 790 791 if(w_count == 1 && b_count == 1) { 792 793 if(section_map[section_trans[w1_man]][section_trans[b1_man]] == -1) 794 { 795 temp = b1_man; 796 b1_man = w1_man; 797 w1_man = temp; 798 799 temp = b1; 800 801/* angrim: can do this without branch */ 802 803 if(w1_man == wpawn || w1_man == bpawn) 804 { 805 /* pawn color was changed, we need to 806 rotate the board 180 degrees */ 807 b1 = rotate[w1]; 808 w1 = rotate[temp]; 809 } 810 else 811 { 812 b1 = w1; 813 w1 = temp; 814 } 815 816 s ^= 1; 817 } 818 819 table = two_piece_data 820 + (section_map[section_trans[w1_man]][section_trans[b1_man]] * TWO_PIECE_SIZE); 821 822 /* flip the board if necessary */ 823 if(white_addr[w1] == -1) 824 { 825 w1 = vertical_flip[w1]; 826 b1 = vertical_flip[b1]; 827 } 828 829 return (int)table[TWO_PIECE_HASH(s, white_addr[w1], b1)]; 830 831 832 } 833 else if((w_count == 1 && b_count == 2) || 834 (w_count == 2 && b_count == 1)) 835 { /* three pieces */ 836 837 if(w_count > 1) 838 { /* need to switch sides */ 839 840 b2_man = w2_man; 841 temp = w1_man; 842 w1_man = b1_man; 843 b1_man = temp; 844 845 temp = w1; 846 847 if(w1_man == wpawn || w1_man == bpawn || 848 b1_man == bpawn || b1_man == wpawn || 849 b2_man == bpawn || b2_man == wpawn) 850 { 851 /* pawn color was changed, we need to 852 rotate the board 180 degrees */ 853 b2 = rotate[w2]; 854 w1 = rotate[b1]; 855 b1 = rotate[temp]; 856 } 857 else 858 { 859 b2 = w2; 860 w1 = b1; 861 b1 = temp; 862 } 863 864 s ^= 1; 865 } 866 867 /* swap black pieces if necessary */ 868 869 if(section_map[section_trans[b1_man]][section_trans[b2_man]] == -1) 870 { 871 872 temp = b1_man; 873 b1_man = b2_man; 874 b2_man = temp; 875 876 temp = b1; 877 b1 = b2; 878 b2 = temp; 879 } 880 881 /* do the vertical flip */ 882 883 if(white_addr[w1] == -1) 884 { 885 w1 = vertical_flip[w1]; 886 b1 = vertical_flip[b1]; 887 b2 = vertical_flip[b2]; 888 } 889 890 891 /* finally, find the table we need either 892 from memory or disk and return the value */ 893 894 t = TABLE_KEY(section_trans[w1_man], 895 section_trans[b1_man], 896 section_trans[b2_man]); 897 898 if(temp_key == t) /* maybe we're generating a table */ 899 table = temp_table; 900 else 901 { 902 /* check the cache */ 903 904 temp = INT_MAX; 905 cache_counter++; 906 907 for(i = 0; i < CACHE_SIZE; i++) 908 { 909 if(table_cache[i].table_key == t) 910 { 911 table = three_piece_data + (i * THREE_PIECE_SIZE); 912 table_cache[i].last_access = cache_counter; 913 return (int) table[THREE_PIECE_HASH(s, white_addr[w1], b1, b2)]; 914 } 915 else if(table_cache[i].last_access < temp) 916 { 917 temp = table_cache[i].last_access; 918 junk = i; 919 } 920 } 921 /* the table was not in the cache, we'll load 922 it into the least recently accessed slot */ 923 924 table = three_piece_data + (junk * THREE_PIECE_SIZE); 925 926 if(!load_3piece(w1_man, b1_man, b2_man, table)) 927 { 928 //printf("Loading error\n"); 929 table_cache[junk].table_key = -1; 930 return (-128); 931 } 932 table_cache[junk].table_key = t; 933 table_cache[junk].last_access = cache_counter; 934 } 935 936 return (int) table[THREE_PIECE_HASH(s, white_addr[w1], b1, b2)]; 937 938 } 939 else 940 return (-128); /* position not in the tables */ 941 942} 943 944int load_2piece() 945{ 946 int i,j; 947 FILE *f; 948 signed char *table; 949 950 if(!(f = fopen(TWO_PIECE_FILE, "r"))) return 0; 951 952 for(i = 0; i < 21; i++) 953 { 954 table = two_piece_data + i * TWO_PIECE_SIZE; 955 956 for(j = 0; j < TWO_PIECE_SIZE; j++) 957 table[j] = (signed char) fgetc(f); 958 } 959 960 fclose(f); 961 return 1; 962} 963 964int load_3piece(int w1_man, int b1_man, int b2_man, signed char *t) 965{ 966 FILE *f; 967 signed char fname[13]; 968 signed char *buf; 969 int i; 970 971 /* generate the filename */ 972 973 strcpy(fname, THREE_PIECE_FILE); 974 fname[4]= xpiece_char[w1_man]; 975 fname[5]= xpiece_char[b1_man]; 976 fname[6]= xpiece_char[b2_man]; 977 978 if(!(f = fopen(fname,"r"))) return 0; 979 980 for(i = 0; i < THREE_PIECE_SIZE; i += IO_BUFSIZE) 981 { 982 buf = t + i; 983 if(!fread(buf, IO_BUFSIZE, 1, f)) { 984 printf("Error reading %s\n",fname); 985 fclose(f); 986 return 0; 987 } 988 } 989 990 fclose(f); 991 return 1; 992} 993 994 995