sjeng-11.2.orig/0042755000175000017500000000000007473543105012540 5ustar lukaslukassjeng-11.2.orig/BUGS0100644000175000017500000000074507307525251013222 0ustar lukaslukas------------------------------------------ Please submit bug reports to gcp@sjeng.org ------------------------------------------ KNOWN ----- Trouble detecting variants and partner tells on chess.net. This is an XBoard/WinBoard Zippy problem, not related to Sjeng itself. The 'ping' command interrupts the search. 'white' and 'black' do not always work as intended. A condition which ends the game will stop the program when in analysis mode. Loses sometimes. sjeng-11.2.orig/NEWS0100644000175000017500000001464707412720631013240 0ustar lukaslukasSjeng 11.x Bugfixes and portability improvements Sjeng 11 New suicide mode New losers mode perft reports leaf nodes (like crafty) Suicide endgame databases Fix to movegen (>300 possible moves) No nullmove on pv Sjeng 10.0 Lots of stability improvements Minor fix to legal move detection Constrain book learning a little Updated losers and suicide OPN books Sjeng 9.2 Endgame tablebase support (Nalimov up to 6 man) Castling in giveaway is now recognized Fixes some lockups in suicide/giveaway More standard chess knowledge (mobility, passed pawns) Smaller aspiration window Fix to 'st' command Updated docs Fixes to draw detection Cull very rare book lines Full losers support Detect when nullmove is probably bad Less futility pruning in qsearch Sjeng 9.1 Bugfix to time allocation Improved speed benchmark Bugfix: may not castle in suicide (dunno about giveaway) Optimized legal move and incheck tests Added bonus for doubled rooks on (half)open file King tropisms for normal chess Updated suicide opening book Sjeng 9.0 More output during analysis Support for future winboard protocols Tecumseh pruning, smarter check extensions Delay in ptells for mating pieces Smarter handling of depth-preferenced stores Free hash/ecache before bookbuild Tweaks and bugfixes to movegen Fix in bookbuilding Platform independent hashes Extend time on fail-low Got rid of suicide learning (not used anyway) Display settings code on servers Static Exchange Evaluation sorting and pruning Root move sort based on nodecount Use ghost piece to anticipate trades Aggressive backpropagating booklearning Tweaks to kingsafety in standard chess Reply immediately on a forced move Partly merged Dawson eval Allow setting SmartEval and Attackeval Support st command Inform partner when trades are bad Fixed fast mode Fixed warnings in source Allowing switching to PN2 via a #define Squares macros added for easy eval editing Workaround for WinBoard/XBoard zippy bug Fixes for losers movegen Sjeng 8.6 Pick new move if search fails high and times out Optimized QSearch ttable usage Sjeng 8.5 Quiescent hashing Fixed book learning Support for losers's chess Extension tweaks Sjeng 8.3 Fixed serious hashing bug Improved moveordering Improved handling of failed searches More book randomness More aggressive book learning Fixes to Winboard support Detection of Chessbase Winboard adapter Recapture extensions Cleaned up some internal structures Recognizes 50-move and 3-rep draws Sjeng 8.0 Much improved crazyhouse evaluation Support for v2 of xboard/Winboard protocol New suicide mode (no more alpha-beta) Simple book learning Tweaked search & extensions Fixes to xboard/Winboard support (setboard, undo) Use a configuration file Use SAN for move output Small suicide opening book Sjeng 7.5 Suicide opening book Fixes to 'test' command Tweaked zh piece/square tables Tweaked suicide eval Optimized movegenerator Tweaked bookbuilding code Faster proof-number search Fixed MVV/LVA move ordering Better extension control Passed pawn extensions Don't nullmove in endgames More carefull R=4 usage Sjeng 7.4 (2000 WCCC Version) Support for suicide Faster movegenerator Faster search Supports analysis mode for zh games 2-level transposition table Full proof-number and proof-number^2 implementation Sjeng 7.3 Faster move generation/Cleaner code Better handling of failed searches at root Binary book with transpositions Automatic bookbuilder Better time usage Built-in benchmark Partial support for SAN moves Improved evaluation, bad trade, drawn endgames Positional learning fixes Improved forward pruning in search Sjeng 7.2 Fixed an out-of-bounds bug Better support for systems that lack ftime() Sjeng 7.1 Books and tests were added to distribution Sjeng VII Modified piece values as per Gnejs request Faster fast mode more bonusses on partner tells penalty for pawns blocking development Marginal Gnejs book support Removed extra book-loading call removed depth checks from search timing code no interruptions in fast mode narrower ext fut windows again book selection is no longer fixed for zh/bug more random book selection Nullmove R factor is dynamic again more strict check limiter, but quiescent lock is now added for all variants Re-enabled internal iterative deepening Go fast if fellow sjeng is dead Sit if losing a --- piece Automatically tell other sjeng to go if no longer mates us Automatically resign if both dead Fixed serious bug in DPVS Major bugfix to loading of learned data R=3 used if depth > 6 Disable nullmove in endgame near root Fix infinite hi-hi bug -/+ p implies b, q -/+ r implies q -/+ b implies b Sjeng VI Check whether allocated time is smaller than 1 sec in fast mode Disable the bug/zh check-qsearch lock Fixed R=2 Disable internal iterative deepening Wider ext-fut pruning window Improved TTable, mate correction, threat and no-null Capture ordering with king Set f5 to bughouse or crazyhouse depending on whether we have a partner Limit check extensions Fixes to variant-switching code Sjeng Vb-Vc Don't try to print search results if mated Enable the EPD parser Disable razoring at root Fix/reorder ptell for bugs Sjeng V abort and flag ptell commands added Only sit if mated in 2 or 1 Don't whisper while playing bug Give warning on + or -piece commands (temporary) 'time' aliased to 'fast' Fixed a bug with the '.' command while analyzing Fixed bugs in edit mode (don't change side to move) Removed early-mate-breaking Fix : dont reset pondering status on newgame Added move-now support (main search may be interrupted now) Added periodic update support Added support for 'st' command (untested) Fixed bug with changing material values & variants Fixed bug with king values (missing sign) Added status output after searching PV at root level Allow qsearch while in check if standard chess Fix to move ordering in internal deepening nodes Severe bugfix in history move ordering Speedups to makemove/unmakemove in standard chess Root PVS uses an aspiration window now (REMOVED) Don't razor the PV More bonus for pawn @f7 and less for king stepping there Alias "move" to "go" Don't accept ptells in standard mode Alias "=" to "x" Futility pruing, extended futility pruning and limited razoring can be toggled Fixed longstanding bug with ep squares Made pawn bonusses more dynamic sjeng-11.2.orig/TODO0100644000175000017500000000017107307525313013217 0ustar lukaslukasTODO Nothing. This thing is getting messier, buggier, slower and less maintainable with each release. Time to move on. sjeng-11.2.orig/crazy.c0100644000175000017500000001575207323305224014031 0ustar lukaslukas/* Sjeng - a chess variants playing program Copyright (C) 2000 Gian-Carlo Pascutto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA File: crazy.c Purpose: bughouse/crazyhouse specific functions */ #include #include "sjeng.h" #include "protos.h" #include "extvars.h" int holding[2][16]; int num_holding[2]; char realholdings[255]; int userealholdings; int drop_piece; int white_hand_eval; int black_hand_eval; unsigned long hold_hash; #define HHash(x,y) (hold_hash ^= zobrist[(x)][(y)]) /* input example : holding [BPPP] [QR] */ /* based on db's parser */ void ProcessHoldings(char str[]) { int c, i; i = 0; memset(holding, 0, sizeof(holding)); hold_hash = 0xC0FFEE00; white_hand_eval = 0; black_hand_eval = 0; reset_ecache(); num_holding[WHITE] = 0; num_holding[BLACK] = 0; for(c = WHITE; c <= BLACK; c++) { while(str[i++] != '[') if(str[i] == 0) return; while(str[i] != ']') { switch(str[i++]) { case 'p': case 'P': holding[c][c == WHITE ? wpawn : bpawn]++; num_holding[c]++; HHash((c == WHITE ? wpawn : bpawn), holding[c][(c == WHITE ? wpawn : bpawn)]); break; case 'q': case 'Q': holding[c][c == WHITE ? wqueen : bqueen]++; num_holding[c]++; HHash((c == WHITE ? wqueen : bqueen), holding[c][(c == WHITE ? wqueen : bqueen)]); break; case 'r': case 'R': holding[c][c == WHITE ? wrook : brook]++; num_holding[c]++; HHash((c == WHITE ? wrook : brook), holding[c][(c == WHITE ? wrook : brook)]); break; case 'b': case 'B': holding[c][c == WHITE ? wbishop : bbishop]++; num_holding[c]++; HHash((c == WHITE ? wbishop : bbishop), holding[c][(c == WHITE ? wbishop : bbishop)]); break; case 'n': case 'N': holding[c][c == WHITE ? wknight : bknight]++; num_holding[c]++; HHash((c == WHITE ? wknight : bknight), holding[c][(c == WHITE ? wknight : bknight)]); break; default: return; } } } /* no fake pieces in crazyhouse! */ if (Variant == Bughouse && !userealholdings) { strncpy(realholdings, str, 200); if (comp_color == 1) { /* computer is white*/ if (holding[BLACK][bpawn] == 0) { holding[BLACK][bpawn]++; num_holding[BLACK]++; HHash(bpawn, holding[BLACK][bpawn]); } if (holding[BLACK][bbishop] == 0) { holding[BLACK][bbishop]++; num_holding[BLACK]++; HHash(bpawn, holding[BLACK][bbishop]); } if (holding[BLACK][bknight] == 0) { holding[BLACK][bknight]++; num_holding[BLACK]++; HHash(bknight, holding[BLACK][bknight]); } if (holding[BLACK][brook] == 0) { holding[BLACK][brook]++; num_holding[BLACK]++; HHash(bknight, holding[BLACK][brook]); } if (holding[BLACK][bqueen] == 0) { holding[BLACK][bqueen]++; num_holding[BLACK]++; HHash(bknight, holding[BLACK][bqueen]); } } else { /* computer is black*/ if (holding[WHITE][wqueen] == 0) { holding[WHITE][wqueen]++; num_holding[WHITE]++; HHash(wqueen, holding[WHITE][wqueen]); } if (holding[WHITE][wrook] == 0) { holding[WHITE][wrook]++; num_holding[WHITE]++; HHash(wqueen, holding[WHITE][wrook]); } if (holding[WHITE][wbishop] == 0) { holding[WHITE][wbishop]++; num_holding[WHITE]++; HHash(wqueen, holding[WHITE][wbishop]); } if (holding[WHITE][wknight] == 0) { holding[WHITE][wknight]++; num_holding[WHITE]++; HHash(wqueen, holding[WHITE][wknight]); } if (holding[WHITE][wpawn] == 0) { holding[WHITE][wpawn]++; num_holding[WHITE]++; HHash(wqueen, holding[WHITE][wpawn]); } } } } int text_to_piece(char txt, int who) { switch(txt) { case 'p': case 'P': return (who == WHITE ? wpawn : bpawn); case 'b': case 'B': return (who == WHITE ? wbishop : bbishop); case 'n': case 'N': return (who == WHITE ? wknight : bknight); case 'r': case 'R': return (who == WHITE ? wrook : brook); case 'q': case 'Q': return (who == WHITE ? wqueen : bqueen); }; return npiece; } int SwitchColor(int piece) { int t[] = { 0, bpawn, wpawn, bknight, wknight, 0, 0, brook, wrook, bqueen, wqueen, bbishop, wbishop }; assert(piece > frame && piece < npiece); return(t[piece]); } int SwitchPromoted(int piece) { int t[] = { 0, bpawn, wpawn, bpawn, wpawn, 0, 0, bpawn, wpawn, bpawn, wpawn, bpawn, wpawn }; assert(piece > frame && piece < npiece); return(t[piece]); } void addHolding(int what, int who) { if (Variant == Crazyhouse) { holding[who][what]++; num_holding[who]++; HHash(what, holding[who][what]); }; if (who == WHITE) white_hand_eval += hand_value[what]; else black_hand_eval += hand_value[what]; Material += material[what]; return; } void removeHolding(int what, int who) { if (Variant == Crazyhouse) { assert(holding[who][what] > 0); assert(holding[who][what] < 20); HHash(what, holding[who][what]); holding[who][what]--; num_holding[who]--; } if (who == WHITE) white_hand_eval -= hand_value[what]; else black_hand_eval -= hand_value[what]; Material -= material[what]; return; } void DropaddHolding(int what, int who) { holding[who][what]++; num_holding[who]++; HHash(what, holding[who][what]); if (who == WHITE) white_hand_eval += hand_value[what]; else black_hand_eval += hand_value[what]; Material += material[what]; return; } void DropremoveHolding(int what, int who) { assert(holding[who][what] > 0); assert(holding[who][what] < 20); HHash(what, holding[who][what]); holding[who][what]--; num_holding[who]--; if (who == WHITE) white_hand_eval -= hand_value[what]; else black_hand_eval -= hand_value[what]; Material -= material[what]; return; } void printHolding(void) { printf("WP: %d WR: %d WB: %d WN: %d WQ: %d\n", holding[WHITE][wpawn], holding[WHITE][wrook], holding[WHITE][wbishop], holding[WHITE][wknight], holding[WHITE][wqueen]); printf("BP: %d BR: %d BB: %d BN: %d BQ: %d\n", holding[BLACK][bpawn], holding[BLACK][brook], holding[BLACK][bbishop], holding[BLACK][bknight], holding[BLACK][bqueen]); } sjeng-11.2.orig/partner.c0100644000175000017500000005146607307525506014367 0ustar lukaslukas/* Sjeng - a chess variants playing program Copyright (C) 2000 Gian-Carlo Pascutto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA File: partner.c Purpose: handle partner communication */ #include "sjeng.h" #include "protos.h" #include "extvars.h" int hand_value[] = { 0, 100, -100, 210, -210, 0, 0, 250, -250, 450, -450, 230, -230 }; int std_hand_value[] = { 0, 100, -100, 210, -210, 0, 0, 250, -250, 450, -450, 230, -230 }; bool piecedead; bool partnerdead; int must_go; void ResetHandValue(void) { memcpy(hand_value, std_hand_value, sizeof(hand_value)); } void BegForPartner(void) { if (xb_mode) { /* printf("tellics tell 24 partner please\n"); */ } return; }; void GreetPartner() { printf("tellics ptell Hello! I am Sjeng and hope you enjoy playing with me.\n"); printf("tellics ptell For help on some commands that I understand, ptell me \'help\'\n"); return; }; void HandlePartner(char *input) { if (input[0] == ' ') { if (!have_partner) { /* catch bogus xboard repartnering */ sscanf(input+1, "%s", my_partner); have_partner = TRUE; GreetPartner(); printf("tellics set f5 bughouse\n"); printf("tellics unseek\n"); } } else { memset(my_partner, 0, sizeof(my_partner)); have_partner = FALSE; BegForPartner(); printf("tellics set f5 1=1\n"); } }; void HandlePtell(char *input) { int change = 0; char howmuch[80] = "is...uh...what did you say?\n"; if (!strncmp(input+6, "help", 4)) { printf("tellics ptell Commands that I understand are : sit, go, fast, slow, abort, flag, +/++/+++/-/--/---{p,n,b,r,q,d,h,trades}, x, dead, formula, help.\n"); return; } if (Variant != Bughouse && (strncmp(input+6, "sorry", 5))) { printf("tellics ptell Sorry, but I'm not playing a bughouse game.\n"); return; } if (!strncmp(input+6, "sit", 3)) { printf("tellics ptell Ok, I sit next move. Tell me when to go.\n"); must_sit = TRUE; must_go = 0; } else if (!strncmp(input+6, "go", 2) || (!strncmp(input+6, "move", 4))) { printf("tellics ptell Ok, I'm moving.\n"); must_sit = FALSE; must_go = 4; } else if (!strncmp(input+6, "fast", 4) || (!strncmp(input+6, "time", 4))) { printf("tellics ptell Ok, I'm going FAST!\n"); go_fast = TRUE; must_sit = FALSE; } else if (!strncmp(input+6, "slow", 4)) { printf("tellics ptell Ok, moving normally.\n"); go_fast = FALSE; must_sit = FALSE; } else if (!strncmp(input+6, "abort", 5)) { printf("tellics ptell Requesting abort...\n"); printf("tellics abort\n"); } else if (!strncmp(input+6, "flag", 4)) { printf("tellics ptell Flagging...\n"); printf("tellics flag\n"); } else if (!strncmp(input+6, "+", 1)) { /* trades are handled seperately */ if ((strstr(input+6, "trade") != NULL) /* either an explicit trade request */ || ( /* or there's just no piece in the string */ (strstr(input+6, "n") == NULL) && (strstr(input+6, "b") == NULL) && (strstr(input+6, "p") == NULL) && (strstr(input+6, "r") == NULL) && (strstr(input+6, "q") == NULL) && (strstr(input+6, "d") == NULL) && (strstr(input+6, "h") == NULL))) { if (comp_color == 1) { hand_value[wpawn] += 25; hand_value[wknight] += 50; hand_value[wbishop] += 50; hand_value[wrook] += 50; hand_value[wqueen] += 100; } else { hand_value[bpawn] -= 25; hand_value[bknight] -= 50; hand_value[bbishop] -= 50; hand_value[brook] -= 50; hand_value[bqueen] -= 100; } printf("tellics ptell Ok, trading is GOOD\n"); } /* first, find how much we want that piece */ else if (strstr(input+6, "+++") != NULL) { change = 50000; strcpy(howmuch, "mates"); } else if (strstr(input+6, "++") != NULL) { change = 1000; strcpy(howmuch, "is VERY good (ptell me 'x' to play normal again)"); } else if (strstr(input+6, "+") != NULL) { change = 150; strcpy(howmuch, "is good (ptell me 'x' to play normal again)"); } else DIE; /* now find which piece we want */ if (strstr(input+6, "n") != NULL) { if (comp_color == 1) /* we want a black knight-> the value for holding a white knight rises */ hand_value[wknight] = std_hand_value[wknight] + change; else /* we want a white knight */ hand_value[bknight] = std_hand_value[bknight] - change; printf("tellics ptell Ok, Knight %s\n", howmuch); } if (strstr(input+6, "b") != NULL) { if (comp_color == 1) hand_value[wbishop] = std_hand_value[wbishop] + change; else hand_value[bbishop] = std_hand_value[bbishop] - change; /* b is good, so q is good too */ if (comp_color == 1) hand_value[wqueen] = std_hand_value[wqueen] + change; else hand_value[bqueen] = std_hand_value[bqueen] - change; printf("tellics ptell Ok, Bishop %s\n", howmuch); } if (strstr(input+6, "r") != NULL) { if (comp_color == 1) hand_value[wrook] = std_hand_value[wrook] + change; else hand_value[brook] = std_hand_value[brook] - change; /* r is good, so q is good too */ if (comp_color == 1) hand_value[wqueen] = std_hand_value[wqueen] + change; else hand_value[bqueen] = std_hand_value[bqueen] - change; printf("tellics ptell Ok, Rook %s\n", howmuch); } if (strstr(input+6, "q") != NULL) { if (comp_color == 1) hand_value[wqueen] = std_hand_value[wqueen] + change; else hand_value[bqueen] = std_hand_value[bqueen] - change; printf("tellics ptell Ok, Queen %s\n", howmuch); } if (strstr(input+6, "p") != NULL) { if (comp_color == 1) hand_value[wpawn] = std_hand_value[wpawn] + change; else hand_value[bpawn] = std_hand_value[bpawn] - change; /* p is good, so b and q are good too */ if (comp_color == 1) { hand_value[wqueen] = std_hand_value[wqueen] + change; hand_value[wbishop] = std_hand_value[wbishop] + change; } else { hand_value[bqueen] = std_hand_value[bqueen] - change; hand_value[bbishop] = std_hand_value[bbishop] - change; } printf("tellics ptell Ok, Pawn %s\n", howmuch); } if (strstr(input+6, "d") != NULL) { if (comp_color == 1) { hand_value[wpawn] = std_hand_value[wpawn] + change; hand_value[wbishop] = std_hand_value[wbishop] + change; hand_value[wqueen] = std_hand_value[wqueen] + change; } else { hand_value[bpawn] = std_hand_value[bpawn] - change; hand_value[bbishop] = std_hand_value[bbishop] - change; hand_value[bqueen] = std_hand_value[bqueen] - change; } printf("tellics ptell Ok, Diagonal %s\n", howmuch); } if (strstr(input+6, "h") != NULL) { if (comp_color == 1) { hand_value[wrook] = std_hand_value[wrook] + change; hand_value[wqueen] = std_hand_value[wqueen] + change; } else { hand_value[brook] = std_hand_value[brook] - change; hand_value[bqueen] = std_hand_value[bqueen] - change; } printf("tellics ptell Ok, Heavy %s\n", howmuch); } } else if (!strncmp(input+6, "-", 1)) { /* trades are handled seperately */ if ((strstr(input+6, "trade") != NULL) /* either an explicit trade request */ || ( /* or there's just no piece in the string */ (strstr(input+6, "n") == NULL) && (strstr(input+6, "b") == NULL) && (strstr(input+6, "p") == NULL) && (strstr(input+6, "r") == NULL) && (strstr(input+6, "q") == NULL) && (strstr(input+6, "d") == NULL) && (strstr(input+6, "h") == NULL))) { if (comp_color == 1) { hand_value[bpawn] -= 20; hand_value[bknight] -= 50; hand_value[bbishop] -= 50; hand_value[brook] -= 50; hand_value[bqueen] -= 100; } else { hand_value[wpawn] += 20; hand_value[wknight] += 50; hand_value[wbishop] += 50; hand_value[wrook] += 50; hand_value[wqueen] += 100; } printf("tellics ptell Ok, trading is BAD\n"); } /* first, find how bad we want to avoid losing that piece */ else if (strstr(input+6, "---") != NULL) { change = 50000; strcpy(howmuch, "mates you (ptell me 'x' when it no longer mates you)"); } else if (strstr(input+6, "--") != NULL) { change = 1000; strcpy(howmuch, "is VERY bad (ptell me 'x' when it is no longer bad)"); } else if (strstr(input+6, "-") != NULL) { change = 150; strcpy(howmuch, "is bad (ptell me 'x' when it is no longer bad)"); } else DIE; if (strstr(input+6, "n") != NULL) { if (comp_color == 1) hand_value[bknight] = std_hand_value[bknight] - change; else hand_value[wknight] = std_hand_value[wknight] + change; printf("tellics ptell Ok, Knight %s\n", howmuch); } if (strstr(input+6, "b") != NULL) { if (comp_color == 1) hand_value[bbishop] = std_hand_value[bbishop] - change; else hand_value[wbishop] = std_hand_value[wbishop] + change; /* b is bad, so q is bad too */ if (comp_color == 1) hand_value[bqueen] = std_hand_value[bqueen] - change; else hand_value[wqueen] = std_hand_value[wqueen] + change; printf("tellics ptell Ok, Bishop %s\n", howmuch); } if (strstr(input+6, "r") != NULL) { if (comp_color == 1) hand_value[brook] = std_hand_value[brook] - change; else hand_value[wrook] = std_hand_value[wrook] + change; /* r is bad, so q is bad too */ if (comp_color == 1) hand_value[bqueen] = std_hand_value[bqueen] - change; else hand_value[wqueen] = std_hand_value[wqueen] + change; printf("tellics ptell Ok, Rook %s\n", howmuch); } if (strstr(input+6, "q") != NULL) { if (comp_color == 1) hand_value[bqueen] = std_hand_value[bqueen] - change; else hand_value[wqueen] = std_hand_value[wqueen] + change; printf("tellics ptell Ok, Queen %s\n", howmuch); } if (strstr(input+6, "p") != NULL) { if (comp_color == 1) hand_value[bpawn] = std_hand_value[bpawn] - change; else hand_value[wpawn] = std_hand_value[wpawn] + change; /* p is bad, so b and q are bad too */ if (comp_color == 1) { hand_value[bqueen] = std_hand_value[bqueen] - change; hand_value[bbishop] = std_hand_value[bbishop] - change; } else { hand_value[wqueen] = std_hand_value[wqueen] + change; hand_value[wbishop] = std_hand_value[wbishop] + change; } printf("tellics ptell Ok, Pawn %s\n", howmuch); } if (strstr(input+6, "d") != NULL) { if (comp_color == 1) { hand_value[bpawn] = std_hand_value[bpawn] - change; hand_value[bbishop] = std_hand_value[bbishop] - change; hand_value[bqueen] = std_hand_value[bqueen] - change; } else { hand_value[wpawn] = std_hand_value[wpawn] + change; hand_value[wbishop] = std_hand_value[wbishop] + change; hand_value[wqueen] = std_hand_value[wqueen] + change; } printf("tellics ptell Ok, Diagonal %s\n", howmuch); } if (strstr(input+6, "h") != NULL) { if (comp_color == 1) { hand_value[brook] = std_hand_value[brook] - change; hand_value[bqueen] = std_hand_value[bqueen] - change; } else { hand_value[wrook] = std_hand_value[wrook] + change; hand_value[wqueen] = std_hand_value[wqueen] + change; } printf("tellics ptell Ok, Heavy %s\n", howmuch); } } else if (((!strncmp(input+6, "x", 1) || (strstr(input+6, "mate me anymore") != NULL) || ((strstr(input+6, "never") != NULL) && (strstr(input+6, "mind") != NULL))) || (!strncmp(input+6, "=", 1))) && (strstr(input+6, "ptell me") == NULL)) { printf("tellics ptell Ok, reverting to STANDARD piece values!\n"); ResetHandValue(); must_sit = FALSE; partnerdead = FALSE; piecedead = FALSE; } else if (!strncmp(input+6, "i'll have to sit...(dead)", 25) || !strncmp(input+6, "dead", 4)) { /* fellow sjeng is dead -> give it all we've got */ go_fast = TRUE; must_sit = FALSE; partnerdead = TRUE; /* maybe also here tell go if partner is sjeng ? */ } else if (!strncmp(input+6, "i'll have to sit...(piece)", 26)) { /* fellow sjeng is dead -> get safe fast */ go_fast = TRUE; must_sit = FALSE; piecedead = TRUE; } else if (!strncmp(input+6, "sorry", 5)) { return; } else if (!strncmp(input+6, "ok", 2)) { return; } else if (!strncmp(input+6, "hi", 2) || (!strncmp(input+6, "hello", 5))) { printf("tellics ptell Greetings.\n"); } else if (strstr(input+6, "formula") != NULL) { printf("tellics ptell Setting formula, if you are still interrupted, complain to my operator.\n"); printf("tellics set f5 bughouse\n"); } else { printf("tellics ptell Sorry, but I don't understand that command.\n"); } return; } #define CANCEL_THRESH 3 void CheckBadFlow(bool reset) { move_s hismoves[MOVE_BUFF]; move_s ourmoves[MOVE_BUFF]; int his_num_moves, our_num_moves, j, i, ic, icc; bool othermove = FALSE; int pawnmates = FALSE, knightmates = FALSE, bishopmates = FALSE, rookmates = FALSE, queenmates = FALSE; static int pawnmated = FALSE, knightmated = FALSE, bishopmated = FALSE, rookmated = FALSE, queenmated = FALSE; bool pawnwarn = FALSE, knightwarn = FALSE, bishopwarn = FALSE, rookwarn = FALSE, queenwarn = FALSE; if (reset) { pawnmated = FALSE; knightmated = FALSE; bishopmated = FALSE; rookmated = FALSE; queenmated = FALSE; return; } ic = in_check(); if (!holding[!white_to_move][(white_to_move ? wpawn : bpawn)]) { DropaddHolding((white_to_move ? wpawn : bpawn) , !white_to_move); gen(&hismoves[0]); his_num_moves = numb_moves; for(i = 0; (i < his_num_moves) && (pawnmates == FALSE); i++) { make(&hismoves[0], i); if (check_legal(&hismoves[0], i, ic)) { pawnmates = CANCEL_THRESH; icc = in_check(); gen(&ourmoves[0]); our_num_moves = numb_moves; for (j = 0; (j < our_num_moves) && (pawnmates != FALSE); j++) { make(&ourmoves[0], j); if (check_legal(&ourmoves[0], j, icc)) pawnmates = FALSE; unmake(&ourmoves[0], j); } } unmake(&hismoves[0], i); } DropremoveHolding((white_to_move ? wpawn : bpawn), !white_to_move); } if (!holding[!white_to_move][(white_to_move ? wknight : bknight)]) { DropaddHolding((white_to_move ? wknight : bknight) , !white_to_move); gen(&hismoves[0]); his_num_moves = numb_moves; for(i = 0; (i < his_num_moves) && (knightmates == FALSE); i++) { make(&hismoves[0], i); if (check_legal(&hismoves[0], i, ic)) { knightmates = CANCEL_THRESH; icc = in_check(); gen(&ourmoves[0]); our_num_moves = numb_moves; for (j = 0; (j < our_num_moves) && (knightmates != FALSE); j++) { make(&ourmoves[0], j); if (check_legal(&ourmoves[0], j, icc)) knightmates = FALSE; unmake(&ourmoves[0], j); } } unmake(&hismoves[0], i); } DropremoveHolding((white_to_move ? wknight : bknight), !white_to_move); } if (!holding[!white_to_move][(white_to_move ? wbishop : bbishop)]) { DropaddHolding((white_to_move ? wbishop : bbishop) , !white_to_move); gen(&hismoves[0]); his_num_moves = numb_moves; for(i = 0; (i < his_num_moves) && (bishopmates == FALSE); i++) { make(&hismoves[0], i); if (check_legal(&hismoves[0], i, ic)) { bishopmates = CANCEL_THRESH; icc = in_check(); gen(&ourmoves[0]); our_num_moves = numb_moves; for (j = 0; (j < our_num_moves) && (bishopmates != FALSE); j++) { make(&ourmoves[0], j); if (check_legal(&ourmoves[0], j, icc)) bishopmates = FALSE; unmake(&ourmoves[0], j); } } unmake(&hismoves[0], i); } DropremoveHolding((white_to_move ? wbishop : bbishop), !white_to_move); } if (!holding[!white_to_move][(white_to_move ? wrook : brook)]) { DropaddHolding((white_to_move ? wrook : brook) , !white_to_move); gen(&hismoves[0]); his_num_moves= numb_moves; for(i = 0; (i < his_num_moves) && (rookmates == FALSE); i++) { make(&hismoves[0], i); if (check_legal(&hismoves[0], i, ic)) { rookmates = CANCEL_THRESH; icc = in_check(); gen(&ourmoves[0]); our_num_moves = numb_moves; for (j = 0; (j < our_num_moves) && (rookmates != FALSE); j++) { make(&ourmoves[0], j); if (check_legal(&ourmoves[0], j, icc)) rookmates = FALSE; unmake(&ourmoves[0], j); } } unmake(&hismoves[0], i); } DropremoveHolding((white_to_move ? wrook : brook), !white_to_move); } if (!holding[!white_to_move][(white_to_move ? wqueen : bqueen)]) { DropaddHolding((white_to_move ? wqueen : bqueen) , !white_to_move); gen(&hismoves[0]); his_num_moves= numb_moves; for(i = 0; (i < his_num_moves) && (queenmates == FALSE); i++) { make(&hismoves[0], i); if (check_legal(&hismoves[0], i, ic)) { queenmates = CANCEL_THRESH; icc = in_check(); gen(&ourmoves[0]); our_num_moves = numb_moves; for (j = 0; (j < our_num_moves) && (queenmates != FALSE); j++) { make(&ourmoves[0], j); if (check_legal(&ourmoves[0], j, icc)) queenmates = FALSE; unmake(&ourmoves[0], j); } } unmake(&hismoves[0], i); } DropremoveHolding((white_to_move ? wqueen : bqueen), !white_to_move); } /* order in which we tell things is important if we partner ourselves */ /* only update if changed */ if (pawnmates != pawnmated) { if (pawnmates == CANCEL_THRESH) pawnwarn = TRUE; else if (pawnmates == 0 && pawnmated == 0) { printf("tellics ptell p doesn't mate me anymore\n"); othermove = TRUE; } } if (knightmates != knightmated) { if (knightmates == CANCEL_THRESH) knightwarn = TRUE; else if (knightmates == 0 && knightmated == 0) { printf("tellics ptell n doesn't mate me anymore\n"); othermove = TRUE; } } if (bishopmates != bishopmated) { if (bishopmates == CANCEL_THRESH) bishopwarn = TRUE; else if (bishopmates == 0 && bishopmated == 0) { printf("tellics ptell b doesn't mate me anymore\n"); othermove = TRUE; } } if (rookmates != rookmated) { if (rookmates == CANCEL_THRESH) rookwarn = TRUE; else if (rookmates == 0 && rookmated == 0) { printf("tellics ptell r doesn't mate me anymore\n"); othermove = TRUE; } } if (queenmates != queenmated) { if (queenmates == CANCEL_THRESH) queenwarn = TRUE; else if (queenmates == 0 && queenmated == 0) { printf("tellics ptell q doesn't mate me anymore\n"); othermove = TRUE; } } if (pawnwarn) printf("tellics ptell ---p\n"); if (knightwarn) printf("tellics ptell ---n\n"); if (bishopwarn) printf("tellics ptell ---b\n"); if (rookwarn) printf("tellics ptell ---r\n"); if (queenwarn) printf("tellics ptell ---q\n"); /* if other sjeng had to sit because of piece-loss, he may be able to go now */ if (piecedead && othermove) { piecedead = FALSE; printf("tellics ptell x\n"); printf("tellics ptell go\n"); go_fast = FALSE; } (pawnmates) ? (pawnmated = pawnmates) : (pawnmated--); (bishopmates) ? (bishopmated = bishopmates) : (bishopmated--); (rookmates) ? (rookmated = rookmates) : (rookmated--); (queenmates) ? (queenmated = queenmates) : (queenmated--); (knightmates) ? (knightmated = knightmates) : (knightmated--); return; } sjeng-11.2.orig/books/0042755000175000017500000000000007473543040013653 5ustar lukaslukassjeng-11.2.orig/books/suicide.opn0100644000175000017500000000212307307524746016017 0ustar lukaslukasa2a4 b7b5 a4b5 b8a6 e2e3 e7e6 b2b3 b7b6 f1a6 b8a6 g1h3 e2e3 e7e6 f1a6 b8a6 e2e3 e7e6 b2b4 f8b4 d1g4! b4d2 g4g7! d2e3 c1e3! e2e3 e7e6 d1f3 f8a3 b2a3 d8g5 f3b7 g8g2 b7b8? g2h1! e2e3 d7d6? d1g4! c8g4? e1d1! g4d1? a2a3! d1c2? a1a2! e2e3 d7d5? d1g4! c8g4? e1d1! g4d1? a2a3! d1c2? a1a2! e2e3 b7b5? f1b5 g8h6? b5d7! e8d7? g2g4! e2e3 b7b5? f1b5 c8b7? b5d7! b7g2? d7e8! d8d2? e8f7! g2h1? b1d2! h1f3? f7g8! h8g8? d1f3! b8d7? f3a8! g2g3 b7b6 c2c4 g2g3 g7g6 b2b3 c7c5 c2c4 g2g3 g7g5 g2g3 b7b5 g1h3 g2g3 d7d5? e2e4! d5e4? d1g4! c8g4? e1d1! g2g3 d7d5? e2e4! d5e4? d1g4! d8d2? c1d2! c8g4? e1d1! g2g3 e7e6? b2b4! c8b4? f1g2! b4d2? g2b7! g2g3 e7e5? b2b4! c8b4? f1g2! b4d2? g2b7! g2g3 g8f6? e2e4! f6e4? d1f3! e4g3? f3b7! g3h1? b7b8! g2g3 g8f6? e2e4! f6e4? d1f3! e4d2? f3b7! g2g3 g8f6? e2e4! f6e4? d1f3! e4f2? f3b7! c8b7? e1f2! b7h1? f1a6! b8a6? b2b4! g2g3 g8f6? e2e4! f6e4? d1f3! e4f2? f3b7! g3h1? b7b8! a8b8? b2b4! b8b4? f1a6! c8a6? c2c4! c2c4 b7b5 c2b5 c8a6 b2b3 g7g6 c2c4 b7b5 g1h3 e7e5? h3f4! e5f4 b2b4! f8b4 c1b2! b4d2 b2g7! d2e1 g7h8! e1f2 d1d7! b1a3 c7c5? b2b4! c5b4? c1b2! b4a3? b2g7! f8g7? d1b1! g7a1? b1b7! c8b7?sjeng-11.2.orig/books/Makefile.am0100644000175000017500000000005407307524730015702 0ustar lukaslukasEXTRA_DIST = bug.opn suicide.opn losers.opn sjeng-11.2.orig/books/Makefile.in0100644000175000017500000001014307412717725015720 0ustar lukaslukas# Makefile.in generated automatically by automake 1.4 from Makefile.am # Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. SHELL = @SHELL@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ sbindir = @sbindir@ libexecdir = @libexecdir@ datadir = @datadir@ sysconfdir = @sysconfdir@ sharedstatedir = @sharedstatedir@ localstatedir = @localstatedir@ libdir = @libdir@ infodir = @infodir@ mandir = @mandir@ includedir = @includedir@ oldincludedir = /usr/include DESTDIR = pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. ACLOCAL = @ACLOCAL@ AUTOCONF = @AUTOCONF@ AUTOMAKE = @AUTOMAKE@ AUTOHEADER = @AUTOHEADER@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ transform = @program_transform_name@ NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : CC = @CC@ CXX = @CXX@ MAKEINFO = @MAKEINFO@ PACKAGE = @PACKAGE@ VERSION = @VERSION@ EXTRA_DIST = bug.opn suicide.opn losers.opn mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = ../config.h CONFIG_CLEAN_FILES = DIST_COMMON = Makefile.am Makefile.in DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = tar GZIP_ENV = --best all: all-redirect .SUFFIXES: $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps books/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) \ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status tags: TAGS TAGS: distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) subdir = books distdir: $(DISTFILES) @for file in $(DISTFILES); do \ d=$(srcdir); \ if test -d $$d/$$file; then \ cp -pr $$/$$file $(distdir)/$$file; \ else \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ || cp -p $$d/$$file $(distdir)/$$file || :; \ fi; \ done info-am: info: info-am dvi-am: dvi: dvi-am check-am: all-am check: check-am installcheck-am: installcheck: installcheck-am install-exec-am: install-exec: install-exec-am install-data-am: install-data: install-data-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am install: install-am uninstall-am: uninstall: uninstall-am all-am: Makefile all-redirect: all-am install-strip: $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install installdirs: mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) -rm -f config.cache config.log stamp-h stamp-h[0-9]* maintainer-clean-generic: mostlyclean-am: mostlyclean-generic mostlyclean: mostlyclean-am clean-am: clean-generic mostlyclean-am clean: clean-am distclean-am: distclean-generic clean-am distclean: distclean-am maintainer-clean-am: maintainer-clean-generic distclean-am @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." maintainer-clean: maintainer-clean-am .PHONY: tags distdir info-am info dvi-am dvi check check-am \ installcheck-am installcheck install-exec-am install-exec \ install-data-am install-data install-am install uninstall-am uninstall \ all-redirect all-am all installdirs mostlyclean-generic \ distclean-generic clean-generic maintainer-clean-generic clean \ mostlyclean distclean maintainer-clean # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: sjeng-11.2.orig/books/losers.opn0100644000175000017500000000205707307524752015704 0ustar lukaslukasa2a4 a7a5 h2h3 a2a4 e7e5? b2b4! f8b4? h2h4! a2a3 b7b5 a2a3 e7e5? c2c3! f8a3? b2a3! a2a3 e7e5? h2h4! f8a3? b2a3! d8h4? h1h4! a2a3 e7e5? d2d4! e5d4? d1d4! f8a3? b1a3! a2a3 c7c6 h2h3 a7a6 c2c3 h7h6 a2a3 e7e5? h2h4 b2b4 e7e5? e2e3! f8b4? d1e2! b4d2? c1d2! b2b3 e7e5? b2b4! c2c3 a7a6? a2a4! a6a5? c3c4! b7b5? c6b5! c2c3 b7b6 a2a3 c2c3 c7c5 a2a4 a7a6 c2c3 c7c6 a2a4 a7a5 c2c3 f7f5 a2a3 g8h6 e2e4 f5e4 c2c3 d7d5? h2h3! c2c3 e7e5? a2a3! f8a3? b2a3! c2c3 e7e6? a2a4! c2c4 e7e5 b2b4 f8b4 h2h4 b4d2 b1d2 d8h4 h1h4 c2c4 c7c5 a2a4 a7a5 d2d3 e7e5? c1e3! e2e4? a7a6! f1a6? b7a6! e2e4? b7b5! f1b5? f7f6! b5d7? b8d7! e2e4? c7c5! d2d4? c5d4! d1d4? a7a6! e2e4? d7d6! f1a6? b7a6! d2d4? g7g6! e2e4? h7h6! f2f4? f7f5! e4f5? g7g6! f2f3 c7c6 c2c4 f2f3 f7f5 b2b3 f2f3 f7f5 g2g3 f2f3 e7e5? b2b4! f8b4? g2g3! b4d2? b1d2! f2f3 e7e5? e2e4! d7d5? e4d5! d8d5? f3f4! e5f4? a2a3! f2f4 b7b5 g2g4 c7c5 f2f4 c7c6 f2f4 e7e5 f4e5 d7d6? e5d6! f8d6? h2h3! c8h3? g2g3 g7g5 f2f3 g2g3 g7g5 h2h4 g2g4 f7f5 g4f5 g7g6 f5g6 h7g6 g1f3 h8h2 f3h2 h2h4 e7e5? g2g3! h2h3 e7e5? f2f4! e5f4? g2g4! f4g3? h1h2! g3h2? h3h4! sjeng-11.2.orig/books/bug.opn0100644000175000017500000000361507075727654015163 0ustar lukaslukas/* The various tags: ! best !? interesting = unusual but solid ?! murky - meant for surprise ? plain bad */ /* Various bad first moves - don't play these! */ a2a3? e7e5! a2a4? e7e5! b1a3? e7e5! b1c3? e7e6! /* Now, 1. b3 is an interesting and OK slow move that can be used for surprise. 1. b4 is an interesting wild move planning to put pressure on the long diagonal and hit a N on c6 with b4-b5 */ b2b3!? b2b4?! /* 1. c3 is too committal to be used as surprise weapon, but 1. c4 is better than it looks. 1. d3 has the same problem as 1.c3: it is likely to transpose to some slow reversed system but without giving black any head aches with move orders. */ c2c3? e7e5! c2c4?! e7e5! d2d3? e7e5! /* 1. d4 is a good, calm move which often leads to semi-blocked positions. I'm interested in seeing how well the program can be taught to handle those. */ d2d4= /* 1. e3 can be used as a surprise weapon intending to make a reversed set up or something slow like Ng1-f3 and b2-b3. */ e2e3?! e7e5! /* 1. e4! Best by test! */ /* Queen's fianchetto */ e2e4 b7b6?! d2d4! /* Queen's knight - most likely to transpose */ e2e4 b8c6= /* C-line crap lines */ e2e4 c7c5? b1c3! e2e4 c7c6? d2d4! d7d5 e4d5 c6d5 c1f4 /* The leaf - God I hate this shitty line. */ e2e4 d7d5? /* 1... d6 - transposing to the Wall most likely, but also some independant lines. */ e2e4 d7d6= /* I would expect the program to handle the tactics in the Kamikaze pretty well. */ e2e4 e7e5!? /* On with the main bulk of opening theory. */ e2e4 e7e6! /* The Dog will suit the computer well. */ e2e4 g8f6! /* 1. f3 is simply bad but 1.f4 is a whole lot better than it looks - an interesting surprise weapon maybe. */ f2f3? e7e5! f2f4?! g8f6! /* 1. Nf3 is a good second string first move along with 1. d4. */ g1f3= /* The rest is just crap. */ g1h3? e7e5! g2g3? e7e5! g2g4? e7e5! h2h3? e7e5! h2h4? e7e5! h4h5 d7d5 P@g6 h7g6 h5g6 h8h1 g6f7 e8f7 sjeng-11.2.orig/aclocal.m40100644000175000017500000001045407412717722014400 0ustar lukaslukasdnl aclocal.m4 generated automatically by aclocal 1.4 dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl This program is distributed in the hope that it will be useful, dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A dnl PARTICULAR PURPOSE. # Do all the work for Automake. This macro actually does too much -- # some checks are only needed if your package does certain things. # But this isn't really a big deal. # serial 1 dnl Usage: dnl AM_INIT_AUTOMAKE(package,version, [no-define]) AC_DEFUN(AM_INIT_AUTOMAKE, [AC_REQUIRE([AC_PROG_INSTALL]) PACKAGE=[$1] AC_SUBST(PACKAGE) VERSION=[$2] AC_SUBST(VERSION) dnl test to see if srcdir already configured if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi ifelse([$3],, AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])) AC_REQUIRE([AM_SANITY_CHECK]) AC_REQUIRE([AC_ARG_PROGRAM]) dnl FIXME This is truly gross. missing_dir=`cd $ac_aux_dir && pwd` AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir) AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir) AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) AC_REQUIRE([AC_PROG_MAKE_SET])]) # # Check to make sure that the build environment is sane. # AC_DEFUN(AM_SANITY_CHECK, [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftestfile # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` if test "[$]*" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftestfile` fi if test "[$]*" != "X $srcdir/configure conftestfile" \ && test "[$]*" != "X conftestfile $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi test "[$]2" = conftestfile ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi rm -f conftest* AC_MSG_RESULT(yes)]) dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY) dnl The program must properly implement --version. AC_DEFUN(AM_MISSING_PROG, [AC_MSG_CHECKING(for working $2) # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. if ($2 --version) < /dev/null > /dev/null 2>&1; then $1=$2 AC_MSG_RESULT(found) else $1="$3/missing $2" AC_MSG_RESULT(missing) fi AC_SUBST($1)]) # Like AC_CONFIG_HEADER, but automatically create stamp file. AC_DEFUN(AM_CONFIG_HEADER, [AC_PREREQ([2.12]) AC_CONFIG_HEADER([$1]) dnl When config.status generates a header, we must update the stamp-h file. dnl This file resides in the same directory as the config header dnl that is generated. We must strip everything past the first ":", dnl and everything past the last "/". AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>, <>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>, <>; do case " <<$>>CONFIG_HEADERS " in *" <<$>>am_file "*<<)>> echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx ;; esac am_indx=`expr "<<$>>am_indx" + 1` done<<>>dnl>>) changequote([,]))]) sjeng-11.2.orig/epd.c0100644000175000017500000001743307326624450013457 0ustar lukaslukas/* Sjeng - a chess variants playing program Copyright (C) 2000 Gian-Carlo Pascutto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA File: epd.c Purpose: run EPD test suite */ #include "sjeng.h" #include "protos.h" #include "extvars.h" void setup_epd_line(char* inbuff) { int i = 0; int rankp = 0; // a8 int rankoffset = 0; int fileoffset = 0; int j; /* 0 : FEN data */ /* 1 : Active color */ /* 2 : Castling status */ /* 3 : EP info */ /* 4 : 50 move */ /* 5 : movenumber */ /* 6 : EPD data */ int stage = 0; static int rankoffsets[] = {110, 98, 86, 74, 62, 50, 38, 26}; /* conversion from algebraic to sjeng internal for ep squares */ int converterf = (int) 'a'; int converterr = (int) '1'; int ep_file, ep_rank, norm_file, norm_rank; memset(board, frame, sizeof(board)); white_castled = no_castle; black_castled = no_castle; book_ply = 50; rankoffset = rankoffsets[0]; while (inbuff[i] == ' ') {i++;}; while((inbuff[i] != '\n') && (inbuff[i] != '\0')) { if(stage == 0 && isdigit(inbuff[i])) { for (j = 0; j < atoi(&inbuff[i]); j++) board[rankoffset + j + fileoffset] = npiece; fileoffset += atoi(&inbuff[i]); } else if (stage == 0 && inbuff[i] == '/') { rankp++; rankoffset = rankoffsets[rankp]; fileoffset = 0; } else if (stage == 0 && isalpha(inbuff[i])) { switch (inbuff[i]) { case 'p' : board[rankoffset + fileoffset] = bpawn; break; case 'P' : board[rankoffset + fileoffset] = wpawn; break; case 'n' : board[rankoffset + fileoffset] = bknight; break; case 'N' : board[rankoffset + fileoffset] = wknight; break; case 'b' : board[rankoffset + fileoffset] = bbishop; break; case 'B' : board[rankoffset + fileoffset] = wbishop; break; case 'r' : board[rankoffset + fileoffset] = brook; break; case 'R' : board[rankoffset + fileoffset] = wrook; break; case 'q' : board[rankoffset + fileoffset] = bqueen; break; case 'Q' : board[rankoffset + fileoffset] = wqueen; break; case 'k' : bking_loc = rankoffset + fileoffset; board[bking_loc] = bking; break; case 'K' : wking_loc = rankoffset + fileoffset; board[wking_loc] = wking; break; } fileoffset++; } else if (inbuff[i] == ' ') { stage++; if (stage == 1) { /* skip spaces */ while (inbuff[i] == ' ') i++; if (inbuff[i] == 'w') white_to_move = 1; else white_to_move = 0; } else if (stage == 2) { /* assume no castling at all */ moved[26] = moved[33] = moved[30] = 1; moved[110] = moved[114] = moved[117] = 1; while(inbuff[i] == ' ') i++; while (inbuff[i] != ' ') { switch (inbuff[i]) { case '-' : break; case 'K' : moved[30] = moved[33] = 0; break; case 'Q' : moved[30] = moved[26] = 0; break; case 'k' : moved[114] = moved[117] = 0; break; case 'q' : moved[114] = moved[110] = 0; break; } i++; } i--; /* go back to space so we move to next stage */ } else if (stage == 3) { /* skip spaces */ while (inbuff[i] == ' ') i++; if (inbuff[i] == '-') { ep_square = 0; } else { ep_file = inbuff[i++]; ep_rank = inbuff[i++]; norm_file = ep_file - converterf; norm_rank = ep_rank - converterr; ep_square = ((norm_rank * 12) + 26) + (norm_file); } } else if (stage == 4) { /* ignore this for now */ } else if (stage == 5) { /* ignore this for now */ } else if (stage == 6) { /* ignore this for now */ } }; i++; } reset_piece_square(); initialize_hash(); } int check_solution(char *inbuff, move_s cmove) { char san[STR_BUFF]; comp_to_san(cmove, san); // printf("Sjeng's move: %s, EPD line: %s\n", san, strstr(inbuff,"bm")); if (strstr(inbuff, "bm") != NULL) { if (strstr(inbuff, san) != NULL) return TRUE; else return FALSE; } else if (strstr(inbuff, "am") != NULL) { if (strstr(inbuff, san) != NULL) return FALSE; else return TRUE; } else printf("No best-move or avoid-move found!"); return FALSE; } void run_epd_testsuite(void) { FILE *testsuite; char readbuff[2000]; char testname[FILENAME_MAX]; char tempbuff[2000]; float elapsed; int nps; long thinktime; move_s comp_move; int tested, found; clock_t cpu_start, cpu_end; tested = 0; found = 0; printf("\nName of EPD testsuite: "); rinput(testname, STR_BUFF, stdin); printf("\nTime per move (s): "); rinput(readbuff, STR_BUFF, stdin); thinktime = atol(readbuff); printf("\n"); thinktime *= 100; testsuite = fopen(testname, "r"); while (fgets(readbuff, 2000, testsuite) != NULL) { tested++; setup_epd_line(readbuff); root_to_move = ToMove; clear_tt(); initialize_hash(); display_board(stdout, 1); forcedwin = FALSE; // pn_time = thinktime; // cpu_start = clock(); // proofnumbersearch(); // cpu_end = clock(); // rdelay(2); elapsed = (cpu_end-cpu_start)/(double) CLOCKS_PER_SEC; printf("Time: %f\n", elapsed); if (interrupt()) rinput(tempbuff, STR_BUFF, stdin); fixed_time = thinktime; cpu_start = clock(); comp_move = think(); cpu_end = clock(); printf ("\nNodes: %ld (%0.2f%% qnodes)\n", nodes, (float) ((float) qnodes / (float) nodes * 100.0)); elapsed = (cpu_end-cpu_start)/(float) CLOCKS_PER_SEC; nps = (int)((float) nodes/(float) elapsed); if (!elapsed) printf ("NPS: N/A\n"); else printf ("NPS: %ld\n", (long int) nps); printf("ECacheProbes : %ld ECacheHits : %ld HitRate : %f%%\n", ECacheProbes, ECacheHits, ((float)ECacheHits/((float)ECacheProbes+1)) * 100); printf("TTStores : %ld TTProbes : %ld TTHits : %ld HitRate : %f%%\n", TTStores, TTProbes, TTHits, ((float)TTHits/((float)TTProbes+1)) * 100); printf("NTries : %d NCuts : %d CutRate : %f%% TExt: %d\n", NTries, NCuts, (((float)NCuts*100)/((float)NTries+1)), TExt); printf("Check extensions: %ld Razor drops : %ld Razor Material : %ld\n", ext_check, razor_drop, razor_material); printf("EGTB Hits: %d EGTB Probes: %d Efficiency: %3.1f%%\n", EGTBHits, EGTBProbes, (((float)EGTBHits*100)/(float)(EGTBProbes+1))); printf("Move ordering : %f%%\n", (((float)FHF*100)/(float)FH+1)); printf("Material score: %d Eval : %d\n", Material, eval()); printf("\n"); if (!forcedwin) { if(check_solution(readbuff, comp_move)) { found++; printf("Solution found.\n"); } else { printf("Solution not found.\n"); } } else { found++; } printf("Solved: %d/%d\n", found, tested); }; printf("\n"); }; sjeng-11.2.orig/see.c0100644000175000017500000001645507307525541013466 0ustar lukaslukas/* Sjeng - a chess variants playing program Copyright (C) 2001 Gian-Carlo Pascutto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA File: see.c Purpose: do static exchange evaluation */ #include "sjeng.h" #include "extvars.h" typedef struct { int piece; int square; } see_data; see_data see_attackers[2][16]; int see_num_attackers[2]; void setup_attackers (int square) { /* this function calculates attack information for a square */ static const int rook_o[4] = {12, -12, 1, -1}; static const int bishop_o[4] = {11, -11, 13, -13}; static const int knight_o[8] = {10, -10, 14, -14, 23, -23, 25, -25}; register int a_sq, b_sq, i; int numw = see_num_attackers[WHITE], numb = see_num_attackers[BLACK]; /* rook-style moves: */ for (i = 0; i < 4; i++) { a_sq = square + rook_o[i]; b_sq = board[a_sq]; /* the king can attack from one square away: */ if (b_sq == wking) { see_attackers[WHITE][numw].piece = b_sq; see_attackers[WHITE][numw].square = a_sq; numw++; break; } else if (b_sq == bking) { see_attackers[BLACK][numb].piece = b_sq; see_attackers[BLACK][numb].square = a_sq; numb++; break; } else { /* otherwise, check for sliding pieces: */ while (b_sq != frame) { if (b_sq == wrook || b_sq == wqueen) { see_attackers[WHITE][numw].piece = b_sq; see_attackers[WHITE][numw].square = a_sq; numw++; break; } else if (b_sq == brook || b_sq == bqueen) { see_attackers[BLACK][numb].piece = b_sq; see_attackers[BLACK][numb].square = a_sq; numb++; break; } else if (b_sq != npiece) break; a_sq += rook_o [i]; b_sq = board[a_sq]; } } } /* bishop-style moves: */ for (i = 0; i < 4; i++) { a_sq = square + bishop_o[i]; b_sq = board[a_sq]; /* check for pawn attacks: */ if (b_sq == wpawn && i%2) { see_attackers[WHITE][numw].piece = b_sq; see_attackers[WHITE][numw].square = a_sq; numw++; break; } else if (b_sq == bpawn && !(i%2)) { see_attackers[BLACK][numb].piece = b_sq; see_attackers[BLACK][numb].square = a_sq; numb++; break; } /* the king can attack from one square away: */ else if (b_sq == wking) { see_attackers[WHITE][numw].piece = b_sq; see_attackers[WHITE][numw].square = a_sq; numw++; break; } else if (b_sq == bking) { see_attackers[BLACK][numb].piece = b_sq; see_attackers[BLACK][numb].square = a_sq; numb++; break; } else { while (b_sq != frame) { if (b_sq == wbishop || b_sq == wqueen) { see_attackers[WHITE][numw].piece = b_sq; see_attackers[WHITE][numw].square = a_sq; numw++; break; } else if (b_sq == bbishop || b_sq == bqueen) { see_attackers[BLACK][numb].piece = b_sq; see_attackers[BLACK][numb].square = a_sq; numb++; break; } else if (b_sq != npiece) break; a_sq += bishop_o [i]; b_sq = board[a_sq]; } } } /* knight-style moves: */ for (i = 0; i < 8; i++) { a_sq = square + knight_o[i]; b_sq = board[a_sq]; if (b_sq == wknight) { see_attackers[WHITE][numw].piece = b_sq; see_attackers[WHITE][numw].square = a_sq; numw++; } else if (b_sq == bknight) { see_attackers[BLACK][numb].piece = b_sq; see_attackers[BLACK][numb].square = a_sq; numb++; } } see_num_attackers[WHITE] = numw; see_num_attackers[BLACK] = numb; } void findlowest(int color, int next) { int lowestp; int lowestv; see_data swap; int i; lowestp = next; lowestv = abs(material[see_attackers[color][next].piece]); for (i = next; i < see_num_attackers[color]; i++) { if (abs(material[see_attackers[color][i].piece]) < lowestv) { lowestp = i; lowestv = abs(material[see_attackers[color][i].piece]); } } /* lowestp now points to the lowest attacker, which we swap with next */ swap = see_attackers[color][next]; see_attackers[color][next] = see_attackers[color][lowestp]; see_attackers[color][lowestp] = swap; } int see(int color, int square, int from) { int sside; int caps[2]; int value; int origpiece; int ourbestvalue; int hisbestvalue; /* reset data */ see_num_attackers[WHITE] = 0; see_num_attackers[BLACK] = 0; /* remove original capturer from board, exposing his first xray-er */ origpiece = board[from]; board[from] = npiece; see_num_attackers[color]++; see_attackers[color][0].piece = origpiece; see_attackers[color][0].square = from; /* calculate all attackers to square */ setup_attackers(square); /* initially we gain the piece we are capturing */ value = abs(material[board[square]]); /* free capture ? */ if (!see_num_attackers[!color]) { board[from] = origpiece; return value; } else { /* we can never get a higher SEE score than the piece we just captured */ /* so that is the current best value for our opponent */ /* we arent sure of anything yet, so -INF */ hisbestvalue = value; ourbestvalue = -INF; } caps[color] = 1; caps[!color] = 0; /* start with recapture */ sside = !color; /* continue as long as there are attackers */ while (caps[sside] < see_num_attackers[sside]) { /* resort capturelist of sside to put lowest attacker in next position */ findlowest(sside, caps[sside]); if (sside == color) { /* capturing more */ /* we capture the opponents recapturer */ value += abs(material[see_attackers[!sside][caps[!sside]-1].piece]); /* if the opp ran out of attackers we can stand pat now! */ if (see_num_attackers[!sside] <= caps[!sside] && value > ourbestvalue) ourbestvalue = value; /* our opponent can always stand pat now */ if (value < hisbestvalue) hisbestvalue = value; } else { /* recapture by opp */ /* we lose whatever we captured with in last iteration */ value -= abs(material[see_attackers[!sside][caps[!sside]-1].piece]); /* we can stand pat if we want to now */ /* our best score goes up, opponent is unaffected */ if (value > ourbestvalue) { ourbestvalue = value; } if (see_num_attackers[!sside] <= caps[!sside] && value < hisbestvalue) hisbestvalue = value; } /* keep track of capture count */ caps[sside]++; /* switch sides */ sside ^= 1; } /* restore capturer */ board[from] = origpiece; /* we return our best score now, keeping in mind that it can never we better than the best for our opponent */ return (ourbestvalue > hisbestvalue) ? hisbestvalue : ourbestvalue; } sjeng-11.2.orig/tests/0042755000175000017500000000000007473543040013700 5ustar lukaslukassjeng-11.2.orig/tests/lct2.epd0100644000175000017500000000501107075727643015241 0ustar lukaslukasr3kb1r/3n1pp1/p6p/2pPp2q/Pp2N3/3B2PP/1PQ2P2/R3K2R w KQkq - bm d6; id "POS-01"; 1k1r3r/pp2qpp1/3b1n1p/3pNQ2/2pP1P2/2N1P3/PP4PP/1K1RR3 b - - bm Bb4; id "POS-02"; r6k/pp4p1/2p1b3/3pP3/7q/P2B3r/1PP2Q1P/2K1R1R1 w - - bm Qc5; id "POS-03"; 1nr5/2rbkppp/p3p3/Np6/2PRPP2/8/PKP1B1PP/3R4 b - - bm e5; id "POS-04"; 2r2rk1/1p1bq3/p3p2p/3pPpp1/1P1Q4/P7/2P2PPP/2R1RBK1 b - - bm Bb5; id "POS-05"; 3r1bk1/p4ppp/Qp2p3/8/1P1B4/Pq2P1P1/2r2P1P/R3R1K1 b - - bm e5; id "POS-06"; r1b2r1k/pp2q1pp/2p2p2/2p1n2N/4P3/1PNP2QP/1PP2RP1/5RK1 w - - bm Nd1; id "POS-07"; r2qrnk1/pp3ppb/3b1n1p/1Pp1p3/2P1P2N/P5P1/1B1NQPBP/R4RK1 w - - bm Bh3; id "POS-08"; 5nk1/Q4bpp/5p2/8/P1n1PN2/q4P2/6PP/1R4K1 w - - bm Qd4; id "POS-09"; r3k2r/3bbp1p/p1nppp2/5P2/1p1NP3/5NP1/PPPK3P/3R1B1R b kq - bm Bf8; id "POS-10"; bn6/1q4n1/1p1p1kp1/2pPp1pp/1PP1P1P1/3N1P1P/4B1K1/2Q2N2 w - - bm h4; id "POS-11"; 3r2k1/pp2npp1/2rqp2p/8/3PQ3/1BR3P1/PP3P1P/3R2K1 b - - bm Rd6; id "POS-12"; 1r2r1k1/4ppbp/B5p1/3P4/pp1qPB2/2n2Q1P/P4PP1/4RRK1 b - - bm Na2; id "POS-13"; r2qkb1r/1b3ppp/p3pn2/1p6/1n1P4/1BN2N2/PP2QPPP/R1BR2K1 w kq - bm d5; id "POS-14"; 1r4k1/1q2bp2/3p2p1/2pP4/p1N4R/2P2QP1/1P3PK1/8 w - - bm Nd6; id "CMB-01"; rn3rk1/pbppq1pp/1p2pb2/4N2Q/3PN3/3B4/PPP2PPP/R3K2R w KQ - bm Qh7; id "CMB-02"; 4r1k1/3b1p2/5qp1/1BPpn2p/7n/r3P1N1/2Q1RPPP/1R3NK1 b - - bm Qf3; id "CMB-03"; 2k2b1r/1pq3p1/2p1pp2/p1n1PnNp/2P2B2/2N4P/PP2QPP1/3R2K1 w - - bm ef6; id "CMB-04"; 2r2r2/3qbpkp/p3n1p1/2ppP3/6Q1/1P1B3R/PBP3PP/5R1K w - - bm Rh7; id "CMB-05"; 2r1k2r/2pn1pp1/1p3n1p/p3PP2/4q2B/P1P5/2Q1N1PP/R4RK1 w q - bm ef6; id "CMB-06"; 2rr2k1/1b3ppp/pb2p3/1p2P3/1P2BPnq/P1N3P1/1B2Q2P/R4R1K b - - bm Rc3; id "CMB-07"; 2b1r1k1/r4ppp/p7/2pNP3/4Q3/q6P/2P2PP1/3RR1K1 w - - bm Nf6; id "CMB-08"; 6k1/5p2/3P2p1/7n/3QPP2/7q/r2N3P/6RK b - - bm Rd2; id "CMB-09"; rq2rbk1/6p1/p2p2Pp/1p1Rn3/4PB2/6Q1/PPP1B3/2K3R1 w - - bm Bh6; id "CMB-10"; rnbq2k1/p1r2p1p/1p1p1Pp1/1BpPn1N1/P7/2P5/6PP/R1B1QRK1 w - - bm Nh7; id "CMB-11"; r2qrb1k/1p1b2p1/p2ppn1p/8/3NP3/1BN5/PPP3QP/1K3RR1 w - - bm e5; id "CMB-12"; 8/1p3pp1/7p/5P1P/2k3P1/8/2K2P2/8 w - - bm f6; id "FIN-01"; 8/pp2r1k1/2p1p3/3pP2p/1P1P1P1P/P5KR/8/8 w - - bm f5; id "FIN-02"; 8/3p4/p1bk3p/Pp6/1Kp1PpPp/2P2P1P/2P5/5B2 b - - bm Be4; id "FIN-03"; 5k2/7R/4P2p/5K2/p1r2P1p/8/8/8 b - - bm h3; id "FIN-04"; 6k1/6p1/7p/P1N5/1r3p2/7P/1b3PP1/3bR1K1 w - - bm a6; id "FIN-05"; 8/3b4/5k2/2pPnp2/1pP4N/pP1B2P1/P3K3/8 b - - bm f4; id "FIN-06"; 6k1/4pp1p/3p2p1/P1pPb3/R7/1r2P1PP/3B1P2/6K1 w - - bm Bb4 ; id "FIN-07"; 2k5/p7/Pp1p1b2/1P1P1p2/2P2P1p/3K3P/5B2/8 w - - bm c5; id "FIN-08"; 8/5Bp1/4P3/6pP/1b1k1P2/5K2/8/8 w - - bm Kg4; id "FIN-09"; sjeng-11.2.orig/tests/bt2630.epd0100644000175000017500000000423207075727643015321 0ustar lukaslukasrq2r1k1/5pp1/p7/4bNP1/1p2P2P/5Q2/PP4K1/5R1R w - - bm Nxg7; id "test 1"; 6k1/2b2p1p/ppP3p1/4p3/PP1B4/5PP1/7P/7K w - - bm Bxb6; id "test 2"; 5r1k/p1q2pp1/1pb4p/n3R1NQ/7P/3B1P2/2P3P1/7K w - - bm Re6; id "test 3"; 5r1k/1P4pp/3P1p2/4p3/1P5P/3q2P1/Q2b2K1/B3R3 w - - bm Qf7; id "test 4"; 3B4/8/2B5/1K6/8/8/3p4/3k4 w - - bm Ka6; id "test 5"; 1k1r4/1pp4p/2n5/P6R/2R1p1r1/2P2p2/1PP2B1P/4K3 b - - bm e3; id "test 6"; 6k1/p3q2p/1nr3pB/8/3Q1P2/6P1/PP5P/3R2K1 b - - bm Rd6; id "test 7"; 2krr3/1p4pp/p1bRpp1n/2p5/P1B1PP2/8/1PP3PP/R1K3B1 w - - bm Rxc6+; id "test 8"; r5k1/pp2p1bp/6p1/n1p1P3/2qP1NP1/2PQB3/P5PP/R4K2 b - - bm g5; id "test 9"; 2r3k1/1qr1b1p1/p2pPn2/nppPp3/8/1PP1B2P/P1BQ1P2/5KRR w - - bm Rxg7+; id "test 10"; 1br3k1/p4p2/2p1r3/3p1b2/3Bn1p1/1P2P1Pq/P3Q1BP/2R1NRK1 b - - bm Qxh2+; id "test 11"; 8/pp3k2/2p1qp2/2P5/5P2/1R2p1rp/PP2R3/4K2Q b - - bm Qe4; id "test 12"; 2bq3k/2p4p/p2p4/7P/1nBPPQP1/r1p5/8/1K1R2R1 b - - bm Be6; id "test 13"; 3r1rk1/1p3pnp/p3pBp1/1qPpP3/1P1P2R1/P2Q3R/6PP/6K1 w - - bm Rxh7; id "test 14"; 2b1q3/p7/1p1p2kb/nPpN3p/P1P1P2P/6P1/5R1K/5Q2 w - - bm e5; id "test 15"; 2krr3/pppb1ppp/3b4/3q4/3P3n/2P2N1P/PP2B1P1/R1BQ1RK1 b - - bm Nxg2; id "test 16"; 4r1k1/p1qr1p2/2pb1Bp1/1p5p/3P1n1R/3B1P2/PP3PK1/2Q4R w - - bm Qxf4; id "test 17"; 8/4p3/8/3P3p/P2pK3/6P1/7b/3k4 w - - bm d6; id "test 18"; 3r2k1/pp4B1/6pp/PP1Np2n/2Pp1p2/3P2Pq/3QPPbP/R4RK1 b - - bm f3; id "test 19"; r4rk1/5p2/1n4pQ/2p5/p5P1/P4N2/1qb1BP1P/R3R1K1 w - - bm Ra2; id "test 20"; k7/8/PP1b2P1/K2Pn2P/4R3/8/6np/8 w - - bm Re1; id "test 21"; rnb1k2r/pp2qppp/3p1n2/2pp2B1/1bP5/2N1P3/PP2NPPP/R2QKB1R w KQkq - bm a3; id "test 22"; 8/7p/8/p4p2/5K2/Bpk3P1/4P2P/8 w - - bm g4; id "test 23"; R7/3p3p/8/3P2P1/3k4/1p5p/1P1NKP1P/7q w - - bm g6; id "test 24"; 8/8/3k1p2/p2BnP2/4PN2/1P2K1p1/8/5b2 b - - bm Nd3; id "test 25"; 2r3k1/pbr1q2p/1p2pnp1/3p4/3P1P2/1P1BR3/PB1Q2PP/5RK1 w - - bm f5; id "test 26"; 3r2k1/p2r2p1/1p1B2Pp/4PQ1P/2b1p3/P3P3/7K/8 w - - bm e6; id "test 27"; rnb1k1nr/p2p1ppp/3B4/1p1N1N1P/4P1P1/3P1Q2/PqP5/R4Kb1 w kq - bm e5; id "test 28"; r1b1kb1r/pp1n1ppp/2q5/2p3B1/Q1B5/2p2N2/PP3PPP/R3K2R w KQkq - bm O-O-O; id "test 29"; 2k5/2p3Rp/p1pb4/1p2p3/4P3/PN1P1P2/1P2KP1r/8 w - - bm f4; id "test 30"; sjeng-11.2.orig/tests/ecm98.epd0100644000175000017500000016571407307524545015335 0ustar lukaslukas2q1r1k1/1ppb4/r2p1Pp1/p4n1p/2P1n3/5NPP/PP3Q1K/2BRRB2 w - - bm f7+; id "ECM.001"; 7r/1p2k3/2bpp3/p3np2/P1PR4/2N2PP1/1P4K1/3B4 b - - bm Bxf3+; id "ECM.002"; 4k3/p1P3p1/2q1np1p/3N4/8/1Q3PP1/6KP/8 w - - bm Qb5; id "ECM.003"; 2r1b1k1/R4pp1/4pb1p/1pBr4/1Pq2P2/3N4/2PQ2PP/5RK1 b - - bm Rcxc5; id "ECM.004"; 6k1/p1qb1p1p/1p3np1/2b2p2/2B5/2P3N1/PP2QPPP/4N1K1 b - - bm Bxf2+; id "ECM.005"; 3q4/pp3pkp/5npN/2bpr1B1/4r3/2P2Q2/PP3PPP/R4RK1 w - - bm Bxf6+; id "ECM.006"; 3rr1k1/pb3pp1/1p1q1b1p/1P2NQ2/3P4/P1NB4/3K1P1P/2R3R1 w - - bm Rxg7+; id "ECM.007"; r1b1r1k1/p1p3pp/2p2n2/2bp4/5P2/3BBQPq/PPPK3P/R4N1R b - - bm Bg4; id "ECM.008"; 3r4/1b2k3/1pq1pp2/p3n1pr/2P5/5PPN/PP1N1QP1/R2R2K1 b - - bm Rxh3; id "ECM.009"; 2r4k/pB4bp/6p1/6q1/1P1n4/2N5/P4PPP/2R1Q1K1 b - - bm Qxc1; id "ECM.010"; 1r5r/3b1pk1/3p1np1/p1qPp3/p1N1PbP1/2P2PN1/1PB1Q1K1/R3R3 b - - bm Nxg4; id "ECM.011"; 5rk1/7p/p1N5/3pNp2/2bPnqpQ/P7/1P3PPP/4R1K1 w - - bm Ne7+; id "ECM.012"; rnb2rk1/pp2np1p/2p2q1b/8/2BPPN2/2P2Q2/PP4PP/R1B2RK1 w - - bm Nd5; id "ECM.013"; r3kb1r/pp2pppp/3q4/3Pn3/6b1/2N1BN2/PP3PPP/R2QKB1R w KQkq - bm Nxe5; id "ECM.015"; r3rbk1/1pq2ppp/2ppbnn1/p3p3/P1PPN3/BP1BPN1P/2Q2PP1/R2R2K1 w - - bm Nxd6; id "ECM.18"; 1rr1nbk1/5ppp/3p4/1q1PpN2/np2P3/5Q1P/P1BB1PP1/2R1R1K1 w - - bm Bxa4; id "ECM.020"; r7/5kp1/2p1p2p/1p1n3P/2rP4/2P3R1/PK2RPP1/2B5 b - - bm Rxc3; id "ECM.021"; r1r3k1/p3qpp1/b1P4p/3p4/3Nn3/4P3/P1Q2PPP/1BR1K2R b K - bm Qb4+; id "ECM.022"; rn3rk1/4bppp/1q2p3/p2pP3/8/1PN2B1P/P4PP1/2RQ1RK1 w - - bm Bxd5; id "ECM.023"; 6rk/1p1br2p/pqp5/3pNP2/3Pp3/P5PR/5PKR/Q7 w - - bm Rxh7+; id "ECM.024"; 2b3k1/5p1p/7b/p2B3p/3P4/P2Q1N1P/1q3PP1/6K1 w - - bm Bxf7+; id "ECM.025"; r1b5/4k3/p7/3p1n2/3Bp3/2P2r1P/PPBK1P2/4R2R w - - bm Bc5+; id "ECM.026"; r4rk1/1b3Npp/p7/1p3Q2/3P4/1B2q3/P5PP/3n1R1K b - - bm Bxg2+; id "ECM.027"; r2q1rk1/p3b1pp/2p5/1pn5/1n1Bp1b1/1P6/PQ1PPP2/2RNKBNR b K - bm Bxe2; id "ECM.030"; 2bnr1k1/2q2ppp/p7/2p1b3/2N1B3/R7/1P2QPPP/2B3K1 w - - bm Nxe5; id "ECM.032"; r1b2r1k/3nN2p/p2Q1p2/8/4PP2/1R6/q1PK2PP/4R3 w - - bm Qd5; id "ECM.033"; 1nk1r1r1/pp2n1pp/4p3/q2pPp1N/b1pP1P2/B1P2R2/2P1B1PP/R2Q2K1 w - - bm Nf6; id "ECM.034"; 2r2bk1/4qp2/3n2p1/2R1p1Np/2p1N3/r6P/1Q3PP1/3R2K1 w - - bm Rxc8; id "ECM.035"; br1r2k1/1q4p1/p2ppb1p/2p2p2/2P1n3/Pn2P2P/QPR2PPB/2NRNBK1 b - - bm Nxc1; id "ECM.036"; 2k4r/ppp1n1p1/2n2qb1/2N5/Q1P3p1/P2r3P/1P3PB1/R1B2RK1 w - - bm Qb5; id "ECM.037"; 8/6bk/1B1R4/6p1/2bNP3/4KP2/1r6/8 b - - bm Be5; id "ECM.038"; r1b1rnk1/1p3pb1/1qpp2p1/2n5/2PNP2p/1PN3PP/3R1PBK/BR1Q4 b - - bm Rxa1; id "ECM.039"; r1b2rk1/pp2b3/2pn1n1p/3pNppq/3P4/BP1N2P1/P3PPBP/R1Q2RK1 w - - bm Nxc6; id "ECM.040"; 5rk1/1b3ppp/p3p3/1p1q2N1/4n3/6P1/PP2PPBP/2Q2RK1 b - - bm Nxg3; id "ECM.041"; 2kr3r/pppq2p1/1bn1R3/6N1/1P6/1QN1B1p1/P4PP1/R5K1 b - - bm gxf2+; id "ECM.042"; r4rk1/pp4pp/2nqb3/3p4/8/2NB4/PP1Q1PPP/4RRK1 w - - bm Bxh7+; id "ECM.044"; 3rk1r1/3b1p1p/p2BpQ2/8/2q5/2P5/PP3PPP/3R2K1 b - - bm Rxg2+; id "ECM.045"; 3r1rk1/4pp1p/p1Q1b1p1/3N4/3b4/5B2/Pq3PPP/R4RK1 b - - bm Bxd5; id "ECM.046"; 5bk1/1bqn1r1p/p3Q1p1/4p3/1PN1Pp2/P1N4P/5PP1/R1BR2K1 w - - bm Qxf7+; id "ECM.047"; 3rkb1r/1p3p2/p1n1p3/q5pp/2PpP3/1P4P1/P1Q1BPKP/R2N3R b k - bm d3; id "ECM.048"; 5rk1/1r1qbnnp/R2p2p1/1p1Pp3/1Pp1P1N1/2P1B1NP/5QP1/5R1K w - - bm Qxf7+; id "ECM.049"; 2kr1b1R/1b3pp1/p2pp3/1pq3P1/2nQPP2/P1N5/1PP1BB2/1K6 w - - bm Rxf8; id "ECM.050"; r3nb1Q/p1q2kr1/2p3p1/2ppnpP1/1P3N2/4P3/PB1P4/1R2KB1R w K - bm Qxf8+; id "ECM.052"; r1bq1rk1/pp3pbp/2pp1np1/2n3B1/2PNP3/2N2P2/PP1QB1PP/R4RK1 b - - bm Nfxe4; id "ECM.053"; 5r2/1b2k2p/3bp3/5PP1/Bn1Q3P/1N6/1Pr5/1K3R2 b - - bm Rxb2+; id "ECM.055"; r1b1r1k1/pp4bp/5np1/2qPB3/8/6NP/PPP1Q1B1/R4R1K w - - bm Rxf6; id "ECM.056"; r1b2r1k/1pq3bp/8/3Qp2n/1P1n1pp1/2NP2P1/3BPPBP/1R2NRK1 b - - bm Qxc3; id "ECM.057"; 4qk2/pp3pp1/1nbr3p/2p5/5N2/2P1Q3/PPB2PPP/2K1R3 w - - bm Ng6+; id "ECM.058"; 3q2k1/pb3p1p/4pbp1/2r5/PpN2N2/1P2P2P/5PP1/Q2R2K1 b - - bm Rd5; id "ECM.059"; r4rk1/pp1b2pp/3bpq2/3p1p2/2PPn3/PP1B4/1BQN1PPP/R4RK1 b - - bm Qh6; id "ECM.060"; r4rk1/1b3ppp/p2q1n2/1p2N3/3P4/1B6/P1Q2PPP/2R1R1K1 w - - bm Nxf7; id "ECM.061"; 2rq1r2/pp3pnk/2n1b1pp/3pQ3/3P1N2/P1N5/1P3PPP/1BR2RK1 w - - bm Bxg6+; id "ECM.062"; 4nk2/r1r1bppp/pN2p3/2np4/8/BPN3PP/P3PPK1/2RR4 w - - bm Ncxd5 Nbxd5; id "ECM.063"; r4r1k/2pqn1b1/p1bp2pp/1p2pn2/4N3/2PP1PPQ/PPB4P/R1B1RNK1 b - - bm Nd4; id "ECM.064"; r1bQ1nk1/bp3ppp/p7/3B4/1P6/P3P1P1/2P4P/q1B2RK1 b - - bm Bxe3+; id "ECM.065"; 3r1rk1/1b2bppp/2q1pn2/pp4Q1/3B1P2/PBN5/1PP3PP/R2R3K b - - bm Rxd4; id "ECM.066"; 2nq2k1/2r3pp/p1p1rp2/PpQ1N3/1P1PR3/8/5PPP/2R3K1 w - - bm Nf7; id "ECM.067"; 3r4/p2nrpkp/2B1p3/2P2pP1/3R3Q/q7/6PP/6RK w - - bm g6; id "ECM.069"; 2r2rk1/5pbp/p5p1/3P2q1/1QbN4/5P2/P4BPP/2RR2K1 b - - bm Bf1; id "ECM.072"; r1bqnrk1/pp2ppb1/1np3pp/4P1N1/5P2/2NBB3/PPP3PP/R2Q1RK1 w - - bm Nh7; id "ECM.073"; 3nk3/3q1p2/1B3pr1/4p3/bP2P2p/r2B4/2Q2RPP/3R2K1 w - - bm Bb5; id "ECM.074"; 3rnr1k/pp3ppp/4b3/2p1qNP1/P2pPR2/1P1P2Q1/2P3BP/5RK1 w - - bm Nh6; id "ECM.075"; 5rk1/3r1p1p/3b2pQ/8/4q3/4B2P/3R1PP1/4R1K1 w - - bm Rxd6; id "ECM.077"; 4rrk1/1bp2ppp/p1q2b1B/1pn2B2/4N1Q1/2P4P/PP3PP1/3RR1K1 w - - bm Nxc5; id "ECM.078"; 2rnrbnk/3q1ppp/p1p5/3p1P2/1p1PPN2/4BQ1R/PP1N2PP/3R2K1 w - - bm Ng6+; id "ECM.079"; 5r1k/pb2r1bp/1p2B1p1/n7/4qNQ1/4B3/P4PPP/2RR2K1 w - - bm Rd4; id "ECM.080"; 1r3rk1/5pp1/1n2qn1p/1p1pPNb1/2pP2QP/2P5/1PB3P1/R1B1R1K1 w - - bm exf6; id "ECM.082"; r2qr1k1/pp3pbp/3p1np1/2pP1bB1/2P1N3/3Q1PN1/PP4PP/R4RK1 b - - bm Nxe4; id "ECM.083"; 4r1k1/1b4pp/p7/1prP3q/2P1B3/5P2/P3Q2P/3RR2K w - - bm Bg6; id "ECM.084"; r1br2k1/ppb1qpp1/2P4p/2n1p3/4B3/P1N2N2/1P3PPP/2RQ1RK1 w - - bm Nd5; id "ECM.085"; 2r3k1/1nqbrp2/p5pp/1p1Pp1N1/8/1P5P/P1B2PP1/2RQR1K1 w - - bm Nxf7; id "ECM.086"; 2r1rbk1/1b3ppp/pp6/2q1pNP1/Pn1RP3/2N5/1PP2QBP/5R1K w - - bm Nh6+; id "ECM.087"; r1b1rk2/3n1pbQ/2qp2p1/p2N2P1/2Bp3N/4P3/PP3PP1/2KR3R w - - bm Nxg6+; id "ECM.088"; r1r2qkb/4pp1p/pBbp3P/3Nn1P1/4Q3/1B6/PPP5/1K1R2R1 w - - bm g6; id "ECM.089"; r4k2/q4npp/P2P4/2p1R3/2N5/6PP/Q5K1/8 w - - bm Re7; id "ECM.090"; 5rk1/6pp/8/2Q4q/N2pP3/4b1Pb/4PP1K/1R3R2 b - - bm Bxf1+; id "ECM.092"; 2r4k/pp2Q1pp/5r2/P2P4/3Pb1P1/4Ppq1/1P1R3N/3R3K b - - bm Qe1+; id "ECM.093"; 1r1rb1k1/2p3pp/p2q1p2/3PpP1Q/Pp1bP2N/1B5R/1P4PP/2B4K w - - bm Qxh7+; id "ECM.094"; r1b4k/p2n1Bpp/1p1Q1n2/5p2/3P4/P3BqP1/1P3P1P/R4RK1 b - - bm Bb7; id "ECM.095"; rn1r2k1/p4ppp/2p3b1/3PQ3/1B2Np1q/1B3P2/P1P3PP/4R1K1 w - - bm Nf6+ Qe8+; id "ECM.096"; 4r2k/5R1p/pp1Bq1pN/2p1P3/1n1b3Q/3P4/1P4KP/8 w - - bm Rxh7+; id "ECM.097"; r2nk1r1/pb3q1p/4p3/3p2pQ/8/BP6/P4PPP/2R1R1K1 w q - bm Rc7; id "ECM.098"; rr4k1/2p1ppb1/3pbnpp/q1pP4/4P3/1PNNBP1P/P1KR2P1/2Q4R b - - bm Qxc3+; id "ECM.100"; 1r3rk1/3Q2pp/p3p3/6B1/3np3/6R1/PqP1B2P/3K2R1 w - - bm Qxg7+; id "ECM.101"; 2r5/p4Q2/k1bBp3/4P3/p1nq4/5B2/2Pr2P1/1R1RK3 w - - bm Qb7+; id "ECM.102"; 5rk1/p1pb2pp/2p5/3p3q/2P3n1/1Q4BN/PP1Np1KP/R3R3 b - - bm Qxh3+; id "ECM.103"; 2r1nk2/4qpbQ/4b3/1p2RpP1/4P3/p7/PBP5/1K5R w - - bm Qxg7+; id "ECM.104"; 2kr4/1bpr3p/4R3/1pQ5/8/6B1/3q2PP/2R4K w - - bm Qxc7+; id "ECM.105"; r4rk1/1pbb2pp/p1p1p2q/2Pp4/1P1Pn3/P3B2P/2Q1BPP1/R4RNK b - - bm Qxe3; id "ECM.106"; r1k4r/ppp1b3/5Npp/4pb1Q/8/1B2B3/PqP2PPP/2RR2K1 w - - bm Qxf5+; id "ECM.107"; 6r1/p4rkp/3RQ1n1/1pp1p1B1/2p1P3/2P3R1/P4qPK/8 w - - bm Qxe5+; id "ECM.108"; 2kr1bnr/1ppq4/p3bp2/6pp/4p3/2N2NBP/PP3PP1/2RQ1RK1 w - - bm Na4; id "ECM.110"; r2q2rk/p3bp1p/4b1p1/3pP2R/1p1B4/3BQ3/PPP3PP/5R1K w - - bm Rxf7; id "ECM.111"; r1b1Q3/6pk/p6p/1pq1n3/4N3/8/PPP3PP/R6K b - - bm Qc6; id "ECM.112"; q6r/pp3pkp/5np1/4Q3/4P3/6N1/P4PPP/5RK1 w - - bm Nh5+; id "ECM.113"; r1b1rk2/pp3ppQ/1np5/4q3/2B4N/4P3/PP3PP1/2R2K1R w - - bm Qg8+; id "ECM.114"; r1bn1rk1/pp3p1p/6p1/2bR2N1/2B2B2/q1P1P3/2Q2PPP/4K2R w K - bm Nxh7; id "ECM.115"; r3r1k1/p2N1pp1/1pn1p3/q1n5/2PQ4/P3B3/4PPKP/R5R1 w - - bm Nf6+; id "ECM.116"; 4qbk1/1R5n/p2pr1p1/2pQpNPp/P1P1P3/2P2P2/3B4/5K2 w - - bm Ra7; id "ECM.117"; 3qr1k1/1p1bppbp/p2p2p1/2rPn3/P2N4/4BP2/1PPQ2PP/R2R1BK1 w - - bm Ne6; id "ECM.118"; 8/R5p1/6k1/pr2p1b1/4K3/7P/5P2/6R1 w - - bm h4; id "ECM.120"; 5rk1/1b1r1p2/p1q1pQp1/1p2P2p/8/1BP1NR2/PP1n2PP/5R1K w - - bm Bxe6; id "ECM.121"; 6k1/p1p2r2/1p1p1P1Q/3P4/2P5/5qr1/PP4RP/6RK w - - bm Qh3; id "ECM.122"; 2b1rr1k/1p5p/1Ppp2q1/p3bN2/2P1n3/5R2/PBQ3BP/3R2K1 w - - bm Bxe5+; id "ECM.123"; 3b2rk/7p/p7/2pbqNrn/Pp1p1R2/1P1Q2P1/1BPN1R1P/6K1 w - - bm Rxd4; id "ECM.124"; 1rbr2k1/1pq1bp1p/p1pNn1p1/2n1p3/2B1P2P/1NQ1BP2/PP4P1/1K1R3R w - - bm Nxf7; id "ECM.125"; r4rk1/1pp1b1pp/p1q5/3pPp2/3Pn3/P3N3/1P3PPP/R1BQR1K1 w - - bm Qb3; id "ECM.126"; rbbq1rk1/p3nppp/1p2p3/8/1B1pN3/P2B4/1P3PPP/2RQ1RK1 w - - bm Nf6+; id "ECM.127"; rn2qbr1/2p4k/p2p1nb1/1p1Pp2p/2P4P/2NBBPN1/PP1Q4/2KR2R1 w - - bm Nxh5; id "ECM.128"; 5r1k/1p2qp1p/p4R1Q/P1p5/2Prp3/7P/1P4P1/5R1K w - - bm Re6; id "ECM.129"; r1bq1rk1/pp2bp1p/2p2np1/3p2B1/3P4/2NQ2N1/PPP2PPP/4RRK1 w - - bm Rxe7; id "ECM.130"; 2rq1rk1/pp2bppp/1npp1n2/3PpN1b/2P5/2N3PP/PP2PPB1/R1BQ1RK1 w - - bm c5; id "ECM.131"; rnbq1rk1/pp2b1pp/5n2/2pPp3/2P1N3/3B1N2/PP4PP/R1BQK2R w KQ - bm d6; id "ECM.132"; 2n1rbk1/5pp1/7p/qP1pp3/4b1Q1/1B5P/1P1N1PP1/2B1R1K1 w - - bm Rxe4; id "ECM.133"; 4k3/2R2p2/5p1p/8/rb6/1N6/5PPP/5K2 w - - bm Rc4; id "ECM.134"; 2k3r1/pp2rp2/1np5/2Np1p2/P2P3p/1R2P1Pq/2Q2P1P/1R4K1 w - - bm Nxb7; id "ECM.135"; 2r1k3/p3nrR1/1p1p4/2p1p1p1/2P1B3/2PP1P2/P5K1/7R w - - bm Rh8+; id "ECM.136"; 2rr1bk1/5p1p/pPN2np1/3Bp3/2Q1n3/1P2B1Pq/P3PP2/R2R2K1 b - - bm Rxd5; id "ECM.138"; 3r2k1/1p4pp/p1q1p3/3p1B2/bP1B2P1/P4Q2/5PKP/2b2R2 w - - bm Rxc1; id "ECM.139"; rnb1r1k1/pp5p/2pp2p1/4b3/2P1P2q/1NN1BPp1/PP1QB1P1/3RR1K1 b - - bm Bf4; id "ECM.140"; 5n1r/1p2kp2/rB1Nb3/4p1Pp/4p2P/1PP5/8/1K1R1R2 w - - bm Rxf7+; id "ECM.141"; b3r3/q2B2k1/3Q2p1/1p5p/3pP3/5P2/1p4PP/5RK1 b - - bm d3+; id "ECM.142"; 4r1k1/3R1ppp/p2p4/5PP1/2q2P2/2n2B2/P1P3QP/1r3R1K w - - bm Rxb1; id "ECM.143"; 8/p3q1kp/1p2Pnp1/3pQ3/2pP4/1nP3N1/1B4PP/6K1 w - - bm Ba3; id "ECM.146"; r2b1rk1/5qp1/2p2P2/2p3Pp/p6P/2Q5/PPP5/2KR2R1 w - - bm g6; id "ECM.147"; 1r2k2r/p5bp/4p1p1/q2pn3/1p2N1P1/6QP/PPP5/1KBR3R w k - bm Bh6; id "ECM.149"; rn1q1rk1/pp3p1p/2p5/3p4/5Q1P/2NP3R/PPP3P1/4RK2 w - - bm Rg3+; id "ECM.150"; 7r/kppQP1pp/p7/2qp1R2/4n3/1P2b2P/P1P3PK/R7 b - - bm Re8; id "ECM.151"; r1b1kb1Q/qp2pp2/p3n1p1/2nN2Pp/2B4P/7N/PPP5/2KRR3 w q - bm Nc7+; id "ECM.152"; 2r1q1r1/6bk/p2pN1pp/1p1N4/4P3/3R3Q/PnP4P/1K4R1 w - - bm Nf6+; id "ECM.154"; 4r3/Q2bppkp/3p2p1/3Nn3/4P3/6PP/1qr2PB1/R3R1K1 b - - bm Ra8; id "ECM.155"; 6k1/p1q2pp1/2n2b2/3B2Pp/2P2P2/5N1P/Pr1Q2K1/4R3 w - - bm Re8+; id "ECM.156"; r1r3k1/p4n2/3p4/5NpR/8/2q2P2/P1PQ4/2K4R w - - bm Rh8+; id "ECM.157"; 8/p5Q1/2ppq2p/3n1ppk/3B4/2P2P1P/P5P1/6K1 w - - bm g4+; id "ECM.158"; r1r3k1/1p1b1nq1/6p1/pN1p4/P2Np2R/1P2P3/1Q3PP1/1K5R w - - bm Nd6; id "ECM.159"; 1r2k2r/3q2pp/p3pp2/P7/2P1Q3/8/1nB3PP/1R3R1K w kq - bm Ba4; id "ECM.160"; r1bq3k/ppp2Qp1/2n1p2p/6N1/2BPN3/2P1n3/PP4PP/R5K1 w - - bm Nf6; id "ECM.161"; 3R4/1p2kp2/p1b1nN2/6p1/8/6BP/2r1qPPK/Q7 w - - bm Rd7+; id "ECM.162"; 6k1/p5p1/1p1p1nN1/1B1P4/4PK2/8/2r3b1/7R w - - bm Rh8+; id "ECM.163"; 8/5P2/4K1kP/4R3/8/8/8/5r2 w - - bm Rg5+; id "ECM.164"; 3r1rk1/p1p1qp1p/2p1b1p1/8/P2PRP2/2P1NQ2/6PP/R5K1 w - - bm f5; id "ECM.165"; 6k1/pr3ppp/1p3qn1/5NQ1/2p5/8/P4PPP/4R1K1 w - - bm Re8+; id "ECM.166"; Q7/1pq2kpp/4bp2/3r4/2B5/P3P3/1r3PPP/2R1K2R b K - bm Rd1+; id "ECM.167"; 4r1k1/p4ppp/4q2r/1Q6/4p3/4P1P1/P4P1P/2RR2K1 w - - bm Rd6; id "ECM.168"; 8/5p1k/4p1p1/3p2K1/3P1Q1P/P4P2/7q/8 b - - bm f6+; id "ECM.169"; r4r2/6k1/3p4/2pPp2p/4Pqp1/3P1P2/1R2Q1KP/5R2 b - - bm Ra1; id "ECM.170"; 4r1k1/1np1r1pp/1ppp1q2/6N1/1P3P2/4RQP1/7P/4R1K1 w - - bm Qh5; id "ECM.171"; r4rk1/pp3p1p/3pq1p1/2nNp3/3R1P2/7Q/PP4PP/5RK1 w - - bm f5; id "ECM.172"; 3qn2k/1p3Bp1/rbn4p/2p5/p1P2p2/P2b2PP/1BQNRP2/1R4K1 w - - bm Qxd3; id "ECM.173"; 3r1rk1/1pp4p/1q3bp1/p3p3/P2n1P2/2BB3P/1PP2QP1/R4RK1 b - - bm Bh4; id "ECM.174"; 4rrk1/2p2ppp/p2b4/1p1P4/3P2nq/2P4P/PPQ1RPP1/RNB3K1 b - - bm Qxf2+; id "ECM.175"; 1q6/2rk1p2/p1n1b1rN/3p2p1/8/3Q4/PP1B1PPP/2R1R1K1 w - - bm Nxf7; id "ECM.176"; r3kb1r/2q2p2/3p4/ppp1n1B1/P6P/1B3pQ1/1PP3b1/2KRR3 w kq - bm Bd5; id "ECM.177"; r1b2rk1/1p4pp/p1n3q1/4ppN1/7Q/2P1B3/P1P2PPP/R2R2K1 w - - bm Rd6; id "ECM.178"; 1rb2r2/1pR1N2p/p2R2pk/5p2/4pP2/1P1nP3/P4P1P/5BK1 w - - bm Rf6; id "ECM.179"; 3r2k1/p2q1r1p/1p1N2p1/1PpP4/3b1Bn1/1Q4Pb/1P2RP1P/R5KB b - - bm Qxd6; id "ECM.181"; 4r1k1/1pbb3p/2pp2q1/p1n5/2P2R2/1PN1n1P1/PB2Q1B1/5RK1 w - - bm Qxe3; id "ECM.182"; 3r2k1/p2r1p1p/1pR1p1qP/3P1pP1/3R4/1P2Q3/P4K2/8 w - - bm dxe6; id "ECM.183"; 3r3k/p1Q3bp/2p3p1/8/2P1BRn1/1P4Pb/P1N1q2P/6BK b - - bm Nf2+; id "ECM.184"; r4k2/p1pr1ppp/2q5/3PR2P/3Q4/8/6P1/5RK1 w - - bm Re7; id "ECM.185"; r1b4r/pp2ppk1/2np1np1/3N3p/2B1P3/q3BP2/P1PQ2PP/1R3RK1 w - - bm Nxe7; id "ECM.187"; r3k2r/pb1n1pbp/4p1p1/q1n1P3/Bp1N1N2/4B3/PP3PPP/R2Q1RK1 w kq - bm Ndxe6; id "ECM.188"; 5rk1/Q2nqppp/5n2/2p5/8/1B2PP1P/Pr1B1P2/R3K2R b KQ - bm Ne4; id "ECM.189"; 2k1r1r1/ppb2p2/6b1/2qP4/2P2P2/4pP1p/P3Q2P/2RBRN1K b - - bm Bd3; id "ECM.191"; 5r1k/pp1n1p1p/1b1qpP2/8/1PrN4/P1N1Q1P1/7P/3R1R1K w - - bm Qh6; id "ECM.192"; 1r3rk1/p4pbp/q1p2pp1/3p1b2/1n1P1P1B/PB3N2/1PPQR1PP/2KR4 b - - bm Bxc2; id "ECM.194"; 1rbr2k1/4qp2/p1n2bpp/1pp1p1N1/4P3/2P1BQ1P/PPB2PP1/3RR1K1 w - - bm Bxc5; id "ECM.195"; 2r2rk1/1p1q1ppp/1p3n2/3p1N2/4n3/1N3Q2/PPP2PPP/R2R2K1 w - - bm Rxd5; id "ECM.196"; rn3rk1/pp2ppbp/6p1/2R3N1/2B3b1/q3B3/P1P1Q1PP/5RK1 w - - bm Rxf7; id "ECM.197"; r1nqr2k/1p1b1Q1p/p5p1/P1pPb3/5B2/2N5/BP4PP/R4RK1 w - - bm Qf8+; id "ECM.199"; 8/k3r1b1/Pp2rpp1/1qpQ4/4nB2/2P2NP1/7P/R4RK1 w - - bm Bb8+; id "ECM.200"; 1k1r4/ppq2p2/8/2pPb1r1/2P1Q1B1/6P1/PP3PK1/R4R2 b - - bm f5; id "ECM.201"; r1b2nk1/2qn1p1p/1ppR2p1/8/1PP1NP2/4r1PP/1Q2N1B1/3R2K1 w - - bm b5; id "ECM.202"; 8/5pk1/3q2p1/8/7P/5Q1K/6B1/6b1 b - - bm Qh2+; id "ECM.203"; 6r1/ppp4k/3p2rp/3Pb3/PPP1Np1q/5P1b/3QRRBP/6K1 b - - bm Bd4; id "ECM.204"; 4br1k/pR4bp/2r1B1pN/4npB1/3p4/P7/5PPP/4R1K1 w - - bm Rxg7; id "ECM.205"; r1bq1rk1/pppn2bp/3p2p1/3N1p2/8/BP1BRQ1P/P1PP1PP1/4R1K1 w - - bm Nxc7; id "ECM.206"; r6r/1p2kp2/3p1b2/pPpPpQ1P/1nP1P2P/6R1/1P2K3/1B6 w - - bm Rg6; id "ECM.207"; 2r1r1k1/pp3pp1/3p3B/P2P1P2/2nb4/7R/1q3PQP/1B3R1K w - - bm Rb3; id "ECM.209"; r2qr1n1/p4pk1/1p1p2p1/4p3/4PQ2/1PN2P2/1PP3P1/2KR3R w - - bm Rh7+; id "ECM.210"; r4rk1/ppp3b1/3p1qp1/3Pp3/2P1Bn2/4BP2/PP1Q4/2K3RR w - - bm Rxg6; id "ECM.211"; 1k1r2r1/pp3p1p/B2q1n2/8/3Pb1p1/2Q5/PR3PPP/2B1R1K1 w - - bm Bf4; id "ECM.212"; k3r3/pR5p/PppR1p1p/4nP2/1PP5/8/4B1rP/2K5 w - - bm Re7; id "ECM.213"; 1q3rk1/r5b1/pNp1bn1p/2Pp1n2/1P2p3/1N2P2P/PBQKB3/3R3R b - - bm Nxe3; id "ECM.214"; 3r2k1/p5pp/bpP1p3/3n1p2/2NQpP1q/P3P3/1B1R1R2/4KBr1 b - - bm Rxf1+; id "ECM.216"; 1rq1r2k/5Rbp/p2p1p1B/2p1p3/2P1P2Q/1P6/P5PP/3b3K w - - bm Bxg7+; id "ECM.217"; 5Q2/5p1p/3p2p1/4p1k1/4P1P1/3R1P1K/r6P/4q3 w - - bm f4+; id "ECM.218"; 2b2r1k/ppq3pp/3b3r/n3NpN1/Q2PpP1B/2P1R3/PP5P/4R1K1 w - - bm Ngf7+; id "ECM.219"; 2r1r1k1/1R4bp/p5p1/2pqn3/8/2B5/1PQ1B1PP/5RK1 w - - bm Bc4; id "ECM.220"; 7k/pp1q2pp/3Nr1n1/3B2Q1/2pP4/B3P1Pb/P6P/6K1 w - - bm Qd8+; id "ECM.221"; r5k1/5p1p/bq1p2p1/r2Pp3/1p2N1P1/1P3P2/1KPQ3P/3R3R b - - bm Ra2+; id "ECM.222"; 5Bk1/pr2pp1p/2b3pQ/2p1q3/8/2P4P/PP4P1/1B1Rb1K1 w - - bm Bg7; id "ECM.223"; 5nk1/2b1q1p1/2p5/3pP1pQ/1r1P2P1/3B1R2/5PP1/6K1 w - - bm Rxf8+; id "ECM.224"; 1k1r3r/1pp2p2/p2b4/4n1p1/N3q1P1/1B2B3/PP3RP1/4RQK1 b - - bm Rh1+; id "ECM.225"; rnb1kr2/p4pQ1/8/1ppPpP2/2p1P3/N6P/Pq4B1/3R1RK1 w q - bm Nxb5; id "ECM.226"; 5r1k/2p3pp/3pQ3/3P1rN1/pp5q/5PR1/P4PKP/B7 w - - bm Bxg7+; id "ECM.227"; 8/pR3Bk1/3p2p1/5b1p/2P4P/6P1/P4bQK/4q3 b - - bm Bg1+; id "ECM.228"; r1b1Rnk1/6pp/p4q2/1pp2P2/3r4/2NB4/PP1Q2PP/4R1K1 w - - bm Nd5; id "ECM.229"; 1Q6/pb3pk1/1p3qp1/1N3p1p/2Pr3P/3BR1PK/r7/6R1 b - - bm Rh2+; id "ECM.230"; 2kr3r/Qpp1n1p1/2b2pp1/4b3/8/6N1/PPP2P2/R1B2RK1 b - - bm Rh1+; id "ECM.232"; 8/2p2Q1p/1rp5/p3q1kp/P7/2P2RP1/5PK1/8 w - - bm Rf5+; id "ECM.233"; 1r2b3/1p2q1bk/p1p1p1p1/P1PpP2r/1P1KpPQP/4P2N/6R1/4B2R b - - bm Rxe5; id "ECM.234"; 6k1/3b1p1p/6p1/2BPR3/8/4Q2P/1q3rPK/8 w - - bm Re8+; id "ECM.235"; 2R5/4ppkp/6p1/p2P4/4P2P/p3B1P1/qbR2PK1/8 w - - bm Rg8+; id "ECM.236"; 3rr1k1/1b5p/p6p/1p3N2/6Pb/P1Q1p3/1PP4P/R5K1 b - - bm Rd1+; id "ECM.237"; 6k1/p4pq1/2n1p1p1/1p1pP1N1/3P1QPP/8/P3K3/8 w - - bm Qc1; id "ECM.238"; 3r1rk1/1pq1nppp/p7/2pB3Q/P4P2/1P2P3/6PP/2RR2K1 w - - bm Bf3 Rxc5; id "ECM.239"; 8/p1r2q1k/1p1p3p/1Pp1nP2/P1P5/3R2PP/1Q4BK/8 w - - bm Rxd6; id "ECM.240"; 6k1/1pp2p2/p2p2q1/2PPb3/4r3/Pr4PK/2R5/2Q2NR1 b - - bm Rh4+; id "ECM.241"; 3r4/1pQ4R/p1b2kp1/P6p/2q5/7P/2P3P1/6K1 b - - bm Rd1+; id "ECM.242"; 6rr/1b3k1p/pbqppPn1/1p5Q/4PN2/P6R/1PP3BP/2B2R1K w - - bm Qxh7+; id "ECM.243"; 4rrk1/3b1ppp/pb6/1pqP4/P1p1PP2/1P2NK2/3QB2P/R2R4 b - - bm Rxe4; id "ECM.244"; 2r1r1k1/1p4bp/p2p1qp1/1n1P4/2P1B2P/1N1Q4/PP2R3/1K5R b - - bm Rxc4; id "ECM.245"; 6rr/ppqb1pkp/2pb1pn1/3p3Q/3P1P1N/3B1RN1/PPP3PP/5RK1 w - - bm Qh6+; id "ECM.246"; r2qr1k1/1pnb1pp1/p1n1p2p/8/P2P3P/B2B1NP1/6P1/R2Q1RK1 w - - bm Bh7+; id "ECM.247"; r2q1rk1/1b1nbpp1/p1p1p2p/1pPpN3/3P1N2/P2BP3/1PQ2PPP/R4RK1 w - - bm Bh7+; id "ECM.248"; 2r2rk1/pb4pp/1p2p3/4Npq1/3P1n2/5P2/PP1R2PP/RB2Q1K1 b - - bm Rc1; id "ECM.249"; 2r1rbk1/5pp1/bq5p/1pnBPN2/6Q1/N7/5PPP/R2R2K1 w - - bm Bxf7+; id "ECM.250"; 1k1r1r2/2b2R2/Bppp2p1/2q4p/Q2pP3/P2P4/2P3PP/1R4K1 w - - bm Bb7; id "ECM.251"; r5k1/pp2ppb1/4qn2/r3B1p1/3P4/3QNP1R/PP2K1P1/7R w - - bm Bxf6; id "ECM.252"; 1R2br1k/5r1p/p2p1P2/6RQ/3p1P2/4p2B/q6P/5N1K w - - bm Rxe8; id "ECM.253"; kr1r4/7p/2bqp1p1/p7/1Pp1PP1P/K1B1nNPB/PP5R/RN2Q3 b - - bm Qxb4+; id "ECM.254"; 5r1r/1pkb4/5pB1/2P5/p3R2P/Pq6/1PQ2Pn1/K2R4 w - - bm Rxd7+; id "ECM.255"; kn5r/p2r2p1/1pqBp1np/1Q1pPp2/R2P4/1N6/2P2PPP/R5K1 w - - bm Rxa7+; id "ECM.256"; 4Rnk1/2p2pp1/3r3p/p2P4/P5Q1/1B5P/5PK1/q7 w - - bm Rxf8+; id "ECM.257"; 4r3/2k1p2q/pp1nR1p1/2pP1pP1/2P2P2/1P6/P1K3B1/4Q3 w - - bm Rxd6; id "ECM.258"; r1b1rbk1/7p/2p1pBp1/p2pP1P1/5P2/1PqB4/P1P1Q3/1K4RR w - - bm Rxh7; id "ECM.260"; 2rq4/5rbk/3p1n1p/p2Pp2P/1p2b3/4BNR1/PP1Q1P2/3BK1R1 w - - bm Bxh6; id "ECM.261"; r2q1rkb/pp2p3/2p2pp1/3pPb2/3P3R/2N3P1/PPPQBPK1/3R4 w - - bm Rxh8+; id "ECM.262"; 3r2k1/p4rPp/1b1q3Q/n1p1pP2/1p6/3B1NR1/P4P1P/6RK w - - bm Qxh7+; id "ECM.263"; r1bqrnk1/p4p2/1p5p/3pB1p1/P2P2n1/1P1B2N1/2Q3PP/R4RK1 w - - bm Bh7+; id "ECM.264"; r2rn1k1/1bqn1ppp/p7/2bpP1P1/1p1N1Q2/1P3B2/PBP1NR1P/3R2K1 w - - bm Qxf7+; id "ECM.265"; r2r2k1/1bqpbpp1/ppn1p2p/2p1P1N1/P1B2B2/2P5/1PPRQPPP/3R2K1 w - - bm Nxf7; id "ECM.266"; r1b1r1k1/1p1n1p2/p1nBp1p1/q2pP1Np/P7/R2B3Q/2P2PPP/5RK1 w - - bm Nxf7; id "ECM.267"; r1b1k2r/ppp3pp/1qp5/2b1Pp2/3Qn3/5N2/PPPBNPPP/2KR3R w kq - bm Qd8+; id "ECM.268"; 1k6/1p4p1/P1p5/5Q2/2q2r2/P7/8/4R2K w - - bm Re8+; id "ECM.269"; 4n1q1/1k1b4/2p4R/2Pp4/1p1N1rpQ/3B4/PPP2P2/2K5 w - - bm Qd8; id "ECM.271"; r2qk2r/1pp2ppp/p3pnn1/6N1/1B1P2P1/1Q2P2P/PP3PK1/R6R b kq - bm Nh4+; id "ECM.272"; 2kr2r1/R2p3p/2n2p2/1R3P2/2P1p3/4BQ2/1Pq4P/4K3 w - - bm Ra8+; id "ECM.273"; r1br4/ppq2pk1/3bpN2/8/2P5/3n2B1/PP2QPPP/R4K1R w - - bm Qg4+; id "ECM.275"; 6kb/B1p2p2/5r2/1r1p2pR/6q1/3P2P1/P1P2PP1/2KR3Q b - - bm Rb1+; id "ECM.276"; rn4k1/pp2p1b1/4b3/q2p2Q1/2B2P2/8/P1P1K1P1/R6R w - - bm Rh8+; id "ECM.277"; 3k2r1/pp1b3Q/1b2pP1p/3pN2q/5B2/7B/PP2nP1K/2R5 b - - bm Rg2+; id "ECM.278"; 2r2rk1/pp3qpp/8/3P1b2/3Q4/P1N1B3/5PKP/R2R4 b - - bm Rxc3; id "ECM.279"; r1b2rk1/1pqp1ppp/p1n1pn2/5N2/8/2PBB3/P1P2PPP/R2QR1K1 w - - bm Nxg7; id "ECM.280"; 4k2r/1bqnbppp/p3p3/1p2P1N1/2r2BB1/8/PPP3PP/R2Q1R1K w k - bm Nxf7; id "ECM.281"; 5r1k/1pqb3p/2n5/p1pB4/2Pp1r1P/1P5P/R2N2K1/3Q1R2 b - - bm Bxh3+; id "ECM.282"; r4r2/pp2qk2/4pnp1/3pQ3/2p2P2/3B4/PPP2P2/2KR3R w - - bm Bxg6+; id "ECM.283"; 3bq3/p1n2rk1/1pp1p1p1/3pPnPp/1P1P1N1P/2PN3K/P2BQR2/8 w - - bm Nxg6; id "ECM.284"; b6r/2q2k2/4pPp1/1p1n2Bp/2pPB1PP/2P2Q2/8/4R1K1 w - - bm Bxg6+; id "ECM.285"; r1b2r2/3pNpkp/3pn1p1/2pN3P/2PnP3/q3QP2/4BKP1/1R5R w - - bm Qh6+; id "ECM.286"; 4k3/p4ppp/nb1P4/4p3/1P6/P4BP1/3q1r1P/2R2QKR w - - bm Qb5+; id "ECM.287"; r2q1rk1/pp2pp2/3pb3/3Qb2R/4P1p1/1BN1Bn2/PPP2P2/2K4R w - - bm Rh8+; id "ECM.288"; 2r1r1k1/pp1nbpp1/4pn1p/q3NN1P/P1pP1B2/2P5/1PQ2PP1/R3R1K1 w - - bm Nxg7; id "ECM.289"; 1rbk2nr/p1pp2b1/7p/2qP1pp1/2Bn4/2NKBP2/PP2N1PP/R2Q3R b - - bm Qxc4+; id "ECM.290"; 1r3rk1/6p1/p1pb1qPp/3p4/4nPR1/2N4Q/PPP4P/2K1BR2 b - - bm Rxb2; id "ECM.291"; r2qnr2/pp3kbQ/2npb1p1/2pN1pP1/4P3/8/PPP1BP2/R1B1K1NR w KQ - bm Qxg6+; id "ECM.294"; r2k3r/2pb1ppp/p1p1q3/2Q5/5B2/2N5/PPP2PPP/3R2K1 w - - bm Bxc7+; id "ECM.295"; 2r2r2/2N2pkp/2Q5/1N2p1b1/1p6/3P1qPb/PPR2P1P/4R1K1 b - - bm e4; id "ECM.296"; 2r1qrk1/pp1b1ppp/4pn2/n1b5/8/2NQ1NP1/PP1BPPBP/R2R2K1 w - - bm b4; id "ECM.297"; 1r2k2r/2p2p1b/q1Pppb1N/p2p2P1/Q2P4/P3B3/1P5P/2KRR3 b k - bm Rb4; id "ECM.299"; 4b1r1/1p3ppk/3r3p/p1p1qP1B/3pPN2/3P3R/nPPQ3P/6RK w - - bm Ne6; id "ECM.301"; 4b2k/7p/3q3P/1p1pRpr1/1P1B4/2P2Q2/7K/8 w - - bm Qg3; id "ECM.302"; 2kr2r1/pbp4p/1p4p1/1NqpNp2/4nQ2/8/PPPR1PPP/2K1R3 w - - bm Nc6; id "ECM.303"; 1rr3k1/1p1bqpbp/1R1p2p1/pN1P4/P3P1n1/1Q6/3NB1PP/2B1R1K1 b - - bm Rc3; id "ECM.304"; r1br4/1p3k2/p2q1p2/3N1Pp1/3Q4/8/PP4P1/4RR1K w - - bm Re6; id "ECM.305"; r3kbnr/p4ppp/2p1p3/8/Q1B3b1/2N1B3/PP3PqP/R3K2R w KQkq - bm Bd5; id "ECM.306"; 3r1rk1/2p1qp1p/pnP3p1/4n3/PP1NpR2/1BQ4P/6P1/5RK1 w - - bm Ne6; id "ECM.307"; r1bq1k2/5pb1/p2p1n2/2pPrP2/2p4B/3B2R1/PP1Q2PP/R5K1 w - - bm Qg5; id "ECM.308"; 2bq1rk1/p4pbp/p2p2p1/3P4/2p1QP2/2Pr3P/PP1N2P1/R1B2RK1 b - - bm Bd4+; id "ECM.309"; r3rk2/p2q1b1p/1pnP1Qp1/5pN1/2p2P2/P1P5/7P/4RRK1 w - - bm Re7; id "ECM.311"; 5r1k/1p1b1p1p/p2ppb2/5P1B/1q6/1Pr3R1/2PQ2PP/5R1K w - - bm Qh6; id "ECM.314"; r1rbb3/1R3pkp/2pBp1p1/p3P3/q6P/6P1/P2Q1P2/1R3BK1 w - - bm R1b4; id "ECM.316"; 4r3/pp1b3k/2p2qpp/2Pp4/1P6/PBbP1N1P/2R3P1/3Q3K b - - bm Re1+; id "ECM.317"; 1rb2rk1/p1p2ppp/2q5/3R4/2P1N3/bP4B1/P1Q2P1P/1K5R w - - bm Bxc7; id "ECM.318"; 8/5k1p/5PpB/3PR3/2r4P/1p3K2/2b5/8 b - - bm Re4; id "ECM.319"; 4r2k/3b3p/p2p4/2pP1p2/q1B2Q1P/2PK1P2/Pr1R4/7R b - - bm Re4; id "ECM.320"; 2R5/2R4p/5p1k/6n1/8/1P2QPPq/r7/6K1 w - - bm Rxh7+; id "ECM.322"; r1b1r1kb/p1qn1pnp/2p1p1p1/4P1N1/2p1NPP1/4B3/PPPQ3P/3RK2R w K - bm Qxd7; id "ECM.323"; 5k1r/ppqnnp2/3b2p1/2pB2Qp/3p3N/1P1P2P1/P1P2P2/2B1R1K1 w - - bm Rxe7; id "ECM.324"; 5rk1/5p1p/8/3pNp2/RPrqn3/1Q5P/1P3PP1/4R1K1 w - - bm Rxe4; id "ECM.325"; 2rr2k1/4qppp/bn6/p1bB4/4N3/6P1/PB2PP1P/2RQ1RK1 w - - bm Rxc5; id "ECM.326"; 3r1rk1/pbqn1pp1/1pp2n1p/2b1p1B1/P1B1P2N/2N4P/1PP1QPP1/3R1RK1 w - - bm Rxd7; id "ECM.327"; 5rk1/r2nqpp1/p3p3/1p2P3/4N1pP/8/PPP3Q1/1K1R3R w - - bm Rxd7; id "ECM.328"; 1rr3k1/4ppb1/2q1bnp1/1p2B1Q1/6P1/2p2P2/2P1B2R/2K4R w - - bm Qh6; id "ECM.329"; 3rqb2/1pR3pk/p3n1pp/3p4/3B4/PP6/1P4PP/4RQK1 w - - bm Rxe6; id "ECM.331"; rkb2qr1/1p5p/pQ1bp3/3p2B1/5n2/3B1N2/PP3PPP/2R2RK1 w - - bm Rxc8; id "ECM.332"; 2r2rk1/1bq2ppp/p7/1p1pNN2/1b1PnB2/3Q3P/PP3PP1/R3R1K1 w - - bm Rxe4; id "ECM.333"; r3r1k1/1p3pPp/p1p5/3bb2N/7q/1P1Q4/2PB2PP/4RRK1 w - - bm Rxe5; id "ECM.334"; 8/5p2/4p1k1/4P1p1/2rBRbK1/5P2/r4P2/7R b - - bm Rxd4; id "ECM.335"; r1bqr1k1/pp3pp1/2p4p/3PN1n1/3P1b2/2NB4/PPQ2PPP/3R1RK1 b - - bm Rxe5; id "ECM.336"; r3r1k1/pbqn1ppp/1p3n2/1Pb5/2p5/5N1P/PBQ1BPP1/1N1R1RK1 b - - bm Rxe2; id "ECM.337"; r1b1r1k1/pp3p1p/1q2p1pQ/2b1P1B1/8/P2B3P/1P3PP1/2R1R1K1 w - - bm Rxc5; id "ECM.339"; 1k2r2r/1bpQN2p/1p6/P3p2q/4np2/2P2N2/2P2PPP/R3R1K1 b - - bm Rxe7; id "ECM.340"; r1k2n1r/2pb4/1p1p1qpp/p2P1p2/3N1P1P/2Q3P1/PPP1R3/2K1RB2 w - - bm Re8+; id "ECM.341"; r1b2r1R/1p2bpk1/4p1p1/4P1N1/p2p4/5Q2/qPP2PP1/1NKR4 w - - bm Qf6+; id "ECM.342"; rnb2rk1/3n1ppp/p3p3/1p2P1q1/3N4/1BN5/PPP3PP/R2Q1RK1 w - - bm Nxe6; id "ECM.343"; 4q1r1/5kpp/2p1nb2/2PpQp2/r4P2/1N3P2/1BP1R2P/6RK w - - bm Rxg7+; id "ECM.344"; 1r3k1r/4Rn1p/pb1p1P2/1p1q2P1/5p2/7Q/PPP1B1RP/2K5 w - - bm Rxf7+; id "ECM.346"; 4rrk1/ppn3pp/2pb1n1q/3p4/1P1P4/P3BNP1/2P1BPKP/R2Q1R2 b - - bm Rxe3; id "ECM.347"; 2b1r2k/2Q4p/4q3/1pp5/3b4/4NP2/1P3BP1/3R2K1 w - - bm Rxd4; id "ECM.348"; 7r/3qbk1r/3p1n2/p1pPp1p1/Pp1nPpP1/1P1Q1P1B/1NP3K1/R3B2R b - - bm Nxg4; id "ECM.350"; r2qn1k1/1p1b3p/2pp1b2/6pQ/p1P1P3/P1N3PB/1P6/3R1R1K w - - bm Rxf6; id "ECM.351"; 2rq3r/5p2/p3pkbQ/3p4/3N4/2P4R/P4PP1/4R1K1 w - - bm Rf3+; id "ECM.352"; r4k1r/pp2pp2/3p1b2/q2PnQpp/3N4/1BP3P1/PP3PP1/3RR1K1 w - - bm Rxe5; id "ECM.353"; 5rk1/2p3pp/p1p4r/2P1p3/3pPnq1/1P3R1P/PN1Q3K/R5N1 b - - bm Qxf3; id "ECM.354"; r1b3rk/pp1n3p/2p2b1n/4pp1q/2P5/1P3NPP/PBQ1NPB1/3RR1K1 w - - bm Rxd7; id "ECM.355"; r3r1k1/4pp1p/b5pB/q1pP4/3b4/2N4P/PP4P1/R2RQ2K w - - bm Rxd4; id "ECM.357"; 1r6/3b1pk1/pr1p1q1p/2pPb1p1/2B1P1P1/2N2PP1/1PQ3K1/RR6 b - - bm Rxb2; id "ECM.358"; 2r2rk1/5ppp/1p2p3/p7/1n1R4/P1NnPN2/1P3PPP/1R4K1 b - - bm Nxb2; id "ECM.359"; 2r3k1/p1r1ppb1/2bp1np1/q5N1/1p1BP2Q/3P4/PP2N1PP/2R2R1K w - - bm Bxf6; id "ECM.360"; r3r1k1/p4ppp/2pp1b2/8/q2n1P2/2BQ3P/PPP3P1/1K1R2NR b - - bm Re3; id "ECM.361"; rn1kr3/pppb4/3p1q2/3P1pNn/2P2P1p/1P2Q2P/P2NR1B1/4R1K1 w - - bm Qxe8+; id "ECM.362"; r2q1rk1/ppp1b1pp/1nn1p3/4P3/2PP4/2N1B2P/PP1Q4/2KR1B1R b - - bm Rxf1; id "ECM.363"; r3k3/1pqb1p2/p3p3/4n2r/3N1Q2/2P5/PP4B1/4RRK1 w q - bm Rxe5; id "ECM.364"; 1rb2bk1/q4r2/pB1p1nn1/3Pp3/N3PpP1/8/1PQ1BNP1/R1R3K1 b - - bm Rxb6; id "ECM.365"; r4rk1/5p2/p1b1pQpq/8/1B2P3/2NR4/PPP3PP/1K6 w - - bm Nd5; id "ECM.367"; 3nr1k1/p6p/2n1pRpB/3pP3/2pP2P1/q1P4P/6BK/5Q2 w - - bm Rxg6+; id "ECM.368"; 2rr2k1/5ppp/p1b1pn2/q1p5/P1B1PQ2/R1PN1P2/6PP/1R4K1 b - - bm Rxd3; id "ECM.369"; 1r2r1k1/1pqb2pp/p2bp1n1/2p3BQ/3pN3/1P1P2P1/P1P3BP/4RRK1 w - - bm Bd8; id "ECM.370"; 1k2rb1r/pbp1q1pp/2pp4/2PnpP2/Q7/1P3NP1/PB5P/2KR1B1R w - - bm Rxd5; id "ECM.371"; 7k/p1p1r2p/1p1pnr1q/5pp1/2PPPp2/2PB1P1P/P2Q1PRK/7R b - - bm g4; id "ECM.372"; 5qk1/p4p2/1p3Pp1/2p4Q/3rr3/7R/PP6/6RK b - - bm Rh4; id "ECM.373"; 5r1k/5Bb1/3p2Pp/p1pP4/1p2Q3/4P1P1/q7/3K3R w - - bm Rxh6+; id "ECM.374"; 2b4B/1pp2k2/1p6/3P3n/5p1P/1P4p1/P2r2P1/R5KR b - - bm f3; id "ECM.375"; r3k2N/pppbq1pp/5n2/3Ppn2/2BP4/2P3bP/PP2Q1P1/RNB2K1R b - - bm Bh2; id "ECM.376"; 5n2/3bp1r1/1r1p3k/p1p2pNp/1nP2P1P/1PN1PB1K/P5R1/6R1 w - - bm Nf7+; id "ECM.378"; r3bb2/P1q3k1/Q2p3p/2pPp1pP/2B1P3/2B5/6P1/R5K1 w - - bm Bxe5; id "ECM.379"; r1b1qbk1/7p/4p1p1/1p2Bp2/p1B2Q2/P3P3/1P3PPP/3R2K1 w - - bm Bc3; id "ECM.380"; 3r1rk1/1pq1bppp/p7/n2RN3/P7/1P6/1B2QPPP/R5K1 w - - bm Nd7; id "ECM.382"; q1r3k1/2r4p/2p3pP/2Qp1p2/PRn5/4P1P1/5PB1/1R4K1 w - - bm Rxc4; id "ECM.383"; r3bknr/1p4pp/p3Q3/q4pb1/P1Bn4/8/1PP2PPP/R1B1R1K1 w - - bm Qd6+; id "ECM.384"; r1b1nrk1/p2n3p/2pp4/8/2P2q1N/1PB4P/P4PB1/R2QR1K1 w - - bm Bd5+; id "ECM.385"; 7k/5rp1/p1bQB2p/1p4nN/4P3/1Pq5/P5PP/3R3K b - - bm Bxe4; id "ECM.386"; r4r1k/1bq4p/p4bp1/3pn3/NP6/Q1PBB2P/6P1/3R1RK1 b - - bm d4; id "ECM.387"; r2r2k1/1bq2pb1/6pp/2P1p3/1nBpN2N/6PP/2Q2P2/3RR1K1 w - - bm Nf6+; id "ECM.388"; r3rbk1/p1q2pp1/1n5p/2pp4/4N3/1PQ3P1/PB2PP1P/3R1RK1 w - - bm Nf6+; id "ECM.389"; r3r1k1/1pp2p1b/7p/2Q5/2PP2p1/2P1NpPq/P2R1P1P/6RK b - - bm Rxe3; id "ECM.391"; 5bk1/5p1p/Q5p1/1B4n1/8/2q1p3/6PP/3R2K1 b - - bm e2; id "ECM.392"; r5k1/1p3pp1/1p3q1p/1P1bQ3/P2P3n/8/3B1PPP/R3R1K1 b - - bm Nf3+; id "ECM.393"; 2k2r1r/1pp1nqbp/p2p1p2/5P2/2PBN3/1P3Q2/1P4PP/R4RK1 w - - bm Rxa6; id "ECM.394"; r5kr/p3PR1p/1p1p2pq/4n3/8/3B4/P4QPP/4R1K1 w - - bm Bc4; id "ECM.395"; 2br1rk1/2qnQ2p/p4pp1/4p3/P1p1P1N1/2Pn1N1P/2B2PP1/1R1R1K2 w - - bm Rxd3; id "ECM.398"; 2r2nk1/6pp/p1rPqp2/1pP1p3/1P6/2B3R1/1P2Q1PP/5RK1 w - - bm Rxf6; id "ECM.399"; 3r2k1/pb3p1p/1q4p1/2b1P3/1Pp5/2P1p1P1/P3Q1BP/R1B4K b - - bm Qc6; id "ECM.400"; r2rnbk1/pp3ppp/1q4n1/3p1N2/5P2/1PQB4/PBP3PP/4RR1K w - - bm Nh6+; id "ECM.401"; r3nrk1/p1pb1qpp/3p1p2/2pP1N2/2P1PR2/P1PB4/4Q1PP/5RK1 w - - bm e5; id "ECM.402"; r1b2rk1/pp2qp2/2nRp1p1/6Pn/1Pp5/P1N1P3/1BQ2PP1/2K2B1R w - - bm Rxh5; id "ECM.403"; 5rr1/pp1kq1bp/2bppn2/2p3B1/4N3/2NP2P1/PPP4P/R3QRK1 b - - bm Nxe4; id "ECM.404"; 1r1q1k2/R4pp1/5p1r/1p1p1n1p/3Pb2N/1BP5/2P1Q1PP/4R1K1 w - - bm Qxe4; id "ECM.405"; R2b2k1/2rq1n1p/3p2p1/1p1Ppp1n/1P6/1B1PQN1P/1B3PP1/6K1 w - - bm Nxe5; id "ECM.406"; r1b3kr/bp3ppp/p1nNp3/4P3/P1Q2P2/BBP5/5qPP/R2R3K w - - bm Nxc8; id "ECM.407"; 6k1/5rb1/6pp/1p2p3/2b5/4B1P1/r4PBP/1RR3K1 w - - bm Rxc4; id "ECM.408"; 4r1k1/1p5p/5ppP/1qnP4/r4R2/P6P/1B1Q2K1/5R2 w - - bm Rxf6; id "ECM.409"; r2q1rnk/1p1bb1pp/p2p4/3NP1P1/P2Bp3/3Q3R/1PP1B2P/6RK w - - bm e6; id "ECM.410"; 6k1/pbq2pp1/4r2p/8/3prb2/1P1Q3P/PN2BPP1/3RRK2 b - - bm Bd2; id "ECM.412"; 6k1/2p3p1/2b4p/p4P2/2pR2PK/2P1r2P/1B6/8 b - - bm Bg2; id "ECM.413"; r1b2rk1/pp2ppbp/2np1np1/q7/4P3/2N1BN2/PPPQBPPP/2KR3R b - - bm Nxe4; id "ECM.414"; 3r1rk1/p1q4p/1p3bp1/3bnp2/3B4/1NPB3P/P1PQ2P1/1R2R2K b - - bm Nf3; id "ECM.415"; r2q1rk1/p5pp/bn1p1p2/2pP4/1bP1NP2/3B1R2/PBQ3PP/R5K1 w - - bm Ng5; id "ECM.416"; 1r1q2k1/7p/2p3p1/1P1n1b1r/2BQ4/4B3/P6P/1R3RK1 w - - bm bxc6; id "ECM.417"; r3kbnr/1ppb3p/p1q1pp2/3p4/3P4/2N2N2/PPP2PPP/R1BQ1RK1 w kq - bm Ne5; id "ECM.418"; r1b1qbk1/pp3r1p/2pR1np1/5p2/2P1pP2/1PN1Q1PP/PB2P1B1/5RK1 w - - bm Rxf6; id "ECM.419"; 2b2r2/rpp2pkp/3pq3/2pR2P1/2n1P1N1/2P2B2/1P3Q1P/1K5R b - - bm Qxd5; id "ECM.421"; 6k1/rnqb3p/5ppQ/2pPp3/p1N1P3/2PB3P/5PP1/1R4K1 w - - bm f4; id "ECM.422"; 7r/pp4k1/3pn1p1/q1pB1b2/2P5/5NR1/1P3PP1/2Q3K1 w - - bm b4; id "ECM.423"; 5r2/4prkp/3q2p1/2pP1n2/N1Q2R2/1P4PP/P5K1/4R3 b - - bm g5; id "ECM.424"; 8/2R4p/2R3bk/8/5N1P/1p3PP1/2pqP1K1/8 w - - bm g4; id "ECM.426"; 6k1/p4p1p/3pqp2/2p1r3/2Pnr1N1/P6P/1P1Q1PP1/3R1RK1 b - - bm Rxg4; id "ECM.427"; 1kqr3r/p1p4p/RpQP4/2P1p3/4B3/4Bp2/P4P1P/6K1 b - - bm Rdg8+; id "ECM.428"; 6k1/3Q1pp1/4p2p/p2pP3/1p1P2P1/nP1R1N2/q1r2PKP/8 w - - bm Qe8+; id "ECM.429"; 6k1/5pp1/p5r1/3Np2q/4P2p/1r3P1Q/n4P1P/3R2RK w - - bm Rxg6; id "ECM.430"; nr2rb2/3q1kpp/3p4/pnpPpNBP/2N1P3/3Q4/PP3P2/2K3RR w - - bm Nh6+; id "ECM.431"; r3k1r1/1pp2ppp/pb1p1qn1/4p2b/2B1P3/N1PP1NPP/PP2QPK1/R4R2 b q - bm Nh4+; id "ECM.432"; 1n2n1r1/r3qppk/p2p3p/3PpP1P/1P2P3/3B2RQ/3B1P1K/6R1 w - - bm Bxh6; id "ECM.433"; r2b4/pb2q1k1/np1p2r1/1N1Pp2Q/PPN1Pp2/8/2R2BPp/2R4K w - - bm Ncxd6 Nbxd6; id "ECM.434"; r7/2qnb1kp/p2p1nP1/1p1Pp1p1/6N1/3BB2Q/PPP4P/5RK1 w - - bm Qxh7+; id "ECM.435"; n1rqk3/1p2p3/1n1pP1p1/pP1P1p1r/3B3P/1BN3p1/3Q4/R3K2R w KQ - bm Qg5; id "ECM.436"; rn2kr2/pp1b1pQp/3Pp3/qB1n4/3N4/P7/1PP2PPP/2KR3R w q - bm Nxe6; id "ECM.437"; 3r1r2/1b4bk/p1n3pp/1p2p3/4P3/q1P1QNB1/B4RPP/5RK1 w - - bm Bh4; id "ECM.438"; r1r3kb/1pqbpp2/p2p1npB/n7/3NP3/1BN2P2/PPPQ2P1/2KR3R w - - bm Bf8; id "ECM.439"; r3k2r/pp2ppbp/1qp5/2n2b2/2P5/4BN2/PP1QBP1P/2KR3R b kq - bm Nb3+; id "ECM.441"; 4qn1k/1b3rpp/pb2pB2/1pp1P2P/3p1NQ1/P2P2PB/1PP4K/5R2 w - - bm Ng6+; id "ECM.442"; 2b5/2qrrpk1/5Rp1/2p4p/1pB1PR1P/1P1P2P1/5Q1K/8 w - - bm Qb2; id "ECM.443"; 2r3k1/n3qppp/1B1r1n2/N7/N4P2/1Q4PP/P5B1/R1b4K b - - bm Qe1+; id "ECM.444"; 7r/2p1q1k1/1p3r1p/p1pPpPp1/2P1P1P1/PP6/3Q2KR/7R w - - bm Qxg5+; id "ECM.445"; rnb2k2/ppbp2p1/2p2pB1/8/1PN5/2P5/P4PPP/R1B3K1 w - - bm Bf4; id "ECM.446"; 2k3r1/1ppr3p/p1pB2q1/6n1/N3Pp2/8/PPP1Q1PP/3R1RK1 b - - bm f3; id "ECM.448"; r3q2r/2p1k1p1/p5p1/1p2Nb2/1P2nB2/P7/2PNQbPP/R2R3K b - - bm Rxh2+; id "ECM.449"; 6r1/6rk/3p3p/p2Rp3/R1PqPp1b/2N2Q2/6PP/7K b - - bm Rxg2; id "ECM.450"; 4r1k1/1p2rq1p/2bQpp2/p1Pp4/3P4/P3RN2/5PPP/4R1K1 w - - bm Ne5; id "ECM.451"; b2b1r1k/3R1ppp/4qP2/4p1PQ/4P3/5B2/4N1KP/8 w - - bm g6; id "ECM.452"; 1k4q1/1p2Rprp/p1p5/2Pp4/1P1Q3P/6P1/P5K1/8 w - - bm Qe5+; id "ECM.453"; r2r3k/ppq3pp/2p1n3/4NQ2/3P4/1B6/PP3PPP/6K1 w - - bm Ng6+; id "ECM.454"; r4r1k/p2bN2p/1p1p1p2/2q4P/3Q4/1P6/1PP3P1/1K2R2R w - - bm Ng6+; id "ECM.455"; 2kr3r/p5b1/Pp2R1p1/2q2p1p/2p2Pn1/2P2BP1/1PQB2P1/5R1K b - - bm h4; id "ECM.456"; r1b2k1r/1p2qp2/pN1p1n2/2pP2pp/P2bP1P1/2N5/1P2BPP1/R2Q1RK1 b - - bm hxg4; id "ECM.457"; 6nk/p4rrp/1p1p1p2/1q1Pp2R/4B1P1/1PP2Q1R/P6P/7K w - - bm g5; id "ECM.458"; r1b1k2r/6pp/p1p1p3/3np1B1/1b2N3/8/q1PQB1PP/3RK2R w Kkq - bm Qxb4; id "ECM.459"; 3qrbk1/1r3p2/p1bp1Pp1/1p2p1Pp/4P2R/1P2BB1Q/P1P4P/R6K w - - bm Bxh5; id "ECM.460"; 2r3k1/4qpp1/2p1r3/pbQpN1Pp/3P1P1P/4P3/PP6/1KR3R1 w - - bm Qxb5; id "ECM.461"; 4r1kb/p2r4/1np1p1p1/3nP1Bp/1p3P1R/1B2qP2/PPPN3Q/2K4R w - - bm Rxh5; id "ECM.463"; r1b3k1/3nqp1p/p1n1p1pP/3pP1N1/Pp3QN1/1Pr3P1/2PR1P2/4RBK1 w - - bm Rxd5; id "ECM.465"; 2r1kr2/p1qbbp1Q/3pp3/5p2/1p1N1PB1/6P1/PPP4P/K2RR3 w - - bm Bxf5; id "ECM.466"; 2rr2k1/5pn1/1b2q1pp/pP1pP3/2pP1PP1/2R1B2P/2Q3B1/3R3K w - - bm f5; id "ECM.468"; 2Q2bkr/5p2/1rb5/1pN1n1qB/1P1pPN2/6P1/5P2/R1R3K1 w - - bm Nce6; id "ECM.469"; 2r4r/1q1kb1p1/4p2p/3pP3/np6/3RBP2/NPP2Q1P/1K2R3 b - - bm Nc3+; id "ECM.470"; 2r4r/3bk1b1/1q2pp2/3pPp1p/1p1N1P1P/1P1R1BP1/P2Q4/1K1R4 w - - bm Nxf5+; id "ECM.471"; 1rb3k1/2r2pbp/p2q1npn/P1pPp1N1/2B1P3/2P1B1NP/5QP1/3R1RK1 w - - bm Ne6; id "ECM.472"; r7/pp4pk/2n3qp/5p2/3p4/P4QB1/1PP1RPPP/6K1 b - - bm d3; id "ECM.473"; r4rk1/5ppp/p7/4PR2/P1qnp2Q/4B3/1P4PP/5RK1 w - - bm Rh5; id "ECM.475"; 4r3/pb3pk1/6p1/8/6P1/1PNrB2K/P4P1P/2R5 b - - bm Rdxe3+; id "ECM.476"; 1r3kr1/p3q1b1/3p2Q1/2p2p2/2P2N2/4Pn2/PB6/K2R3R w - - bm Ne6+; id "ECM.477"; 5r1k/6bp/3p1q2/3Q1nP1/8/6P1/PP3BKP/R2N4 b - - bm Ne3+; id "ECM.478"; 1r1q1k1r/Q4ppp/2B2n2/8/Pbbp4/1P4P1/2PP1P1P/R1B1K2R b KQ - bm Qe8+; id "ECM.479"; 5rk1/p1p1R1p1/1p5p/8/2pP1P2/3n2P1/PP2Q2P/5KNq b - - bm Nxf4; id "ECM.480"; r5k1/1N3ppp/4b3/1Nq5/Pn3pn1/5B2/1PPQ3P/R6K b - - bm Qxb5; id "ECM.481"; 1r2k2r/1bq2pp1/pn2p2p/1p2P1b1/3N4/2N3Q1/PPP3PP/1K1R1BR1 w k - bm Bxb5+; id "ECM.482"; r1bqn1r1/p2k1pp1/1p5p/n1pPpN2/2P1P3/P1PBB2P/4Q1P1/R4RK1 w - - bm Nxh6; id "ECM.483"; 2r2r2/p4p1k/1p2pBpn/2p5/6N1/8/P4P2/R3R1K1 w - - bm Kg2; id "ECM.484"; r4rk1/p1p2pp1/bp1p1q1p/n1nPpN2/2P1P2P/2PB4/P2BQPP1/R3K2R w KQ - bm Bg5; id "ECM.485"; 3rn1k1/pp3ppp/6b1/2p1Q3/2P1P3/P4P2/1B1qBP1P/1R5K w - - bm Rd1; id "ECM.486"; 4r1k1/5ppp/p1q3b1/1ppNr3/2P1P3/1P4QP/P4PP1/4RRK1 w - - bm f4; id "ECM.487"; 2kr2r1/2pqbp1p/p1n1b3/1P1pP3/4n3/1BP1BN2/1P4PP/RN1Q1RK1 b - - bm Bh3; id "ECM.488"; 6k1/5rp1/4Nb1p/2p5/4Q3/1r5P/q5P1/3R1R1K w - - bm Rxf6; id "ECM.490"; 1r2r1k1/p4ppb/q1pbnn1p/4p3/N1P1P3/pPB2NP1/2Q1RPBP/R5K1 b - - bm Nxe4; id "ECM.491"; r4r2/1pnqb2k/3p1p1p/p1pPpPpP/2P1N1P1/4BP2/PP1Q4/R2R2K1 w - - bm Bxc5; id "ECM.492"; rnb3kr/ppp2ppp/1b6/3q4/3pN3/Q4N2/PPP2KPP/R1B1R3 w - - bm Nf6+; id "ECM.493"; 3Rq1k1/1pp1Ppbp/r1b3p1/p7/P1N5/1P4P1/1B2PP1P/2R3K1 w - - bm Nd6; id "ECM.495"; r2q1rk1/pp1n2pp/2pb4/1P1p3n/P1PPpP2/4P2b/1BNNBP1P/R2QR1K1 b - - bm Nxf4; id "ECM.496"; r4rk1/1bq1bppp/8/p2pPR2/3B4/1NnP3Q/1P4PP/4R1K1 w - - bm Rh5; id "ECM.498"; r4rk1/1nqb1pbn/6pB/pppPp2p/8/1PP2NNP/P1BQ2P1/R4RK1 w - - bm Nxh5; id "ECM.499"; r1b2rk1/pp4bp/2p3p1/4q2n/NQPN1p1P/1P5n/P3PPB1/2BRRK2 b - - bm f3; id "ECM.500"; r2qkr2/1p3pQp/2p1b3/1B1pN3/1p6/8/1P1K1PPP/2B1R3 w q - bm Nxc6; id "ECM.502"; r3rk2/pb2bpp1/1n5p/q1pP1B2/1p3B2/5N2/PPQ2PPP/R2R2K1 w - - bm Bc8; id "ECM.503"; r3k2r/1p1b1p2/p3p3/2b3p1/4N1n1/1B5P/PPP3P1/R1B2R1K b kq - bm Bc6; id "ECM.506"; r3kb1r/npqbpp1p/p3n1p1/P3P3/6N1/3B1NB1/1PP3PP/R3QRK1 w kq - bm Ng5; id "ECM.507"; 7k/p6p/4bppb/1N6/P2p1p2/1PrP2P1/2r1P2P/1R1Q2K1 b - - bm f3; id "ECM.508"; 2kr4/pp1r1pp1/4n1p1/4R3/2Pp1qP1/3P2QP/5PB1/1R4K1 w - - bm Rc5+; id "ECM.509"; r2qkn1r/pb2bp2/1pp1p3/5p1p/2BPN3/5NQ1/PPP2PPP/1K1RR3 w kq - bm d5; id "ECM.511"; 2rr1nk1/pp2q1b1/4p1p1/5p2/1nB5/2B1N1QP/PP4P1/4RRK1 w - - bm Nxf5; id "ECM.512"; 3r3k/p4npp/1p2qpb1/4P3/5P2/P3N3/1B2QP1P/6RK w - - bm exf6; id "ECM.513"; 6rk/1b2bp1p/ppq1p3/2p1Pp2/P1Br1P2/1PNR2P1/2P1QK1P/6R1 b - - bm Rxf4+; id "ECM.514"; r3r1k1/p1q2pp1/b1pb3p/n7/B3n3/2P1BN2/PP1N1PPP/R2QK2R b KQ - bm Nxc3; id "ECM.515"; 4qrk1/pp1bbppp/4pn2/2r1Q1B1/7P/2N3R1/PPP2PP1/2KR1B2 w - - bm Bxf6; id "ECM.516"; r5n1/pppb1B2/2k1pb2/3p2B1/5P2/2N5/PPP3P1/2KR4 w - - bm Nxd5; id "ECM.517"; 2b2q2/r2n2kp/1n1p1pp1/p1pP4/1pP1NPN1/1P1B4/P5PP/Q3R1K1 w - - bm Nexf6; id "ECM.518"; 1k1r2r1/p1p3q1/2p2p2/3pn3/1P1b2bB/1QN5/P4PPP/1R2RBK1 b - - bm Nf3+; id "ECM.519"; r3k2r/1bq1bp1p/p2p1np1/1p2p3/3NP3/P1N2QB1/1PP2PPP/3RR1K1 w kq - bm Ndxb5; id "ECM.520"; r2q4/5p1P/2p1bR2/ppk1p1P1/3pB2Q/8/PPP5/6K1 w - - bm g6; id "ECM.521"; r3kb1r/pp1b1pp1/4p3/2q3Qp/5B2/2PB4/P4PPP/R3R1K1 w kq - bm Rxe6+; id "ECM.522"; 1rbr2k1/p4pp1/5b1p/2p1p3/3qPP2/1PNB2PP/PKP2Q2/5R1R b - - bm c4; id "ECM.523"; r3r1k1/p6p/bp4p1/2bPN3/6n1/6P1/PB2RPB1/3R2K1 w - - bm d6; id "ECM.524"; 3r1k2/1q1r1pp1/3p2bp/p2N4/8/2P1RQ1P/P4PP1/4R1K1 w - - bm Nf6; id "ECM.526"; 3q3r/p2r1pkp/bp1N1np1/n2p4/5Q2/B1P5/P4PPP/R3R1K1 w - - bm Nf5+; id "ECM.527"; r4Nk1/1p2pp1p/p1np2p1/3N4/P3PPn1/8/1bPKBqPP/R2Q1R2 b - - bm Qd4+; id "ECM.528"; 1kb3rr/1p2n2q/1Np2p2/1p6/1P1N1P1p/8/2P1RQPP/R6K w - - bm Nxb5; id "ECM.529"; r3r1k1/p3Rp1p/1qp1bQ2/8/1p1P4/3R4/PP3PPP/6K1 w - - bm Rg3+; id "ECM.530"; rn4k1/pp2rpb1/2pNb1pp/4p3/P3Pq2/2P2N1P/1PB1QPP1/R3R1K1 w - - bm Nf5; id "ECM.531"; 3r1rk1/pp3ppp/8/2p5/4PB1n/P1P2qPP/Q3RP1K/6R1 b - - bm Qg2+; id "ECM.532"; r4rn1/ppp1q3/2bp2kp/6P1/3QpP2/2N5/PPP1B3/2KR3R w - - bm f5+; id "ECM.533"; 3qr2r/1p1bppk1/3p2p1/p1nP1PQp/3N3R/1P4PP/P1P3BK/4R3 w - - bm Ne6+; id "ECM.534"; 2rq1rk1/1b1nbpp1/1p5p/p2pNB2/3p1N2/4P3/PPQ2PPP/2RR2K1 w - - bm Bh7+; id "ECM.535"; 8/5pkp/2pp2p1/4P3/1P2P3/2QBq2P/2PnNnPK/8 b - - bm Nf1+; id "ECM.536"; r3r2k/pb2q1p1/1p2Nn1p/2b5/2B5/2P2P2/PPQ3PP/4RR1K w - - bm Nf4; id "ECM.537"; r1b2nk1/ppq2ppp/8/1BP1p1NQ/5p2/8/PP3PPP/3R2K1 w - - bm Rd7; id "ECM.538"; 5r1n/r2q1pkp/3p1npN/NppPp2P/1P2P3/2P1Q1P1/5P2/R3K2R w KQ - bm Nf5+; id "ECM.540"; 6rk/p2b4/3p1Nqp/2pPpn2/P1P4p/5P1P/Q2B1NP1/6RK b - - bm Ng3+; id "ECM.541"; r4r1k/pppb2pp/8/3q4/2N5/P1P2nQ1/BP2R2P/R6K b - - bm Ne1+; id "ECM.542"; r5rk/1pp1n1pp/p1n1b1q1/3p1p2/7R/2QB1N2/PB3PPP/4R1K1 w - - bm Rxe6; id "ECM.543"; 8/4Ppk1/6p1/1p6/1Pb1Q3/6pq/8/6K1 w - - bm Qe5+; id "ECM.544"; 3R4/4Qpk1/4p1p1/7p/7K/5rP1/5P2/2q5 w - - bm Qf8+; id "ECM.545"; 8/5pk1/p6p/2R5/3q2p1/6P1/2Q3PK/4r3 w - - bm Rg5+; id "ECM.546"; 1Q4R1/8/P1b2p2/2p2k2/2P5/5p2/1r5P/4R1K1 b - - bm f2+; id "ECM.547"; 5r1k/1q2R3/8/6Q1/8/8/6P1/7K b - - bm Rf1+; id "ECM.548"; 8/4p3/8/3P3p/P2pK3/6P1/7b/3k4 w - - bm d6; id "ECM.549"; 3Q4/k3K3/q7/2N1P3/1P6/5r2/8/8 b - - bm Rf7+; id "ECM.550"; 3k4/p1p5/8/2p1p3/4P3/PpPP2K1/1P6/8 b - - bm c4; id "ECM.551"; 6r1/5p1k/4p3/3pQp2/1p1P1P1q/1P3RR1/7r/5K2 w - - bm Rxg8; id "ECM.552"; r1b2rk1/ppp2ppp/2n3q1/b2N2N1/2BP4/4p2P/PPP3P1/R2Q1RK1 w - - bm Rxf7; id "ECM.553"; 1r4k1/3qb2p/pr1pppn1/2p2N2/2P2PQ1/1P4P1/P2R2BP/R5K1 w - - bm Bd5; id "ECM.554"; r6r/pR1nqkpp/2p1p3/3p4/6Q1/2b4P/P1PP1PP1/2B1R1K1 w - - bm Rxe6; id "ECM.555"; 1k1r3r/ppq2pnp/1npbb1p1/3p4/3P1NP1/2NBP2P/PPQ2P1B/1KR4R w - - bm Nb5; id "ECM.556"; r5r1/4q2k/p2p3p/5p2/4p3/P2QR3/1PP2PPP/4R1K1 w - - bm Rxe4; id "ECM.558"; r1bq1rk1/1pp2ppn/1pnp3p/3N4/2B1PN2/3P4/PPP3PP/R2Q1RK1 w - - bm Ng6; id "ECM.563"; r1b2rk1/pp3p1p/2pq2pn/2nNN3/2B1QP2/8/P1PP2PP/R1B1K2R w KQ - bm Nxf7; id "ECM.564"; 1r2r1k1/1bn2pbp/pp1q1np1/2pPN1B1/P1B5/2N4P/1P1Q1PP1/R3R1K1 w - - bm Nxf7; id "ECM.565"; 1rb2bk1/2n2qp1/p2p3p/R1pP1p2/2B5/1PBQ1N1P/2P2PP1/6K1 w - - bm Ne5 Rxc5; id "ECM.566"; r1b3k1/2pq2pp/p4p2/1p1Nr3/2n2R2/1B6/PPQ2PPP/R5K1 w - - bm Rxc4; id "ECM.567"; 2rq1rk1/3bbppp/p3pn2/1p1pN3/2nP1B2/P1NBP2Q/1P3PPP/2R2RK1 w - - bm Nxd5; id "ECM.568"; 2r1r1k1/pp1b1ppp/1q6/3P4/7N/Pn1Q4/1P3PPP/1RB2RK1 b - - bm Nxc1; id "ECM.569"; 1r4nk/3b2bp/3p4/3P3p/2pNPq2/P1N2p1P/1P3Q2/1R4KR b - - bm Rxb2; id "ECM.570"; 2r5/p3kpp1/P2p4/1P2pP1p/1P2PqnP/6R1/r2N2P1/3RQ1K1 b - - bm Rxd2; id "ECM.571"; 2br2k1/1p2qppp/r1n1p3/pQ1nN3/P2P4/2B3P1/1P3PBP/2RR2K1 w - - bm Qxa6; id "ECM.572"; 5rk1/3q2bp/3pb2r/1p1n1p2/3p1P2/P2B1QN1/1P1B2PP/2R1R1K1 w - - bm Nxf5; id "ECM.573"; 4r1k1/1ppQr1p1/1p1p1pP1/3P3p/7P/1P3q2/P1P5/1KRR4 w - - bm Re1; id "ECM.574"; 2Rr2k1/7p/4pqp1/p4p2/1p1P1Q1P/8/PP3PP1/6K1 w - - bm Qe5; id "ECM.575"; 4r1kb/5p1p/6pB/3Np3/4n3/P3Q1PP/2q2P2/R5K1 w - - bm Rc1; id "ECM.576"; 5rk1/bp4p1/p2rp2p/8/8/2PN4/PP1R1PPP/3R2K1 b - - bm e5; id "ECM.577"; 2q1rk2/QR3ppp/1pPpb3/1P2p1b1/4P3/6P1/3N1PBP/6K1 w - - bm Bh3; id "ECM.578"; n1bq3k/pp4bp/6p1/5pP1/3p1P2/1B1P4/PB3Q1P/4R1K1 w - - bm Bxd4; id "ECM.579"; r3r1k1/p2n4/3p1pp1/qnp3B1/1p2P1P1/1P3P2/PP2N2Q/1K1R1B2 w - - bm Nf4; id "ECM.580"; 6k1/pb3ppp/1p2p3/4P3/5P2/P1r5/1q4PP/1B2Q1RK b - - bm Rc1; id "ECM.581"; 2rq1kbR/4R1p1/3p3r/pp1P1Pp1/6P1/3B4/PPP1Q3/6K1 w - - bm f6; id "ECM.582"; 2r5/5kb1/4ppp1/pp1qB3/2rP4/1RP2R1Q/P4PP1/6K1 b - - bm Rh8; id "ECM.583"; 4k3/4Bp2/1p2nP1P/2p5/2K1b1B1/8/P7/8 w - - bm Bf3; id "ECM.584"; 3rr1k1/ppp1qp1p/3b2p1/4np1P/1P1N1Pn1/P1P4R/1B1NB3/R2Q1K2 b - - bm Nf3; id "ECM.585"; 1k1r3r/ppqb4/5Ppp/3p4/P2np3/3BR1Q1/2PB1PPP/R5K1 w - - bm Rxe4; id "ECM.586"; r2q1rk1/pb1nbpp1/1pp1pn1p/3pN3/2PPP3/2N1B1P1/PP3PBP/R2Q1RK1 w - - bm Nxc6; id "ECM.587"; 8/2R2pbk/6pp/1p2pq2/1P2Qn2/3P3P/3B1PP1/r3N1K1 b - - bm Nxd3; id "ECM.588"; 2r2rk1/pp2pp1p/2np2p1/q4P2/2PBP1b1/2N5/PP1Q2PP/R4RK1 w - - bm h3; id "ECM.589"; r2b1rnk/1p4qp/p1p1b1p1/2PpNp2/PP1PnP1Q/3BB2R/4N1PP/R6K w - - bm Qxh7+; id "ECM.590"; r1b2rk1/1p3pbp/2p3p1/p1q5/1P6/1Q4P1/1P2PPBP/R1B1R1K1 b - - bm Be6; id "ECM.591"; r1b1k2r/2q1bppp/p3p3/1p1nP1B1/3Q4/2N5/PPP1B1PP/2KR3R w kq - bm Bxe7; id "ECM.594"; 1rb1r1k1/p1p1qppp/2pb4/8/2P3n1/4P1P1/PB2BP1P/R1QN1RK1 b - - bm Nxh2; id "ECM.595"; 2rqk1nr/pp3ppp/2n1p3/2b5/3N4/2NQB1P1/PP2PPKP/R4R2 w k - bm Nxe6; id "ECM.596"; rnb2rk1/pp4pp/2pb1n2/3N1p1q/2P5/3N2P1/P1Q1PPBP/R1B2RK1 w - - bm Bf4; id "ECM.597"; 8/8/1p1k4/5ppp/PPK1p3/6P1/5PP1/8 b - - bm f4; id "ECM.598"; 8/5pp1/7p/5P1P/2p3P1/2k5/5P2/2K5 w - - bm f6; id "ECM.599"; 7k/8/1p1ppp1p/1Pp5/2P2P2/8/3P2PP/6K1 w - - bm f5; id "ECM.600"; 8/p5k1/2p2p2/4p1p1/1p2P3/1P4PP/1PP5/5K2 b - - bm g4; id "ECM.601"; 8/2k3p1/2p4p/5P2/2K3PP/8/8/8 w - - bm g5; id "ECM.603"; 8/1kp1b3/1p4K1/4P2p/P1P3p1/5pP1/P4P2/4B3 b - - bm h4; id "ECM.604"; 8/8/4b1p1/2Bp3p/5P1P/1pK1Pk2/8/8 b - - bm g5; id "ECM.605"; 8/8/3K1k2/5p1p/4p1p1/4P1P1/5PP1/8 b - - bm f4; id "ECM.606"; r1b5/p2k1r1p/3P2pP/1ppR4/2P2p2/2P5/P1B4P/4R1K1 w - - bm Bxg6; id "ECM.607"; 6r1/1p3k2/pPp4R/K1P1p1p1/1P2Pp1p/5P1P/6P1/8 w - - bm Rxc6; id "ECM.608"; 1k2b3/4bpp1/p2pp1P1/1p3P2/2q1P3/4B3/PPPQN2r/1K1R4 w - - bm f6; id "ECM.609"; 2kr3r/ppp1qpp1/2p5/2b2b2/2P1pPP1/1P2P1p1/PBQPB3/RN2K1R1 b Q - bm Rh1; id "ECM.610"; 1r3qk1/pb3p1p/1pn2PpQ/2pN4/3r4/5B2/PPP4P/4RRK1 w - - bm Ne7+; id "ECM.611"; 4r1k1/5p1p/3q2p1/1p1P4/1P6/2p4P/2Q1nPB1/4RK2 b - - bm Ng3+; id "ECM.612"; 6k1/2q3p1/1n2Pp1p/pBp2P2/Pp2P3/1P1Q1KP1/8/8 w - - bm e5; id "ECM.613"; 5r2/pp1RRrk1/4Qq1p/1PP3p1/8/4B3/1b3P1P/6K1 w - - bm Qxf7+; id "ECM.614"; 6k1/1q2rpp1/p6p/P7/1PB1n3/5Q2/6PP/5R1K w - - bm b5; id "ECM.615"; r5r1/8/bRP1pk1p/3pNp2/5P2/7P/PR4P1/6K1 w - - bm Rxa6; id "ECM.616"; 3r2k1/p6p/b2r2p1/2qPQp2/2P2P2/8/6BP/R4R1K w - - bm Rxa6; id "ECM.617"; 8/p3q1k1/6p1/1p3nP1/2pp1QBr/P2P4/1PP2K2/R7 b - - bm Qe3+; id "ECM.618"; 7k/4b2p/5p1P/5PP1/1pNp1P2/1P1B4/2P2K2/r7 w - - bm g6; id "ECM.619"; 5r1k/1p1b2rP/p2p4/3P3B/P2P4/5pP1/1P2pP2/R3R1K1 b - - bm Rxg3+; id "ECM.620"; 6B1/2p2pp1/2p5/p3K3/1k6/nP4P1/5P1P/8 b - - bm Nc4; id "ECM.621"; 3q1k2/5p2/p5pN/1b2Q2P/8/8/5PPK/8 w - - bm Qh8+; id "ECM.622"; 6k1/p3b1pp/4p3/4Pp2/Pp1r1P1P/1P4P1/2p2R2/5RK1 b - - bm Rc4; id "ECM.623"; 2r2rk1/p1N2p1p/2P1p1p1/1Pp3q1/3b4/5Q2/P1P3PP/4RR1K w - - bm Nxe6; id "ECM.625"; 3r1r2/pp1P3k/4Rbp1/1BP2p1p/8/7P/P4KP1/3R4 w - - bm Ba6; id "ECM.626"; rn1q2k1/pp3pb1/3p2pp/2pP2N1/3r1P2/7Q/PP4PP/R1B2RK1 w - - bm Nxf7; id "ECM.628"; 8/6Bp/6p1/2k1p3/4PPP1/1pb4P/8/2K5 b - - bm b2+; id "ECM.629"; 5bk1/r4ppp/1r1P1n2/2p2N2/b7/2B3P1/5PBP/R3R1K1 w - - bm Bxf6; id "ECM.630"; 8/8/8/P2k1p2/2N5/1pb2P2/4P3/2K5 w - - bm a6; id "ECM.631"; 3qr1k1/p4ppp/1p1P4/2r1nN2/4P2n/P7/1B4P1/3QRRK1 w - - bm d7; id "ECM.632"; 6k1/5pbp/6p1/2p1r3/1pPr4/3n2NP/1PB2PP1/1R1R2K1 b - - bm Nxb2; id "ECM.633"; 2r1rbk1/p1Bq1ppp/Ppn1b3/1Npp4/B7/3P2Q1/1PP2PPP/R4RK1 w - - bm Nxa7; id "ECM.635"; r4rk1/ppq3pp/2p1Pn2/4p1Q1/8/2N5/PP4PP/2KR1R2 w - - bm Rxf6; id "ECM.636"; r3qr1k/1b4pp/p2RQ3/Bp2p3/4p3/6P1/PPP2P1P/3R2K1 b - - bm Qh5; id "ECM.637"; 8/6kP/6p1/1p1pP3/pP6/P1n2K2/2N5/8 w - - bm e6; id "ECM.638"; 8/Pb6/8/8/7K/5k1p/6pB/8 b - - bm g1=Q; id "ECM.639"; 8/pR4pk/1b6/2p5/N1p5/8/PP1r2PP/6K1 b - - bm Rxb2; id "ECM.640"; 6k1/p4pp1/Pp2r3/1QPq3p/8/6P1/2P2P1P/1R4K1 w - - bm cxb6; id "ECM.641"; 6k1/p4pbp/Bp2p1p1/n2P4/q3P3/B1rQP3/P5PP/5RK1 w - - bm dxe6; id "ECM.642"; 5r2/R4p2/5P1k/4PK2/1p6/8/8/8 w - - bm Rxf7; id "ECM.643"; 4r2k/pppb2pp/2np2q1/3B4/2P2P2/1PB1R1P1/PQ5P/6K1 w - - bm f5; id "ECM.644"; 1r6/3r1Pk1/p2p1np1/5q2/1p3P2/1B5R/PPP4Q/1K1R4 w - - bm Rh8; id "ECM.645"; 8/2k5/2p5/2pb2K1/pp4P1/1P1R4/P7/8 b - - bm Bxb3; id "ECM.646"; 2r5/1r5k/1P3p2/PR2pP1p/4P2p/2p1BP2/1p2n3/4R2K b - - bm Nd4; id "ECM.647"; 4r2k/p2qr1pp/1pp2p2/2p1nP1N/4R3/1P1P2RP/1PP2QP1/7K w - - bm Rxg7; id "ECM.648"; 6k1/p4p2/5Ppp/3RP3/Pr4P1/2p2K2/7P/8 w - - bm Rd8+; id "ECM.649"; 8/1R2P3/6k1/3B4/2P2P2/1p2r3/1Kb4p/8 w - - bm Be6; id "ECM.650"; 2kr2r1/pp2bQ1p/2b1P3/2qN4/8/1B2p2P/PPP3P1/3R1R1K b - - bm e2; id "ECM.651"; r1b2rk1/1p2qppp/p3p3/2n5/3N4/3B1R2/PPP1Q1PP/R5K1 w - - bm Bxh7+; id "ECM.652"; r2qrbk1/5ppp/pn1p4/np2P1P1/3p4/5N2/PPB2PP1/R1BQR1K1 w - - bm Bxh7+; id "ECM.654"; 6rk/3nrpbp/p1bq1npB/1p2p1N1/4P1PQ/P2B3R/1PP1N2P/5R1K w - - bm Nxh7; id "ECM.655"; 1rb2rk1/3nqppp/p1n1p3/1p1pP3/5P2/2NBQN2/PPP3PP/2KR3R w - - bm Bxh7+; id "ECM.656"; 2k5/ppp3pp/8/NQ2n2q/2Pp1n2/R4bP1/1P3P1P/4R1K1 b - - bm Qxh2+; id "ECM.657"; 5rrk/1p3qpp/p3pn2/2PpBp2/3P1P1Q/P1P1R2R/2b1B1PP/6K1 w - - bm Qxh7+; id "ECM.658"; r4rk1/1bq2ppp/p1p1p3/2b1P1B1/3p2Q1/3B4/PPP2PPP/R3R1K1 w - - bm Bxh7+; id "ECM.659"; r4rk1/pb1q1ppp/2N1p3/2Rn4/3P4/3BPQ2/1P3PPP/2R3K1 w - - bm Bxh7+; id "ECM.660"; r5rk/1p1q1p1p/5pn1/p2p1N1Q/3P2P1/PP2R3/5P1P/5RK1 w - - bm Qxh7+; id "ECM.661"; 2r2r2/p2qppkp/3p2p1/3P1P2/2n2R2/7R/P5PP/1B1Q2K1 w - - bm Rxh7+; id "ECM.662"; 1r1qr1k1/5p1p/1n2p1p1/pp1pP1P1/2pP1BB1/PnP3P1/1P3PK1/1R1Q3R w - - bm Rxh7; id "ECM.663"; 4rrk1/2q1bppp/p2p4/1p1Pn3/3B1R2/P2B2Q1/1PP3PP/5R1K w - - bm Bxh7+; id "ECM.664"; r1b2rk1/2q1bppp/p1n1p3/1p1np1P1/5P2/1NNBBQ2/PPP4P/R4RK1 w - - bm Bxh7+; id "ECM.665"; 5r1k/ppp2qnp/1n1p1N1Q/3Ppb2/2P4P/7B/PP6/2KR2R1 w - - bm Nxh7; id "ECM.666"; r4rk1/pp2q1p1/4b2p/2ppb3/6n1/2P3N1/PPQBBPPP/R4RK1 b - - bm Nxh2; id "ECM.667"; b3r1k1/2rN1ppp/2n1p3/p7/P3BP2/1R6/q1P2QPP/3R2K1 w - - bm Bxh7+; id "ECM.668"; 2r1qrk1/3n3p/b3pPp1/4P3/1pp1nBN1/pP4PQ/P1P2PK1/3RR3 w - - bm Qxh7+; id "ECM.669"; r1b1rnk1/pp1nb1pp/2p1pp2/q3N3/2PP1P2/3BP1N1/PBQ3PP/R4RK1 w - - bm Bxh7+; id "ECM.670"; 4r1k1/2q2r1p/p3bQ2/1p4Bp/2np4/8/PPB2PP1/3RR1K1 w - - bm Bxh7+; id "ECM.671"; 5rk1/pbrn1ppp/1ppN1q2/2P1p3/3P4/1PRB4/P3QPPP/5RK1 w - - bm Bxh7+; id "ECM.672"; 2rqr1k1/1p1bbppp/p3p3/n7/3P2Q1/2PB1N2/P4PPP/R1B1R1K1 w - - bm Bxh7+; id "ECM.673"; r1b2r1k/ppppq1pp/2n1n3/6N1/2B2P2/4B3/PPP3PP/R2Q1RK1 w - - bm Nxh7; id "ECM.674"; rn1q1rk1/pb1p1ppp/4p3/2pnP3/1bp5/2N2N2/PP3PPP/RBBQK2R w KQ - bm Bxh7+; id "ECM.675"; r2r2k1/p1p2p1p/4pPp1/1Pqb4/8/7R/1PB2PPP/3QR1K1 w - - bm Rxh7; id "ECM.676"; rnq3rk/4bp1p/p1p3pQ/1p1pP3/1P1N1B2/2P3R1/1P3PPP/R5K1 w - - bm e6; id "ECM.678"; rn3rk1/pp1bppbp/1qp3p1/4P1N1/PP1PB3/2P1B3/4Q1PP/R4RK1 w - - bm Nxh7; id "ECM.679"; 3rr1k1/1pq1nppp/p1p2b2/4pB2/2QPP3/P1P1B3/1P4PP/3R1RK1 w - - bm Bxh7+; id "ECM.680"; 1r2nrkb/2n2p1p/p2p1Pp1/P1pPp1P1/1pP1P1q1/1P1BB1N1/3Q4/2KR3R w - - bm Qh2; id "ECM.681"; 2rrn1k1/2q2ppp/p2pp3/1p2P1P1/4B3/P5Q1/1PP3PP/R4R1K w - - bm Bxh7+; id "ECM.682"; 2rq1rk1/pp1bnpbp/4p1p1/3pP1N1/3P2Q1/2PB4/P4PPP/R1B1R1K1 w - - bm Nxh7; id "ECM.684"; 2rq1bk1/1br2p1p/p2p2p1/1p1P4/4Q3/PP3N2/1BP5/1K1R3R w - - bm Rxh7; id "ECM.685"; r4rk1/pp1n1ppp/3qp3/3nN1P1/b2P4/P2B1Q2/3B1P1P/1R2R1K1 w - - bm Bxh7+; id "ECM.687"; r2r2k1/ppqbbppp/4pn2/6N1/n1P4P/3B1N2/PP2QPP1/1KBR3R w - - bm Nxh7; id "ECM.688"; r5k1/6bp/2q1p1p1/p2pP3/3P4/1rP2QP1/3B1PK1/2R4R w - - bm Rxh7; id "ECM.689"; r6r/4ppk1/p2p1bp1/B2p4/3P2p1/QP2P3/P1R1qPPP/2R3K1 b - - bm Rxh2; id "ECM.690"; r3k2r/1b1n1p2/pq1p1bp1/1p4p1/P3P3/1NN5/1PP3PP/R2QRB1K b kq - bm Rxh2+; id "ECM.692"; rn1q1rk1/pppbb1pp/4p3/3pP1p1/3P3P/2NB4/PPP2PP1/R2QK2R w KQ - bm Bxh7+; id "ECM.694"; 1r2nr1k/6pp/pp1p1p2/2pPnN2/q1P1PB2/5PR1/4K1P1/2Q4R w - - bm Bxe5; id "ECM.695"; 3r1rk1/4qp1p/p1bb2p1/2p5/3P4/1P6/PBQN1PPP/2R2RK1 b - - bm Bxh2+; id "ECM.696"; r2q1rk1/3n1ppp/8/1pbP2P1/p1N4P/PnBBPQ2/5P2/R3K2R w KQ - bm Bxh7+; id "ECM.697"; 2k3r1/ppq2p1p/n1Pb1p2/8/6r1/4BN1b/PPQ2PPP/R3RBK1 b - - bm Bxh2+; id "ECM.698"; 3qr1k1/1br2ppp/p2b4/8/PpNp4/3P4/1PP2PPP/R1BQ1RK1 b - - bm Bxh2+; id "ECM.699"; 3r2k1/p1R2p2/4pQp1/1q5p/5P1P/1PR5/2Pr2P1/6K1 b - - bm Rxg2+; id "ECM.700"; 3r2k1/pb5p/1p2qpp1/8/2p5/1P1nP3/P1N2PPP/1Q1R1R1K b - - bm Bxg2+; id "ECM.703"; 4rrk1/2qb2pp/p5P1/1p2p3/1b2P3/2N5/PPPQ4/1K1R2R1 w - - bm gxh7+; id "ECM.704"; 3q1k2/pp3ppn/2p1n2p/4pN1N/P3P2P/5Q2/1PP2PP1/6K1 w - - bm Nhxg7; id "ECM.705"; 2r2r1k/3b1pb1/p3pp1p/q2p1P1B/8/2N2RR1/P1PQ2PP/7K w - - bm Rxg7; id "ECM.706"; 5bk1/1p4p1/4N1R1/3p4/p1r2P1q/Pr1QP2P/1P6/1K4R1 w - - bm Rxg7+; id "ECM.707"; 2r1r1k1/5ppp/p3pn2/1pb1N3/2P5/1PQ3R1/PB2qPPP/3R2K1 w - - bm Rxg7+; id "ECM.708"; 7k/1bp1P1p1/3p2rp/1pb2p1q/5P2/1BP2N1P/1P4P1/R1B2R1K b - - bm Rxg2; id "ECM.709"; r1q1bk1r/1p3pp1/4pn1p/p3Q3/P1P2N2/1B4R1/1P3PPP/4R1K1 w - - bm Rxg7; id "ECM.710"; r4rk1/p2n2p1/1q1Qpn1p/1P6/P6B/2p5/2B1KP1P/R5R1 w - - bm Rxg7+; id "ECM.711"; r2qr1k1/1p3ppp/2pb4/2Np4/1P1P2bn/3BP3/2QN1PPP/1RR3K1 b - - bm Nxg2; id "ECM.712"; r3r1k1/pp3pp1/3p4/2q4p/2P5/1PB2Q1P/n4PP1/3R1RK1 w - - bm Bxg7; id "ECM.713"; r5k1/pn1q1rpp/2pp4/5R1N/bP6/4BQ2/P4PPP/2R3K1 w - - bm Nxg7; id "ECM.714"; 3r1rk1/5pp1/pq1n1n1p/2pPR3/2B2P2/1PBQ2RP/P5P1/6K1 w - - bm Rxg7+; id "ECM.715"; rn3rk1/ppq2ppp/2pb1nb1/5N2/2BP4/8/PPP1N1P1/R1B1QR1K w - - bm Nxg7; id "ECM.716"; r1qb1r1k/2p3pp/p1n1bp2/1p1Np2Q/P3P3/1BP3R1/1P3PPP/R1B3K1 w - - bm Rxg7; id "ECM.717"; r4rk1/5ppp/p2pbb2/3B3Q/qp2p3/4B3/PPP2P1P/2KR2R1 w - - bm Rxg7+; id "ECM.718"; 4q1k1/1b3r1p/p4pp1/1p6/2P2n2/1P3N2/1B3PPP/R2Q3K b - - bm Nxg2; id "ECM.719"; r2r3k/5bp1/2p2N2/5P1p/3q3Q/3B2R1/n5PP/3R3K w - - bm Rxg7; id "ECM.720"; 4rrk1/2pn2pb/p1p1qp2/1pb1pN2/P3P1PN/1P1P4/1BP2PK1/R2Q3R w - - bm Nxg7; id "ECM.721"; r3r1k1/p3bppp/q1b2n2/5Q2/1p1B4/1BNR4/PPP3PP/2K2R2 w - - bm Rg3; id "ECM.722"; r4rk1/1p1q1ppp/p1b4B/8/2R3R1/P2P4/1b1N1QPP/6K1 w - - bm Bxg7; id "ECM.723"; rq3rk1/3b1ppp/p2bp3/3pB2Q/8/1B5P/PP3PP1/2RR2K1 w - - bm Bxg7; id "ECM.724"; 4kbr1/pp1bpp1p/3p1p2/3N4/1PBQP3/q7/P1r2PPP/R4RK1 b - - bm Rxg2+; id "ECM.725"; 2r3k1/1p2R1p1/p3n2p/2pq4/7P/1P1P2P1/PB1Q3K/8 w - - bm Bxg7; id "ECM.726"; 2rr2k1/4bppp/p1n1p3/3q4/1p1P2N1/2P3R1/P3QPPP/2B2RK1 w - - bm Nh6+; id "ECM.727"; rq1r1bk1/1b3pp1/3pn2p/1n2BN1P/1P2P3/3R1NP1/3Q1PB1/2R3K1 w - - bm Bxg7; id "ECM.728"; r1b5/ppqn2bk/3R2pp/2p2p2/2P1rN2/4BN2/PPQ2PPP/4R1K1 w - - bm Rxg6; id "ECM.729"; 3q1r2/1p1b1pk1/pn5p/3pN1pQ/3P3P/2r3B1/P4PP1/3RR1K1 w - - bm Nxf7; id "ECM.730"; r1bqkbnr/pp2ppp1/2p4p/3n2N1/2BP4/5N2/PPP2PPP/R1BQK2R w KQkq - bm Nxf7; id "ECM.731"; r2qr1k1/1ppb1p1p/p1np2p1/7Q/3PP2b/1B2N2P/PP3PP1/R1B2RK1 w - - bm Bxf7+; id "ECM.732"; 2r3k1/pbq1np1p/1p1b1Bp1/8/6QP/2P2N2/B4PP1/4R1K1 w - - bm Bxf7+; id "ECM.733"; r3r1k1/1bqn1ppp/1pp2p2/8/3P4/1B4N1/PP3PPP/R2QR1K1 w - - bm Bxf7+; id "ECM.734"; r2r2k1/1b2qpp1/1p2n3/p1b1p2p/4P1n1/PP1B2PP/1B1NQP2/R3NRK1 b - - bm Nxf2; id "ECM.736"; r2qr1k1/1b2bp1p/p3p1p1/1p2N1Bn/3P4/P6Q/1P3PPP/RB2R1K1 w - - bm Nxf7; id "ECM.737"; r5k1/1pp3pp/1b1p1r2/pN1P1n2/P1P3nq/6N1/1P1B1PQP/4RRK1 b - - bm Nxf2; id "ECM.738"; 2rqnk1r/pp2bpp1/2p1pn1p/2P1N2P/3P1BP1/3BQ3/PP6/2K2R1R w - - bm Nxf7; id "ECM.739"; 2rq1rk1/1b2bppp/p1n5/1p1BN3/5B2/P7/1P3PPP/R2Q1RK1 w - - bm Nd7; id "ECM.740"; 3r1qrk/p1p5/bbp3pp/4p3/4Pp1N/2Pn3P/PPQN1PPB/R4RK1 b - - bm Nxf2; id "ECM.741"; r2qr1k1/pb2bp1p/1pn1p1pB/8/2BP4/P1P2N2/4QPPP/3R1RK1 w - - bm d5; id "ECM.742"; 3r1qrk/p1p5/bbp3pp/4p3/4Pp1N/2Pn3P/PPQN1PPB/R4RK1 b - - bm Nxf2; id "ECM.741"; r5k1/p4ppp/3qpb2/1P2N3/1nBP4/1P5P/4QPP1/4R1K1 w - - bm Nxf7; id "ECM.744"; r2qr1k1/1b1nbp1p/p3pp2/1p2N3/3P4/3B1N2/PP2QPPP/R2R2K1 w - - bm Nxf7; id "ECM.745"; r3k2r/p1qb1p2/1p2p2p/3pPpN1/P1nP3Q/8/2P2PPP/R1B1R1K1 w kq - bm Nxf7; id "ECM.746"; 3qNk2/5p1p/1r3p2/2p5/Q1pb4/3b2P1/P4PBP/4R1K1 b - - bm Bxf2+; id "ECM.747"; 2r1r1k1/1pq1bp1p/p3pnp1/P2n2N1/7R/2P4P/1PB1QPP1/2B1R1K1 w - - bm Nxf7; id "ECM.748"; r1bq2k1/pp1n1ppp/3b1n2/PQ1B3r/3N1P2/2N5/1PP3PP/R1B2RK1 w - - bm Bxf7+; id "ECM.749"; 2r1r1k1/5ppp/pq3b2/2pB1P2/2p2B2/5Q1P/Pn3PP1/2R1R1K1 w - - bm Bxf7+; id "ECM.750"; r4rk1/ppRn1p2/6pb/2P1pq1p/3N4/P1QPn1Pb/1B1NPP1P/4R1KB b - - bm Qxf2+; id "ECM.751"; r3kr2/1b2qp2/pp2p2N/4p2Q/8/2n5/P3B1PP/3R1R1K w q - bm Nxf7; id "ECM.752"; b2r1rk1/pq2bpp1/1p2p2p/4N2n/2P2R2/1PB2N2/1P2QPPP/4R1K1 w - - bm Rxf7; id "ECM.753"; 1r2q1k1/p3pp2/3p1bp1/2pP2N1/8/P5PB/2Q2PK1/1rBR4 w - - bm Nxf7; id "ECM.756"; 2rqrbk1/pb1n1p1p/1p2pnp1/4N3/2BP1N2/1P2Q3/PB3PPP/3R1RK1 w - - bm Nxf7; id "ECM.757"; r1bqrbk1/5p1p/2pp2nB/pp5Q/4P3/PBNPR2P/1P4P1/R5K1 w - - bm Bxf7+; id "ECM.759"; r1bqkb1r/1p3ppp/pn1P1n2/4p3/2B5/2N2N2/PP3PPP/R1BQ1RK1 w kq - bm Bxf7+; id "ECM.760"; 2rqr1k1/pp2nppp/3p2b1/6B1/2BNn1Q1/P7/1PP2PPP/2KRR3 w - - bm Bxf7+; id "ECM.761"; r3r1k1/pbq1ppbp/1pp2np1/4N3/3P4/2P5/PPB1QPPP/R1B1R1K1 w - - bm Nxf7; id "ECM.762"; r1b2rk1/p6p/2p3Pb/3pp1q1/8/2PB4/PP3PP1/RN1Q1K1R b - - bm Rxf2+; id "ECM.763"; r2rn3/1p3pk1/p1pNn1pp/q3P3/P7/1PN4P/2QR1PP1/3R2K1 w - - bm Nxf7; id "ECM.764"; r1bqr1k1/1p1nnpb1/p5pp/2P1p1B1/B3N3/5N2/P4PPP/2RQR1K1 w - - bm Nd6; id "ECM.765"; r1b1r1k1/pp2qpbp/2p3p1/2P5/3NnB2/7P/PPQ1PPB1/2RR2K1 b - - bm Nxf2; id "ECM.766"; 5rk1/r2qnppp/p1nN4/2Q5/3PB3/4P3/6PP/R4RK1 w - - bm Nxf7; id "ECM.768"; 1bq2k2/1b1n1pp1/pp5p/2pBpN2/P3P2B/3Q1P2/1PP3PP/4K3 w - - bm Be7+; id "ECM.769"; rnb2rk1/pp3pbp/2p3pB/2q5/4P3/1BN5/PPP3PP/R2Q1R1K w - - bm Rxf7; id "ECM.770"; 3qr1k1/1br1bp1p/p3p1pB/1p1nN3/3PB3/7Q/PP3PPP/3RR1K1 w - - bm Nxf7; id "ECM.771"; 1qr1b1k1/4bpp1/pn2p2p/1p1nN3/3P4/P2BBN1Q/1P3PPP/4R1K1 w - - bm Bxh6; id "ECM.772"; rr1q2k1/1p2bpp1/2p1p2p/P1Pn4/2NP4/3Q1RP1/5PKP/2B1R3 w - - bm Bxh6; id "ECM.773"; r2r2k1/pb1nbpp1/1qp1pn1p/1p2N3/3P1B2/P1N1P3/BPQ2PPP/2R2RK1 w - - bm Bxh6; id "ECM.774"; 2r5/1p4bk/3p2rp/4pN2/1P2P1pR/2P2q2/QP6/1K5R w - - bm Rxh6+; id "ECM.775"; r1b1r3/pp2Npbk/3pp2p/q5p1/2QNPP2/6P1/PPP3P1/2KR3R w - - bm Ndf5; id "ECM.776"; r1q3r1/1ppQ2pk/3bNp1p/p3pP2/P3P3/7R/1PP3PP/3R2K1 w - - bm Rxh6+; id "ECM.777"; 4r1k1/p1pq1pp1/2p5/3p1b2/Q7/2P1B2P/P1P1rPP1/2R2RK1 b - - bm Bxh3; id "ECM.778"; 1rbqnr2/5p1k/p1np3p/1p1Np3/4P2P/1Q2B3/PPP1BP2/2KR3R w - - bm Bxh6; id "ECM.779"; r1br2k1/p1q2pp1/4p1np/2ppP2Q/2n5/2PB1N2/2P2PPP/R1B1R1K1 w - - bm Bxh6; id "ECM.780"; 3r1r1k/p5p1/n1p2p1p/1qp2b2/N1R4R/1PB1P1P1/P2P3P/3Q2K1 w - - bm Rxh6+; id "ECM.781"; r4rk1/2q1b1p1/p4p1p/n3pP2/1p2Q1N1/4B3/PPP3PP/4RR1K w - - bm Nxh6+; id "ECM.782"; 6rk/3b1n1p/1p1q3b/1PpNp3/2P1Pp2/2Q2NrP/5RP1/2R2B1K b - - bm Bxh3; id "ECM.783"; r2q1rk1/ppp2pp1/1b2b2p/3n3Q/2Bp4/3P1N2/PPP2PPP/R1B1R1K1 w - - bm Bxh6; id "ECM.784"; r3rbk1/1bp1qpp1/p6p/np2p2Q/4P2N/1BP4P/PP3PP1/R1B1R1K1 w - - bm Bg5; id "ECM.785"; 4q3/p2r1ppk/R6p/3n4/3B1Q2/4P2P/5PP1/6K1 w - - bm Rxh6+; id "ECM.786"; 7r/1p2qk2/pQ1p2p1/3Ppp2/P4b2/2P2PrP/1P2R1B1/4R2K b - - bm Rhxh3+; id "ECM.787"; 5rk1/Qp5p/3pp1p1/4n3/2P1P2q/5r1P/P3NPP1/3R1RK1 b - - bm Rxh3; id "ECM.788"; 2r1r1k1/pb1n1pp1/1p1qpn1p/4N1B1/2PP4/3B4/P2Q1PPP/3RR1K1 w - - bm Bxh6; id "ECM.789"; 3q1rk1/p2bbpp1/1rn4p/1pp2P2/3pBBP1/3P3P/PPPQ3N/R4RK1 w - - bm Bxh6; id "ECM.790"; 2br2k1/4qppp/p5r1/2pBp3/2P1Pn2/4Q2P/RP3PPK/1N4R1 b - - bm Bxh3; id "ECM.791"; r2qr3/2p1b1pk/p5pp/1p2p3/nP2P1P1/1BP2RP1/P3QPK1/R1B5 w - - bm Bxh6; id "ECM.792"; r5r1/pbn4k/1p1p1Ppp/2pPn3/4BQq1/1PN3P1/PB3PK1/3R1R2 w - - bm Qxh6+; id "ECM.793"; r1b2rk1/pp2bpp1/4p2p/2q4Q/5nNB/2PB4/PP3PPP/2KR3R w - - bm Nxh6+; id "ECM.794"; 6k1/p4ppp/1pn1b1rr/8/PBpPp2q/2P1P1NP/5PP1/RR3QK1 b - - bm Bxh3; id "ECM.795"; r1b2rk1/1p3pp1/p5Pp/2bpPp1Q/3N4/1Pq1B1R1/2P4P/3R2K1 w - - bm Bxh6; id "ECM.796"; r2r2k1/pp1n1bp1/2p2p1p/b4N2/q2BR3/2QB2PP/1PP5/2KR4 w - - bm Nxh6+; id "ECM.797"; 3r2bk/1q4p1/p2P1N1p/2p1rP2/pb5R/7P/1P4P1/2Q2RK1 w - - bm Rxh6+; id "ECM.798"; 2b1rk2/r6p/1pP1p1p1/p2pNnR1/5Q2/P1B4q/1PP2P1P/1K4R1 w - - bm Rxf5+ Nxg6+; id "ECM.799"; 6R1/6Q1/3q2p1/5p1p/P3p1k1/1P1r2P1/5PK1/8 b - - bm Rxg3+; id "ECM.800"; r6r/ppnqpk2/3pbpp1/5N2/1PP1P3/5RR1/P2QB1PP/6K1 w - - bm Nh6+; id "ECM.801"; 3r3r/p4pk1/5Rp1/3q4/1p1P2RQ/5N2/P1P4P/2b4K w - - bm Rfxg6+; id "ECM.802"; 2b2r1k/2p3pp/2Nb4/pP5q/2PP4/P4pP1/5P1P/R1BQ2K1 b - - bm Bxg3; id "ECM.803"; r1bq2k1/pp3r1p/2n1p1p1/3pP3/6Q1/2PB2P1/P4PK1/R1B4R w - - bm Bxg6; id "ECM.804"; 3q1rk1/2r4p/n1p1n1pQ/p2pP3/Np1P2R1/5PN1/PP3KP1/2R5 w - - bm Rxg6+; id "ECM.805"; 2Nq1rk1/6pp/b1p2b2/p6Q/np1p4/6P1/PB3PBP/R3R1K1 w - - bm Be4; id "ECM.806"; r2r4/p4pk1/2p3p1/1p1nPR2/5p1Q/2N5/PPPq4/1K4R1 w - - bm e6; id "ECM.807"; 2kr3r/pbq3p1/1p2pp2/2b4n/2P1B3/1P1N2Pp/PB2QP1P/R4RK1 b - - bm Nxg3; id "ECM.808"; r5k1/1p2Rpb1/3p1np1/2nP2B1/1qP5/1pN1Q2P/P5P1/1B4K1 w - - bm Bxg6; id "ECM.809"; 2rqr1k1/pb2bp1p/1pn1pnpB/4N3/3P4/P1N3R1/1P3PPP/RB1Q2K1 w - - bm Nxg6; id "ECM.810"; 3rr3/3q1p1k/p2P2pp/1bp1b3/5N2/6QP/P1B3P1/3RR1K1 w - - bm Bxg6+; id "ECM.812"; r2q1rk1/pp2ppb1/3pn1pQ/3R4/2P3B1/4BR2/PP4PP/6K1 w - - bm Qxg6; id "ECM.813"; 1n1b1rk1/r4p1p/p1p2qpQ/P3Np2/2BP4/2P1R3/5PPP/R5K1 w - - bm Rb1; id "ECM.814"; 6rk/pb3p1p/3bpPq1/3P4/1p1B3r/1B4P1/PPRQ1R1P/6K1 b - - bm Bxg3; id "ECM.815"; 3rr1k1/pb2bp1p/3qp1pB/1p2N3/3P2Q1/2P1R3/P4PPP/4R1K1 w - - bm Nxg6; id "ECM.816"; r2q1rk1/pb1nbp1p/1p2p1p1/4N1BQ/2PP4/P7/5PPP/RB2R1K1 w - - bm Nxg6; id "ECM.817"; 1Q4R1/r2qbp2/3p1kp1/3Bp2p/8/3PP1P1/5PKP/8 w - - bm e4 Rxg6+; id "ECM.818"; r3r1k1/b1p2pn1/p2q1Bp1/1p1bN1Qp/3P4/2P4P/PPB2PP1/R3R1K1 w - - bm Nxg6; id "ECM.819"; 3r2k1/p1rn1p1p/1p2pp2/6q1/3PQNP1/5P2/P1P4R/R5K1 w - - bm Nxe6; id "ECM.820"; k2r3r/ppq2p1p/n1pb1Pp1/4p3/2Q5/1R2B1P1/PPP2PBP/R5K1 w - - bm Rxb7; id "ECM.821"; 1rb2rk1/p1p1qppp/2p2n2/3P4/1b3P2/2NB4/PPPBQ1PP/2KR3R b - - bm Ba3; id "ECM.822"; k7/pp1N4/4P3/5P2/8/5p2/1R6/B4Knq w - - bm Nb6+; id "ECM.823"; 4rrk1/p5pp/1p4q1/3p2n1/2pP2P1/P1P1PP2/3B2K1/1R2QR2 b - - bm Rxf3 Nxf3; id "ECM.824"; 1q1r3k/3P1pp1/ppBR1n1p/4Q2P/P4P2/8/5PK1/8 w - - bm Rxf6; id "ECM.825"; 1rbq2k1/b1p3pp/p1Pp4/3Ppr2/8/5N2/PPQ2PPP/R1B2RK1 b - - bm Rxf3; id "ECM.826"; r4rk1/2p1qpp1/p1p5/2Ppn2b/2PQ1N1p/4P3/PB3PPP/R4RK1 b - - bm Nf3+; id "ECM.828"; r1bq1rk1/1p2bppp/p3p3/n3P3/4N3/1P1P1N2/PB4PP/R3QR1K w - - bm Nf6+; id "ECM.829"; 1n2r3/p1pq1kp1/1b1pNpp1/3P4/5RP1/3Q3P/1B3P2/6K1 w - - bm Bxf6; id "ECM.830"; r1bq1rk1/ppp3p1/7p/3P2n1/2PQ1p2/1N5P/PPP2PPK/R1B2R2 b - - bm Nf3+; id "ECM.831"; 3r1b2/p4bkp/1p1P1p2/r3p1p1/2q1N3/2N2P2/1P1R2PP/2QR3K w - - bm Nxf6; id "ECM.832"; rqbn1rk1/1p3ppp/p3p3/8/4NP2/8/PPP1BQPP/1K1R3R w - - bm Nf6+; id "ECM.833"; r1b1kb1r/1p4pp/p2ppn2/8/2qNP3/2N1B3/PPP3PP/R2Q1RK1 w kq - bm Rxf6; id "ECM.834"; 1rn5/p3Bk1p/1pq1bpp1/P3p3/1Q2P2P/2P3P1/5PB1/1R4K1 w - - bm Bxf6; id "ECM.835"; 6nk/pn2qr1r/1pbp1p1p/2p1pPpN/P1P1P1PP/2PP3R/7Q/2BBK2R w K - bm Nxf6; id "ECM.837"; 7r/4p1k1/p3Pppp/1p6/3N1R2/3PQ2P/qr4b1/5RK1 w - - bm Rxf6; id "ECM.838"; r3k2r/1bq1bp2/p3p1pp/1p2P3/3NpP2/4B1Q1/PPP3PP/1K1R3R w kq - bm Nxe6; id "ECM.839"; rnbqkb1r/pp1n1p2/4p1p1/1N1pP2p/1P4Q1/3B1N2/P1PB1PPP/R3K2R w KQkq - bm Qxe6+; id "ECM.840"; r1b1kb1r/1p1n1ppp/p2ppn2/6BB/2qNP3/2N5/PPP2PPP/R2Q1RK1 w kq - bm Nxe6; id "ECM.841"; r1b1k1nr/3n1p1p/1qpBp1p1/pp2b3/4PN2/PBN2Q2/1PP2PPP/2KR3R w kq - bm Nxe6; id "ECM.842"; 2r2rk1/1b3ppp/pq2p3/1pbn2N1/3B3P/1B4P1/P1P1QP2/2KRR3 w - - bm Qh5; id "ECM.843"; r3k2r/pp1n1pb1/1qn1p1p1/2p3Pp/4R2P/2NP2QB/PPPB1P2/2K1R3 w kq - bm Rxe6+; id "ECM.844"; r3k2r/1q3ppp/p3p3/2b1P3/p2N1Q2/P7/1PP3PP/3R1R1K w kq - bm Nxe6; id "ECM.845"; 3qr1k1/rp3pbp/2p3p1/3p1b2/N1nP4/P2NP3/1PQ2PPP/1BRR2K1 b - - bm Rxe3; id "ECM.846"; rnbqkb1r/1p1n1pp1/p3p2p/3pP3/3p1NQP/2N5/P1PB1PP1/R3KB1R w KQkq - bm Nxe6; id "ECM.847"; 3r1b1R/3bkpp1/1p1np3/1BqpPPP1/PQ1N4/8/1PP5/1K6 w - - bm f6+; id "ECM.848"; 4r1k1/pp2n2p/1r1n1bp1/q2p1pB1/3P3N/P1NQ1P1P/1PP3R1/1K5R b - - bm Rxb2+; id "ECM.849"; 3r2k1/2p1bppp/4b3/p2pP3/qr1N1B1P/8/1PPQ2P1/1K1RR3 b - - bm Rxb2+; id "ECM.850"; 1k1r3r/ppR2ppp/1q2b3/1N6/4Q3/8/PP3PPP/4R1K1 w - - bm Rxb7+; id "ECM.851"; 1r3rk1/5pbp/p2Pp1p1/q1n3P1/2p2P1P/2N1Q2R/PP6/1BKR4 b - - bm Nd3+ Rxb2; id "ECM.852"; rr4k1/5p1p/n2p1npQ/q1pP4/6P1/2N2P1N/PP1R3P/2K4R b - - bm Rxb2; id "ECM.853"; 1k2bb1r/1p3p1p/p2qpP1p/3pN3/3P1Q2/2RB2P1/PP3P1P/6K1 w - - bm Qc1; id "ECM.854"; 1r4k1/1r3p2/p1p1b1pQ/q3P3/P7/bPN1R1P1/2P4P/1K1R1B2 b - - bm Bxb3; id "ECM.855"; 5rk1/5rp1/p2qb3/R2Np2Q/3bP2B/7P/P5PK/1R6 b - - bm Rf1; id "ECM.856"; 6k1/5p2/R3p1p1/1pq1PpB1/4nP2/5Q1P/P2r2PK/8 w - - bm Ra8+; id "ECM.857"; 1r6/5pk1/p1b2qpp/P1P1n3/1N6/Q5NP/5PP1/3R2K1 b - - bm Bxg2; id "ECM.859"; 2R5/p3q1kp/6p1/3p4/b2P2p1/Pr4N1/5Q2/3K3R w - - bm Nf5+; id "ECM.861"; 3r4/kb6/pp6/4R1pr/PPpq4/2N3Q1/2P3PP/3R3K b - - bm Rf8; id "ECM.862"; 4r1k1/5p1p/4q1p1/8/Q5n1/3B2P1/P4P1P/2R3K1 b - - bm Nxf2; id "ECM.863"; 7k/1p4p1/2p4r/5p2/p1QP1q2/2P2PR1/r4P1P/4R2K b - - bm Rxh2+; id "ECM.869"; 1r3r2/6kp/3p1pp1/qnp1pP2/1p2P2N/3P4/PPPQ1P1P/1K1R2R1 w - - bm fxg6; id "ECM.870"; 5rk1/1rP3pp/p4n2/3Pp3/1P2Pq2/2Q4P/P5P1/R3R1K1 b - - bm Rxc7; id "ECM.871"; 2rq1rk1/5ppp/2b1pb2/np6/6N1/2NBB3/PP3PPP/R2Q2K1 w - - bm Bb6; id "ECM.872"; 5r2/p2p2kp/3PnNp1/1qr1Pp2/2p5/P1R5/6PP/2Q1R1K1 w - - bm Qh6+; id "ECM.873"; 2Qbq1k1/6p1/1p4Np/4p2P/3rP3/8/3p2PK/3R4 w - - bm Rf1; id "ECM.874"; 2K5/6p1/kp2P3/1p6/1P6/2P1P2p/8/1r6 w - - bm e7; id "ECM.876"; 2kr3r/1Rp1bpp1/p6q/Q3P3/2P5/3p1NP1/P3P2P/1R4K1 b - - bm Qe3+; id "ECM.877"; 6k1/1R4pp/2p5/8/P1rNp3/6Pb/4PK2/8 w - - bm a5; id "ECM.878"; sjeng-11.2.orig/tests/bk.epd0100644000175000017500000000375607075727641015005 0ustar lukaslukas1k1r4/pp1b1R2/3q2pp/4p3/2B5/4Q3/PPP2B2/2K5 b - - bm Qd1+; id "position 01"; 3r1k2/4npp1/1ppr3p/p6P/P2PPPP1/1NR5/5K2/2R5 w - - bm d5; id "position 02"; 2q1rr1k/3bbnnp/p2p1pp1/2pPp3/PpP1P1P1/1P2BNNP/2BQ1PRK/7R b - - bm f5; id "position 03"; rnbqkb1r/p3pppp/1p6/2ppP3/3N4/2P5/PPP1QPPP/R1B1KB1R w KQkq - bm e6; id "position 04"; r1b2rk1/2q1b1pp/p2ppn2/1p6/3QP3/1BN1B3/PPP3PP/R4RK1 w - - bm Nd5 a4; id "position 05"; 2r3k1/pppR1pp1/4p3/4P1P1/5P2/1P4K1/P1P5/8 w - - bm g6; id "position 06"; 1nk1r1r1/pp2n1pp/4p3/q2pPp1N/b1pP1P2/B1P2R2/2P1B1PP/R2Q2K1 w - - bm Nf6; id "position 07"; 4b3/p3kp2/6p1/3pP2p/2pP1P2/4K1P1/P3N2P/8 w - - bm f5; id "position 08"; 2kr1bnr/pbpq4/2n1pp2/3p3p/3P1P1B/2N2N1Q/PPP3PP/2KR1B1R w - - bm f5; id "position 09"; 3rr1k1/pp3pp1/1qn2np1/8/3p4/PP1R1P2/2P1NQPP/R1B3K1 b - - bm Ne5; id "position 10"; 2r1nrk1/p2q1ppp/bp1p4/n1pPp3/P1P1P3/2PBB1N1/4QPPP/R4RK1 w - - bm f4; id "position 11"; r3r1k1/ppqb1ppp/8/4p1NQ/8/2P5/PP3PPP/R3R1K1 b - - bm Bf5; id "position 12"; r2q1rk1/4bppp/p2p4/2pP4/3pP3/3Q4/PP1B1PPP/R3R1K1 w - - bm b4; id "position 13"; rnb2r1k/pp2p2p/2pp2p1/q2P1p2/8/1Pb2NP1/PB2PPBP/R2Q1RK1 w - - bm Qd2; id "position 14"; 2r3k1/1p2q1pp/2b1pr2/p1pp4/6Q1/1P1PP1R1/P1PN2PP/5RK1 w - - bm Qxg7+; id "position 15"; r1bqkb1r/4npp1/p1p4p/1p1pP1B1/8/1B6/PPPN1PPP/R2Q1RK1 W kq - bm Ne4; id "position 16"; r2q1rk1/1ppnbppp/p2p1nb1/3Pp3/2P1P1P1/2N2N1P/PPB1QP2/R1B2RK1 b - - bm h5; id "position 17"; r1bq1rk1/pp2ppbp/2np2p1/2n5/P3PP2/N1P2N2/1PB3PP/R1B1QRK1 b - - bm Nb3; id "position 18"; 3rr3/2pq2pk/p2p1pnp/8/2QBPP2/1P6/P5PP/4RRK1 b - - bm Rxe4; id "position 19"; r4k2/pb2bp1r/1p1qp2p/3pNp2/3P1P2/2N3P1/PPP1Q2P/2KRR3 w - - bm g4; id "position 20"; 3rn2k/ppb2rpp/2ppqp2/5N2/2P1P3/1P5Q/PB3PPP/3RR1K1 w - - bm Nh6; id "position 21"; 2r2rk1/1bqnbpp1/1p1ppn1p/pP6/N1P1P3/P2B1N1P/1B2QPP1/R2R2K1 b - - bm Bxe4; id "position 22"; r1bqk2r/pp2bppp/2p5/3pP3/P2Q1P2/2N1B3/1PP3PP/R4RK1 b kq - bm f6; id "position 23"; r2qnrnk/p2b2b1/1p1p2pp/2pPpp2/1PP1P3/PRNBB3/3QNPPP/5RK1 w - - bm f4; id "position 24"; sjeng-11.2.orig/tests/Makefile.am0100644000175000017500000000007207307524520015724 0ustar lukaslukasEXTRA_DIST = bk.epd bt2630.epd lct2.epd wac.epd ecm98.epd sjeng-11.2.orig/tests/Makefile.in0100644000175000017500000001016107412717725015745 0ustar lukaslukas# Makefile.in generated automatically by automake 1.4 from Makefile.am # Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. SHELL = @SHELL@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ sbindir = @sbindir@ libexecdir = @libexecdir@ datadir = @datadir@ sysconfdir = @sysconfdir@ sharedstatedir = @sharedstatedir@ localstatedir = @localstatedir@ libdir = @libdir@ infodir = @infodir@ mandir = @mandir@ includedir = @includedir@ oldincludedir = /usr/include DESTDIR = pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. ACLOCAL = @ACLOCAL@ AUTOCONF = @AUTOCONF@ AUTOMAKE = @AUTOMAKE@ AUTOHEADER = @AUTOHEADER@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ transform = @program_transform_name@ NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : CC = @CC@ CXX = @CXX@ MAKEINFO = @MAKEINFO@ PACKAGE = @PACKAGE@ VERSION = @VERSION@ EXTRA_DIST = bk.epd bt2630.epd lct2.epd wac.epd ecm98.epd mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = ../config.h CONFIG_CLEAN_FILES = DIST_COMMON = Makefile.am Makefile.in DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = tar GZIP_ENV = --best all: all-redirect .SUFFIXES: $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps tests/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) \ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status tags: TAGS TAGS: distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) subdir = tests distdir: $(DISTFILES) @for file in $(DISTFILES); do \ d=$(srcdir); \ if test -d $$d/$$file; then \ cp -pr $$/$$file $(distdir)/$$file; \ else \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ || cp -p $$d/$$file $(distdir)/$$file || :; \ fi; \ done info-am: info: info-am dvi-am: dvi: dvi-am check-am: all-am check: check-am installcheck-am: installcheck: installcheck-am install-exec-am: install-exec: install-exec-am install-data-am: install-data: install-data-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am install: install-am uninstall-am: uninstall: uninstall-am all-am: Makefile all-redirect: all-am install-strip: $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install installdirs: mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) -rm -f config.cache config.log stamp-h stamp-h[0-9]* maintainer-clean-generic: mostlyclean-am: mostlyclean-generic mostlyclean: mostlyclean-am clean-am: clean-generic mostlyclean-am clean: clean-am distclean-am: distclean-generic clean-am distclean: distclean-am maintainer-clean-am: maintainer-clean-generic distclean-am @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." maintainer-clean: maintainer-clean-am .PHONY: tags distdir info-am info dvi-am dvi check check-am \ installcheck-am installcheck install-exec-am install-exec \ install-data-am install-data install-am install uninstall-am uninstall \ all-redirect all-am all installdirs mostlyclean-generic \ distclean-generic clean-generic maintainer-clean-generic clean \ mostlyclean distclean maintainer-clean # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: sjeng-11.2.orig/tests/wac.epd0100644000175000017500000005424707075727654015170 0ustar lukaslukas2rr3k/pp3pp1/1nnqbN1p/3pN3/2pP4/2P3Q1/PPB4P/R4RK1 w - - bm Qg6; id "WAC.001"; 8/7p/5k2/5p2/p1p2P2/Pr1pPK2/1P1R3P/8 b - - bm Rxb2; id "WAC.002"; 5rk1/1ppb3p/p1pb4/6q1/3P1p1r/2P1R2P/PP1BQ1P1/5RKN w - - bm Rg3; id "WAC.003"; r1bq2rk/pp3pbp/2p1p1pQ/7P/3P4/2PB1N2/PP3PPR/2KR4 w - - bm Qxh7+; id "WAC.004"; 5k2/6pp/p1qN4/1p1p4/3P4/2PKP2Q/PP3r2/3R4 b - - bm Qc4+; id "WAC.005"; 7k/p7/1R5K/6r1/6p1/6P1/8/8 w - - bm Rb7; id "WAC.006"; rnbqkb1r/pppp1ppp/8/4P3/6n1/7P/PPPNPPP1/R1BQKBNR b KQkq - bm Ne3; id "WAC.007"; r4q1k/p2bR1rp/2p2Q1N/5p2/5p2/2P5/PP3PPP/R5K1 w - - bm Rf7; id "WAC.008"; 3q1rk1/p4pp1/2pb3p/3p4/6Pr/1PNQ4/P1PB1PP1/4RRK1 b - - bm Bh2+; id "WAC.009"; 2br2k1/2q3rn/p2NppQ1/2p1P3/Pp5R/4P3/1P3PPP/3R2K1 w - - bm Rxh7; id "WAC.010"; r1b1kb1r/3q1ppp/pBp1pn2/8/Np3P2/5B2/PPP3PP/R2Q1RK1 w kq - bm Bxc6; id "WAC.011"; 4k1r1/2p3r1/1pR1p3/3pP2p/3P2qP/P4N2/1PQ4P/5R1K b - - bm Qxf3+; id "WAC.012"; 5rk1/pp4p1/2n1p2p/2Npq3/2p5/6P1/P3P1BP/R4Q1K w - - bm Qxf8+; id "WAC.013"; r2rb1k1/pp1q1p1p/2n1p1p1/2bp4/5P2/PP1BPR1Q/1BPN2PP/R5K1 w - - bm Qxh7+; id "WAC.014"; 1R6/1brk2p1/4p2p/p1P1Pp2/P7/6P1/1P4P1/2R3K1 w - - bm Rxb7; id "WAC.015"; r4rk1/ppp2ppp/2n5/2bqp3/8/P2PB3/1PP1NPPP/R2Q1RK1 w - - bm Nc3; id "WAC.016"; 1k5r/pppbn1pp/4q1r1/1P3p2/2NPp3/1QP5/P4PPP/R1B1R1K1 w - - bm Ne5; id "WAC.017"; R7/P4k2/8/8/8/8/r7/6K1 w - - bm Rh8; id "WAC.018"; r1b2rk1/ppbn1ppp/4p3/1QP4q/3P4/N4N2/5PPP/R1B2RK1 w - - bm c6; id "WAC.019"; r2qkb1r/1ppb1ppp/p7/4p3/P1Q1P3/2P5/5PPP/R1B2KNR b kq - bm Bb5; id "WAC.020"; 5rk1/1b3p1p/pp3p2/3n1N2/1P6/P1qB1PP1/3Q3P/4R1K1 w - - bm Qh6; id "WAC.021"; r1bqk2r/ppp1nppp/4p3/n5N1/2BPp3/P1P5/2P2PPP/R1BQK2R w KQkq - bm Ba2 Nxf7; id "WAC.022"; r3nrk1/2p2p1p/p1p1b1p1/2NpPq2/3R4/P1N1Q3/1PP2PPP/4R1K1 w - - bm g4; id "WAC.023"; 6k1/1b1nqpbp/pp4p1/5P2/1PN5/4Q3/P5PP/1B2B1K1 b - - bm Bd4; id "WAC.024"; 3R1rk1/8/5Qpp/2p5/2P1p1q1/P3P3/1P2PK2/8 b - - bm Qh4+; id "WAC.025"; 3r2k1/1p1b1pp1/pq5p/8/3NR3/2PQ3P/PP3PP1/6K1 b - - bm Bf5; id "WAC.026"; 7k/pp4np/2p3p1/3pN1q1/3P4/Q7/1r3rPP/2R2RK1 w - - bm Qf8+; id "WAC.027"; 1r1r2k1/4pp1p/2p1b1p1/p3R3/RqBP4/4P3/1PQ2PPP/6K1 b - - bm Qe1+; id "WAC.028"; r2q2k1/pp1rbppp/4pn2/2P5/1P3B2/6P1/P3QPBP/1R3RK1 w - - bm c6; id "WAC.029"; 1r3r2/4q1kp/b1pp2p1/5p2/pPn1N3/6P1/P3PPBP/2QRR1K1 w - - bm Nxd6; id "WAC.030"; rb3qk1/pQ3ppp/4p3/3P4/8/1P3N2/1P3PPP/3R2K1 w - - bm Qxa8 d6 dxe6; id "WAC.031"; 6k1/p4p1p/1p3np1/2q5/4p3/4P1N1/PP3PPP/3Q2K1 w - - bm Qd8+; id "WAC.032"; 8/p1q2pkp/2Pr2p1/8/P3Q3/6P1/5P1P/2R3K1 w - - bm Qe5+ Qf4; id "WAC.033"; 7k/1b1r2p1/p6p/1p2qN2/3bP3/3Q4/P5PP/1B1R3K b - - bm Bg1; id "WAC.034"; r3r2k/2R3pp/pp1q1p2/8/3P3R/7P/PP3PP1/3Q2K1 w - - bm Rxh7+; id "WAC.035"; 3r4/2p1rk2/1pQq1pp1/7p/1P1P4/P4P2/6PP/R1R3K1 b - - bm Re1+; id "WAC.036"; 2r5/2rk2pp/1pn1pb2/pN1p4/P2P4/1N2B3/nPR1KPPP/3R4 b - - bm Nxd4+; id "WAC.037"; 4k3/p4prp/1p6/2b5/8/2Q3P1/P2R1PKP/4q3 w - - bm Rd8+; id "WAC.038"; r1br2k1/pp2bppp/2nppn2/8/2P1PB2/2N2P2/PqN1B1PP/R2Q1R1K w - - bm Na4; id "WAC.039"; 3r1r1k/1p4pp/p4p2/8/1PQR4/6Pq/P3PP2/2R3K1 b - - bm Rc8; id "WAC.040"; 1k6/5RP1/1P6/1K6/6r1/8/8/8 w - - bm Ka5 Kc5; id "WAC.041"; r1b1r1k1/pp1n1pbp/1qp3p1/3p4/1B1P4/Q3PN2/PP2BPPP/R4RK1 w - - bm Ba5; id "WAC.042"; r2q3k/p2P3p/1p3p2/3QP1r1/8/B7/P5PP/2R3K1 w - - bm Be7 Qxa8; id "WAC.043"; 3rb1k1/pq3pbp/4n1p1/3p4/2N5/2P2QB1/PP3PPP/1B1R2K1 b - - bm dxc4; id "WAC.044"; 7k/2p1b1pp/8/1p2P3/1P3r2/2P3Q1/1P5P/R4qBK b - - bm Qxa1; id "WAC.045"; r1bqr1k1/pp1nb1p1/4p2p/3p1p2/3P4/P1N1PNP1/1PQ2PP1/3RKB1R w K - bm Nb5; id "WAC.046"; r1b2rk1/pp2bppp/2n1pn2/q5B1/2BP4/2N2N2/PP2QPPP/2R2RK1 b - - bm Nxd4; id "WAC.047"; 1rbq1rk1/p1p1bppp/2p2n2/8/Q1BP4/2N5/PP3PPP/R1B2RK1 b - - bm Rb4; id "WAC.048"; 2b3k1/4rrpp/p2p4/2pP2RQ/1pP1Pp1N/1P3P1P/1q6/6RK w - - bm Qxh7+; id "WAC.049"; k4r2/1R4pb/1pQp1n1p/3P4/5p1P/3P2P1/r1q1R2K/8 w - - bm Rxb6+; id "WAC.050"; r1bq1r2/pp4k1/4p2p/3pPp1Q/3N1R1P/2PB4/6P1/6K1 w - - bm Rg4+; id "WAC.051"; r1k5/1p3q2/1Qpb4/3N1p2/5Pp1/3P2Pp/PPPK3P/4R3 w - - bm Re7; id "WAC.052"; 6k1/6p1/p7/3Pn3/5p2/4rBqP/P4RP1/5QK1 b - - bm Re1; id "WAC.053"; r3kr2/1pp4p/1p1p4/7q/4P1n1/2PP2Q1/PP4P1/R1BB2K1 b q - bm Qh1+; id "WAC.054"; r3r1k1/pp1q1pp1/4b1p1/3p2B1/3Q1R2/8/PPP3PP/4R1K1 w - - bm Qxg7+; id "WAC.055"; r1bqk2r/pppp1ppp/5n2/2b1n3/4P3/1BP3Q1/PP3PPP/RNB1K1NR b KQkq - bm Bxf2+; id "WAC.056"; r3q1kr/ppp5/3p2pQ/8/3PP1b1/5R2/PPP3P1/5RK1 w - - bm Rf8+; id "WAC.057"; 8/8/2R5/1p2qp1k/1P2r3/2PQ2P1/5K2/8 w - - bm Qd1+; id "WAC.058"; r1b2rk1/2p1qnbp/p1pp2p1/5p2/2PQP3/1PN2N1P/PB3PP1/3R1RK1 w - - bm Nd5; id "WAC.059"; rn1qr1k1/1p2np2/2p3p1/8/1pPb4/7Q/PB1P1PP1/2KR1B1R w - - bm Qh8+; id "WAC.060"; 3qrbk1/ppp1r2n/3pP2p/3P4/2P4P/1P3Q2/PB6/R4R1K w - - bm Qf7+; id "WAC.061"; 6r1/3Pn1qk/p1p1P1rp/2Q2p2/2P5/1P4P1/P3R2P/5RK1 b - - bm Rxg3+; id "WAC.062"; r1brnbk1/ppq2pp1/4p2p/4N3/3P4/P1PB1Q2/3B1PPP/R3R1K1 w - - bm Nxf7; id "WAC.063"; 8/6pp/3q1p2/3n1k2/1P6/3NQ2P/5PP1/6K1 w - - bm g4+; id "WAC.064"; 1r1r1qk1/p2n1p1p/bp1Pn1pQ/2pNp3/2P2P1N/1P5B/P6P/3R1RK1 w - - bm Ne7+; id "WAC.065"; 1k1r2r1/ppq5/1bp4p/3pQ3/8/2P2N2/PP4P1/R4R1K b - - bm Qxe5; id "WAC.066"; 3r2k1/p2q4/1p4p1/3rRp1p/5P1P/6PK/P3R3/3Q4 w - - bm Rxd5; id "WAC.067"; 6k1/5ppp/1q6/2b5/8/2R1pPP1/1P2Q2P/7K w - - bm Qxe3; id "WAC.068"; 2k5/pppr4/4R3/4Q3/2pp2q1/8/PPP2PPP/6K1 w - - bm f3 h3; id "WAC.069"; 2kr3r/pppq1ppp/3p1n2/bQ2p3/1n1PP3/1PN1BN1P/1PP2PP1/2KR3R b - - bm Na2+; id "WAC.070"; 2kr3r/pp1q1ppp/5n2/1Nb5/2Pp1B2/7Q/P4PPP/1R3RK1 w - - bm Nxa7+; id "WAC.071"; r3r1k1/pp1n1ppp/2p5/4Pb2/2B2P2/B1P5/P5PP/R2R2K1 w - - bm e6; id "WAC.072"; r1q3rk/1ppbb1p1/4Np1p/p3pP2/P3P3/2N4R/1PP1Q1PP/3R2K1 w - - bm Qd2; id "WAC.073"; 5r1k/pp4pp/2p5/2b1P3/4Pq2/1PB1p3/P3Q1PP/3N2K1 b - - bm Qf1+; id "WAC.074"; r3r1k1/pppq1ppp/8/8/1Q4n1/7P/PPP2PP1/RNB1R1K1 b - - bm Qd6; id "WAC.075"; r1b1qrk1/2p2ppp/pb1pnn2/1p2pNB1/3PP3/1BP5/PP2QPPP/RN1R2K1 w - - bm Bxf6; id "WAC.076"; 3r2k1/ppp2ppp/6q1/b4n2/3nQB2/2p5/P4PPP/RN3RK1 b - - bm Ng3; id "WAC.077"; r2q3r/ppp2k2/4nbp1/5Q1p/2P1NB2/8/PP3P1P/3RR1K1 w - - bm Ng5+; id "WAC.078"; r3k2r/pbp2pp1/3b1n2/1p6/3P3p/1B2N1Pq/PP1PQP1P/R1B2RK1 b kq - bm Qxh2+; id "WAC.079"; r4rk1/p1B1bpp1/1p2pn1p/8/2PP4/3B1P2/qP2QP1P/3R1RK1 w - - bm Ra1; id "WAC.080"; r4rk1/1bR1bppp/4pn2/1p2N3/1P6/P3P3/4BPPP/3R2K1 b - - bm Bd6; id "WAC.081"; 3rr1k1/pp3pp1/4b3/8/2P1B2R/6QP/P3q1P1/5R1K w - - bm Bh7+; id "WAC.082"; 3rr1k1/ppqbRppp/2p5/8/3Q1n2/2P3N1/PPB2PPP/3R2K1 w - - bm Qxd7; id "WAC.083"; r2q1r1k/2p1b1pp/p1n5/1p1Q1bN1/4n3/1BP1B3/PP3PPP/R4RK1 w - - bm Qg8+; id "WAC.084"; kr2R3/p4r2/2pq4/2N2p1p/3P2p1/Q5P1/5P1P/5BK1 w - - bm Na6; id "WAC.085"; 8/p7/1ppk1n2/5ppp/P1PP4/2P1K1P1/5N1P/8 b - - bm Ng4+; id "WAC.086"; 8/p3k1p1/4r3/2ppNpp1/PP1P4/2P3KP/5P2/8 b - - bm Rxe5; id "WAC.087"; r6k/p1Q4p/2p1b1rq/4p3/B3P3/4P3/PPP3P1/4RRK1 b - - bm Rxg2+; id "WAC.088"; 1r3b1k/p4rpp/4pp2/3q4/2ppbPPQ/6RK/PP5P/2B1NR2 b - - bm g5; id "WAC.089"; 3qrrk1/1pp2pp1/1p2bn1p/5N2/2P5/P1P3B1/1P4PP/2Q1RRK1 w - - bm Nxg7; id "WAC.090"; 2qr2k1/4b1p1/2p2p1p/1pP1p3/p2nP3/PbQNB1PP/1P3PK1/4RB2 b - - bm Be6; id "WAC.091"; r4rk1/1p2ppbp/p2pbnp1/q7/3BPPP1/2N2B2/PPP4P/R2Q1RK1 b - - bm Bxg4; id "WAC.092"; r1b1k1nr/pp3pQp/4pq2/3pn3/8/P1P5/2P2PPP/R1B1KBNR w KQkq - bm Bh6; id "WAC.093"; 8/k7/p7/3Qp2P/n1P5/3KP3/1q6/8 b - - bm e4+; id "WAC.094"; 2r5/1r6/4pNpk/3pP1qp/8/2P1QP2/5PK1/R7 w - - bm Ng4+; id "WAC.095"; r1b4k/ppp2Bb1/6Pp/3pP3/1qnP1p1Q/8/PPP3P1/1K1R3R w - - bm Qd8+; id "WAC.096"; 6k1/5p2/p5np/4B3/3P4/1PP1q3/P3r1QP/6RK w - - bm Qa8+; id "WAC.097"; 1r3rk1/5pb1/p2p2p1/Q1n1q2p/1NP1P3/3p1P1B/PP1R3P/1K2R3 b - - bm Nxe4; id "WAC.098"; r1bq1r1k/1pp1Np1p/p2p2pQ/4R3/n7/8/PPPP1PPP/R1B3K1 w - - bm Rh5; id "WAC.099"; 8/k1b5/P4p2/1Pp2p1p/K1P2P1P/8/3B4/8 w - - bm b6+; id "WAC.100"; 5rk1/p5pp/8/8/2Pbp3/1P4P1/7P/4RN1K b - - bm Bc3; id "WAC.101"; 2Q2n2/2R4p/1p1qpp1k/8/3P3P/3B2P1/5PK1/r7 w - - bm Qxf8+; id "WAC.102"; 6k1/2pb1r1p/3p1PpQ/p1nPp3/1q2P3/2N2P2/PrB5/2K3RR w - - bm Qxg6+; id "WAC.103"; b4r1k/pq2rp2/1p1bpn1p/3PN2n/2P2P2/P2B3K/1B2Q2N/3R2R1 w - - bm Qxh5; id "WAC.104"; r2r2k1/pb3ppp/1p1bp3/7q/3n2nP/PP1B2P1/1B1N1P2/RQ2NRK1 b - - bm Qxh4; id "WAC.105"; 4rrk1/pppb4/7p/3P2pq/3Qn3/P5P1/1PP4P/R3RNNK b - - bm Nf2+; id "WAC.106"; 5n2/pRrk2p1/P4p1p/4p3/3N4/5P2/6PP/6K1 w - - bm Nb5; id "WAC.107"; r5k1/1q4pp/2p5/p1Q5/2P5/5R2/4RKPP/r7 w - - bm Qe5; id "WAC.108"; rn2k1nr/pbp2ppp/3q4/1p2N3/2p5/QP6/PB1PPPPP/R3KB1R b KQkq - bm c3; id "WAC.109"; 2kr4/bp3p2/p2p2b1/P7/2q5/1N4B1/1PPQ2P1/2KR4 b - - bm Be3; id "WAC.110"; 6k1/p5p1/5p2/2P2Q2/3pN2p/3PbK1P/7P/6q1 b - - bm Qf1+; id "WAC.111"; r4kr1/ppp5/4bq1b/7B/2PR1Q1p/2N3P1/PP3P1P/2K1R3 w - - bm Rxe6; id "WAC.112"; rnbqkb1r/1p3ppp/5N2/1p2p1B1/2P5/8/PP2PPPP/R2QKB1R b KQkq - bm Qxf6; id "WAC.113"; r1b1rnk1/1p4pp/p1p2p2/3pN2n/3P1PPq/2NBPR1P/PPQ5/2R3K1 w - - bm Bxh7+; id "WAC.114"; 4N2k/5rpp/1Q6/p3q3/8/P5P1/1P3P1P/5K2 w - - bm Nd6; id "WAC.115"; r2r2k1/2p2ppp/p7/1p2P1n1/P6q/5P2/1PB1QP1P/R5RK b - - bm Rd2; id "WAC.116"; 3r1rk1/q4ppp/p1Rnp3/8/1p6/1N3P2/PP3QPP/3R2K1 b - - bm Ne4; id "WAC.117"; r5k1/pb2rpp1/1p6/2p4q/5R2/2PB2Q1/P1P3PP/5R1K w - - bm Rh4; id "WAC.118"; r2qr1k1/p1p2ppp/2p5/2b5/4nPQ1/3B4/PPP3PP/R1B2R1K b - - bm Qxd3; id "WAC.119"; r4rk1/1bn2qnp/3p1B1Q/p2P1pP1/1pp5/5N1P/PPB2P2/2KR3R w - - bm g6; id "WAC.120"; 6k1/5p1p/2bP2pb/4p3/2P5/1p1pNPPP/1P1Q1BK1/1q6 b - - bm Bxf3+; id "WAC.121"; 1k6/ppp4p/1n2pq2/1N2Rb2/2P2Q2/8/P4KPP/3r1B2 b - - bm Rxf1+; id "WAC.122"; 6k1/1b2rp2/1p4p1/3P4/PQ4P1/2N2q2/5P2/3R2K1 b - - bm Bxd5 Rc7; id "WAC.123"; 6k1/3r4/2R5/P5P1/1P4p1/8/4rB2/6K1 b - - bm g3; id "WAC.124"; r1bqr1k1/pp3ppp/1bp5/3n4/3B4/2N2P1P/PPP1B1P1/R2Q1RK1 b - - bm Bxd4+; id "WAC.125"; r5r1/pQ5p/1qp2R2/2k1p3/4P3/2PP4/P1P3PP/6K1 w - - bm Rxc6+; id "WAC.126"; 2k4r/1pr1n3/p1p1q2p/5pp1/3P1P2/P1P1P3/1R2Q1PP/1RB3K1 w - - bm Rxb7; id "WAC.127"; 6rk/1pp2Qrp/3p1B2/1pb1p2R/3n1q2/3P4/PPP3PP/R6K w - - bm Qg6; id "WAC.128"; 3r1r1k/1b2b1p1/1p5p/2p1Pp2/q1B2P2/4P2P/1BR1Q2K/6R1 b - - bm Bf3; id "WAC.129"; 6k1/1pp3q1/5r2/1PPp4/3P1pP1/3Qn2P/3B4/4R1K1 b - - bm Qh6 Qh8; id "WAC.130"; 2rq1bk1/p4p1p/1p4p1/3b4/3B1Q2/8/P4PpP/3RR1K1 w - - bm Re8; id "WAC.131"; 4r1k1/5bpp/2p5/3pr3/8/1B3pPq/PPR2P2/2R2QK1 b - - bm Re1; id "WAC.132"; r1b1k2r/1pp1q2p/p1n3p1/3QPp2/8/1BP3B1/P5PP/3R1RK1 w kq - bm Bh4; id "WAC.133"; 3r2k1/p6p/2Q3p1/4q3/2P1p3/P3Pb2/1P3P1P/2K2BR1 b - - bm Rd1+; id "WAC.134"; 3r1r1k/N2qn1pp/1p2np2/2p5/2Q1P2N/3P4/PP4PP/3R1RK1 b - - bm Nd4; id "WAC.135"; 6kr/1q2r1p1/1p2N1Q1/5p2/1P1p4/6R1/7P/2R3K1 w - - bm Rc8+; id "WAC.136"; 3b1rk1/1bq3pp/5pn1/1p2rN2/2p1p3/2P1B2Q/1PB2PPP/R2R2K1 w - - bm Rd7; id "WAC.137"; r1bq3r/ppppR1p1/5n1k/3P4/6pP/3Q4/PP1N1PP1/5K1R w - - bm h5; id "WAC.138"; rnb3kr/ppp2ppp/1b6/3q4/3pN3/Q4N2/PPP2KPP/R1B1R3 w - - bm Nf6+; id "WAC.139"; r2b1rk1/pq4p1/4ppQP/3pB1p1/3P4/2R5/PP3PP1/5RK1 w - - bm Rc7; id "WAC.140"; 4r1k1/p1qr1p2/2pb1Bp1/1p5p/3P1n1R/1B3P2/PP3PK1/2Q4R w - - bm Qxf4; id "WAC.141"; r2q3n/ppp2pk1/3p4/5Pr1/2NP1Qp1/2P2pP1/PP3K2/4R2R w - - bm Re8 f6+; id "WAC.142"; 5b2/pp2r1pk/2pp1pRp/4rP1N/2P1P3/1P4QP/P3q1P1/5R1K w - - bm Rxh6+; id "WAC.143"; r2q1rk1/pp3ppp/2p2b2/8/B2pPPb1/7P/PPP1N1P1/R2Q1RK1 b - - bm d3; id "WAC.144"; r1bq4/1p4kp/3p1n2/p4pB1/2pQ4/8/1P4PP/4RRK1 w - - bm Re8; id "WAC.145"; 8/8/2Kp4/3P1B2/2P2k2/5p2/8/8 w - - bm Bc8; id "WAC.146"; r2r2k1/ppqbppbp/2n2np1/2pp4/6P1/1P1PPNNP/PBP2PB1/R2QK2R b KQ - bm Nxg4; id "WAC.147"; 2r1k3/6pr/p1nBP3/1p3p1p/2q5/2P5/P1R4P/K2Q2R1 w - - bm Rxg7; id "WAC.148"; 6k1/6p1/2p4p/4Pp2/4b1qP/2Br4/1P2RQPK/8 b - - bm Bxg2; id "WAC.149"; r3r1k1/5p2/pQ1b2pB/1p6/4p3/6P1/Pq2BP1P/2R3K1 b - - bm Ba3 Bf8 e3; id "WAC.150"; 8/3b2kp/4p1p1/pr1n4/N1N4P/1P4P1/1K3P2/3R4 w - - bm Nc3; id "WAC.151"; 1br2rk1/1pqb1ppp/p3pn2/8/1P6/P1N1PN1P/1B3PP1/1QRR2K1 w - - bm Ne4; id "WAC.152"; 2r3k1/q4ppp/p3p3/pnNp4/2rP4/2P2P2/4R1PP/2R1Q1K1 b - - bm Nxd4; id "WAC.153"; r1b2rk1/2p2ppp/p7/1p6/3P3q/1BP3bP/PP3QP1/RNB1R1K1 w - - bm Qxf7+; id "WAC.154"; 5bk1/1rQ4p/5pp1/2pP4/3n1PP1/7P/1q3BB1/4R1K1 w - - bm d6; id "WAC.155"; r1b1qN1k/1pp3p1/p2p3n/4p1B1/8/1BP4Q/PP3KPP/8 w - - bm Qxh6+; id "WAC.156"; 5rk1/p4ppp/2p1b3/3Nq3/4P1n1/1p1B2QP/1PPr2P1/1K2R2R w - - bm Ne7+; id "WAC.157"; 5rk1/n1p1R1bp/p2p4/1qpP1QB1/7P/2P3P1/PP3P2/6K1 w - - bm Rxg7+; id "WAC.158"; r1b2r2/5P1p/ppn3pk/2p1p1Nq/1bP1PQ2/3P4/PB4BP/1R3RK1 w - - bm Ne6+; id "WAC.159"; qn1kr2r/1pRbb3/pP5p/P2pP1pP/3N1pQ1/3B4/3B1PP1/R5K1 w - - bm Qxd7+; id "WAC.160"; 3r3k/3r1P1p/pp1Nn3/2pp4/7Q/6R1/Pq4PP/5RK1 w - - bm Qxd8+; id "WAC.161"; r3kbnr/p4ppp/2p1p3/8/Q1B3b1/2N1B3/PP3PqP/R3K2R w KQkq - bm Bd5; id "WAC.162"; 5rk1/2p4p/2p4r/3P4/4p1b1/1Q2NqPp/PP3P1K/R4R2 b - - bm Qg2+; id "WAC.163"; 8/6pp/4p3/1p1n4/1NbkN1P1/P4P1P/1PR3K1/r7 w - - bm Rxc4+; id "WAC.164"; 1r5k/p1p3pp/8/8/4p3/P1P1R3/1P1Q1qr1/2KR4 w - - bm Re2; id "WAC.165"; r3r1k1/5pp1/p1p4p/2Pp4/8/q1NQP1BP/5PP1/4K2R b K - bm d4; id "WAC.166"; 7Q/ppp2q2/3p2k1/P2Ppr1N/1PP5/7R/5rP1/6K1 b - - bm Rxg2+; id "WAC.167"; r3k2r/pb1q1p2/8/2p1pP2/4p1p1/B1P1Q1P1/P1P3K1/R4R2 b kq - bm Qd2+; id "WAC.168"; 5rk1/1pp3bp/3p2p1/2PPp3/1P2P3/2Q1B3/4q1PP/R5K1 b - - bm Bh6; id "WAC.169"; 5r1k/6Rp/1p2p3/p2pBp2/1qnP4/4P3/Q4PPP/6K1 w - - bm Qxc4; id "WAC.170"; 2rq4/1b2b1kp/p3p1p1/1p1nNp2/7P/1B2B1Q1/PP3PP1/3R2K1 w - - bm Bh6+; id "WAC.171"; 5r1k/p5pp/8/1P1pq3/P1p2nR1/Q7/5BPP/6K1 b - - bm Qe1+; id "WAC.172"; 2r1b3/1pp1qrk1/p1n1P1p1/7R/2B1p3/4Q1P1/PP3PP1/3R2K1 w - - bm Qh6+; id "WAC.173"; 2r2rk1/6p1/p3pq1p/1p1b1p2/3P1n2/PP3N2/3N1PPP/1Q2RR1K b - - bm Nxg2; id "WAC.174"; r5k1/pppb3p/2np1n2/8/3PqNpP/3Q2P1/PPP5/R4RK1 w - - bm Nh5; id "WAC.175"; r1bq3r/ppp2pk1/3p1pp1/8/2BbPQ2/2NP2P1/PPP4P/R4R1K b - - bm Rxh2+; id "WAC.176"; r1b3r1/4qk2/1nn1p1p1/3pPp1P/p4P2/1p3BQN/PKPBN3/3R3R b - - bm Qa3+; id "WAC.177"; 3r2k1/p1rn1p1p/1p2pp2/6q1/3PQNP1/5P2/P1P4R/R5K1 w - - bm Nxe6; id "WAC.178"; r1b2r1k/pp4pp/3p4/3B4/8/1QN3Pn/PP3q1P/R3R2K b - - bm Qg1+; id "WAC.179"; r1q2rk1/p3bppb/3p1n1p/2nPp3/1p2P1P1/6NP/PP2QPB1/R1BNK2R b KQ - bm Nxd5; id "WAC.180"; r3k2r/2p2p2/p2p1n2/1p2p3/4P2p/1PPPPp1q/1P5P/R1N2QRK b kq - bm Ng4; id "WAC.181"; r1b2rk1/ppqn1p1p/2n1p1p1/2b3N1/2N5/PP1BP3/1B3PPP/R2QK2R w KQ - bm Qh5; id "WAC.182"; 1r2k1r1/5p2/b3p3/1p2b1B1/3p3P/3B4/PP2KP2/2R3R1 w - - bm Bf6; id "WAC.183"; 4kn2/r4p1r/p3bQ2/q1nNP1Np/1p5P/8/PPP3P1/2KR3R w - - bm Qe7+; id "WAC.184"; 1r1rb1k1/2p3pp/p2q1p2/3PpP1Q/Pp1bP2N/1B5R/1P4PP/2B4K w - - bm Qxh7+; id "WAC.185"; r5r1/p1q2p1k/1p1R2pB/3pP3/6bQ/2p5/P1P1NPPP/6K1 w - - bm Bf8+; id "WAC.186"; 6k1/5p2/p3p3/1p3qp1/2p1Qn2/2P1R3/PP1r1PPP/4R1K1 b - - bm Nh3+; id "WAC.187"; 3RNbk1/pp3p2/4rQpp/8/1qr5/7P/P4P2/3R2K1 w - - bm Qg7+; id "WAC.188"; 3r1k2/1ppPR1n1/p2p1rP1/3P3p/4Rp1N/5K2/P1P2P2/8 w - - bm Re8+; id "WAC.189"; 8/p2b2kp/1q1p2p1/1P1Pp3/4P3/3B2P1/P2Q3P/2Nn3K b - - bm Bh3; id "WAC.190"; 2r1Rn1k/1p1q2pp/p7/5p2/3P4/1B4P1/P1P1QP1P/6K1 w - - bm Qc4; id "WAC.191"; r3k3/ppp2Npp/4Bn2/2b5/1n1pp3/N4P2/PPP3qP/R2QKR2 b Qq - bm Nd3+; id "WAC.192"; 5bk1/p4ppp/Qp6/4B3/1P6/Pq2P1P1/2rr1P1P/R4RK1 b - - bm Qxe3; id "WAC.193"; 5rk1/ppq2ppp/2p5/4bN2/4P3/6Q1/PPP2PPP/3R2K1 w - - bm Nh6+; id "WAC.194"; 3r1rk1/1p3p2/p3pnnp/2p3p1/2P2q2/1P5P/PB2QPPN/3RR1K1 w - - bm g3; id "WAC.195"; rr4k1/p1pq2pp/Q1n1pn2/2bpp3/4P3/2PP1NN1/PP3PPP/R1B1K2R b KQ - bm Nb4; id "WAC.196"; 7k/1p4p1/7p/3P1n2/4Q3/2P2P2/PP3qRP/7K b - - bm Qf1+; id "WAC.197"; 2br2k1/ppp2p1p/4p1p1/4P2q/2P1Bn2/2Q5/PP3P1P/4R1RK b - - bm Rd3; id "WAC.198"; r1br2k1/pp2nppp/2n5/1B1q4/Q7/4BN2/PP3PPP/2R2RK1 w - - bm Bxc6 Rfd1; id "WAC.199"; 2rqrn1k/pb4pp/1p2pp2/n2P4/2P3N1/P2B2Q1/1B3PPP/2R1R1K1 w - - bm Bxf6; id "WAC.200"; 2b2r1k/4q2p/3p2pQ/2pBp3/8/6P1/1PP2P1P/R5K1 w - - bm Ra7; id "WAC.201"; QR2rq1k/2p3p1/3p1pPp/8/4P3/8/P1r3PP/1R4K1 b - - bm Rxa2; id "WAC.202"; r4rk1/5ppp/p3q1n1/2p2NQ1/4n3/P3P3/1B3PPP/1R3RK1 w - - bm Qh6; id "WAC.203"; r1b1qrk1/1p3ppp/p1p5/3Nb3/5N2/P7/1P4PQ/K1R1R3 w - - bm Rxe5; id "WAC.204"; r3rnk1/1pq2bb1/p4p2/3p1Pp1/3B2P1/1NP4R/P1PQB3/2K4R w - - bm Qxg5; id "WAC.205"; 1Qq5/2P1p1kp/3r1pp1/8/8/7P/p4PP1/2R3K1 b - - bm Rc6; id "WAC.206"; r1bq2kr/p1pp1ppp/1pn1p3/4P3/2Pb2Q1/BR6/P4PPP/3K1BNR w - - bm Qxg7+; id "WAC.207"; 3r1bk1/ppq3pp/2p5/2P2Q1B/8/1P4P1/P6P/5RK1 w - - bm Bf7+; id "WAC.208"; 4kb1r/2q2p2/r2p4/pppBn1B1/P6P/6Q1/1PP5/2KRR3 w k - bm Rxe5+; id "WAC.209"; 3r1rk1/pp1q1ppp/3pn3/2pN4/5PP1/P5PQ/1PP1B3/1K1R4 w - - bm Rh1; id "WAC.210"; r1bqrk2/pp1n1n1p/3p1p2/P1pP1P1Q/2PpP1NP/6R1/2PB4/4RBK1 w - - bm Qxf7+; id "WAC.211"; rn1qr2Q/pbppk1p1/1p2pb2/4N3/3P4/2N5/PPP3PP/R4RK1 w - - bm Qxg7+; id "WAC.212"; 3r1r1k/1b4pp/ppn1p3/4Pp1R/Pn5P/3P4/4QP2/1qB1NKR1 w - - bm Rxh7+; id "WAC.213"; r2r2k1/1p2qpp1/1np1p1p1/p3N3/2PPN3/bP5R/4QPPP/4R1K1 w - - bm Ng5; id "WAC.214"; 3r2k1/pb1q1pp1/1p2pb1p/8/3N4/P2QB3/1P3PPP/1Br1R1K1 w - - bm Qh7+; id "WAC.215"; r2qr1k1/1b1nbppp/p3pn2/1p1pN3/3P1B2/2PB1N2/PP2QPPP/R4RK1 w - - bm Nxf7; id "WAC.216"; r3kb1r/1pp3p1/p3bp1p/5q2/3QN3/1P6/PBP3P1/3RR1K1 w kq - bm Qd7+; id "WAC.217"; 6k1/pp5p/2p3q1/6BP/2nPr1Q1/8/PP3R1K/8 w - - bm Bh6; id "WAC.218"; 7k/p4q1p/1pb5/2p5/4B2Q/2P1B3/P6P/7K b - - bm Qf1+; id "WAC.219"; 3rr1k1/ppp2ppp/8/5Q2/4n3/1B5R/PPP1qPP1/5RK1 b - - bm Qxf1+; id "WAC.220"; r3k3/P5bp/2N1bp2/4p3/2p5/6NP/1PP2PP1/3R2K1 w q - bm Rd8+; id "WAC.221"; 2r1r2k/1q3ppp/p2Rp3/2p1P3/6QB/p3P3/bP3PPP/3R2K1 w - - bm Bf6; id "WAC.222"; r1bqk2r/pp3ppp/5n2/8/1b1npB2/2N5/PP1Q2PP/1K2RBNR w kq - bm Nxe4; id "WAC.223"; 5rk1/p1q3pp/1p1r4/2p1pp1Q/1PPn1P2/3B3P/P2R2P1/3R2K1 b - - bm Rh6 e4; id "WAC.224"; 4R3/4q1kp/6p1/1Q3b2/1P1b1P2/6KP/8/8 b - - bm Qh4+; id "WAC.225"; 2b2rk1/p1p4p/2p1p1p1/br2N1Q1/1p2q3/8/PB3PPP/3R1RK1 w - - bm Nf7; id "WAC.226"; 2k1rb1r/ppp3pp/2np1q2/5b2/2B2P2/2P1BQ2/PP1N1P1P/2KR3R b - - bm d5; id "WAC.227"; r4rk1/1bq1bp1p/4p1p1/p2p4/3BnP2/1N1B3R/PPP3PP/R2Q2K1 w - - bm Bxe4; id "WAC.228"; 8/8/8/1p5r/p1p1k1pN/P2pBpP1/1P1K1P2/8 b - - bm Rxh4 b4; id "WAC.229"; 2b5/1r6/2kBp1p1/p2pP1P1/2pP4/1pP3K1/1R3P2/8 b - - bm Rb4; id "WAC.230"; r4rk1/1b1nqp1p/p5p1/1p2PQ2/2p5/5N2/PP3PPP/R1BR2K1 w - - bm Bg5; id "WAC.231"; 1R2rq1k/2p3p1/Q2p1pPp/8/4P3/8/P1r3PP/1R4K1 w - - bm Qb5 Rxe8; id "WAC.232"; 5rk1/p1p2r1p/2pp2p1/4p3/PPPnP3/3Pq1P1/1Q1R1R1P/4NK2 b - - bm Nb3; id "WAC.233"; 2kr1r2/p6p/5Pp1/2p5/1qp2Q1P/7R/PP6/1KR5 w - - bm Rb3; id "WAC.234"; 5r2/1p1RRrk1/4Qq1p/1PP3p1/8/4B3/1b3P1P/6K1 w - - bm Qxf7+ Rxf7+; id "WAC.235"; 1R6/p5pk/4p2p/4P3/8/2r3qP/P3R1b1/4Q1K1 b - - bm Rc1; id "WAC.236"; r5k1/pQp2qpp/8/4pbN1/3P4/6P1/PPr4P/1K1R3R b - - bm Rc1+; id "WAC.237"; 1k1r4/pp1r1pp1/4n1p1/2R5/2Pp1qP1/3P2QP/P4PB1/1R4K1 w - - bm Bxb7; id "WAC.238"; 8/6k1/5pp1/Q6p/5P2/6PK/P4q1P/8 b - - bm Qf1+; id "WAC.239"; 2b4k/p1b2p2/2p2q2/3p1PNp/3P2R1/3B4/P1Q2PKP/4r3 w - - bm Qxc6; id "WAC.240"; 2rq1rk1/pp3ppp/2n2b2/4NR2/3P4/PB5Q/1P4PP/3R2K1 w - - bm Qxh7+; id "WAC.241"; r1b1r1k1/pp1nqp2/2p1p1pp/8/4N3/P1Q1P3/1P3PPP/1BRR2K1 w - - bm Rxd7; id "WAC.242"; 1r3r1k/3p4/1p1Nn1R1/4Pp1q/pP3P1p/P7/5Q1P/6RK w - - bm Qe2; id "WAC.243"; r6r/pp3ppp/3k1b2/2pb4/B4Pq1/2P1Q3/P5PP/1RBR2K1 w - - bm Qxc5+; id "WAC.244"; 4rrn1/ppq3bk/3pPnpp/2p5/2PB4/2NQ1RPB/PP5P/5R1K w - - bm Qxg6+; id "WAC.245"; 6R1/4qp1p/ppr1n1pk/8/1P2P1QP/6N1/P4PP1/6K1 w - - bm Qh5+; id "WAC.246"; 2k1r3/1p2Bq2/p2Qp3/Pb1p1p1P/2pP1P2/2P5/2P2KP1/1R6 w - - bm Rxb5; id "WAC.247"; 5r1k/1p4pp/3q4/3Pp1R1/8/8/PP4PP/4Q1K1 b - - bm Qc5+; id "WAC.248"; r4rk1/pbq2pp1/1ppbpn1p/8/2PP4/1P1Q1N2/PBB2PPP/R3R1K1 w - - bm c5 d5; id "WAC.249"; 1b5k/7P/p1p2np1/2P2p2/PP3P2/4RQ1R/q2r3P/6K1 w - - bm Re8+; id "WAC.250"; k7/p4p2/P1q1b1p1/3p3p/3Q4/7P/5PP1/1R4K1 w - - bm Qe5 Qf4; id "WAC.251"; 1rb1r1k1/p1p2ppp/5n2/2pP4/5P2/2QB4/qNP3PP/2KRB2R b - - bm Re2; id "WAC.252"; k5r1/p4b2/2P5/5p2/3P1P2/4QBrq/P5P1/4R1K1 w - - bm Qe8+; id "WAC.253"; r6k/pp3p1p/2p1bp1q/b3p3/4Pnr1/2PP2NP/PP1Q1PPN/R2B2RK b - - bm Nxh3; id "WAC.254"; 3r3r/p4pk1/5Rp1/3q4/1p1P2RQ/5N2/P1P4P/2b4K w - - bm Rfxg6+; id "WAC.255"; 3r1rk1/1pb1qp1p/2p3p1/p7/P2Np2R/1P5P/1BP2PP1/3Q1BK1 w - - bm Nf5; id "WAC.256"; 4r1k1/pq3p1p/2p1r1p1/2Q1p3/3nN1P1/1P6/P1P2P1P/3RR1K1 w - - bm Rxd4; id "WAC.257"; r3brkn/1p5p/2p2Ppq/2Pp3B/3Pp2Q/4P1R1/6PP/5R1K w - - bm Bxg6; id "WAC.258"; r1bq1rk1/ppp2ppp/2np4/2bN1PN1/2B1P3/3p4/PPP2nPP/R1BQ1K1R w - - bm Qh5; id "WAC.259"; 2r2b1r/p1Nk2pp/3p1p2/N2Qn3/4P3/q6P/P4PP1/1R3K1R w - - bm Qe6+; id "WAC.260"; r5k1/1bp3pp/p2p4/1p6/5p2/1PBP1nqP/1PP3Q1/R4R1K b - - bm Nd4; id "WAC.261"; 6k1/p1B1b2p/2b3r1/2p5/4p3/1PP1N1Pq/P2R1P2/3Q2K1 b - - bm Rh6; id "WAC.262"; rnbqr2k/pppp1Qpp/8/b2NN3/2B1n3/8/PPPP1PPP/R1B1K2R w KQ - bm Qg8+; id "WAC.263"; r2r2k1/1R2qp2/p5pp/2P5/b1PN1b2/P7/1Q3PPP/1B1R2K1 b - - bm Rab8; id "WAC.264"; 2r1k2r/2pn1pp1/1p3n1p/p3PP2/4q2B/P1P5/2Q1N1PP/R4RK1 w k - bm exf6; id "WAC.265"; r3q2r/2p1k1p1/p5p1/1p2Nb2/1P2nB2/P7/2PNQbPP/R2R3K b - - bm Rxh2+; id "WAC.266"; 2r1kb1r/pp3ppp/2n1b3/1q1N2B1/1P2Q3/8/P4PPP/3RK1NR w Kk - bm Nc7+; id "WAC.267"; 2r3kr/ppp2n1p/7B/5q1N/1bp5/2Pp4/PP2RPPP/R2Q2K1 w - - bm Re8+; id "WAC.268"; 2kr2nr/pp1n1ppp/2p1p3/q7/1b1P1B2/P1N2Q1P/1PP1BPP1/R3K2R w KQ - bm axb4; id "WAC.269"; 2r1r1k1/pp1q1ppp/3p1b2/3P4/3Q4/5N2/PP2RPPP/4R1K1 w - - bm Qg4; id "WAC.270"; 2kr4/ppp3Pp/4RP1B/2r5/5P2/1P6/P2p4/3K4 w - - bm Rd6; id "WAC.271"; nrq4r/2k1p3/1p1pPnp1/pRpP1p2/P1P2P2/2P1BB2/1R2Q1P1/6K1 w - - bm Bxc5; id "WAC.272"; 2k4B/bpp1qp2/p1b5/7p/1PN1n1p1/2Pr4/P5PP/R3QR1K b - - bm Ng3+; id "WAC.273"; 8/1p6/p5R1/k7/Prpp4/K7/1NP5/8 w - - bm Rb6; id "WAC.274"; r1b2rk1/1p1n1ppp/p1p2q2/4p3/P1B1Pn2/1QN2N2/1P3PPP/3R1RK1 b - - bm Nxg2 b5; id "WAC.275"; r5k1/pp1RR1pp/1b6/6r1/2p5/B6P/P4qPK/3Q4 w - - bm Qd5+; id "WAC.276"; 1r4r1/p2kb2p/bq2p3/3p1p2/5P2/2BB3Q/PP4PP/3RKR2 b - - bm Rg3 Rxg2; id "WAC.277"; r2qkb1r/pppb2pp/2np1n2/5pN1/2BQP3/2N5/PPP2PPP/R1B1K2R w KQkq - bm Bf7+; id "WAC.278"; r7/4b3/2p1r1k1/1p1pPp1q/1P1P1P1p/PR2NRpP/2Q3K1/8 w - - bm Nxf5; id "WAC.279"; r1r2bk1/5p1p/pn4p1/N2b4/3Pp3/B3P3/2q1BPPP/RQ3RK1 b - - bm Bxa3; id "WAC.280"; 2R5/2R4p/5p1k/6n1/8/1P2QPPq/r7/6K1 w - - bm Rxh7+; id "WAC.281"; 6k1/2p3p1/1p1p1nN1/1B1P4/4PK2/8/2r3b1/7R w - - bm Rh8+; id "WAC.282"; 3q1rk1/4bp1p/1n2P2Q/3p1p2/6r1/Pp2R2N/1B4PP/7K w - - bm Ng5; id "WAC.283"; 3r3k/pp4pp/8/1P6/3N4/Pn2P1qb/1B1Q2B1/2R3K1 w - - bm Nf5; id "WAC.284"; 2rr3k/1b2bppP/p2p1n2/R7/3P4/1qB2P2/1P4Q1/1K5R w - - bm Qxg7+; id "WAC.285"; 3r1k2/1p6/p4P2/2pP2Qb/8/1P1KB3/P6r/8 b - - bm Rxd5+; id "WAC.286"; rn3k1r/pp2bBpp/2p2n2/q5N1/3P4/1P6/P1P3PP/R1BQ1RK1 w - - bm Qh5; id "WAC.287"; r1b2rk1/p4ppp/1p1Qp3/4P2N/1P6/8/P3qPPP/3R1RK1 w - - bm Nf6+; id "WAC.288"; 2r3k1/5p1p/p3q1p1/2n3P1/1p1QP2P/1P4N1/PK6/2R5 b - - bm Qe5; id "WAC.289"; 2k2r2/2p5/1pq5/p1p1n3/P1P2n1B/1R4Pp/2QR4/6K1 b - - bm Ne2+; id "WAC.290"; 5r1k/3b2p1/p6p/1pRpR3/1P1P2q1/P4pP1/5QnP/1B4K1 w - - bm h3; id "WAC.291"; 4r3/1Q1qk2p/p4pp1/3Pb3/P7/6PP/5P2/4R1K1 w - - bm d6+; id "WAC.292"; 1nbq1r1k/3rbp1p/p1p1pp1Q/1p6/P1pPN3/5NP1/1P2PPBP/R4RK1 w - - bm Nfg5; id "WAC.293"; 3r3k/1r3p1p/p1pB1p2/8/p1qNP1Q1/P6P/1P4P1/3R3K w - - bm Bf8 Nf5 Qf4; id "WAC.294"; 4r3/p4r1p/R1p2pp1/1p1bk3/4pNPP/2P1K3/2P2P2/3R4 w - - bm Rxd5+; id "WAC.295"; 3r4/1p2k2p/p1b1p1p1/4Q1Pn/2B3KP/4pP2/PP2R1N1/6q1 b - - bm Rd4+ Rf8; id "WAC.296"; 3r1rk1/p3qp1p/2bb2p1/2p5/3P4/1P6/PBQN1PPP/2R2RK1 b - - bm Bxg2 Bxh2+; id "WAC.297"; 3Q4/p3b1k1/2p2rPp/2q5/4B3/P2P4/7P/6RK w - - bm Qh8+; id "WAC.298"; 1n2rr2/1pk3pp/pNn2p2/2N1p3/8/6P1/PP2PPKP/2RR4 w - - bm Nca4; id "WAC.299"; b2b1r1k/3R1ppp/4qP2/4p1PQ/4P3/5B2/4N1K1/8 w - - bm g6; id "WAC.300"; sjeng-11.2.orig/README0100644000175000017500000002533507412717631013423 0ustar lukaslukasWhat is Sjeng ? --------------- Sjeng is a chessprogram that plays many variants. In addition to that, it can also play normal chess quite well and is fully compatible with the standard XBoard/WinBoard protocol (version 1 and 2). Sjeng also supports some broken WinBoard implementations, such as the one present in the ChessBase/Fritz WinBoard adapter. Technically, Sjeng is a highly advanced alpha-beta searcher, using modern techniques like history and killer moves, transposition tables, SEE move ordering and pruning, and search enhancements like selective extensions, Aspiration Principal Variation Search, Adaptive nullmove pruning, Extended Futility Pruning and Limited Razoring. Sjeng can use an opening book and learns from the games it plays. In it's suicide and losers mode, Sjeng use proof-number searches to quickly find forced wins. Sjeng plays at the same level that the best humans are capable of. On 14th of October 2000, Sjeng won it's first title by becoming the World Computer Crazyhouse Chess Champion. On December 31th 2000, Sjeng became the first computer program to reach the #1 spot on the crazyhouse rating list on the Free Internet Chess Server. It had been #1 on the Internet Chess Club before. Early 2001 Sjeng became the #1 losers/giveaway player on the Internet Chess Club. What variants are supported ? ----------------------------- Sjeng currently plays standard chess, crazyhouse, bughouse, suicide (aka giveaway or anti-chess) and losers. It can also play variants which have the same rules as normal chess, but a different starting position. How do I get it to work ? ------------------------- Building it ----------- GNU/Linux, FreeBSD, other Un*x variants: ---------------------------------------- Building Sjeng should be as simple as: ./configure make (su to root if needed) make install If you notice Sjeng is only reporting time in full second increments, edit config.h and change #define HAVE_FTIME into #undef HAVE_FTIME. Windows ------- I have succesfully compiled Sjeng with Microsoft Visual C++. Other compilers are not tested, but may also work. The easiest way is to locate a Windows port of Sjeng's sources, which you can compile out-of-the-box. If those are not available, follow these instructions: You need to find a Windows port of the GDBM library. There are several (free) ones available on the internet. You will have to create a config.h file which contains #define HAVE_SYS_TIMEB_H #define HAVE_FTIME #define VERSION "11.2" You may have to define _WIN32 also, if your compiler doesn't already do so. You also need an implementation of the strcasecmp function. An implementation is available in the file strcasec.c in the DJGPP distribution. Alternatively you can use the Cygnus utilities. I have never used them myself so I cannot help you there, but I have had reports from users which successfully built Sjeng with it. The opening books ----------------- Sjeng uses two kind of books: .opn books and binary books The .opn books are intended to be created manually, and are ideal for getting Sjeng to play your favorite openings. Some examples are in the books directory. To use a .opn book, just copy it to the same directory where you are running Sjeng from. Sjeng will always look in the .opn book first and will never apply learning to it. The binary books are created automatically from PGN databases, by a built-in bookbuilder. To use it, just start Sjeng and enter 'book'. To generate a crazyhouse/bughouse book, first type 'variant crazyhouse', then type 'book'. ('losers' and 'suicide' are also supported) Be sure to make the keycache large enough or the book-generation will be slow and you will end up with very large files. One byte in the keycache is enough for one position. The keycache is stored in RAM, so do not make it bigger than the actual amount of RAM you have. You need about 12 bytes diskspace per position that will be stored. You must use a pure PGN database. PGN derivates like BPGN are not (yet) supported, nor is the psuedo-PGN that some other programs output. I recommend running your PGN database through the 'Extract' program by David Barnes first. It has options to strip variantions, comments and NAG's and to suppress duplicates which will significantly speed up the bookbuilding process, as well as getting rid of any psuedo-SAN. A PGN database of some high-quality crazyhouse games is available at ftp://sjeng.sourceforge.net/pub/sjeng/zhbook.pgn Getting an interface -------------------- You can start Sjeng now by typing 'sjeng', but you will probably find the text-based interface unpleasant. The recommended interface for playing standard chess with Sjeng is WinBoard/XBoard, by Tim Mann. http://www.tim-mann.org/xboard.html You will need to start WinBoard/xboard with the -variant option to play bughouse, crazyhouse, suicide or losers. If you need more help with WinBoard/xboard read its documentation. If you want to let Sjeng play on a chess server, be sure to read zippy.README Zon Juan Jan wrote a Windows interface for crazyhouse-playing programs that can be used with Sjeng. Go to http://bughouse.net and look in the downloads section. The program is called Zhouse Challenger. It works nicely and I can recommend it a lot! There is an alternate download at: http://www.d2d4.de/download/zchall-sfx.exe EBoard is a chess interface for POSIX systems (GNU/Linux, FreeBSD, etc.) based on the GTK+ GUI toolkit. It is available on http://eboard.sourceforge.net/ and has extensive support for Sjeng. Generating endgame databases ------------------------- Sjeng support endgame databases for the suicide variant. You can generate them as follows: 1) Make a subdirectory named 'stb' in Sjeng's directory 2) Start Sjeng form the command line and issue the command 'buildegtb' This will take an hour or so, depending on the speed of your computer. Tuning Sjeng ------------ A great deal Sjeng's workings can be customized without recompiling it. You should take a look at sjeng.rc and adjust the parameters to your likings. Especially the first three are imporant because they control how much memory Sjeng will use for transposition tables and caches. If those are set too big for your RAM, Sjeng will crash. Benchmarking ------------ As a little test of your computer's speed, you can start Sjeng and give the 'speed' command. This will run a little benchmark of the most commonly-used functions in Sjeng. Running testsuites ------------------ Sjeng can automatically run testsuites by use of the 'test' command. Input data is expected to be in EPD format with either a 'best move' (bm) or 'avoid move' (am) tag. Some testsuites are included in the 'tests' directory of the Sjeng distribution. Getting more info ----------------- For more info about Sjeng, you can visit the homepage http://www.sjeng.org/ If you are in need of info about Sjeng's internal workings, send me a mail at gcp@sjeng.org Reporting bugs -------------- If you spot a bug, or Sjeng crashes on you, please send email to gcp@sjeng.org Please try to provide an accurate description of the problem and, if possible, how to reproduce it. Starting XBoard/WinBoard with the -debug option will produce debug output (either on screen or in a winboard.debug file) that can help a lot in tracking down the problem. Copying/Distribution -------------------- Sjeng is Free Software and is licensed under the GNU General Public License. For more details see the file COPYING that comes with Sjeng. If this file is missing, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sjeng should have come with source code, or you should have been given the possibility to obtain it for a charge no more than the cost of physically performing the source distribution. If not, please contact gcp@sjeng.org. Sjeng includes tablebase accessing code written by Andrew Kadatch and Eugene Nalimov. This code is contained in the files tbindex.cpp and tbdecode.h and is copyrighted by them, all rights reserved. This code does _not_ fall under the GPL. You are hereby given the additional right to compile and link Sjeng with this code, as well as to distribute the resulting executable and code under the conditions of the GPL, except for the files tbindex.cpp and tbdecode.h, which do not fall under the GPL, but may also be distributed together with Sjeng. The author regrets having to include this non-free code with Sjeng, but no free replacement of the same quality is availble yet. What is bughouse ? ------------------ Bughouse is a form of chess which is played with 2 teams, each consisting of 2 players. Each player plays his opponent on a seperate board. If a piece is captured, the capturing player can pass it on to his partner, who can then drop the piece into his game and use it. If you have never played bughouse before, you are really missing out on something. Try it, you'll like it. for a more complete description of the rules: http://matador.unige.ch/nabla/Bug/rules.html What is crazyhouse ? -------------------- Crazyhouse is similar to bughouse, but is played with only 2 players, on 1 board. What is suicide/giveaway/anti-chess ? ------------------------------------- Suicide is a form of chess where the goal is to lose all your pieces. Your king acts like a normal piece and can be captured, and you can promote pawns to a king. If you can capture, you must. Suicide is sometimes referred to as giveaway or anti-chess, although there are minor differences between variants. In suicide, castling is not allowed, but in giveaway it is. If a player is stalemated, he loses in giveaway, but in suicide he wins if he has less material than his opponent. What is losers ? ---------------- Losers is similar to suicide with the exception that the king may not be captured, you cannot promote pawns to kings, and if you are checkmated you win. Where can I play bughouse ? ---------------------------- The most common place to play bughouse is the Free Internet Chess Server (FICS). Most important chess servers also offer it, like the Internet Chess Club. http://www.freechess.org http://www.chessclub.com Or even better, gather a few friends, 2 chessboards, 2 clocks, some beer, and have fun beating each other ;) -- last revised 2001-12-27 -- gcp@sjeng.org -- sjeng-11.2.orig/learn.c0100644000175000017500000000637307355046565014020 0ustar lukaslukas/* Sjeng - a chess variants playing program Copyright (C) 2000 Gian-Carlo Pascutto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA File: learn.c Purpose: remembering of positions */ #include "sjeng.h" #include "protos.h" #include "extvars.h" typedef struct { signed Depth:7; unsigned OnMove:1; unsigned char Bestmove; unsigned long Hash; unsigned long Hold_hash; signed long Bound; } LearnType; void Learn(int score, int best, int depth) { int number = 0, next = 0; LearnType draft; FILE **lrnfile; printf("Learning score: %d best: %d depth:%d hash: %X\n", score, best, depth, hash); if (Variant == Normal) { lrnfile = &lrn_standard; } else if ((Variant == Crazyhouse) || (Variant == Bughouse)) { lrnfile = &lrn_zh; } else if (Variant == Suicide) { lrnfile = &lrn_suicide; } else if (Variant == Losers) { lrnfile = &lrn_losers; } else return; fseek(*lrnfile, 0, SEEK_SET); fread(&number, sizeof(int), 1, *lrnfile); fread(&next, sizeof(int), 1, *lrnfile); if (number < 50000) number++; fseek(*lrnfile, 0, SEEK_SET); fwrite(&number, sizeof(int), 1, *lrnfile); next++; if (next == 50000) next = 1; fwrite(&next, sizeof(int), 1, *lrnfile); fseek(*lrnfile, (2*sizeof(int)) + ((next-1)*sizeof(LearnType)), SEEK_SET); draft.Depth = depth; draft.OnMove = ToMove; draft.Hash = hash; draft.Hold_hash = hold_hash; draft.Bound = score; draft.Bestmove = best; fwrite(&draft, sizeof(draft), 1, *lrnfile); fflush(*lrnfile); } void LoadLearn(void) { int number = 0, posloop; LearnType draft; FILE **lrnfile; if (((Variant == Crazyhouse) || (Variant == Bughouse)) && (!lrn_zh)) return; else if ((Variant == Normal) && !lrn_standard) return; else if (Variant == Suicide && !lrn_suicide) return; else if (Variant == Losers && !lrn_losers) return; if (Variant == Normal) { lrnfile = &lrn_standard; } else if ((Variant == Crazyhouse) || (Variant == Bughouse)) { lrnfile = &lrn_zh; } else if (Variant == Suicide) { lrnfile = &lrn_suicide; } else if (Variant == Losers) { lrnfile = &lrn_losers; } fseek(*lrnfile, 0, SEEK_SET); fread(&number, sizeof(int), 1, *lrnfile); fseek(*lrnfile, 2*sizeof(int), SEEK_SET); for (posloop = 0; posloop < number; posloop++) { fread(&draft, sizeof(LearnType), 1, *lrnfile); LearnStoreTT(draft.Bound, draft.Hash, draft.Hold_hash, draft.OnMove, draft.Bestmove, draft.Depth); } return; } sjeng-11.2.orig/THANKS0100644000175000017500000000065407307525305013451 0ustar lukaslukasThe following people helped a lot during Sjeng development, either by testing, giving usefull suggestions or contributing code: Adrien Regimbald Daniel Clausen Dann Corbit Lenny Taelman David Dawson Ben Nye (aka angrim@FICS) Ronald De Man (aka Syzygy@FICS) Eugene Nalimov sjeng-11.2.orig/configure0100755000175000017500000017431107412717722014452 0ustar lukaslukas#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated automatically using autoconf version 2.13 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. # Defaults: ac_help= ac_default_prefix=/usr/local # Any additions from configure.in: # Initialize some variables set by options. # The variables have the same names as the options, with # dashes changed to underlines. build=NONE cache_file=./config.cache exec_prefix=NONE host=NONE no_create= nonopt=NONE no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= target=NONE verbose= x_includes=NONE x_libraries=NONE bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' # Initialize some other variables. subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. ac_max_here_lines=12 ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi case "$ac_option" in -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; *) ac_optarg= ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case "$ac_option" in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir="$ac_optarg" ;; -build | --build | --buil | --bui | --bu) ac_prev=build ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build="$ac_optarg" ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file="$ac_optarg" ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir="$ac_optarg" ;; -disable-* | --disable-*) ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` eval "enable_${ac_feature}=no" ;; -enable-* | --enable-*) ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "enable_${ac_feature}='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix="$ac_optarg" ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he) # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat << EOF Usage: configure [options] [host] Options: [defaults in brackets after descriptions] Configuration: --cache-file=FILE cache test results in FILE --help print this message --no-create do not create output files --quiet, --silent do not print \`checking...' messages --version print the version of autoconf that created configure Directory and file names: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [same as prefix] --bindir=DIR user executables in DIR [EPREFIX/bin] --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] --libexecdir=DIR program executables in DIR [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data in DIR [PREFIX/share] --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data in DIR [PREFIX/com] --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] --libdir=DIR object code libraries in DIR [EPREFIX/lib] --includedir=DIR C header files in DIR [PREFIX/include] --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] --infodir=DIR info documentation in DIR [PREFIX/info] --mandir=DIR man documentation in DIR [PREFIX/man] --srcdir=DIR find the sources in DIR [configure dir or ..] --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names EOF cat << EOF Host type: --build=BUILD configure for building on BUILD [BUILD=HOST] --host=HOST configure for HOST [guessed] --target=TARGET configure for TARGET [TARGET=HOST] Features and packages: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR EOF if test -n "$ac_help"; then echo "--enable and --with options recognized:$ac_help" fi exit 0 ;; -host | --host | --hos | --ho) ac_prev=host ;; -host=* | --host=* | --hos=* | --ho=*) host="$ac_optarg" ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir="$ac_optarg" ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir="$ac_optarg" ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir="$ac_optarg" ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir="$ac_optarg" ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir="$ac_optarg" ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir="$ac_optarg" ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir="$ac_optarg" ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix="$ac_optarg" ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix="$ac_optarg" ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix="$ac_optarg" ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name="$ac_optarg" ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir="$ac_optarg" ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir="$ac_optarg" ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site="$ac_optarg" ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir="$ac_optarg" ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir="$ac_optarg" ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target="$ac_optarg" ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers) echo "configure generated by autoconf version 2.13" exit 0 ;; -with-* | --with-*) ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "with_${ac_package}='$ac_optarg'" ;; -without-* | --without-*) ac_package=`echo $ac_option|sed -e 's/-*without-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` eval "with_${ac_package}=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes="$ac_optarg" ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries="$ac_optarg" ;; -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } ;; *) if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then echo "configure: warning: $ac_option: invalid host type" 1>&2 fi if test "x$nonopt" != xNONE; then { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } fi nonopt="$ac_option" ;; esac done if test -n "$ac_prev"; then { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } fi trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 # File descriptor usage: # 0 standard input # 1 file creation # 2 errors and warnings # 3 some systems may open it to /dev/tty # 4 used on the Kubota Titan # 6 checking for... messages and results # 5 compiler messages saved in config.log if test "$silent" = yes; then exec 6>/dev/null else exec 6>&1 fi exec 5>./config.log echo "\ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. " 1>&5 # Strip out --no-create and --no-recursion so they do not pile up. # Also quote any args containing shell metacharacters. ac_configure_args= for ac_arg do case "$ac_arg" in -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) ac_configure_args="$ac_configure_args '$ac_arg'" ;; *) ac_configure_args="$ac_configure_args $ac_arg" ;; esac done # NLS nuisances. # Only set these to C if already set. These must not be set unconditionally # because not all systems understand e.g. LANG=C (notably SCO). # Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! # Non-C LC_CTYPE values break the ctype check. if test "${LANG+set}" = set; then LANG=C; export LANG; fi if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo > confdefs.h # A filename unique to this package, relative to the directory that # configure is in, which we can look for to find out if srcdir is correct. ac_unique_file=sjeng.c # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_prog=$0 ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } else { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } fi fi srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then echo "loading site script $ac_site_file" . "$ac_site_file" fi done if test -r "$cache_file"; then echo "loading cache $cache_file" . $cache_file else echo "creating cache $cache_file" > $cache_file fi ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross ac_exeext= ac_objext=o if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then ac_n= ac_c=' ' ac_t=' ' else ac_n=-n ac_c= ac_t= fi else ac_n= ac_c='\c' ac_t= fi ac_aux_dir= for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do if test -f $ac_dir/install-sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f $ac_dir/install.sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break fi done if test -z "$ac_aux_dir"; then { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } fi ac_config_guess=$ac_aux_dir/config.guess ac_config_sub=$ac_aux_dir/config.sub ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 echo "configure:557: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" for ac_dir in $PATH; do # Account for people who put trailing slashes in PATH elements. case "$ac_dir/" in /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do if test -f $ac_dir/$ac_prog; then if test $ac_prog = install && grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : else ac_cv_path_install="$ac_dir/$ac_prog -c" break 2 fi fi done ;; esac done IFS="$ac_save_IFS" fi if test "${ac_cv_path_install+set}" = set; then INSTALL="$ac_cv_path_install" else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. INSTALL="$ac_install_sh" fi fi echo "$ac_t""$INSTALL" 1>&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6 echo "configure:610: checking whether build environment is sane" >&5 # Just in case sleep 1 echo timestamp > conftestfile # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftestfile` fi if test "$*" != "X $srcdir/configure conftestfile" \ && test "$*" != "X conftestfile $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". { echo "configure: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" 1>&2; exit 1; } fi test "$2" = conftestfile ) then # Ok. : else { echo "configure: error: newly created file is older than distributed files! Check your system clock" 1>&2; exit 1; } fi rm -f conftest* echo "$ac_t""yes" 1>&6 if test "$program_transform_name" = s,x,x,; then program_transform_name= else # Double any \ or $. echo might interpret backslashes. cat <<\EOF_SED > conftestsed s,\\,\\\\,g; s,\$,$$,g EOF_SED program_transform_name="`echo $program_transform_name|sed -f conftestsed`" rm -f conftestsed fi test "$program_prefix" != NONE && program_transform_name="s,^,${program_prefix},; $program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s,\$\$,${program_suffix},; $program_transform_name" # sed with no file args requires a program. test "$program_transform_name" = "" && program_transform_name="s,x,x," echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 echo "configure:667: checking whether ${MAKE-make} sets \${MAKE}" >&5 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftestmake <<\EOF all: @echo 'ac_maketemp="${MAKE}"' EOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` if test -n "$ac_maketemp"; then eval ac_cv_prog_make_${ac_make}_set=yes else eval ac_cv_prog_make_${ac_make}_set=no fi rm -f conftestmake fi if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then echo "$ac_t""yes" 1>&6 SET_MAKE= else echo "$ac_t""no" 1>&6 SET_MAKE="MAKE=${MAKE-make}" fi PACKAGE=Sjeng-Free VERSION=11.2 if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; } fi cat >> confdefs.h <> confdefs.h <&6 echo "configure:713: checking for working aclocal" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. if (aclocal --version) < /dev/null > /dev/null 2>&1; then ACLOCAL=aclocal echo "$ac_t""found" 1>&6 else ACLOCAL="$missing_dir/missing aclocal" echo "$ac_t""missing" 1>&6 fi echo $ac_n "checking for working autoconf""... $ac_c" 1>&6 echo "configure:726: checking for working autoconf" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. if (autoconf --version) < /dev/null > /dev/null 2>&1; then AUTOCONF=autoconf echo "$ac_t""found" 1>&6 else AUTOCONF="$missing_dir/missing autoconf" echo "$ac_t""missing" 1>&6 fi echo $ac_n "checking for working automake""... $ac_c" 1>&6 echo "configure:739: checking for working automake" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. if (automake --version) < /dev/null > /dev/null 2>&1; then AUTOMAKE=automake echo "$ac_t""found" 1>&6 else AUTOMAKE="$missing_dir/missing automake" echo "$ac_t""missing" 1>&6 fi echo $ac_n "checking for working autoheader""... $ac_c" 1>&6 echo "configure:752: checking for working autoheader" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. if (autoheader --version) < /dev/null > /dev/null 2>&1; then AUTOHEADER=autoheader echo "$ac_t""found" 1>&6 else AUTOHEADER="$missing_dir/missing autoheader" echo "$ac_t""missing" 1>&6 fi echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6 echo "configure:765: checking for working makeinfo" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. if (makeinfo --version) < /dev/null > /dev/null 2>&1; then MAKEINFO=makeinfo echo "$ac_t""found" 1>&6 else MAKEINFO="$missing_dir/missing makeinfo" echo "$ac_t""missing" 1>&6 fi # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:785: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="gcc" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:815: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_prog_rejected=no ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" break fi done IFS="$ac_save_ifs" if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# -gt 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift set dummy "$ac_dir/$ac_word" "$@" shift ac_cv_prog_CC="$@" fi fi fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then case "`uname -s`" in *win32* | *WIN32*) # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:866: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="cl" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi ;; esac fi test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 echo "configure:898: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext << EOF #line 909 "configure" #include "confdefs.h" main(){return(0);} EOF if { (eval echo configure:914: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then ac_cv_prog_cc_cross=no else ac_cv_prog_cc_cross=yes fi else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 ac_cv_prog_cc_works=no fi rm -fr conftest* ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 echo "configure:940: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 echo "configure:945: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no fi fi echo "$ac_t""$ac_cv_prog_gcc" 1>&6 if test $ac_cv_prog_gcc = yes; then GCC=yes else GCC= fi ac_test_CFLAGS="${CFLAGS+set}" ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 echo "configure:973: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo 'void f(){}' > conftest.c if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then ac_cv_prog_cc_g=yes else ac_cv_prog_cc_g=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 if test "$ac_test_CFLAGS" = set; then CFLAGS="$ac_save_CFLAGS" elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi for ac_prog in $CCC c++ g++ gcc CC cxx cc++ cl do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:1009: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CXX="$ac_prog" break fi done IFS="$ac_save_ifs" fi fi CXX="$ac_cv_prog_CXX" if test -n "$CXX"; then echo "$ac_t""$CXX" 1>&6 else echo "$ac_t""no" 1>&6 fi test -n "$CXX" && break done test -n "$CXX" || CXX="gcc" echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6 echo "configure:1041: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5 ac_ext=C # CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext << EOF #line 1052 "configure" #include "confdefs.h" int main(){return(0);} EOF if { (eval echo configure:1057: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cxx_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then ac_cv_prog_cxx_cross=no else ac_cv_prog_cxx_cross=yes fi else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 ac_cv_prog_cxx_works=no fi rm -fr conftest* ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6 if test $ac_cv_prog_cxx_works = no; then { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 echo "configure:1083: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6 cross_compiling=$ac_cv_prog_cxx_cross echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6 echo "configure:1088: checking whether we are using GNU C++" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.C <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gxx=yes else ac_cv_prog_gxx=no fi fi echo "$ac_t""$ac_cv_prog_gxx" 1>&6 if test $ac_cv_prog_gxx = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS="${CXXFLAGS+set}" ac_save_CXXFLAGS="$CXXFLAGS" CXXFLAGS= echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6 echo "configure:1116: checking whether ${CXX-g++} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo 'void f(){}' > conftest.cc if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then ac_cv_prog_cxx_g=yes else ac_cv_prog_cxx_g=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_prog_cxx_g" 1>&6 if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS="$ac_save_CXXFLAGS" elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi echo $ac_n "checking for gdbm_open in -lgdbm""... $ac_c" 1>&6 echo "configure:1149: checking for gdbm_open in -lgdbm" >&5 ac_lib_var=`echo gdbm'_'gdbm_open | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lgdbm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_lib=HAVE_LIB`echo gdbm | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` cat >> confdefs.h <&6 fi echo $ac_n "checking for floor in -lm""... $ac_c" 1>&6 echo "configure:1197: checking for floor in -lm" >&5 ac_lib_var=`echo m'_'floor | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_lib=HAVE_LIB`echo m | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` cat >> confdefs.h <&6 fi echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 echo "configure:1245: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else # This must be in double quotes, not single quotes, because CPP may get # substituted into the Makefile and "${CC-cc}" will confuse make. CPP="${CC-cc} -E" # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1266: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1283: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1300: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP=/lib/cpp fi rm -f conftest* fi rm -f conftest* fi rm -f conftest* ac_cv_prog_CPP="$CPP" fi CPP="$ac_cv_prog_CPP" else ac_cv_prog_CPP="$CPP" fi echo "$ac_t""$CPP" 1>&6 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 echo "configure:1325: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #include #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1338: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* ac_cv_header_stdc=yes else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "memchr" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "free" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') #define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF if { (eval echo configure:1405: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_header_stdc=no fi rm -fr conftest* fi fi fi echo "$ac_t""$ac_cv_header_stdc" 1>&6 if test $ac_cv_header_stdc = yes; then cat >> confdefs.h <<\EOF #define STDC_HEADERS 1 EOF fi for ac_hdr in sys/time.h sys/timeb.h unistd.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo "configure:1432: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1442: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done echo $ac_n "checking for working const""... $ac_c" 1>&6 echo "configure:1470: checking for working const" >&5 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; } ; return 0; } EOF if { (eval echo configure:1524: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_const=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_c_const=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_c_const" 1>&6 if test $ac_cv_c_const = no; then cat >> confdefs.h <<\EOF #define const EOF fi echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6 echo "configure:1545: checking whether time.h and sys/time.h may both be included" >&5 if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #include int main() { struct tm *tp; ; return 0; } EOF if { (eval echo configure:1559: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_time=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_time=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_header_time" 1>&6 if test $ac_cv_header_time = yes; then cat >> confdefs.h <<\EOF #define TIME_WITH_SYS_TIME 1 EOF fi echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6 echo "configure:1581: checking return type of signal handlers" >&5 if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #ifdef signal #undef signal #endif #ifdef __cplusplus extern "C" void (*signal (int, void (*)(int)))(int); #else void (*signal ()) (); #endif int main() { int i; ; return 0; } EOF if { (eval echo configure:1603: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_type_signal=void else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_type_signal=int fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_signal" 1>&6 cat >> confdefs.h <&6 echo "configure:1624: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:1652: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 fi done trap '' 1 2 15 cat > confcache <<\EOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs. It is not useful on other systems. # If it contains results you don't want to keep, you may remove or edit it. # # By default, configure uses ./config.cache as the cache file, # creating it if it does not exist already. You can give configure # the --cache-file=FILE option to use a different cache file; that is # what configure does when it calls configure scripts in # subdirectories, so they share the cache. # Giving --cache-file=/dev/null disables caching, for debugging configure. # config.status only pays attention to the cache file if you give it the # --recheck option to rerun configure. # EOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. (set) 2>&1 | case `(ac_space=' '; set | grep ac_space) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote substitution # turns \\\\ into \\, and sed turns \\ into \). sed -n \ -e "s/'/'\\\\''/g" \ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' ;; esac >> confcache if cmp -s $cache_file confcache; then : else if test -w $cache_file; then echo "updating cache $cache_file" cat confcache > $cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Any assignment to VPATH causes Sun make to only execute # the first set of double-colon rules, so remove it if not needed. # If there is a colon in the path, we need to keep it. if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' fi trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 DEFS=-DHAVE_CONFIG_H # Without the "./", some shells look in PATH for config.status. : ${CONFIG_STATUS=./config.status} echo creating $CONFIG_STATUS rm -f $CONFIG_STATUS cat > $CONFIG_STATUS </dev/null | sed 1q`: # # $0 $ac_configure_args # # Compiler output produced by configure, useful for debugging # configure, is in ./config.log if it exists. ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" for ac_option do case "\$ac_option" in -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) echo "$CONFIG_STATUS generated by autoconf version 2.13" exit 0 ;; -help | --help | --hel | --he | --h) echo "\$ac_cs_usage"; exit 0 ;; *) echo "\$ac_cs_usage"; exit 1 ;; esac done ac_given_srcdir=$srcdir ac_given_INSTALL="$INSTALL" trap 'rm -fr `echo "Makefile tests/Makefile books/Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 EOF cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF $ac_vpsub $extrasub s%@SHELL@%$SHELL%g s%@CFLAGS@%$CFLAGS%g s%@CPPFLAGS@%$CPPFLAGS%g s%@CXXFLAGS@%$CXXFLAGS%g s%@FFLAGS@%$FFLAGS%g s%@DEFS@%$DEFS%g s%@LDFLAGS@%$LDFLAGS%g s%@LIBS@%$LIBS%g s%@exec_prefix@%$exec_prefix%g s%@prefix@%$prefix%g s%@program_transform_name@%$program_transform_name%g s%@bindir@%$bindir%g s%@sbindir@%$sbindir%g s%@libexecdir@%$libexecdir%g s%@datadir@%$datadir%g s%@sysconfdir@%$sysconfdir%g s%@sharedstatedir@%$sharedstatedir%g s%@localstatedir@%$localstatedir%g s%@libdir@%$libdir%g s%@includedir@%$includedir%g s%@oldincludedir@%$oldincludedir%g s%@infodir@%$infodir%g s%@mandir@%$mandir%g s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g s%@INSTALL_DATA@%$INSTALL_DATA%g s%@PACKAGE@%$PACKAGE%g s%@VERSION@%$VERSION%g s%@ACLOCAL@%$ACLOCAL%g s%@AUTOCONF@%$AUTOCONF%g s%@AUTOMAKE@%$AUTOMAKE%g s%@AUTOHEADER@%$AUTOHEADER%g s%@MAKEINFO@%$MAKEINFO%g s%@SET_MAKE@%$SET_MAKE%g s%@CC@%$CC%g s%@CXX@%$CXX%g s%@CPP@%$CPP%g CEOF EOF cat >> $CONFIG_STATUS <<\EOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. ac_file=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_cmds # Line after last line for current file. ac_more_lines=: ac_sed_cmds="" while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file else sed "${ac_end}q" conftest.subs > conftest.s$ac_file fi if test ! -s conftest.s$ac_file; then ac_more_lines=false rm -f conftest.s$ac_file else if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f conftest.s$ac_file" else ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" fi ac_file=`expr $ac_file + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_cmds` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" # A "../" for each directory in $ac_dir_suffix. ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` else ac_dir_suffix= ac_dots= fi case "$ac_given_srcdir" in .) srcdir=. if test -z "$ac_dots"; then top_srcdir=. else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; *) # Relative path. srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" top_srcdir="$ac_dots$ac_given_srcdir" ;; esac case "$ac_given_INSTALL" in [/$]*) INSTALL="$ac_given_INSTALL" ;; *) INSTALL="$ac_dots$ac_given_INSTALL" ;; esac echo creating "$ac_file" rm -f "$ac_file" configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." case "$ac_file" in *Makefile*) ac_comsub="1i\\ # $configure_input" ;; *) ac_comsub= ;; esac ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` sed -e "$ac_comsub s%@configure_input@%$configure_input%g s%@srcdir@%$srcdir%g s%@top_srcdir@%$top_srcdir%g s%@INSTALL@%$INSTALL%g " $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file fi; done rm -f conftest.s* # These sed commands are passed to sed as "A NAME B NAME C VALUE D", where # NAME is the cpp macro being defined and VALUE is the value it is being given. # # ac_d sets the value in "#define NAME VALUE" lines. ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' ac_dC='\3' ac_dD='%g' # ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_uB='\([ ]\)%\1#\2define\3' ac_uC=' ' ac_uD='\4%g' # ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_eB='$%\1#\2define\3' ac_eC=' ' ac_eD='%g' if test "${CONFIG_HEADERS+set}" != set; then EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF fi for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac echo creating $ac_file rm -f conftest.frag conftest.in conftest.out ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` cat $ac_file_inputs > conftest.in EOF # Transform confdefs.h into a sed script conftest.vals that substitutes # the proper values into config.h.in to produce config.h. And first: # Protect against being on the right side of a sed subst in config.status. # Protect against being in an unquoted here document in config.status. rm -f conftest.vals cat > conftest.hdr <<\EOF s/[\\&%]/\\&/g s%[\\$`]%\\&%g s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp s%ac_d%ac_u%gp s%ac_u%ac_e%gp EOF sed -n -f conftest.hdr confdefs.h > conftest.vals rm -f conftest.hdr # This sed command replaces #undef with comments. This is necessary, for # example, in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. cat >> conftest.vals <<\EOF s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% EOF # Break up conftest.vals because some shells have a limit on # the size of here documents, and old seds have small limits too. rm -f conftest.tail while : do ac_lines=`grep -c . conftest.vals` # grep -c gives empty output for an empty file on some AIX systems. if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi # Write a limited-size here document to conftest.frag. echo ' cat > conftest.frag <> $CONFIG_STATUS sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS echo 'CEOF sed -f conftest.frag conftest.in > conftest.out rm -f conftest.in mv conftest.out conftest.in ' >> $CONFIG_STATUS sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail rm -f conftest.vals mv conftest.tail conftest.vals done rm -f conftest.vals cat >> $CONFIG_STATUS <<\EOF rm -f conftest.frag conftest.h echo "/* $ac_file. Generated automatically by configure. */" > conftest.h cat conftest.in >> conftest.h rm -f conftest.in if cmp -s $ac_file conftest.h 2>/dev/null; then echo "$ac_file is unchanged" rm -f conftest.h else # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" fi rm -f $ac_file mv conftest.h $ac_file fi fi; done EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h exit 0 EOF chmod +x $CONFIG_STATUS rm -fr confdefs* $ac_clean_files test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 sjeng-11.2.orig/leval.c0100644000175000017500000002362607344411125014004 0ustar lukaslukas/* Sjeng - a chess variants playing program Copyright (C) 2000-2001 Gian-Carlo Pascutto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA File: leval.c Purpose: functions for evaluating positions in losers chess */ #include "sjeng.h" #include "extvars.h" #include "protos.h" static int lcentral[144] = { 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,-20,-15,-15,-15,-15,-15,-15,-20,0,0, 0,0,-15,0,3,5,5,3,0,-15,0,0, 0,0,-15,0,15,15,15,15,0,-15,0,0, 0,0,-15,0,15,30,30,15,0,-15,0,0, 0,0,-15,0,15,30,30,15,0,-15,0,0, 0,0,-15,0,15,15,15,15,0,-15,0,0, 0,0,-15,0,3,5,5,3,0,-15,0,0, 0,0,-20,-15,-15,-15,-15,-15,-15,-20,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0}; static int l_bishop_mobility(int square) { register int l; register int m = 0; for (l = square-13; board[l] == npiece; l-=13) m++; for (l = square-11; board[l] == npiece; l-=11) m++; for (l = square+11; board[l] == npiece; l+=11) m++; for (l = square+13; board[l] == npiece; l+=13) m++; return m; } static int l_rook_mobility(int square) { register int l; register int m = 0; for (l = square-12; board[l] == npiece; l-=12) m++; for (l = square-1; board[l] == npiece; l-=1) m++; for (l = square+1; board[l] == npiece; l+=1) m++; for (l = square+12; board[l] == npiece; l+=12) m++; return m; } static int l_knight_mobility(int square) { static const int knight_o[8] = {10, -10, 14, -14, 23, -23, 25, -25}; register int d, m = 0; for (d = 0; d < 8; d++) { if (board[square + knight_o[d]] == npiece) m++; } return m; } static int l_pawn_mobility(int square) { register int m = 0; if (board[square] == wpawn) { if (board[square + 12] == npiece) m++; } else { if (board[square - 12] == npiece) m++; } return m; } static int l_king_mobility(int square) { static const int king_o[8] = {13, 12, 11, 1, -1, -11, -12, -13}; register int d, m = 0; for (d = 0; d < 8; d++) { if (board[square + king_o[d]] == npiece) m++; } return m; } long int losers_eval (void) { /* return a score for the current middlegame position: */ int srank, pawn_file, pawns[2][11], white_back_pawn[11], black_back_pawn[11]; int isolated, backwards; int i, a, j; long int score = 0; int in_cache; int wp = 0, bp = 0; int wks, bks; int wpassp = 0, bpassp = 0; int wpawns = 0, bpawns = 0; in_cache = 0; checkECache(&score, &in_cache); if(in_cache) { if (white_to_move == 1) return score; return -score; } /* initialize the pawns array, (files offset by one to use dummy files in order to easier determine isolated status) and also initialize the arrays keeping track of the rank of the most backward pawn: */ memset (pawns, 0, sizeof (pawns)); for (i = 0; i < 11; i++) { white_back_pawn[i] = 7; black_back_pawn[i] = 2; } for (j = 1, a = 1; (a <= piece_count); j++) { i = pieces[j]; if (!i) continue; else a++; assert((i > 0) && (i < 145)); pawn_file = file (i)+1; srank = rank (i); if (board[i] == wpawn) { pawns[1][pawn_file]++; if (srank < white_back_pawn[pawn_file]) { white_back_pawn[pawn_file] = srank; } } else if (board[i] == bpawn) { pawns[0][pawn_file]++; if (srank > black_back_pawn[pawn_file]) { black_back_pawn[pawn_file] = srank; } } } /* loop through the board, adding material value, as well as positional bonuses for all pieces encountered: */ for (j = 1, a = 1; (a <= piece_count); j++) { i = pieces[j]; if (!i) continue; else a++; switch (board[i]) { case (wpawn): wp++; wpawns++; score += lcentral[i]; score += l_pawn_mobility(i) << 2; score += (rank(i) - 2) * 8; isolated = FALSE; backwards = FALSE; /* check for backwards pawns: */ if (white_back_pawn[pawn_file+1] > srank && white_back_pawn[pawn_file-1] > srank) { score -= 8; backwards = TRUE; /* check to see if it is furthermore isolated: */ if (!pawns[1][pawn_file+1] && !pawns[1][pawn_file-1]) { score -= 12; isolated = TRUE; } } /* give weak, exposed pawns a penalty (not as much as in the midgame, since there may be no pieces to take advantage of it): */ if (!pawns[0][pawn_file]) { if (backwards) score -= 5; if (isolated) score -= 8; } /* give doubled, trippled, etc.. pawns a penalty (bigger in the endgame, since they will become big targets): */ if (pawns[1][pawn_file] > 1) score -= 8*(pawns[1][pawn_file]-1); /* give bonuses for passed pawns (bigger in the endgame since passed pawns are what wins the endgame): */ if (!pawns[0][pawn_file] && srank >= black_back_pawn[pawn_file-1] && srank >= black_back_pawn[pawn_file+1]) { score += 25 + 10*(rank(i)-2); if (rank(i) == 7) score += 50; wpassp++; /* outside passer ? */ if (file(i) == 1 || file(i) == 8) score += 4 + 2*(rank(i)-2); /* give an extra bonus if a connected, passed pawn: */ if (!isolated) { score += 24; } } /* check for pawn islands */ if (!pawns[1][pawn_file-1]) score -= 5; break; case (bpawn): bp++; bpawns++; score -= lcentral[i]; score -= l_pawn_mobility(i) << 2; score -= (7 - rank(i)) * 8; isolated = FALSE; backwards = FALSE; /* in general, bonuses/penalties in the endgame evaluation will be higher, since pawn structure becomes more important for the creation of passed pawns */ /* check for backwards pawns: */ if (black_back_pawn[pawn_file+1] < srank && black_back_pawn[pawn_file-1] < srank) { score += 8; backwards = TRUE; /* check to see if it is furthermore isolated: */ if (!pawns[0][pawn_file+1] && !pawns[0][pawn_file-1]) { score += 12; isolated = TRUE; } } /* give weak, exposed pawns a penalty (not as much as in the midgame, since there may be no pieces to take advantage of it): */ if (!pawns[1][pawn_file]) { if (backwards) score += 5; if (isolated) score += 8; } /* give doubled, trippled, etc.. pawns a penalty (bigger in the endgame, since they will become big targets): */ if (pawns[0][pawn_file] > 1) score += 8*(pawns[0][pawn_file]-1); /* give bonuses for passed pawns (bigger in the endgame since passed pawns are what wins the endgame): */ if (!pawns[1][pawn_file] && srank <= white_back_pawn[pawn_file-1] && srank <= white_back_pawn[pawn_file+1]) { score -= 25 + 10*(7-rank(i)); if (rank(i) == 2) score -= 50; bpassp++; /* outside passer ? */ if (file(i) == 1 || file(i) == 8) score -= 4 + 2*(7-rank(i)); /* give an extra bonus if a connected, passed pawn: */ if (!isolated) { score -= 24; } } if (!pawns[0][pawn_file-1]) score += 5; break; case (wrook): wp++; score += l_rook_mobility(i) << 2; score += lcentral[i]; break; case (brook): bp++; score -= l_rook_mobility(i) << 2; score -= lcentral[i]; break; case (wbishop): wp++; score += l_bishop_mobility(i) << 2; score += lcentral[i]; break; case (bbishop): bp++; score -= l_bishop_mobility(i) << 2; score -= lcentral[i]; break; case (wknight): wp++; score += lcentral[i] << 1; score += l_knight_mobility(i) << 2; break; case (bknight): bp++; score -= lcentral[i] << 1; score -= l_knight_mobility(i) << 2; break; case (wqueen): wp++; score += l_bishop_mobility(i) << 1; score += l_rook_mobility(i) << 1; score += lcentral[i]; break; case (bqueen): bp++; score -= l_bishop_mobility(i) << 1; score -= l_rook_mobility(i) << 1; score -= lcentral[i]; break; case (wking): /* being in center is BAD */ wks = lcentral[i] << 1; score += l_king_mobility(i); break; case (bking): /* being in center is BAD */ bks = lcentral[i] << 1; score -= l_king_mobility(i); break; } } if (wp + bp > 10) { score -= wks - bks; } if (abs(Material) <= 900) { score += Material; } else { /* one side has a huge advantage, which could * become problematic */ /* only apply this to self, we assume somebody * else can handle this just fine */ /* I would swear the colors are reversed here, * but it works this way and not otherwise :) */ /* disable this if we have passers...else they'll just sit on last rank */ if (Material > 0 && comp_color == !WHITE && !wpassp) { score += 1800 - Material; } else if (Material < 0 && comp_color == !BLACK && !bpassp) { score += -(1800 + Material); } else { score += Material; } } if (!wpawns) score += 200; else if (!bpawns) score -= 200; if (!wp) score = INF; else if (!bp) score = -INF; storeECache(score); /* adjust for color: */ if (white_to_move == 1) { return score; } else { return -score; } } sjeng-11.2.orig/segtb.c0100644000175000017500000005115607412722321014003 0ustar lukaslukas/* Sjeng - a chess variants playing program Copyright (C) 2001 Gian-Carlo Pascutto and Nubie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA File: segtb.c Purpose: suicide endgame tablebases */ #include #include "sjeng.h" #include "extvars.h" #include "protos.h" #include "squares.h" #define FILE(x) ((x) & 7) #define RANK(x) ((x) >> 3) #define TWO_PIECE_SIZE 4096 #define TWO_PIECE_HASH(x,y,z) (((((x) << 5) | (y)) << 6) | (z)) #define TWO_PIECE_FILE "stb/2pieces.bin" #define THREE_PIECE_SIZE (64*TWO_PIECE_SIZE) #define THREE_PIECE_HASH(x,y,z,w) (((((((x) << 5) | (y)) << 6) | (z)) << 6) | (w)) #define THREE_PIECE_FILE "stb/xxx.bin" #define TABLE_KEY(x,y,z) (((((x) << 3) | (y)) << 3) | (z)) #define IO_BUFSIZE 4096 #define CACHE_SIZE 8 int upscale[64] = { A1,B1,C1,D1,E1,F1,G1,H1, A2,B2,C2,D2,E2,F2,G2,H2, A3,B3,C3,D3,E3,F3,G3,H3, A4,B4,C4,D4,E4,F4,G4,H4, A5,B5,C5,D5,E5,F5,G5,H5, A6,B6,C6,D6,E6,F6,G6,H6, A7,B7,C7,D7,E7,F7,G7,H7, A8,B8,C8,D8,E8,F8,G8,H8 }; int vertical_flip[64] = { 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8, 23, 22, 21, 20, 19, 18, 17, 16, 31, 30, 29, 28, 27, 26, 25, 24, 39, 38, 37, 36, 35, 34, 33, 32, 47, 46, 45, 44, 43, 42, 41, 40, 55, 54, 53, 52, 51, 50, 49, 48, 63, 62, 61, 60, 59, 58, 57, 56 }; /* angrim : this is 63-x, no need to lookup */ int rotate[64] = { 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; int white_addr[64] = { 0, 1, 2, 3, -1, -1, -1, -1, 4, 5, 6, 7, -1, -1, -1, -1, 8, 9, 10, 11, -1, -1, -1, -1, 12, 13, 14, 15, -1, -1, -1, -1, 16, 17, 18, 19, -1, -1, -1, -1, 20, 21, 22, 23, -1, -1, -1, -1, 24, 25, 26, 27, -1, -1, -1, -1, 28, 29, 30, 31, -1, -1, -1, -1 }; int section_map[6][6] = { { 0, 1, 2, 3, 4, 5 }, { -1, 6, 7, 8, 9, 10 }, { -1, -1, 11, 12, 13, 14 }, { -1, -1, -1, 15, 16, 17 }, { -1, -1, -1, -1, 18, 19 }, { -1, -1, -1, -1, -1, 20 } }; int section_trans[] = {666, 0, 0, 1, 1, 5, 5, 3, 3, 4, 4, 2, 2, 6}; char xpiece_char[] = {'F','P','P','N','N','K','K','R','R','Q','Q','B','B','E' }; typedef struct { int table_key; int last_access; } cache_data; signed char *two_piece_data; signed char *three_piece_data; signed char *temp_table; /* used when generating new tables */ int cache_counter; cache_data table_cache[CACHE_SIZE]; int temp_key; int SEGTB; int valid_2piece(int w, int b, int w_man, int b_man) { /* white piece on the wrong half-board? */ if(white_addr[w] == -1) return 0; /* pieces on the same square? */ if(w == b) return 0; if(w_man == wpawn || w_man == bpawn) if(w < 8 || w > 55) return 0; if(b_man == bpawn || b_man == wpawn) if(b < 8 || b > 55) return 0; return 1; } int valid_3piece(int w, int b1, int b2, int w_man, int b1_man, int b2_man) { /* white piece on the wrong half-board? */ if(white_addr[w] == -1) return 0; /* pieces on the same square? */ if(w == b1) return 0; if(w == b2) return 0; if(b1 == b2) return 0; /* pawn on a bad rank? */ if(w_man == wpawn || w_man == bpawn) if(w < 8 || w > 55) return 0; if(b1_man == bpawn || b1_man == wpawn) if(b1 < 8 || b1 > 55) return 0; if(b2_man == bpawn || b2_man == wpawn) if(b2 < 8 || b2 > 55) return 0; return 1; } int check_result() { int p, xp, res; int wp = 0, bp = 0; int a, j, i; move_s moves[MOVE_BUFF]; int num_moves; for (j = 1, a = 1; (a <= piece_count); j++) { i = pieces[j]; if (!i) continue; else a++; switch (board[i]) { case wpawn: case wbishop: case wrook: case wking: case wqueen: case wknight: wp++; break; case bpawn: case bbishop: case brook: case bking: case bqueen: case bknight: bp++; break; } } if (!(wp) && (bp)) { if (white_to_move) { return -127; } else { return 126; } } else if ((!bp) && (wp)) { if (white_to_move) { return 126; } else { return -127; } } gen(&moves[0]); num_moves = numb_moves; if(!num_moves) { if (white_to_move) { p = wp; xp = bp; } else { p = bp; xp = wp; } if(p < xp) return -127; else if(xp < p) return 126; /* can't really happen */ else return 0; } res = egtb(white_to_move); if(res > -10 && res < 10 && res) printf("Warning: near zero values!\n"); if(res > 0) return -res+1; else if(res < 0 && res > -128) return -res-1; return res; } void gen_2piece(int w_man, int b_man, signed char *table) { int i, w, b, t, addr; signed char best, res; int f, unknown; move_s moves[MOVE_BUFF]; int num_moves; ply = 1; reset_board(); /* initialise the table */ memset(table, -128, TWO_PIECE_SIZE); if (!(w_man & 1)) w_man--; if (b_man & 1) b_man++; do { f = FALSE; for(t = 0; t < 2; t++) { white_to_move = t; for(w = 0; w < 64; w++) { for(b = 0; b < 64; b++) { if(!valid_2piece(w, b, w_man, b_man)) continue; addr = TWO_PIECE_HASH(t, white_addr[w], b); if(table[addr] != -128) continue; board[upscale[w]] = w_man; board[upscale[b]] = b_man; pieces[1] = upscale[w]; pieces[2] = upscale[b]; squares[upscale[w]] = 1; squares[upscale[b]] = 2; piece_count = 2; ep_square = 0; gen(&moves[0]); num_moves = numb_moves; if(num_moves == 0) { if (table[addr] != 0) f = TRUE; table[addr] = 0; } else { best = -128; unknown = FALSE; for(i = 0; i < num_moves; i++) { make(&moves[0], i); res = (signed char) check_result(); unmake(&moves[0], i); if(res == -128) { unknown = TRUE; continue; } if(res > best) best = res; } if(best > 0 || (best < 0 && !unknown)) { if (table[addr] != best) f = TRUE; table[addr] = best; } } board[upscale[w]] = npiece; board[upscale[b]] = npiece; squares[upscale[w]] = 0; squares[upscale[b]] = 0; pieces[1] = 0; pieces[2] = 0; } } } printf("."); } while(f); printf("\n"); for(i = 0; i < TWO_PIECE_SIZE; i++) if(table[i] == -128) table[i] = 0; } void gen_3piece(int w_man, int b1_man, int b2_man, signed char *table) { int i, w, b1, b2, t, addr; signed char best, res; int f, unknown; move_s moves[MOVE_BUFF]; int num_moves; ply = 1; reset_board(); /* initialise the table */ memset(table, -128, THREE_PIECE_SIZE); /* normalize colors if needed */ if (!(w_man & 1)) w_man--; if (b1_man & 1) b1_man++; if (b2_man & 1) b2_man++; do { f = FALSE; for(t = 0; t < 2; t++) { white_to_move = t; for(w = 0; w < 64; w++) { for(b1 = 0; b1 < 64; b1++) { for(b2 = 0; b2 < 64; b2++) { if(!valid_3piece(w, b1, b2, w_man, b1_man, b2_man)) continue; addr = THREE_PIECE_HASH(t, white_addr[w], b1, b2); // if(table[addr] != -128) continue; board[upscale[w]] = w_man; board[upscale[b1]] = b1_man; board[upscale[b2]] = b2_man; piece_count = 3; pieces[1] = upscale[w]; pieces[2] = upscale[b1]; pieces[3] = upscale[b2]; squares[upscale[w]] = 1; squares[upscale[b1]] = 2; squares[upscale[b2]] = 3; ep_square = 0; gen(&moves[0]); num_moves = numb_moves; if(!num_moves) { if (table[addr] != (white_to_move ? 126 : -127)) f = TRUE; table[addr] = (white_to_move ? 126 : -127); } else { best = -128; unknown = FALSE; for(i = 0; i < num_moves; i++) { make(&moves[0], i); res = (signed char) check_result(); unmake(&moves[0], i); if(res == -128) { unknown = TRUE; continue; } if(res > best) best = res; } if(best > 0 || (best < 0 && !unknown)) { if (table[addr] != best) f = TRUE; table[addr] = best; } } board[upscale[w]] = npiece; board[upscale[b1]] = npiece; board[upscale[b2]] = npiece; squares[upscale[w]] = 0; squares[upscale[b1]] = 0; squares[upscale[b2]] = 0; pieces[1] = 0; pieces[2] = 0; pieces[3] = 0; } } } } printf("."); } while(f); printf("\n"); for(i = 0; i < THREE_PIECE_SIZE; i++) if(table[i] == -128) table[i] = 0; } int save_2piece() { int i, j; FILE *f; signed char *table; if(!(f = fopen(TWO_PIECE_FILE, "w"))) return 0; for(i = 0; i < 21; i++) { table = two_piece_data + i * TWO_PIECE_SIZE; for(j = 0 ; j < TWO_PIECE_SIZE; j++) { fputc(table[j], f); } } fclose(f); return 1; } int save_3piece(int w1_man, int b1_man, int b2_man, signed char *t) { FILE *f; signed char fname[13]; signed char *buf; int i; /* generate the filename */ strcpy(fname, THREE_PIECE_FILE); fname[4] = xpiece_char[w1_man]; fname[5] = xpiece_char[b1_man]; fname[6] = xpiece_char[b2_man]; if(!(f = fopen(fname,"w"))) return 0; for(i = 0; i < THREE_PIECE_SIZE; i += IO_BUFSIZE) { buf = t + i; if(!fwrite(buf, IO_BUFSIZE, 1, f)) { printf("Error writing %s\n",fname); fclose(f); return 0; } } fclose(f); return 1; } void gen_all_tables() { int w_man, b1_man, b2_man; signed char *base_addr; printf("Two-piece tables:\n"); /* first generate pawnless tables */ for(w_man = wknight; w_man <= wbishop; w_man += 2) { for(b1_man = bknight; b1_man <= bbishop; b1_man += 2) { if(section_map[section_trans[w_man]][section_trans[b1_man]] == -1) continue; printf("Generating %c vs %c ", xpiece_char[w_man], xpiece_char[b1_man]); base_addr = two_piece_data + (section_map[section_trans[w_man]][section_trans[b1_man]] * TWO_PIECE_SIZE); gen_2piece(w_man, b1_man, base_addr); } } /* pawns are the tricky ones that can be promoted, that's why we need the other tables to exist */ w_man = wpawn; for(b1_man = bknight; b1_man <= bbishop; b1_man += 2) { if(section_map[section_trans[w_man]][section_trans[b1_man]] == -1) continue; printf("Generating %c vs %c ", xpiece_char[w_man], xpiece_char[b1_man]); base_addr = two_piece_data + (section_map[section_trans[w_man]][section_trans[b1_man]] * TWO_PIECE_SIZE); gen_2piece(w_man, b1_man, base_addr); } /* finally, pawn vs pawn */ printf("Generating %c vs %c ", xpiece_char[wpawn], xpiece_char[bpawn]); base_addr = two_piece_data + (section_map[section_trans[wpawn]][section_trans[bpawn]]*TWO_PIECE_SIZE); gen_2piece(wpawn, bpawn, base_addr); if(save_2piece()) printf("Saved two-piece tables in %s\n", TWO_PIECE_FILE); /* now, start doing pawnless three-piece tables */ temp_table = malloc(THREE_PIECE_SIZE); if(!temp_table) return; for(w_man = wknight; w_man <= wbishop; w_man += 2) for(b1_man = bknight; b1_man <= bbishop ; b1_man += 2) for(b2_man = bknight; b2_man <= bbishop; b2_man += 2) { if(section_map[section_trans[b1_man]][section_trans[b2_man]] == -1) continue; printf("Generating %c vs %c+%c ", xpiece_char[w_man], xpiece_char[b1_man], xpiece_char[b2_man]); temp_key = TABLE_KEY(section_trans[w_man], section_trans[b1_man], section_trans[b2_man]); gen_3piece(w_man, b1_man, b2_man, temp_table); save_3piece(w_man, b1_man, b2_man, temp_table); } /* white piece is a pawn */ w_man = wpawn; for(b1_man = bknight; b1_man <= bbishop; b1_man += 2) for(b2_man = bknight; b2_man <= bbishop; b2_man += 2) { if(section_map[section_trans[b1_man]][section_trans[b2_man]] == -1) continue; printf("Generating %c vs %c+%c ", xpiece_char[w_man], xpiece_char[b1_man], xpiece_char[b2_man]); temp_key = TABLE_KEY(section_trans[w_man], section_trans[b1_man], section_trans[b2_man]); gen_3piece(w_man, b1_man, b2_man, temp_table); save_3piece(w_man, b1_man, b2_man, temp_table); } /* one black piece is a pawn */ for(w_man = wknight; w_man <= wbishop; w_man += 2) { b1_man = bpawn; for(b2_man = wknight; b2_man <= bbishop; b2_man += 2) { printf("Generating %c vs %c+%c ", xpiece_char[w_man], xpiece_char[b1_man], xpiece_char[b2_man]); temp_key = TABLE_KEY(section_trans[w_man], section_trans[b1_man], section_trans[b2_man]); gen_3piece(w_man, b1_man, b2_man, temp_table); save_3piece(w_man, b1_man, b2_man, temp_table); } } w_man = wpawn; b1_man = bpawn; for(b2_man = bknight; b2_man <= bbishop; b2_man += 2) { printf("Generating %c vs %c+%c ", xpiece_char[w_man], xpiece_char[b1_man], xpiece_char[b2_man]); temp_key = TABLE_KEY(section_trans[w_man], section_trans[b1_man], section_trans[b2_man]); gen_3piece(w_man, b1_man, b2_man, temp_table); save_3piece(w_man, b1_man, b2_man, temp_table); } /* both black pieces are pawns */ for(w_man = wknight; w_man <= wbishop; w_man += 2) { b1_man = bpawn; b2_man = bpawn; printf("Generating %c vs %c+%c ", xpiece_char[w_man], xpiece_char[b1_man], xpiece_char[b2_man]); temp_key = TABLE_KEY(section_trans[w_man], section_trans[b1_man], section_trans[b2_man]); gen_3piece(w_man, b1_man, b2_man, temp_table); save_3piece(w_man, b1_man, b2_man, temp_table); } /* three pawns */ w_man = wpawn; b1_man = bpawn; b2_man = bpawn; printf("Generating %c vs %c+%c ", xpiece_char[w_man], xpiece_char[b1_man], xpiece_char[b2_man]); temp_key = TABLE_KEY(section_trans[w_man], section_trans[b1_man], section_trans[b2_man]); gen_3piece(w_man, b1_man, b2_man, temp_table); save_3piece(w_man, b1_man, b2_man, temp_table); printf("\nAll done.\n"); free(temp_table); reset_board(); } void free_egtb() { free(two_piece_data); free(three_piece_data); } int init_segtb() { int i; two_piece_data = malloc(21 * TWO_PIECE_SIZE); three_piece_data = malloc(CACHE_SIZE * THREE_PIECE_SIZE); if(!two_piece_data || !three_piece_data) { return FALSE; } if(!load_2piece()) { return FALSE; } for(i = 0; i < CACHE_SIZE; i++) { table_cache[i].table_key = -1; table_cache[i].last_access = 0; } cache_counter = 0; temp_key = -1; printf("Two-piece suicide endgame tables preloaded (using %d kB of memory)\n", (21 * TWO_PIECE_SIZE) / 1024); printf("Three-piece suicide endgame table cache %d kB\n", (CACHE_SIZE * THREE_PIECE_SIZE) / 1024); return TRUE; } int egtb(int s) { int w1_man, w2_man, b1_man, b2_man; int w1, w2, b1, b2; int w_count = 0, b_count = 0; int i, t, temp, junk, bpc; signed char *table; /* first figure out what kind of position we have */ for(i = 0; i < 64; i++) { bpc = board[upscale[i]]; if (bpc == npiece) continue; if(bpc & 1) { if(!w_count) { w1_man = bpc; w1 = i; } else { w2_man = bpc; w2 = i; } w_count++; } else { if(!b_count) { b1_man = bpc; b1 = i; } else { b2_man = bpc; b2 = i; } b_count++; } } /* two pieces? */ if(w_count == 1 && b_count == 1) { if(section_map[section_trans[w1_man]][section_trans[b1_man]] == -1) { temp = b1_man; b1_man = w1_man; w1_man = temp; temp = b1; /* angrim: can do this without branch */ if(w1_man == wpawn || w1_man == bpawn) { /* pawn color was changed, we need to rotate the board 180 degrees */ b1 = rotate[w1]; w1 = rotate[temp]; } else { b1 = w1; w1 = temp; } s ^= 1; } table = two_piece_data + (section_map[section_trans[w1_man]][section_trans[b1_man]] * TWO_PIECE_SIZE); /* flip the board if necessary */ if(white_addr[w1] == -1) { w1 = vertical_flip[w1]; b1 = vertical_flip[b1]; } return (int)table[TWO_PIECE_HASH(s, white_addr[w1], b1)]; } else if((w_count == 1 && b_count == 2) || (w_count == 2 && b_count == 1)) { /* three pieces */ if(w_count > 1) { /* need to switch sides */ b2_man = w2_man; temp = w1_man; w1_man = b1_man; b1_man = temp; temp = w1; if(w1_man == wpawn || w1_man == bpawn || b1_man == bpawn || b1_man == wpawn || b2_man == bpawn || b2_man == wpawn) { /* pawn color was changed, we need to rotate the board 180 degrees */ b2 = rotate[w2]; w1 = rotate[b1]; b1 = rotate[temp]; } else { b2 = w2; w1 = b1; b1 = temp; } s ^= 1; } /* swap black pieces if necessary */ if(section_map[section_trans[b1_man]][section_trans[b2_man]] == -1) { temp = b1_man; b1_man = b2_man; b2_man = temp; temp = b1; b1 = b2; b2 = temp; } /* do the vertical flip */ if(white_addr[w1] == -1) { w1 = vertical_flip[w1]; b1 = vertical_flip[b1]; b2 = vertical_flip[b2]; } /* finally, find the table we need either from memory or disk and return the value */ t = TABLE_KEY(section_trans[w1_man], section_trans[b1_man], section_trans[b2_man]); if(temp_key == t) /* maybe we're generating a table */ table = temp_table; else { /* check the cache */ temp = INT_MAX; cache_counter++; for(i = 0; i < CACHE_SIZE; i++) { if(table_cache[i].table_key == t) { table = three_piece_data + (i * THREE_PIECE_SIZE); table_cache[i].last_access = cache_counter; return (int) table[THREE_PIECE_HASH(s, white_addr[w1], b1, b2)]; } else if(table_cache[i].last_access < temp) { temp = table_cache[i].last_access; junk = i; } } /* the table was not in the cache, we'll load it into the least recently accessed slot */ table = three_piece_data + (junk * THREE_PIECE_SIZE); if(!load_3piece(w1_man, b1_man, b2_man, table)) { //printf("Loading error\n"); table_cache[junk].table_key = -1; return (-128); } table_cache[junk].table_key = t; table_cache[junk].last_access = cache_counter; } return (int) table[THREE_PIECE_HASH(s, white_addr[w1], b1, b2)]; } else return (-128); /* position not in the tables */ } int load_2piece() { int i,j; FILE *f; signed char *table; if(!(f = fopen(TWO_PIECE_FILE, "r"))) return 0; for(i = 0; i < 21; i++) { table = two_piece_data + i * TWO_PIECE_SIZE; for(j = 0; j < TWO_PIECE_SIZE; j++) table[j] = (signed char) fgetc(f); } fclose(f); return 1; } int load_3piece(int w1_man, int b1_man, int b2_man, signed char *t) { FILE *f; signed char fname[13]; signed char *buf; int i; /* generate the filename */ strcpy(fname, THREE_PIECE_FILE); fname[4]= xpiece_char[w1_man]; fname[5]= xpiece_char[b1_man]; fname[6]= xpiece_char[b2_man]; if(!(f = fopen(fname,"r"))) return 0; for(i = 0; i < THREE_PIECE_SIZE; i += IO_BUFSIZE) { buf = t + i; if(!fread(buf, IO_BUFSIZE, 1, f)) { printf("Error reading %s\n",fname); fclose(f); return 0; } } fclose(f); return 1; } sjeng-11.2.orig/seval.c0100644000175000017500000002745407323124077014022 0ustar lukaslukas/* Sjeng - a chess variants playing program Copyright (C) 2000 Gian-Carlo Pascutto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA File: seval.c Purpose: functions for evaluating positions (suicide chess) */ #include "sjeng.h" #include "extvars.h" #include "protos.h" static int scentral[144] = { 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,-20,-10,-10,-10,-10,-10,-10,-20,0,0, 0,0,-10,0,3,5,5,3,0,-10,0,0, 0,0,-10,2,15,15,15,15,2,-10,0,0, 0,0,-10,7,15,25,25,15,7,-10,0,0, 0,0,-10,7,15,25,25,15,7,-10,0,0, 0,0,-10,2,15,15,15,15,2,-10,0,0, 0,0,-10,0,3,5,5,3,0,-10,0,0, 0,0,-20,-10,-10,-10,-10,-10,-10,-20,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0}; static const int rook_o[4] = {12, -12, 1, -1}; static const int bishop_o[4] = {11, -11, 13, -13}; static const int knight_o[8] = {10, -10, 14, -14, 23, -23, 25, -25}; static int s_bishop_mobility(int square) { register int l; register int m = 0; for (l = square-13; board[l] == npiece; l-=13) m++; for (l = square-11; board[l] == npiece; l-=11) m++; for (l = square+11; board[l] == npiece; l+=11) m++; for (l = square+13; board[l] == npiece; l+=13) m++; return m << 2; } static int s_rook_mobility(int square) { register int l; register int m = 0; for (l = square-12; board[l] == npiece; l-=12) m++; for (l = square-1; board[l] == npiece; l-=1) m++; for (l = square+1; board[l] == npiece; l+=1) m++; for (l = square+12; board[l] == npiece; l+=12) m++; return m << 2; } static int s_knight_mobility(int square) { static const int knight_o[8] = {10, -10, 14, -14, 23, -23, 25, -25}; register int d, m = 0; for (d = 0; d < 8; d++) { if (board[square + knight_o[d]] == npiece) m++; } return m << 2; } static int s_pawn_mobility(int square) { register int m = 0; if (board[square] == wpawn) { if (board[square + 12] == npiece) m++; } else { if (board[square - 12] == npiece) m++; } return m << 3; } static int s_king_mobility(int square) { static const int king_o[8] = {13, 12, 11, 1, -1, -11, -12, -13}; register int d, m = 0; for (d = 0; d < 8; d++) { if (board[square + king_o[d]] == npiece) m++; } return m << 2; } static int black_saccers(int square) { register int ndir, a_sq; register int basq, i; register int f = FALSE; /* for white pawn on square, any black * pieces that can sac themselves to it? */ /* check for case where is_attacked fails because pawns dont move to their attacks */ if (board[square + 24] == bpawn || board[square + 22] == bpawn || board[square + 26] == bpawn) { return 0; } /* ok, now check pawn moves */ if ((rank(square) < 6) && (board[square + 25] == bpawn || board[square + 23] == bpawn)) { f = TRUE; } else if (rank(square) == 4 && board[square + 35] == bpawn || board[square + 37] == bpawn) { f = TRUE; } if (!f) { f = (is_attacked(square + 11, 0) ? 1 : 0); } if (!f) { f = (is_attacked(square + 13, 0) ? 2 : 0); } if (!f) { return 0; } else { /* black can sac, but is the saccer defended ? */ if (f == 1) { if (calc_attackers(square + 11, 0) > 1) { /* yep */ return 0; } else { /* nope */ return 30; } } else { if (calc_attackers(square + 13, 0) > 1) { return 0; } else { return 30; } } } } static int white_saccers(int square) { /* for black pawn on square, any black * pieces that can sac themselves to it? */ register int ndir, a_sq; register int basq, i; register int f = FALSE; /* for white pawn on square, any black * pieces that can sac themselves to it? */ /* check for case where is_attacked fails because pawns dont move to their attacks */ if (board[square - 24] == wpawn || board[square - 22] == wpawn || board[square - 26] == wpawn) { return 0; } /* ok, now check pawn moves */ if ((rank(square) > 3) && (board[square - 25] == wpawn || board[square - 23] == wpawn)) { f = TRUE; } else if (rank(square) == 5 && board[square - 35] == wpawn || board[square - 37] == wpawn) { f = TRUE; } if (!f) { f = (is_attacked(square - 11, 1) ? 1 : 0); } if (!f) { f = (is_attacked(square - 13, 1) ? 2 : 0); } if (!f) { return 0; } else { /* black can sac, but is the saccer defended ? */ if (f == 1) { if (calc_attackers(square - 11, 1) > 1) { /* yep */ return 0; } else { /* nope */ return 30; } } else { if (calc_attackers(square - 13, 1) > 1) { return 0; } else { return 30; } } } } long int suicide_eval (void) { /* select the appropriate eval() routine: */ return (suicide_mid_eval ()); } long int suicide_mid_eval (void) { /* return a score for the current middlegame position: */ int srank, pawn_file, pawns[2][11], white_back_pawn[11], black_back_pawn[11]; int isolated, backwards, i, a, j; long int score = 0; int in_cache; int wb = 0, bb = 0, wbc, bbc; int wk = 0, bk = 0, wr = 0, br = 0; int wn = 0, bn = 0, wp = 0, bp = 0; in_cache = 0; checkECache(&score, &in_cache); if(in_cache) { if (white_to_move == 1) return score; return -score; } score = Material; /* initialize the pawns array, (files offset by one to use dummy files in order to easier determine isolated status) and also initialize the arrays keeping track of the rank of the most backward pawn: */ memset (pawns, 0, sizeof (pawns)); for (i = 0; i < 11; i++) { white_back_pawn[i] = 7; black_back_pawn[i] = 2; } for (j = 1, a = 1; (a <= piece_count); j++) { i = pieces[j]; if (!i) continue; else a++; assert((i > 0) && (i < 145)); pawn_file = file (i)+1; srank = rank (i); if (board[i] == wpawn) { pawns[1][pawn_file]++; if (srank < white_back_pawn[pawn_file]) { white_back_pawn[pawn_file] = srank; } } else if (board[i] == bpawn) { pawns[0][pawn_file]++; if (srank > black_back_pawn[pawn_file]) { black_back_pawn[pawn_file] = srank; } } } /* loop through the board, adding material value, as well as positional bonuses for all pieces encountered: */ for (j = 1, a = 1; (a <= piece_count); j++) { i = pieces[j]; if (!i) continue; else a++; pawn_file = file (i)+1; srank = rank (i); switch (board[i]) { case (wpawn): score += scentral[i]; score += s_pawn_mobility(i); score -= black_saccers(i); wp++; isolated = FALSE; backwards = FALSE; /* check for backwards pawns: */ if (white_back_pawn[pawn_file+1] > srank && white_back_pawn[pawn_file-1] > srank) { score -= 8; backwards = TRUE; /* check to see if it is furthermore isolated: */ if (!pawns[1][pawn_file+1] && !pawns[1][pawn_file-1]) { score -= 12; isolated = TRUE; } } /* give weak, exposed pawns a penalty (not as much as in the midgame, since there may be no pieces to take advantage of it): */ if (!pawns[0][pawn_file]) { if (backwards) score -= 5; if (isolated) score -= 8; } /* give doubled, trippled, etc.. pawns a penalty (bigger in the endgame, since they will become big targets): */ if (pawns[1][pawn_file] > 1) score -= 15*(pawns[1][pawn_file]-1); /* give bonuses for passed pawns (bigger in the endgame since passed pawns are what wins the endgame): */ if (!pawns[0][pawn_file] && srank >= black_back_pawn[pawn_file-1] && srank >= black_back_pawn[pawn_file+1]) { score += 30 + 3*(rank(i)-2); /* outside passer ? */ if (file(i) == 1 || file(i) == 8) score += 4 + 2*(rank(i)-2); /* give an extra bonus if a connected, passed pawn: */ if (!isolated) { score += 6; } } /* check for pawn islands */ if (!pawns[1][pawn_file-1]) score -= 20; break; case (bpawn): score -= scentral[i]; score -= s_pawn_mobility(i); score += white_saccers(i); isolated = FALSE; backwards = FALSE; bp++; /* in general, bonuses/penalties in the endgame evaluation will be higher, since pawn structure becomes more important for the creation of passed pawns */ /* check for backwards pawns: */ if (black_back_pawn[pawn_file+1] < srank && black_back_pawn[pawn_file-1] < srank) { score += 8; backwards = TRUE; /* check to see if it is furthermore isolated: */ if (!pawns[0][pawn_file+1] && !pawns[0][pawn_file-1]) { score += 12; isolated = TRUE; } } /* give weak, exposed pawns a penalty (not as much as in the midgame, since there may be no pieces to take advantage of it): */ if (!pawns[1][pawn_file]) { if (backwards) score += 5; if (isolated) score += 8; } /* give doubled, trippled, etc.. pawns a penalty (bigger in the endgame, since they will become big targets): */ if (pawns[0][pawn_file] > 1) score += 15*(pawns[0][pawn_file]-1); /* give bonuses for passed pawns (bigger in the endgame since passed pawns are what wins the endgame): */ if (!pawns[1][pawn_file] && srank <= white_back_pawn[pawn_file-1] && srank <= white_back_pawn[pawn_file+1]) { score -= 30 + 3*(7-rank(i)); /* outside passer ? */ if (file(i) == 1 || file(i) == 8) score -= 4 + 2*(7-rank(i)); /* give an extra bonus if a connected, passed pawn: */ if (!isolated) { score -= 6; } } if (!pawns[0][pawn_file-1]) score += 20; break; case (wrook): score += scentral[i]; score += s_rook_mobility(i); wr++; break; case (brook): score -= scentral[i]; score -= s_rook_mobility(i); br++; break; case (wbishop): score += scentral[i]; score += s_bishop_mobility(i); if (wb) { if (sqcolor[i] != wbc) wb = 99; } wb++; wbc = sqcolor[i]; break; case (bbishop): score -= scentral[i]; score -= s_bishop_mobility(i); if (bb) { /* two bishops, check for same color */ if (sqcolor[i] != bbc) bb = 99; } bb++; bbc = sqcolor[i]; break; case (wknight): score += scentral[i]; score += s_knight_mobility(i); wn++; break; case (bknight): score -= scentral[i]; score -= s_knight_mobility(i); bn++; break; case (wqueen): score += scentral[i]; score += s_rook_mobility(i); score += s_bishop_mobility(i); break; case (bqueen): score -= scentral[i]; score -= s_rook_mobility(i); score -= s_bishop_mobility(i); break; case (wking): score += scentral[i] >> 1; score += s_king_mobility(i); wk++; break; case (bking): score -= scentral[i] >> 1; score -= s_king_mobility(i); bk++; break; } } /* opposite color bishops */ if ((wb < 99) && (bb < 99) && (wbc != bbc) && (piece_count < 32)) { score = (int)((float)score * (float)((float)piece_count / 32.0)); } storeECache(score); /* adjust for color: */ if (white_to_move == 1) { return score; } else { return -score; } } sjeng-11.2.orig/ttable.c0100644000175000017500000002031307323363300014140 0ustar lukaslukas/* Sjeng - a chess variants playing program Copyright (C) 2000-2001 Gian-Carlo Pascutto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA File: ttable.c Purpose: handling of transposition tables and hashes */ #include "sjeng.h" #include "protos.h" #include "extvars.h" #include "limits.h" unsigned long zobrist[17][144]; unsigned long hash; unsigned long TTProbes; unsigned long TTHits; unsigned long TTStores; typedef struct { signed char Depth; /* unsigned char may be a bit small for bughouse/crazyhouse */ unsigned short Bestmove; unsigned OnMove:1, Threat:1, Type:2; unsigned long Hash; unsigned long Hold_hash; signed long Bound; } TType; typedef struct { unsigned short Bestmove; unsigned OnMove:1, Type:2; unsigned long Hash; unsigned long Hold_hash; signed long Bound; } QTType; /*TType DP_TTable[TTSIZE]; TType AS_TTable[TTSIZE]; */ TType *DP_TTable; TType *AS_TTable; QTType *QS_TTable; void clear_tt(void) { memset(DP_TTable, 0, sizeof(TType) * TTSize); memset(AS_TTable, 0, sizeof(TType) * TTSize); }; void clear_dp_tt(void) { memset(DP_TTable, 0, sizeof(TType) * TTSize); }; void initialize_zobrist(void) { int p, q; seedMT(31657); for(p = 0; p < 17; p++) { for(q = 0; q < 144; q++) { zobrist[p][q] = randomMT(); } } /* our magic number */ hash = 0xDEADBEEF; } void initialize_hash(void) { int p; hash = 0xDEADBEEF; for(p = 0; p < 144; p++) { if (board[p] != npiece && board[p] != frame) hash = hash ^ zobrist[board[p]][p]; } hold_hash = 0xC0FFEE00; /* we need to set up hold_hash here, rely on ProcessHolding for now */ } void QStoreTT(int score, int alpha, int beta, int best) { unsigned long index; TTStores++; index = hash % TTSize; if (score <= alpha) QS_TTable[index].Type = UPPER; else if(score >= beta) QS_TTable[index].Type = LOWER; else QS_TTable[index].Type = EXACT; QS_TTable[index].Hash = hash; QS_TTable[index].Hold_hash = hold_hash; QS_TTable[index].Bestmove = best; QS_TTable[index].Bound = score; QS_TTable[index].OnMove = ToMove; return; } void StoreTT(int score, int alpha, int beta, int best, int threat, int depth) { unsigned long index; TTStores++; index = hash % TTSize; /* Prefer storing entries with more information */ if (( (DP_TTable[index].Depth < depth) || ((DP_TTable[index].Depth == depth) && ( ((DP_TTable[index].Type == UPPER) && (score > alpha)) || ((score > alpha) && (score < beta)) ) ) ) && !is_pondering) { if (score <= alpha) { DP_TTable[index].Type = UPPER; if (score < -INF+500) score = -INF+500; } else if(score >= beta) { DP_TTable[index].Type = LOWER; if (score > INF-500) score = INF-500; } else { DP_TTable[index].Type = EXACT; /* normalize mate scores */ if (score > (+INF-500)) score += ply; else if (score < (-INF+500)) score -= ply; } DP_TTable[index].Hash = hash; DP_TTable[index].Hold_hash = hold_hash; DP_TTable[index].Depth = depth; DP_TTable[index].Bestmove = best; DP_TTable[index].Bound = score; DP_TTable[index].OnMove = ToMove; DP_TTable[index].Threat = threat; } else { if (score <= alpha) { AS_TTable[index].Type = UPPER; if (score < -INF+500) score = -INF+500; } else if(score >= beta) { AS_TTable[index].Type = LOWER; if (score > INF-500) score = INF-500; } else { AS_TTable[index].Type = EXACT; /* normalize mate scores */ if (score > (+INF-500)) score += ply; else if (score < (-INF+500)) score -= ply; } AS_TTable[index].Hash = hash; AS_TTable[index].Hold_hash = hold_hash; AS_TTable[index].Depth = depth; AS_TTable[index].Bestmove = best; AS_TTable[index].Bound = score; AS_TTable[index].OnMove = ToMove; AS_TTable[index].Threat = threat; }; return; } void LearnStoreTT(int score, unsigned nhash, unsigned hhash, int tomove, int best, int depth) { unsigned long index; index = nhash % TTSize; AS_TTable[index].Depth = depth; if (Variant != Suicide && Variant != Losers) { AS_TTable[index].Type = EXACT; } else { AS_TTable[index].Type = UPPER; } AS_TTable[index].Hash = nhash; AS_TTable[index].Hold_hash = hhash; AS_TTable[index].Bestmove = best; AS_TTable[index].Bound = score; AS_TTable[index].OnMove = tomove; AS_TTable[index].Threat = 0; } int ProbeTT(int *score, int alpha, int beta, int *best, int *threat, int *donull, int depth) { unsigned long index; *donull = TRUE; TTProbes++; index = hash % TTSize; if ((DP_TTable[index].Hash == hash) && (DP_TTable[index].Hold_hash == hold_hash) && (DP_TTable[index].OnMove == ToMove)) { TTHits++; if ((DP_TTable[index].Type == UPPER) && ((depth-2-1) <= DP_TTable[index].Depth) && (DP_TTable[index].Bound < beta)) *donull = FALSE; if (DP_TTable[index].Threat) depth++; if (DP_TTable[index].Depth >= depth) { *score = DP_TTable[index].Bound; if (*score > (+INF-500)) *score -= ply; else if (*score < (-INF+500)) *score += ply; *best = DP_TTable[index].Bestmove; *threat = DP_TTable[index].Threat; return DP_TTable[index].Type; } else { *best = DP_TTable[index].Bestmove; *threat = DP_TTable[index].Threat; return DUMMY; } } else if ((AS_TTable[index].Hash == hash) && (AS_TTable[index].Hold_hash == hold_hash) && (AS_TTable[index].OnMove == ToMove)) { TTHits++; if ((AS_TTable[index].Type == UPPER) && ((depth-2-1) <= AS_TTable[index].Depth) && (AS_TTable[index].Bound < beta)) *donull = FALSE; if (AS_TTable[index].Threat) depth++; if (AS_TTable[index].Depth >= depth) { *score = AS_TTable[index].Bound; if (*score > (+INF-500)) *score -= ply; else if (*score < (-INF+500)) *score += ply; *best = AS_TTable[index].Bestmove; *threat = AS_TTable[index].Threat; return AS_TTable[index].Type; } else { *best = AS_TTable[index].Bestmove; *threat = AS_TTable[index].Threat; return DUMMY; } } else return HMISS; } int QProbeTT(int *score, int alpha, int beta, int *best) { unsigned long index; TTProbes++; index = hash % TTSize; if ((QS_TTable[index].Hash == hash) && (QS_TTable[index].Hold_hash == hold_hash) && (QS_TTable[index].OnMove == ToMove)) { TTHits++; *score = QS_TTable[index].Bound; *best = QS_TTable[index].Bestmove; return QS_TTable[index].Type; } else return HMISS; } void alloc_hash(void) { AS_TTable = (TType *) malloc(sizeof(TType) * TTSize); DP_TTable = (TType *) malloc(sizeof(TType) * TTSize); QS_TTable = (QTType *) malloc(sizeof(QTType) * TTSize); if (AS_TTable == NULL || DP_TTable == NULL || QS_TTable == NULL) { printf("Out of memory allocating hashtables.\n"); exit(EXIT_FAILURE); } printf("Allocated 2*%d hash entries, totalling %lu bytes.\n", TTSize, (unsigned long)(2*sizeof(TType)*TTSize)); printf("Allocated %d quiescenthash entries, totalling %lu bytes.\n", TTSize, (unsigned long)(sizeof(QTType)*TTSize)); return; } void free_hash(void) { free(AS_TTable); free(DP_TTable); free(QS_TTable); return; } sjeng-11.2.orig/sjeng.rc0100644000175000017500000001022107412721217014156 0ustar lukaslukas# Sample rcfile for Sjeng 10.0 # # First number is size of hash table (transposition table) # An entry is about 16 bytes, and there are three tables, # so the total hash size is the number below times 48. # Normal, Bughouse, Crazyhouse, Losers # 1000000 # # Evaluation cache entries # An entry is normally about 8 bytes # Normal, Bughouse, Crazyhouse, Losers # 4000 # # Proofnumber search buffer # In suicide/giveaway and losers Sjeng uses proofnumbersearch instead # of the more common alpha-beta search. If the buffer is filled # Sjeng will have to stop searching. Make this a large # number if you will play suicide or losers at slow timecontrols. # You can safely set this to 0 if you do not play suicide/giveaway # or losers. # Each entry is about 28 bytes. # Suicide/Giveaway and Losers only # 10000000 # # Kingsafety scalefactor (range 0<->2.5) # This controls how much emphasis Sjeng will # put on kingattacks vs material gain. # The eval can be completely finetuned below. # Crazyhouse/bughouse only # 1.0 # # Development scaling (1=enabled/0=disabled) # Sjeng will put less emphasis on trying to # get pieces on good squares if it does not # have much material in hand. # Crazyhouse/bughouse only 1 # # Razor drop moves (1=enabled/0=disabled) # Sjeng will look less deep at # drop moves that seem passive. # Crazyhouse/bughouse only 1 # # Cut drop moves (1=enabled/0=disabled) # Sjeng will try to avoid looking at drop moves # where the dropped piece can be captured immediately. # EXPERIMENTAL # Crazyhouse/bughouse only 1 # # Book learning # Sjeng will adjust the openings it plays # depending on the outcome of the game. # All variants 1 # # Futility pruning/Limited Razoring (1=enabled/0=disabled) # Sjeng will try to avoid looking at positions # where it is materially lost, or will look at # them less deeply. # All variants 1 # # One-reply extension (1=enabled/0=disabeled) # Sjeng will loop deeper at very forcing lines. # This can cause Sjeng to see some tactics faster, # but it may reduce overall search depth. # Normal/Crazyhouse/Bughouse 1 # # Recapture extension (1=enabled/0=disabled) # Sjeng will treat a recapture like a forced move. # Normal/Crazyhouse/Bughouse 1 # # Use Smarteval (1=enabled/0=disabled) # This enables the use of an evalution # which can detect some typical threats, # but which will also slow the search down. # Crazyhouse and Bughouse only 1 # # Use Attackeval (1=enabled/0=disabled) # Sjeng will do a full calculation of # which squares near the king are threatened. # This will increase its awareness of # kingsafety, but will also cause it # to search slower, and hence look less deeply. # Crazyhouse and Bughouse only 1 # # Kingsafety (Crazyhouse/Bughouse only) # # The following tables are the 'tropisms'. # They are basically bonusses for having pieces # close to the opposing king. The closer our # pieces are, the better. First number is a # maximum distance of 1 file/rank. Second 2 etc... # # Pawn tropisms 40 20 10 3 1 1 0 # Bishop tropisms 50 25 15 5 2 2 2 # Knight tropisms 50 70 35 10 2 1 0 # Rook tropisms 50 40 15 5 1 1 0 # Queen tropisms 100 60 20 5 2 0 0 # # # KingAttacks table (Crazyhouse/Bughouse only) # # The following table is used to give penalties # depending on the number of squares around our # king that are attacked, taking into account # the pieces in our opponents hand. # # It is only used if AttackEval is also enabled # # # Columns are the number of squares that are attacked. # Rows are the number of points in the opponents hand. # -5 5 10 15 50 80 150 150 150 -5 15 20 25 70 150 200 200 200 -5 15 30 30 100 200 300 300 300 -10 20 40 40 100 200 300 300 400 -10 30 50 80 150 300 400 400 500 -10 35 60 100 200 250 400 400 500 -10 40 70 110 210 300 500 500 600 -10 45 75 125 215 300 500 600 700 -10 60 90 130 240 350 500 600 700 -15 60 95 145 260 350 500 600 700 -15 60 100 150 270 350 500 600 700 -15 60 110 160 280 400 600 700 800 -20 70 115 165 290 400 600 700 800 -20 80 120 170 300 450 700 800 900 -20 80 125 175 310 450 700 800 900 sjeng-11.2.orig/sjeng.c0100644000175000017500000006503207412717266014017 0ustar lukaslukas/* Sjeng - a chess variants playing program Copyright (C) 2000-2001 Gian-Carlo Pascutto Originally based on Faile, Copyright (c) 2000 Adrien M. Regimbald This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA As a special exception, Gian-Carlo Pascutto gives permission to link this program with the Nalimov endgame database access code. See the Copying/Distribution section in the README file for more details. File: sjeng.c Purpose: main program, xboard/user interface */ #include "sjeng.h" #include "protos.h" #include "extvars.h" #include "config.h" char divider[50] = "-------------------------------------------------"; move_s dummy = {0,0,0,0,0}; int board[144], moved[144], ep_square, white_to_move, comp_color, wking_loc, bking_loc, white_castled, black_castled, result, ply, pv_length[PV_BUFF], pieces[62], squares[144], num_pieces, i_depth, fifty, piece_count; long int nodes, raw_nodes, qnodes, killer_scores[PV_BUFF], killer_scores2[PV_BUFF], killer_scores3[PV_BUFF], moves_to_tc, min_per_game, sec_per_game, inc, time_left, opp_time, time_cushion, time_for_move, cur_score; unsigned long history_h[144][144]; unsigned long hash_history[600]; int move_number; bool captures, searching_pv, post, time_exit, time_failure; int xb_mode, maxdepth; int phase; int root_to_move; int my_rating, opp_rating; char setcode[30]; move_s pv[PV_BUFF][PV_BUFF], killer1[PV_BUFF], killer2[PV_BUFF], killer3[PV_BUFF]; move_x path_x[PV_BUFF]; move_s path[PV_BUFF]; rtime_t start_time; int is_promoted[62]; int NTries, NCuts, TExt; unsigned long PVS, FULL, PVSF; unsigned long ext_check; bool is_pondering, allow_pondering, is_analyzing; int Variant; int Giveaway; char my_partner[STR_BUFF]; bool have_partner; bool must_sit; bool go_fast; long fixed_time; FILE *lrn_standard; FILE *lrn_zh; FILE *lrn_suicide; FILE *lrn_losers; int main (int argc, char *argv[]) { char input[STR_BUFF], *p, output[STR_BUFF]; char readbuff[STR_BUFF]; move_s move, comp_move; int depth = 4; bool force_mode, show_board; double nps, elapsed; clock_t cpu_start, cpu_end; move_s game_history[600]; move_x game_history_x[600]; int is_edit_mode, edit_color; int pingnum; int braindeadinterface; int automode; rtime_t xstart_time; read_rcfile(); initialize_zobrist(); Variant = Normal; //Variant = Crazyhouse; memcpy(material, std_material, sizeof(std_material)); //memcpy(material, zh_material, sizeof(zh_material)); if (!init_book()) printf("No .OPN opening book found.\n"); if ((lrn_standard = fopen ("standard.lrn", "rb+")) == NULL) { printf("No standard learn file.\n"); if ((lrn_standard = fopen ("standard.lrn", "wb+")) == NULL) { printf("Error creating standard learn file.\n"); } else { fclose(lrn_standard); lrn_standard = fopen ("standard.lrn", "rb+"); } } if ((lrn_zh = fopen ("bug.lrn", "rb+")) == NULL) { printf("No crazyhouse learn file.\n"); if ((lrn_zh = fopen ("bug.lrn", "wb+")) == NULL) { printf("Error creating crazyhouse learn file.\n"); } else { fclose(lrn_zh); lrn_zh = fopen ("bug.lrn", "rb+"); } } if ((lrn_suicide = fopen ("suicide.lrn", "rb+")) == NULL) { printf("No suicide learn file.\n"); if ((lrn_suicide = fopen ("suicide.lrn", "wb+")) == NULL) { printf("Error creating suicide learn file.\n"); } else { fclose(lrn_suicide); lrn_suicide = fopen ("suicide.lrn", "rb+"); } } if ((lrn_losers = fopen ("losers.lrn", "rb+")) == NULL) { printf("No losers learn file.\n"); if ((lrn_losers = fopen ("losers.lrn", "wb+")) == NULL) { printf("Error creating losers learn file.\n"); } else { fclose(lrn_losers); lrn_losers = fopen ("losers.lrn", "rb+"); } } start_up (); init_game (); initialize_hash(); clear_tt(); init_egtb(); if (init_segtb()) SEGTB = TRUE; else SEGTB = FALSE; EGTBProbes = 0; EGTBHits = 0; ECacheProbes = 0; ECacheHits = 0; TTProbes = 0; TTStores = 0; TTHits = 0; bookidx = 0; total_moves = 0; ply = 0; braindeadinterface = 0; moves_to_tc = 40; min_per_game = 5; time_left = 30000; my_rating = opp_rating = 2000; maxdepth = 40; must_go = 1; tradefreely = 1; automode = 0; xb_mode = FALSE; force_mode = FALSE; comp_color = 0; show_board = TRUE; is_pondering = FALSE; allow_pondering = TRUE; is_analyzing = FALSE; is_edit_mode = FALSE; have_partner = FALSE; must_sit = FALSE; go_fast = FALSE; fixed_time = FALSE; phase = Opening; root_to_move = WHITE; kibitzed = FALSE; move_number = 0; memset(game_history, 0, sizeof(game_history)); memset(game_history_x, 0, sizeof(game_history_x)); hash_history[move_number] = hash; setbuf (stdout, NULL); setbuf (stdin, NULL); /* keep looping for input, and responding to it: */ while (TRUE) { /* case where it's the computer's turn to move: */ if (!is_edit_mode && (comp_color == white_to_move || automode) && !force_mode && !must_sit && !result) { /* whatever happens, never allow pondering in normal search */ is_pondering = FALSE; cpu_start = clock (); comp_move = think (); cpu_end = clock(); ply = 0; /* must_sit can be changed by search */ if (!must_sit || must_go != 0) { /* check for a game end: */ if (( ((Variant == Losers || Variant == Suicide) && ((result != white_is_mated) && (result != black_is_mated))) || ((Variant == Normal || Variant == Crazyhouse || Variant == Bughouse) && ((comp_color == 1 && result != white_is_mated) || (comp_color == 0 && result != black_is_mated) ))) && result != stalemate && result != draw_by_fifty && result != draw_by_rep) { comp_to_coord (comp_move, output); hash_history[move_number] = hash; game_history[move_number] = comp_move; make (&comp_move, 0); /* saves state info */ game_history_x[move_number++] = path_x[0]; userealholdings = 0; must_go--; /* check to see if we draw by rep/fifty after our move: */ if (is_draw ()) { result = draw_by_rep; } else if (fifty > 100) { result = draw_by_fifty; } root_to_move ^= 1; reset_piece_square (); if (book_ply < 40) { if (!book_ply) { strcpy(opening_history, output); } else { strcat(opening_history, output); } } book_ply++; printf ("\nNodes: %ld (%0.2f%% qnodes)\n", nodes, (float) ((float) qnodes / (float) nodes * 100.0)); elapsed = (cpu_end-cpu_start)/(double) CLOCKS_PER_SEC; nps = (float) nodes/(float) elapsed; if (!elapsed) printf ("NPS: N/A\n"); else printf ("NPS: %ld\n", (long int) nps); printf("ECacheProbes : %ld ECacheHits : %ld HitRate : %f%%\n", ECacheProbes, ECacheHits, ((float)ECacheHits/((float)ECacheProbes+1)) * 100); printf("TTStores : %ld TTProbes : %ld TTHits : %ld HitRate : %f%%\n", TTStores, TTProbes, TTHits, ((float)TTHits/((float)TTProbes+1)) * 100); printf("NTries : %d NCuts : %d CutRate : %f%% TExt: %d\n", NTries, NCuts, (((float)NCuts*100)/((float)NTries+1)), TExt); printf("Check extensions: %ld Razor drops : %ld Razor Material : %ld\n", ext_check, razor_drop, razor_material); printf("EGTB Hits: %d EGTB Probes: %d Efficiency: %3.1f%%\n", EGTBHits, EGTBProbes, (((float)EGTBHits*100)/(float)(EGTBProbes+1))); printf("Move ordering : %f%%\n", (((float)FHF*100)/(float)(FH+1))); printf("Material score: %d Eval : %d White hand: %d Black hand : %d\n", Material, eval(), white_hand_eval, black_hand_eval); printf("Hash : %X HoldHash : %X\n", hash, hold_hash); /* check to see if we mate our opponent with our current move: */ if (!result) { if (xb_mode) { /* safety in place here */ if (comp_move.from != dummy.from || comp_move.target != dummy.target) printf ("move %s\n", output); if (Variant == Bughouse) { CheckBadFlow(FALSE); } } else { if (comp_move.from != dummy.from || comp_move.target != dummy.target) printf ("\n%s\n", output); } } else { if (xb_mode) { if (comp_move.from != dummy.from || comp_move.target != dummy.target) printf ("move %s\n", output); } else { if (comp_move.from != dummy.from || comp_move.target != dummy.target) printf ("\n%s\n", output); } if (result == white_is_mated) { printf ("0-1 {Black Mates}\n"); } else if (result == black_is_mated) { printf ("1-0 {White Mates}\n"); } else if (result == draw_by_fifty) { printf ("1/2-1/2 {Fifty move rule}\n"); } else if (result == draw_by_rep) { printf ("1/2-1/2 {3 fold repetition}\n"); } else { printf ("1/2-1/2 {Draw}\n"); } automode = 0; } } /* we have been mated or stalemated: */ else { if (result == white_is_mated) { printf ("0-1 {Black Mates}\n"); } else if (result == black_is_mated) { printf ("1-0 {White Mates}\n"); } else if (result == draw_by_fifty) { printf ("1/2-1/2 {Fifty move rule}\n"); } else if (result == draw_by_rep) { printf ("1/2-1/2 {3 fold repetition}\n"); } else { printf ("1/2-1/2 {Draw}\n"); } automode = 0; } } } /* get our input: */ if (!xb_mode) { if (show_board) { printf ("\n"); display_board (stdout, 1-comp_color); } if (!automode) { printf ("Sjeng: "); rinput (input, STR_BUFF, stdin); } } else { /* start pondering */ if ((must_sit || (allow_pondering && !is_edit_mode && !force_mode && move_number != 0) || is_analyzing) && !result && !automode) { is_pondering = TRUE; think(); is_pondering = FALSE; ply = 0; } if (!automode) { rinput (input, STR_BUFF, stdin); } } /* check to see if we have a move. If it's legal, play it. */ if (!is_edit_mode && is_move (&input[0])) { if (verify_coord (input, &move)) { game_history[move_number] = move; hash_history[move_number] = hash; make (&move, 0); game_history_x[move_number++] = path_x[0]; reset_piece_square (); root_to_move ^= 1; if (book_ply < 40) { if (!book_ply) { strcpy(opening_history, input); } else { strcat(opening_history, input); } } book_ply++; if (show_board) { printf ("\n"); display_board (stdout, 1-comp_color); } } else { printf ("Illegal move: %s\n", input); } } else { /* make everything lower case for convenience: */ /* GCP: except for setboard, which is case sensitive */ if (!strstr(input, "setboard")) for (p = input; *p; p++) *p = tolower (*p); /* command parsing: */ if (!strcmp (input, "quit")) { fclose(lrn_standard); fclose(lrn_zh); fclose(lrn_suicide); fclose(lrn_losers); free_hash(); free_ecache(); exit (EXIT_SUCCESS); } else if (!strcmp (input, "exit")) { if (is_analyzing) { is_analyzing = FALSE; is_pondering = FALSE; time_for_move = 0; } else { fclose(lrn_standard); fclose(lrn_zh); fclose(lrn_suicide); fclose(lrn_losers); free_hash(); free_ecache(); exit (EXIT_SUCCESS); } } else if (!strcmp (input, "diagram") || !strcmp (input, "d")) { toggle_bool (&show_board); } else if (!strncmp (input, "perft", 5)) { sscanf (input+6, "%d", &depth); raw_nodes = 0; xstart_time = rtime(); perft (depth); printf ("Raw nodes for depth %d: %ld\n", depth, raw_nodes); printf("Time : %.2f\n", (float)rdifftime(rtime(), xstart_time)/100.); } else if (!strcmp (input, "new")) { if (xb_mode) { printf("tellics set 1 Sjeng " VERSION " (2001-9-28/%s)\n", setcode); } if (!is_analyzing) { memcpy(material, std_material, sizeof(std_material)); Variant = Normal; // memcpy(material, zh_material, sizeof(zh_material)); //Variant = Crazyhouse; init_game (); initialize_hash(); if (!braindeadinterface) { clear_tt(); init_book(); reset_ecache(); } force_mode = FALSE; must_sit = FALSE; go_fast = FALSE; piecedead = FALSE; partnerdead = FALSE; kibitzed = FALSE; fixed_time = FALSE; root_to_move = WHITE; comp_color = 0; move_number = 0; hash_history[move_number] = 0; bookidx = 0; my_rating = opp_rating = 2000; must_go = 0; tradefreely = 1; automode = 0; CheckBadFlow(TRUE); ResetHandValue(); } else { init_game (); move_number = 0; } } else if (!strcmp (input, "xboard")) { xb_mode = TRUE; toggle_bool (&show_board); signal (SIGINT, SIG_IGN); printf ("\n"); /* Reset f5 in case we left with partner */ printf("tellics set f5 1=1\n"); BegForPartner(); } else if (!strcmp (input, "nodes")) { printf ("Number of nodes: %ld (%0.2f%% qnodes)\n", nodes, (float) ((float) qnodes / (float) nodes * 100.0)); } else if (!strcmp (input, "nps")) { elapsed = (cpu_end-cpu_start)/(double) CLOCKS_PER_SEC; nps = (float) nodes/(float) elapsed; if (!elapsed) printf ("NPS: N/A\n"); else printf ("NPS: %ld\n", (long int) nps); } else if (!strcmp (input, "post")) { toggle_bool (&post); if (xb_mode) post = TRUE; } else if (!strcmp (input, "nopost")) { post = FALSE; } else if (!strcmp (input, "random")) { continue; } else if (!strcmp (input, "hard")) { allow_pondering = TRUE; continue; } else if (!strcmp (input, "easy")) { allow_pondering = FALSE; continue; } else if (!strcmp (input, "?")) { continue; } else if (!strcmp (input, "white")) { white_to_move = 1; root_to_move = WHITE; comp_color = 0; } else if (!strcmp (input, "black")) { white_to_move = 0; root_to_move = BLACK; comp_color = 1; } else if (!strcmp (input, "force")) { force_mode = TRUE; } else if (!strcmp (input, "eval")) { check_phase(); printf("Eval: %d\n", eval()); } else if (!strcmp (input, "go")) { comp_color = white_to_move; force_mode = FALSE; } else if (!strncmp (input, "time", 4)) { sscanf (input+5, "%ld", &time_left); } else if (!strncmp (input, "otim", 4)) { sscanf (input+5, "%ld", &opp_time); } else if (!strncmp (input, "level", 5)) { if (strstr(input+6, ":")) { /* time command with seconds */ sscanf (input+6, "%ld %ld:%ld %ld", &moves_to_tc, &min_per_game, &sec_per_game, &inc); time_left = (min_per_game*6000) + (sec_per_game * 100); opp_time = time_left; } else { /* extract the time controls: */ sscanf (input+6, "%ld %ld %ld", &moves_to_tc, &min_per_game, &inc); time_left = min_per_game*6000; opp_time = time_left; } fixed_time = FALSE; time_cushion = 0; } else if (!strncmp (input, "rating", 6)) { sscanf (input+7, "%ld %ld", &my_rating, &opp_rating); if (my_rating == 0) my_rating = 2000; if (opp_rating == 0) opp_rating = 2000; } else if (!strncmp (input, "holding", 7)) { ProcessHoldings(input); } else if (!strncmp (input, "variant", 7)) { if (strstr(input, "normal")) { Variant = Normal; memcpy(material, std_material, sizeof(std_material)); init_book(); } else if (strstr(input, "crazyhouse")) { Variant = Crazyhouse; memcpy(material, zh_material, sizeof(zh_material)); init_book(); } else if (strstr(input, "bughouse")) { Variant = Bughouse; memcpy(material, zh_material, sizeof(zh_material)); init_book(); } else if (strstr(input, "suicide")) { Variant = Suicide; Giveaway = FALSE; memcpy(material, suicide_material, sizeof(suicide_material)); init_book(); } else if (strstr(input, "giveaway")) { Variant = Suicide; Giveaway = TRUE; memcpy(material, suicide_material, sizeof(suicide_material)); init_book(); } else if (strstr(input, "losers")) { Variant = Losers; memcpy(material, losers_material, sizeof(losers_material)); init_book(); } initialize_hash(); clear_tt(); reset_ecache(); } else if (!strncmp (input, "analyze", 7)) { is_analyzing = TRUE; is_pondering = TRUE; think(); ply = 0; } else if (!strncmp (input, "undo", 4)) { printf("Move number : %d\n", move_number); if (move_number > 0) { path_x[0] = game_history_x[--move_number]; unmake(&game_history[move_number], 0); reset_piece_square(); root_to_move ^= 1; } } else if (!strncmp (input, "remove", 5)) { if (move_number > 1) { path_x[0] = game_history_x[--move_number]; unmake(&game_history[move_number], 0); reset_piece_square(); path_x[0] = game_history_x[--move_number]; unmake(&game_history[move_number], 0); reset_piece_square(); } } else if (!strncmp (input, "edit", 4)) { is_edit_mode = TRUE; edit_color = WHITE; } else if (!strncmp (input, ".", 1) && is_edit_mode) { is_edit_mode = FALSE; if (wking_loc == 30) white_castled = no_castle; if (bking_loc == 114) black_castled = no_castle; book_ply = 50; ep_square = 0; move_number = 0; memset(opening_history, 0, sizeof(opening_history)); clear_tt(); initialize_hash(); reset_piece_square(); } else if (is_edit_mode && !strncmp (input, "c", 1)) { if (edit_color == WHITE) edit_color = BLACK; else edit_color = WHITE; } else if (is_edit_mode && !strncmp (input, "#", 1)) { reset_board(); move_number = 0; } else if (is_edit_mode && isalpha(input[0]) && isalpha(input[1]) && isdigit(input[2])) { PutPiece(edit_color, input[0], input[1], input[2]); } else if (!strncmp (input, "partner", 7)) { HandlePartner(input+7); } else if (!strncmp (input, "$partner", 8)) { HandlePartner(input+8); } else if (!strncmp (input, "ptell", 5)) { HandlePtell(input); } else if (!strncmp (input, "test", 4)) { run_epd_testsuite(); } else if (!strncmp (input, "st", 2)) { sscanf(input+3, "%d", &fixed_time); fixed_time = fixed_time * 100; } else if (!strncmp (input, "book", 4)) { build_book(); } else if (!strncmp (input, "speed", 5)) { speed_test(); } else if (!strncmp (input, "result", 6)) { if (cfg_booklearn) { if (strstr (input+7, "1-0")) { if (comp_color == 1) book_learning(WIN); else book_learning(LOSS); } else if (strstr(input+7, "0-1")) { if (comp_color == 1) book_learning(LOSS); else book_learning(WIN); } else if (strstr(input+7, "1/2-1/2")) { book_learning(DRAW); }; } } else if (!strncmp (input, "prove", 5)) { printf("\nMax time to search (s): "); start_time = rtime(); rinput(readbuff, STR_BUFF, stdin); pn_time = atol(readbuff) * 100; printf("\n"); proofnumbersearch(); } else if (!strncmp (input, "ping", 4)) { sscanf (input+5, "%d", &pingnum); printf("pong %d\n", pingnum); } else if (!strncmp (input, "fritz", 5)) { braindeadinterface = TRUE; } else if (!strncmp (input, "reset", 5)) { memcpy(material, std_material, sizeof(std_material)); Variant = Normal; init_game (); initialize_hash(); clear_tt(); init_book(); reset_ecache(); force_mode = FALSE; fixed_time = FALSE; root_to_move = WHITE; comp_color = 0; move_number = 0; bookidx = 0; my_rating = opp_rating = 2000; } else if (!strncmp (input, "setboard", 8)) { setup_epd_line(input+9); } else if (!strncmp (input, "buildegtb", 9)) { Variant = Suicide; gen_all_tables(); } else if (!strncmp (input, "lookup", 6)) { Variant = Suicide; printf("Value : %d\n", egtb(white_to_move)); } else if (!strncmp (input, ".", 1)) { /* periodic updating and were not searching */ /* most likely due to proven mate */ continue; } else if (!strncmp (input, "sd", 2)) { sscanf(input+3, "%d", &maxdepth); printf("New max depth set to: %d\n", maxdepth); continue; } else if (!strncmp (input, "auto", 4)) { automode = 1; continue; } else if (!strncmp (input, "protover", 8)) { printf("feature ping=1 setboard=1 playother=0 san=0 usermove=0 time=1\n"); printf("feature draw=0 sigint=0 sigterm=0 reuse=1 analyze=1\n"); printf("feature myname=\"Sjeng " VERSION "\"\n"); printf("feature variants=\"normal,bughouse,crazyhouse,suicide,giveaway,losers\"\n"); printf("feature colors=1 ics=0 name=0 pause=0 done=1\n"); xb_mode = 2; } else if (!strncmp (input, "accepted", 8)) { /* do nothing as of yet */ } else if (!strncmp (input, "rejected", 8)) { printf("Interface does not support a required feature...expect trouble.\n"); } else if (!strncmp (input, "warranty", 8)) { printf("\n BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\n" "FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN\n" "OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\n" "PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\n" "OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n" "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS\n" "TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE\n" "PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\n" "REPAIR OR CORRECTION.\n" "\n"); printf(" IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\n" "WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\n" "REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\n" "INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\n" "OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\n" "TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\n" "YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\n" "PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\n" "POSSIBILITY OF SUCH DAMAGES.\n\n"); } else if (!strncmp (input, "distribution", 12)) { printf("\n You may copy and distribute verbatim copies of the Program's\n" "source code as you receive it, in any medium, provided that you\n" "conspicuously and appropriately publish on each copy an appropriate\n" "copyright notice and disclaimer of warranty; keep intact all the\n" "notices that refer to this License and to the absence of any warranty;\n" "and give any other recipients of the Program a copy of this License\n" "along with the Program.\n" "\n" "You may charge a fee for the physical act of transferring a copy, and\n" "you may at your option offer warranty protection in exchange for a fee.\n\n"); } else if (!strcmp (input, "help")) { printf ("\n%s\n\n", divider); printf ("diagram/d: toggle diagram display\n"); printf ("exit/quit: terminate Sjeng\n"); printf ("go: make Sjeng play the side to move\n"); printf ("new: start a new game\n"); printf ("level : the xboard style command to set time\n"); printf (" should be in the form: where:\n"); printf (" a -> moves to TC (0 if using an ICS style TC)\n"); printf (" b -> minutes per game\n"); printf (" c -> increment in seconds\n"); printf ("nodes: outputs the number of nodes searched\n"); printf ("nps: outputs Sjeng's NPS in search\n"); printf ("perft : compute raw nodes to depth x\n"); printf ("post: toggles thinking output\n"); printf ("xboard: put Sjeng into xboard mode\n"); printf ("test: run an EPD testsuite\n"); printf ("speed: test movegen and evaluation speed\n"); printf ("warranty: show warranty details\n"); printf ("distribution: show distribution details\n"); printf( "proof: try to prove or disprove the current pos\n"); printf( "sd : limit thinking to depth x\n"); printf( "st : limit thinking to x centiseconds\n"); printf( "setboard : set board to a specified FEN string\n"); printf( "undo: back up a half move\n"); printf( "remove: back up a full move\n"); printf( "force: disable computer moving\n"); printf( "auto: computer plays both sides\n"); printf ("\n%s\n\n", divider); show_board = 0; } else if (!xb_mode) { printf ("Illegal move: %s\n", input); } } } return 0; } sjeng-11.2.orig/sjeng.h0100644000175000017500000000646307343452327014024 0ustar lukaslukas/* Sjeng - a chess variants playing program Copyright (C) 2000 Gian-Carlo Pascutto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA File: sjeng.h Purpose: global definitions */ #ifndef SJENG_H #define SJENG_H #include "config.h" #include #include #include #include #include #include #ifdef HAVE_SYS_TIMEB_H #include #endif #define NDEBUG #include #define DIE (*(int *)(NULL) = 0) /* GCP : my code uses WHITE=0 and BLACK=1 so reverse this */ #define WHITE 0 #define BLACK 1 #define ToMove (white_to_move ? 0 : 1) #define NotToMove (white_to_move ? 1 : 0) #define Hash(x,y) (hash ^= zobrist[(x)][(y)]) #define Crazyhouse 0 #define Bughouse 1 #define Normal 2 #define Suicide 3 #define Losers 4 #define Opening 0 #define Middlegame 1 #define Endgame 2 #define mindepth 2 /* define names for piece constants: */ #define frame 0 #define wpawn 1 #define bpawn 2 #define wknight 3 #define bknight 4 #define wking 5 #define bking 6 #define wrook 7 #define brook 8 #define wqueen 9 #define bqueen 10 #define wbishop 11 #define bbishop 12 #define npiece 13 /* result flags: */ #define no_result 0 #define stalemate 1 #define white_is_mated 2 #define black_is_mated 3 #define draw_by_fifty 4 #define draw_by_rep 5 /* arrays maybe ? */ #undef FASTCALC #ifdef FASTCALC #define rank(square) ((((square)-26)/12)+1) #define file(square) ((((square)-26)%12)+1) #else #define rank(square) (rank[(square)]) #define file(square) (file[(square)]) #endif #define diagl(square) (diagl[(square)]) #define diagr(square) (diagr[(square)]) #ifndef INPROBECODE typedef enum {FALSE, TRUE} bool; #endif /* castle flags: */ #define no_castle 0 #define wck 1 #define wcq 2 #define bck 3 #define bcq 4 typedef struct { int from; int target; int captured; int promoted; int castled; int ep; } move_s; typedef struct { int cap_num; int was_promoted; int epsq; int fifty; } move_x; #if defined(HAVE_SYS_TIMEB_H) && (defined(HAVE_FTIME) || defined(HAVE_GETTIMEOFDAY)) typedef struct timeb rtime_t; #else typedef time_t rtime_t; #endif #define STR_BUFF 256 #define MOVE_BUFF 512 #define INF 1000000 #define PV_BUFF 300 #define AddMaterial(x) Material += material[(x)] #define RemoveMaterial(x) Material -= material[(x)] #define UPPER 1 #define LOWER 2 #define EXACT 3 #define HMISS 4 #define DUMMY 0 #define LOSS 0 #define WIN 1 #define DRAW 2 #define max(x, y) ((x) > (y) ? (x) : (y)) #define mix(x, y) ((x) < (y) ? (x) : (y)) #endif sjeng-11.2.orig/configure.in0100644000175000017500000000122207412717506015042 0ustar lukaslukasdnl Process this file with autoconf to produce a configure script. AC_INIT(sjeng.c) AM_INIT_AUTOMAKE(Sjeng-Free, 11.2) AM_CONFIG_HEADER(config.h) dnl Checks for programs. AC_PROG_CC AC_PROG_CXX dnl Checks for libraries. AC_CHECK_LIB(gdbm, gdbm_open) dnl Check for floor() in the math library AC_CHECK_LIB(m, floor) dnl Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS(sys/time.h sys/timeb.h unistd.h) dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_HEADER_TIME dnl Checks for library functions. AC_TYPE_SIGNAL AC_CHECK_FUNCS(ftime select strstr gettimeofday) AC_OUTPUT(Makefile tests/Makefile books/Makefile) sjeng-11.2.orig/install-sh0100644000175000017500000001124307114425141014524 0ustar lukaslukas#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. # # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" tranformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 sjeng-11.2.orig/missing0100644000175000017500000001421307114425142014120 0ustar lukaslukas#! /bin/sh # Common stub for a few missing GNU programs while installing. # Copyright (C) 1996, 1997 Free Software Foundation, Inc. # Franc,ois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi case "$1" in -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file yacc create \`y.tab.[ch]', if possible, from existing .[ch]" ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing - GNU libit 0.0" ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; aclocal) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acinclude.m4' or \`configure.in'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`configure.in'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acconfig.h' or \`configure.in'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' configure.in` test -z "$files" && files="config.h" touch_files= for f in $files; do case "$f" in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; bison|yacc) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.h fi ;; esac fi if [ ! -f y.tab.h ]; then echo >y.tab.h fi if [ ! -f y.tab.c ]; then echo 'main() { return 0; }' >y.tab.c fi ;; lex|flex) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if [ ! -f lex.yy.c ]; then echo 'main() { return 0; }' >lex.yy.c fi ;; makeinfo) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` fi touch $file ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and you do not seem to have it handy on your system. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequirements for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 sjeng-11.2.orig/book.c0100644000175000017500000001464407324554140013636 0ustar lukaslukas/* Sjeng - a chess variants playing program Copyright (C) 2000 Gian-Carlo Pascutto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA File: book.c Purpose: book initialization, selection of book moves, etc... */ #include "sjeng.h" #include "protos.h" #include "extvars.h" char book[4000][161]; char book_flags[4000][41]; int num_book_lines; int book_ply; int use_book; char opening_history[STR_BUFF]; #define book_always 1 /* corresponds with ! */ #define book_never 2 /* corresponds with ? */ #define book_interesting 3 /* !? */ #define book_solid 4 /* = */ #define book_murky 5 /* ?! */ int init_book (void) { /* simply read all the book moves into a book array. The book will be a simple char[5000][81] array (5000 max book lines, since you can't have *too* many when you're doing this slow strncpy method ;) After all, this is really just a kludge 'till I add hashing, and support transpositions and such ;) Returns true if reading in the book was successful. */ FILE *f_book; int ch, i = 0, j = 0; int tagmode = FALSE; /* recognize multiple tags */ int commentmode = FALSE; memset(book_flags, 0, sizeof(book_flags)); memset(book, 0, sizeof(book)); num_book_lines = 0; /* init our random numbers: */ srand((unsigned) time (NULL)); if (Variant == Normal) { if ((f_book = fopen ("normal.opn", "r")) == NULL) return FALSE; } else if (Variant == Crazyhouse) { if ((f_book = fopen ("zh.opn", "r")) == NULL) return FALSE; } else if (Variant == Suicide) { if ((f_book = fopen ("suicide.opn", "r")) == NULL) return FALSE; } else if (Variant == Losers) { if ((f_book = fopen ("losers.opn", "r")) == NULL) return FALSE; } else { if ((f_book = fopen ("bug.opn", "r")) == NULL) return FALSE; } while ((ch = getc(f_book)) != EOF) { if (commentmode) { if (ch == '/') /* end comment */ { commentmode = FALSE; } } else { if (ch == '\n') { /* end of book line */ /* not ending an empty book line */ if (j > 0) { book[i++][j] = '\0'; j = 0; } tagmode = FALSE; } else if (ch == '!') { if (!tagmode) { book_flags[i][((j + 1) / 4) - 1] = book_always; tagmode = TRUE; } else { book_flags[i][((j + 1) / 4) - 1] = book_murky; } } else if (ch == '?') { if (!tagmode) { book_flags[i][((j + 1) / 4) - 1] = book_never; tagmode = TRUE; } else { book_flags[i][((j + 1) / 4) - 1] = book_interesting; } } else if (ch == '=') { book_flags[i][((j + 1) / 4) - 1] = book_solid; tagmode = TRUE; } else if ((ch == ' ') || (ch == '\t')) { /* skip spaces and tabs */ tagmode = FALSE; } else if (ch == '/') /* start comment */ { commentmode = TRUE; } else if (j < 160 && i < 4000) /* middle of book line */ { book[i][j++] = ch; tagmode = FALSE; } /* If j >= 100, then the book line was too long. The rest will be read, but ignored, and will be null-character terminated when a '\n' is read. If i >= 2000, then there are too many book lines. The remaining lines will be read, but ignored. */ } } num_book_lines = i; fclose(f_book); return TRUE; } move_s choose_book_move (void) { /* Since the book is sorted alphabetically, we can use strncpy, and hope to get early exits once we've found the first few moves in the book. Once we choose a book move, we'll make a variable indicate where it was found, so we can start our search for the next move there. */ static int last_book_move = 0; int book_match = FALSE; int i, j, num_moves, random_number, num_replies; char possible_move[5], coord_move[5]; move_s book_replies[4000], moves[400]; char force_move = FALSE; int ic; srand(time(0)); if (!book_ply) last_book_move = 0; num_replies = 0; gen(&moves[0]); num_moves = numb_moves; for (i = last_book_move; i < num_book_lines; i++) { /* check to see if opening line matches up to current book_ply: */ if (!strncmp(opening_history, book[i], (book_ply * 4)) || (!book_ply)) { /* if book move is legal, add it to possible list of book moves */ if ((book_flags[i][book_ply] != book_never) && (book_flags[i][book_ply] != book_murky)) { if (book_flags[i][book_ply] == book_always) { if (force_move != TRUE) { /* found 1st ! move -> remove normal ones */ force_move = TRUE; num_replies = 0; } } if ((force_move != TRUE) || ((force_move == TRUE) && (book_flags[i][book_ply] == book_always))) { strncpy(possible_move, book[i] + (book_ply * 4), 4); possible_move[4] = '\0'; for (j = 0; j < num_moves; j++) { comp_to_coord(moves[j], coord_move); if (!strcmp(possible_move, coord_move)) { ic = in_check(); make(&moves[0], j); if (check_legal(&moves[0], j, ic)) { book_replies[num_replies++] = moves[j]; book_match = TRUE; } unmake(&moves[0], j); } } } } } /* we can exit the search for a book move early, if we've no longer have a match, but we have found at least one match */ if (!book_match && num_replies) break; } /* now, if we have some book replies, pick our move randomly from book_replies: */ if (!num_replies) return dummy; printf("Book moves: %d\n", num_replies); random_number = rand() % num_replies; return book_replies[random_number]; } sjeng-11.2.orig/mkinstalldirs0100644000175000017500000000121107114425142015321 0ustar lukaslukas#!/bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Last modified: 1994-03-25 # Public domain errstatus=0 for file in ${1+"$@"} ; do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d in ${1+"$@"} ; do pathcomp="$pathcomp$d" case "$pathcomp" in -* ) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" 1>&2 mkdir "$pathcomp" || errstatus=$? fi pathcomp="$pathcomp/" done done exit $errstatus # mkinstalldirs ends here sjeng-11.2.orig/draw.c0100644000175000017500000000667107307525444013650 0ustar lukaslukas/* Sjeng - a chess variants playing program Copyright (C) 2000-2001 Gian-Carlo Pascutto Originally based on Faile, Copyright (c) 2000 Adrien M. Regimbald This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA File: draw.c Purpose: Detect draws */ #include "config.h" #include "sjeng.h" #include "extvars.h" #include "protos.h" bool is_draw (void) { /* GCP: this is straigth from Faile but converted to Sjeng internals */ /* is_draw () is used to see if a position is a draw. Some notes: * - the 2 repetition trick is attempted first: if we have already seen a * position in the search history (not game history), we haven't found * anything better to do than repeat, and searching the position again would * be a waste of time * - if there is no match on the 2 repetition check, we look for an actual * 3 fold repetition * - we can't check for the 50 move rule here, since the 50 move rule must be * checked at the end of a search node due to mates on the 50th move, yet * we want to check for a draw by repetition before we waste any time * searching the position or generating moves * - is_draw () can be used in both search () and search_root () as the * for loop for the 2 repetition trick will exit immediately at the root */ int i, repeats = 0, end, start; /* Check on the 2 repetition trick. Some notes: * - a position can't possibly have occurred once before if fifty isn't * at least 4 * - the end point is picked to look at the least number of positions, ie * if going to the last capture is shorter than looking at the whole search * history, we will do only that much */ if (fifty >= 4) { if ((move_number) < (move_number + ply - 1 - fifty)) { end = move_number + ply - 1 - fifty; } else { end = move_number; } for (i = (move_number + ply - 3); i >= 0 && i >= end; i -= 2) { if (hash == hash_history[i]) { return TRUE; } } } /* Check for actual 3 repetition match. Some notes: * - a position can't possibly have occurred twice before if fifty isn't * at least 6 * - there is no need for us to consider positions encountered during search, * as if there was a match on any of them, it would have been found above * - we need to adjust the starting point here based on who's turn it is: * if it's the same as at the root, we need to subtract one extra */ if (fifty >= 6) { start = move_number - 1 - (ply % 2); end = move_number + ply - 1 - fifty; for (i = start; i >= 0 && i >= end; i -= 2) { if (hash == hash_history[i]) { repeats++; } if (repeats >= 2) { return TRUE; } } } return FALSE; }; sjeng-11.2.orig/eval.c0100644000175000017500000005126607412720160013627 0ustar lukaslukas/* Sjeng - a chess variants playing program Copyright (C) 2000 Gian-Carlo Pascutto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA File: eval.c Purpose: evaluate crazyhouse/bughouse positions */ #include "sjeng.h" #include "extvars.h" #include "protos.h" #include "squares.h" int Material; int std_material[] = { 0, 100, -100, 310, -310, 4000, -4000, 500, -500, 900, -900, 325, -325, 0 }; int zh_material[] = { 0, 100, -100, 210, -210, 4000, -4000, 250, -250, 450, -450, 230, -230, 0 }; int suicide_material[] = { 0, 15, -15, 150, -150, 500, -500, 150, -150, 50, -50, 0, 0, 0 }; int losers_material[] = { 0, 80, -80, 320, -320, 1000, -1000, 350, -350, 400, -400, 270, -270, 0 }; int material[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; const int file[144] = { 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,1,2,3,4,5,6,7,8,0,0, 0,0,1,2,3,4,5,6,7,8,0,0, 0,0,1,2,3,4,5,6,7,8,0,0, 0,0,1,2,3,4,5,6,7,8,0,0, 0,0,1,2,3,4,5,6,7,8,0,0, 0,0,1,2,3,4,5,6,7,8,0,0, 0,0,1,2,3,4,5,6,7,8,0,0, 0,0,1,2,3,4,5,6,7,8,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0 }; const int rank[144] = { 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,1,1,1,1,1,1,1,1,0,0, 0,0,2,2,2,2,2,2,2,2,0,0, 0,0,3,3,3,3,3,3,3,3,0,0, 0,0,4,4,4,4,4,4,4,4,0,0, 0,0,5,5,5,5,5,5,5,5,0,0, 0,0,6,6,6,6,6,6,6,6,0,0, 0,0,7,7,7,7,7,7,7,7,0,0, 0,0,8,8,8,8,8,8,8,8,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0 }; const int diagl[144] = { 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0, 1, 2, 3, 4, 5, 6, 7, 8,0,0, 0,0, 9, 1, 2, 3, 4, 5, 6, 7,0,0, 0,0,10, 9, 1, 2, 3, 4, 5, 6,0,0, 0,0,11,10, 9, 1, 2, 3, 4, 5,0,0, 0,0,12,11,10, 9, 1, 2, 3, 4,0,0, 0,0,13,12,11,10, 9, 1, 2, 3,0,0, 0,0,14,13,12,11,10, 9, 1, 2,0,0, 0,0,15,14,13,12,11,10, 9, 1,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0 }; const int diagr[144] = { 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,15,14,13,12,11,10,9,1,0,0, 0,0,14,13,12,11,10,9,1,2,0,0, 0,0,13,12,11,10,9,1,2,3,0,0, 0,0,12,11,10,9,1,2,3,4,0,0, 0,0,11,10,9,1,2,3,4,5,0,0, 0,0,10,9,1,2,3,4,5,6,0,0, 0,0,9,1,2,3,4,5,6,7,0,0, 0,0,1,2,3,4,5,6,7,8,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0 }; const int sqcolor[144] = { 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,1,0,1,0,1,0,1,0,0,0, 0,0,0,1,0,1,0,1,0,1,0,0, 0,0,1,0,1,0,1,0,1,0,0,0, 0,0,0,1,0,1,0,1,0,1,0,0, 0,0,1,0,1,0,1,0,1,0,0,0, 0,0,0,1,0,1,0,1,0,1,0,0, 0,0,1,0,1,0,1,0,1,0,0,0, 0,0,0,1,0,1,0,1,0,1,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0 }; /* these tables will be used for positional bonuses: */ const int bishop[144] = { 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,-5,-5,-10,-5,-5,-10,-5,-5,0,0, 0,0,-5,10,5,10,10,5,10,-5,0,0, 0,0,-5,5,6,15,15,6,5,-5,0,0, 0,0,-5,3,15,10,10,15,3,-5,0,0, 0,0,-5,3,15,10,10,15,3,-5,0,0, 0,0,-5,5,6,15,15,6,5,-5,0,0, 0,0,-5,10,5,10,10,5,10,-5,0,0, 0,0,-5,-5,-10,-5,-5,-10,-5,-5,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0}; const int black_knight[144] = { 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,-20,-10,-10,-10,-10, -10,-10,-20,0,0, 0,0,-10, 15, 25, 25, 25, 25, 15,-10,0,0, 0,0,-10, 15, 25, 35, 35 , 35, 15,-10,0,0, 0,0,-10, 10, 25, 20, 25, 25, 10,-10,0,0, 0,0,-10, 0, 20, 20, 20, 20, 0,-10,0,0, 0,0,-10, 0, 15, 15, 15, 15, 0,-10,0,0, 0,0,-10, 0, 0, 3, 3, 0, 0,-10,0,0, 0,0,-20,-35,-10,-10,-10, -10,-35,-20,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0}; const int white_knight[144] = { 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,-20, -35,-10, -10, -10,-10, -35, -20,0,0, 0,0,-10, 0, 0, 3, 3, 0, 0, -10,0,0, 0,0,-10, 0, 15, 15, 15, 15, 0, -10,0,0, 0,0,-10, 0, 20, 20, 20, 20, 0, -10,0,0, 0,0,-10, 10, 25, 20, 25, 25, 10, -10,0,0, 0,0,-10, 15, 25, 35, 35, 35, 15, -10,0,0, 0,0,-10, 15, 25, 25, 25, 25, 15, -10,0,0, 0,0,-20, -10,-10, -10, -10,-10, -10, -20,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0}; const int white_pawn[144] = { 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,25, 25, 35, 5, 5, 50, 45, 30,0,0, 0,0, 0, 0, 0, 7, 7, 5, 5, 0,0,0, 0,0, 0, 0, 0, 14, 14, 0, 0, 0,0,0, 0,0, 0, 0, 10, 20, 20, 10, 5, 5,0,0, 0,0,12, 18, 18, 27, 27, 18, 18, 18,0,0, 0,0,25, 30, 30, 35, 35, 35, 30, 25,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0 }; const int black_pawn[144] = { 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,30, 30, 30, 35, 35, 35, 30, 25,0,0, 0,0,12, 18, 18, 27, 27, 18, 18, 18,0,0, 0,0, 0, 0, 10, 20, 20, 10, 5, 5,0,0, 0,0, 0, 0, 0, 14, 14, 0, 0, 0,0,0, 0,0, 0, 0, 0, 7, 7, 5, 5, 0,0,0, 0,0,25, 25, 35, 5, 5, 50, 45, 30,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0 }; /* to be used during opening and middlegame for white king positioning: */ const int white_king[144] = { 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,-100, 7, 4, 0, 10 , 4, 7,-100,0,0, 0,0,-250,-200,-150,-100,-100,-150,-200,-250,0,0, 0,0,-350,-300,-300,-250,-250,-300,-300,-350,0,0, 0,0,-400,-400,-400,-350,-350,-400,-400,-400,0,0, 0,0,-450,-450,-450,-450,-450,-450,-450,-450,0,0, 0,0,-500,-500,-500,-500,-500,-500,-500,-500,0,0, 0,0,-500,-500,-500,-500,-500,-500,-500,-500,0,0, 0,0,-500,-500,-500,-500,-500,-500,-500,-500,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0}; /* to be used during opening and middlegame for black king positioning: */ const int black_king[144] = { 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,-500,-500,-500,-500,-500,-500,-500,-500,0,0, 0,0,-500,-500,-500,-500,-500,-500,-500,-500,0,0, 0,0,-500,-500,-500,-500,-500,-500,-500,-500,0,0, 0,0,-450,-450,-450,-450,-450,-450,-450,-450,0,0, 0,0,-400,-400,-400,-350,-350,-400,-400,-400,0,0, 0,0,-350,-300,-300,-250,-250,-300,-300,-350,0,0, 0,0,-250,-200,-150,-100,-100,-150,-200,-250,0,0, 0,0,-100, 7, 4, 0, 10 , 4, 7,-100,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0}; const int black_queen[144] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5,10,10, 5, 5, 5, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0,-30,-30,-30,-30,-30,-30,-30,-30,0, 0, 0,0,-60,-40,-40,-60,-60,-40,-40,-60,0,0, 0,0,-40,-40,-40,-40,-40,-40,-40,-40,0,0, 0,0,-15,-15,-15,-10,-10,-15,-15,-15,0,0, 0,0,0,0,0,7,10,5,0,0,0,0, 0,0,0,0,0, 5,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0}; const int white_queen[144] = { 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,5,0,0,0,0,0,0, 0,0,0,0,0,7,10,5,0,0,0,0, 0,0,-15,-15,-15,-10,-10,-15,-15,-15,0,0, 0,0,-40,-40,-40,-40,-40,-40,-40,-40,0,0, 0,0,-60,-40,-40,-60,-60,-40,-40,-60,0,0, 0, 0,-30,-30,-30,-30,-30,-30,-30,-30,0, 0, 0, 0, 0, 0, 3, 3, 3,3,3, 0, 0, 0, 0, 0, 5, 5, 5,10,10,5,5,5, 0, 0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0}; const int black_rook[144] = { 0,0, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0,0, 10, 15, 20, 25, 25, 20, 15, 10,0,0, 0,0, 0, 10, 15, 20, 20, 15, 10, 0,0,0, 0,0,-20,-20,-20,-20,-20,-20,-20,-20,0,0, 0,0,-20,-20,-20,-30,-30,-20,-20,-20,0,0, 0,0,-20,-20,-20,-20,-20,-20,-20,-20,0,0, 0,0,-15,-15,-15,-10,-10,-15,-15,-15,0,0, 0,0, 0, 0, 0, 7, 10, 0, 0, 0,0,0, 0,0, 2, 2, 2, 2, 2, 2, 2, 2,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0 }; const int white_rook[144] = { 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0, 2, 2, 2, 2, 2, 2, 2, 2,0,0, 0,0, 0, 0, 0, 7, 10, 0, 0, 0,0,0, 0,0,-15,-15,-15,-10,-10,-15,-15,-15,0,0, 0,0,-20,-20,-20,-20,-20,-20,-20,-20,0,0, 0,0,-20,-20,-20,-30,-30,-20,-20,-20,0,0, 0,0,-20,-20,-20,-20,-20,-20,-20,-20,0,0, 0,0, 0, 10, 15, 20, 20, 15, 10, 0,0,0, 0,0, 10, 15, 20, 25, 25, 20, 15, 10,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0 }; /* tropism values of 0 and 8 are bogus, and should never happen in the actual eval */ int pre_p_tropism[9] = { 9999, 40, 20, 10, 3, 1, 1, 0, 9999}; int pre_r_tropism[9] = { 9999, 50, 40, 15, 5, 1, 1, 0, 9999}; int pre_n_tropism[9] = { 9999, 50, 70, 35, 10, 2, 1, 0, 9999}; int pre_q_tropism[9] = { 9999, 100, 60, 20, 5, 2, 0, 0, 9999}; int pre_b_tropism[9] = { 9999, 50, 25, 15, 5, 2, 2, 2, 9999}; unsigned char p_tropism[144][144]; unsigned char q_tropism[144][144]; unsigned char n_tropism[144][144]; unsigned char r_tropism[144][144]; unsigned char b_tropism[144][144]; int ksafety_scaled[15][9] = { { -5, 5, 10, 15, 50, 80, 150, 150, 150 }, /* nothing */ { -5, 15, 20, 25, 70, 150, 200, 200, 200 }, /* 1 pawns */ { -5, 15, 30, 30, 100, 200, 300, 300, 300 }, /* 2 pawns */ { -10, 20, 40, 40, 100, 200, 300, 300, 400 }, /* 1 minor piece */ { -10, 30, 50, 80, 150, 300, 400, 400, 500 }, /* 1 minor piece + pawn */ { -10, 35, 60, 100, 200, 250, 400, 400, 500 }, /* queen */ { -10, 40, 70, 110, 210, 300, 500, 500, 600 }, /* queen + pawn */ { -10, 45, 75, 125, 215, 300, 500, 600, 700 }, /* queen + 2 pawn */ { -10, 60, 90, 130, 240, 350, 500, 600, 700 }, /* queen + piece */ { -15, 60, 95, 145, 260, 350, 500, 600, 700 }, /* queen + piece + pawn */ { -15, 60, 100, 150, 270, 350, 500, 600, 700 }, /* 2 queen */ { -15, 60, 110, 160, 280, 400, 600, 700, 800 }, { -20, 70, 115, 165, 290, 400, 600, 700, 800 }, { -20, 80, 120, 170, 300, 450, 700, 800, 900 }, { -20, 80, 125, 175, 310, 450, 700, 800, 900 } }; void initialize_eval(void) { int i, j; if (havercfile) { for (i = 0; i < 15; i++) { for(j = 0; j < 9; j++) { ksafety_scaled[i][j] = (int)((float)cfg_ksafety[i][j] * (float)cfg_scalefac); } } for(i = 1; i < 8; i++) { pre_p_tropism[i] = (int)((float)cfg_tropism[0][i-1] * (float)cfg_scalefac); pre_b_tropism[i] = (int)((float)cfg_tropism[1][i-1] * (float)cfg_scalefac); pre_n_tropism[i] = (int)((float)cfg_tropism[2][i-1] * (float)cfg_scalefac); pre_r_tropism[i] = (int)((float)cfg_tropism[3][i-1] * (float)cfg_scalefac); pre_q_tropism[i] = (int)((float)cfg_tropism[4][i-1] * (float)cfg_scalefac); } } for(i = 0; i < 144; i++) { for(j = 0; j < 144; j++) { p_tropism[i][j] = pre_p_tropism[max(abs(rank(i) - rank(j)), abs(file(i) - file(j)))]; b_tropism[i][j] = pre_b_tropism[max(abs(rank(i) - rank(j)), abs(file(i) - file(j)))]; n_tropism[i][j] = pre_n_tropism[max(abs(rank(i) - rank(j)), abs(file(i) - file(j)))]; r_tropism[i][j] = pre_r_tropism[max(abs(rank(i) - rank(j)), abs(file(i) - file(j)))]; q_tropism[i][j] = pre_q_tropism[max(abs(rank(i) - rank(j)), abs(file(i) - file(j)))]; } } } long int eval (void) { /* return a score for the current middlegame position: */ int i, a, j; long int score = 0; int in_cache; int safety, badsquares; int norm_white_hand_eval, norm_black_hand_eval; int wdev_dscale, bdev_dscale; if (Variant == Normal) { return std_eval(); } else if (Variant == Suicide) { return suicide_eval(); } else if (Variant == Losers) { return losers_eval(); } in_cache = 0; checkECache(&score, &in_cache); if(in_cache) { if (white_to_move == 1) return score; return -score; } /* set up development scalefactor depending on material * in hand */ if (cfg_devscale) { /* computer plays black -> no white downscaling */ if (white_to_move != comp_color) { if (white_hand_eval <= 200 && (Variant != Bughouse)) { /* 2 pawns or less */ wdev_dscale = 2; } else if (white_hand_eval >= 700) { /* queen + minor, three minors or more */ wdev_dscale = 0; } else { wdev_dscale = 1; } } else wdev_dscale = 0; if (white_to_move == comp_color) { if ((-black_hand_eval) <= 200 && (Variant != Bughouse)) { /* 2 pawns or less */ bdev_dscale = 2; } else if ((-black_hand_eval) >= 700) { /* queen + pawn, two minors + pawn */ bdev_dscale = 0; } else { bdev_dscale = 1; } } else bdev_dscale = 0; } else { wdev_dscale = bdev_dscale = 0; } /* loop through the board, adding material value, as well as positional bonuses for all pieces encountered: */ for (a = 1, j = 1;(a <= piece_count); j++) { i = pieces[j]; if (!i) continue; else a++; switch (board[i]) { case (wpawn): score += 100; score += white_pawn[i] >> wdev_dscale; score += p_tropism[i][bking_loc]; break; case (bpawn): score -= 100; score -= black_pawn[i] >> bdev_dscale; score -= p_tropism[i][wking_loc]; break; case (wrook): score += 250; score += white_rook[i] >> wdev_dscale; score += r_tropism[i][bking_loc]; break; case (brook): score -= 250; score -= black_rook[i] >> bdev_dscale; score -= r_tropism[i][wking_loc]; break; case (wbishop): score += 230; score += bishop[i] >> wdev_dscale; score += b_tropism[i][bking_loc]; break; case (bbishop): score -= 230; score -= bishop[i] >> bdev_dscale; score -= b_tropism[i][wking_loc]; break; case (wknight): score += 210; score += white_knight[i] >> wdev_dscale; score += n_tropism[i][bking_loc]; break; case (bknight): score -= 210; score -= black_knight[i] >> bdev_dscale; score -= n_tropism[i][wking_loc]; break; case (wqueen): score += 450; score += white_queen[i] >> wdev_dscale; score += q_tropism[i][bking_loc]; break; case (bqueen): score -= 450; score -= black_queen[i] >> bdev_dscale; score -= q_tropism[i][wking_loc]; break; } } /* we scale our kings position depending on how much material the _other_ side has in hand */ score += white_king[wking_loc] >> bdev_dscale; score -= black_king[bking_loc] >> wdev_dscale; /* we do not give a bonus for castling, but it is important to keep our options open */ if (!white_castled && moved[30]) { score -= 30; } if (!black_castled && moved[114]) { score += 30; } /* give penalties for blocking the e/d pawns: */ if (!moved[41] && board[53] != npiece) score -= 15; if (!moved[42] && board[54] != npiece) score -= 15; if (!moved[101] && board[89] != npiece) score += 15; if (!moved[102] && board[90] != npiece) score += 15; if (cfg_smarteval) { /* Pawn cover for the King please... */ /* White */ if (wking_loc != E1 && wking_loc != D1) { if (board[wking_loc+11] != wpawn) score -= 24; if (board[wking_loc+12] != wpawn) score -= 35; if (board[wking_loc+13] != wpawn) score -= 24; /* When castled, building a fortress wont hurt */ if (white_castled) { if (board[bking_loc-25] == bpawn) score += 11; if (board[bking_loc-24] == bpawn) score += 15; if (board[bking_loc-23] == bpawn) score += 11; } } /* Black */ if (bking_loc != E8 && bking_loc != D8) { if (board[bking_loc-13] != bpawn) score += 24; if (board[bking_loc-12] != bpawn) score += 35; if (board[bking_loc-11] != bpawn) score += 24; /* When castled, building a fortress wont hurt */ if (black_castled) { if (board[bking_loc-25] == bpawn) score -= 11; if (board[bking_loc-24] == bpawn) score -= 15; if (board[bking_loc-23] == bpawn) score -= 11; } } /* Develop stuff */ if (moved[E2]) { score += 30; if (moved[D2]) score += 25; if (moved[G1]) score += 20; if (moved[B1]) score += 15; if (moved[C1]) score += 10; } if (moved[E7]) { score -= 30; if (moved[D7]) score -= 25; if (moved[G8]) score -= 20; if (moved[B8]) score -= 15; if (moved[C8]) score -= 10; } /* Bad holes in the kingside (g2/e2) or (g7/e7) allow attacks */ if ((board[G2] != wpawn) && (board[F3] == bpawn || board[E4] == bpawn)) score -= 30; if ((board[G7] != bpawn) && (board[F6] == wpawn || board[E5] == wpawn)) score += 30; #define Fis_attacked(x,y) (board[(x)] == frame ? 0 : is_attacked((x),(y))) #define Gis_attacked(x,y) (board[(x)] == frame ? 0 : nk_attacked((x),(y))) /* An enemy pawn in front of the king can be deadly.*/ /* especially if it is protected */ if (board[wking_loc + 12] == bpawn || board[wking_loc + 12] == bbishop) { score -= 35; if (Fis_attacked(wking_loc + 12, 0)) score -= 150 >> bdev_dscale; } if (board[bking_loc - 12] == wpawn || board[bking_loc - 12] == wbishop) { score += 35; if (Fis_attacked(bking_loc - 12,1)) score += 150 >> wdev_dscale; } /* If e6 is attacked but there is no pawn there (just P-f7) */ /* I rely on CSE to remove the extra square checks and avoid the * is_attacked call */ if (((board[F2] == wpawn) || (board[E3] == wpawn) || board[E3] == bpawn) && Fis_attacked(E3,0)) { if (board[F2] == wpawn) score += 10; if (board[E3] == wpawn) score += 20; else if (board[E3] == bpawn) score -= 15; } if (((board[F7] == bpawn) || (board[E6] == bpawn) || board[E6] == wpawn) && Fis_attacked(E6,1)) { if (board[F7] == bpawn) score -= 10; if (board[E6] == bpawn) score -= 20; else if (board[E6] == wpawn) score += 15; } /* Bonus if in check */ if (Fis_attacked(bking_loc,1)) score += 50 >> wdev_dscale; else if (Fis_attacked(wking_loc,0)) score -= 50 >> bdev_dscale; /* Give big pentalty for knight or pawn at g2/g7 especially if supported */ /* Also protect with Rook and Bishop */ if (board[G2] == bknight) { score -= 20; if (Fis_attacked(G2,0)) score -= 40; if (board[G1] == wrook) score += 10; if (board[F1] == wbishop) score += 10; } if (board[G7] == wknight) { score += 20; if (Fis_attacked(G7,1)) score += 40; if (board[G8] == brook) score -= 10; if (board[F8] == bbishop)score -= 10; } /* Bishop at h3/h6 often leads to crushing attacks */ /* Especially when the king is trapped behind a N */ if ((board[H3] == bbishop) && (board[G2] != wpawn)) { score -= 20; if (board[G2] == bknight) { score -= 40; if (board[F1] == wking || board[G1] == wking || board[H1] == wking) score -= 80; } } if ((board[H6] == wbishop) && (board[G7] != bpawn)) { score += 20; if (board[G7] == wknight) { score += 40; if (board[F8] == bking || board[G8] == bking || board[H8] == bking) score += 80; } } } if (cfg_attackeval) { badsquares = 0; safety = 0; badsquares += Gis_attacked(wking_loc - 13, 0); badsquares += Gis_attacked(wking_loc - 12, 0); badsquares += Gis_attacked(wking_loc - 11, 0); badsquares += Gis_attacked(wking_loc - 1, 0); badsquares += Gis_attacked(wking_loc + 1, 0); badsquares += Gis_attacked(wking_loc + 11, 0); badsquares += Gis_attacked(wking_loc + 12, 0); badsquares += Gis_attacked(wking_loc + 13, 0); norm_black_hand_eval = ((-black_hand_eval) / 100); if (norm_black_hand_eval > 14) norm_black_hand_eval = 14; else if (norm_black_hand_eval < 0) norm_black_hand_eval = 0; safety -= ksafety_scaled[norm_black_hand_eval][badsquares]; badsquares = 0; badsquares += Gis_attacked(bking_loc - 13, 1); badsquares += Gis_attacked(bking_loc - 12, 1); badsquares += Gis_attacked(bking_loc - 11, 1); badsquares += Gis_attacked(bking_loc - 1, 1); badsquares += Gis_attacked(bking_loc + 1, 1); badsquares += Gis_attacked(bking_loc + 11, 1); badsquares += Gis_attacked(bking_loc + 12, 1); badsquares += Gis_attacked(bking_loc + 13, 1); norm_white_hand_eval = (white_hand_eval / 100); if (norm_white_hand_eval > 14) norm_white_hand_eval = 14; else if (norm_white_hand_eval < 0) norm_white_hand_eval = 0; safety += ksafety_scaled[norm_white_hand_eval][badsquares]; score += safety; } score += (white_hand_eval + black_hand_eval); storeECache(score); /* adjust for color: */ if (white_to_move == 1) { return score; } else { return -score; } } sjeng-11.2.orig/moves.c0100644000175000017500000014617407307525336014047 0ustar lukaslukas/* Sjeng - a chess variants playing program Copyright (C) 2000 Gian-Carlo Pascutto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA File: moves.c Purpose: functions used to generate & make moves */ #include "sjeng.h" #include "extvars.h" #include "protos.h" unsigned long total_moves; unsigned long total_movegens; int numb_moves; static move_s *genfor; int fcaptures; int gfrom; int kingcap; /* break if we capture the king */ bool check_legal (move_s moves[], int m, int incheck) { /* determines if a move made was legal. Checks to see if the player who just moved castled through check, or is in check. If the move made was illegal, returns FALSE, otherwise, returns TRUE. */ int castled = moves[m].castled; int from = moves[m].from; int target = moves[m].target; int l; if (Variant == Suicide) return TRUE; /* check for castling moves: */ if (castled) { /* white kingside castling: */ if (castled == wck) { if (is_attacked (30, 0)) return FALSE; if (is_attacked (31, 0)) return FALSE; if (is_attacked (32, 0)) return FALSE; return TRUE; } /* white queenside castling: */ if (castled == wcq) { if (is_attacked (30, 0)) return FALSE; if (is_attacked (29, 0)) return FALSE; if (is_attacked (28, 0)) return FALSE; return TRUE; } /* black kingside castling: */ if (castled == bck) { if (is_attacked (114, 1)) return FALSE; if (is_attacked (115, 1)) return FALSE; if (is_attacked (116, 1)) return FALSE; return TRUE; } /* black queenside castling: */ if (castled == bcq) { if (is_attacked (114, 1)) return FALSE; if (is_attacked (113, 1)) return FALSE; if (is_attacked (112, 1)) return FALSE; return TRUE; } } /* otherwise, just check on the kings: */ /* black king: */ /* the code in here checks whether a move could * have put the king in check, if he was not in * check before, if not, an early exit is taken */ else if (white_to_move&1) { if (!incheck) { if (moves[m].from == 0) return TRUE; switch (moves[m].promoted ? bpawn : board[target]) { case bpawn: /* pawn moves, it can discover a rank or diagonal check * a capture can also discover a file check */ if (moves[m].captured != npiece) { if (file(from) != file(bking_loc) && rank(from) != rank(bking_loc) && diagl(from) != diagl(bking_loc) && diagr(from) != diagr(bking_loc)) return TRUE; } else { if (rank(from) != rank(bking_loc) && diagl(from) != diagl(bking_loc) && diagr(from) != diagr(bking_loc)) return TRUE; } break; case bknight: /* discovers all */ if (file(from) != file(bking_loc) && rank(from) != rank(bking_loc) && diagl(from) != diagl(bking_loc) && diagr(from) != diagr(bking_loc)) return TRUE; break; case bbishop: /* always discovers file and rank * always discovers one diagonal */ if (file(from) != file(bking_loc) && rank(from) != rank(bking_loc)) { if (diagl(from) == diagl(target)) { /* stays on diag, can only uncover check on * other diag */ if (diagr(from) != diagr(bking_loc)) return TRUE; } else { if (diagl(from) != diagl(bking_loc)) return TRUE; } } break; case brook: /* discovers diagonal always */ /* one file or rank discovered */ if (diagr(from) != diagr(bking_loc) && diagl(from) != diagl(bking_loc)) { /* rank move ? */ if(rank(from) == rank(target)) { if (file(from) != file(bking_loc)) return TRUE; } else { /* file move */ if (rank(from) != rank(bking_loc)) return TRUE; } } break; case bqueen: /* find out what move it was: ldiag/rdiag/file/rank*/ if (file(from) == file(target)) { if (diagr(from) != diagr(bking_loc) && diagl(from) != diagl(bking_loc) && rank(from) != rank(bking_loc)) return TRUE; } else if (rank(from) == rank(target)) { if (diagr(from) != diagr(bking_loc) && file(from) != file(bking_loc) && diagl(from) != diagl(bking_loc)) return TRUE; } else if (diagl(from) == diagl(target)) { if (diagr(from) != diagr(bking_loc) && file(from) != file(bking_loc) && rank(from) != rank(bking_loc)) return TRUE; } else if (diagr(from) == diagr(target)) { if (diagl(from) != diagl(bking_loc) && file(from) != file(bking_loc) && rank(from) != rank(bking_loc)) return TRUE; } break; default: break; } /* we got so far, we know there can only be some * kind of possible discovering */ /* find out what */ /* we do not need to check for pawn, king or knightattacks, * as they cannot be discovered*/ if (board[target] != bking) { if (file(from) == file(bking_loc)) { if (bking_loc > from) { for (l = bking_loc-12; board[l] == npiece; l-=12); if (board[l] == wrook || board[l] == wqueen) return FALSE; } else { for (l = bking_loc+12; board[l] == npiece; l+=12); if (board[l] == wrook || board[l] == wqueen) return FALSE; } } else if (rank(from) == rank(bking_loc)) { if (bking_loc > from) { for (l = bking_loc-1; board[l] == npiece; l-=1); if (board[l] == wrook || board[l] == wqueen) return FALSE; } else { for (l = bking_loc+1; board[l] == npiece; l+=1); if (board[l] == wrook || board[l] == wqueen) return FALSE; } } else if (diagl(from) == diagl(bking_loc)) { if (bking_loc > from) { for (l = bking_loc-13; board[l] == npiece; l-=13); if (board[l] == wbishop || board[l] == wqueen) return FALSE; } else { for (l = bking_loc+13; board[l] == npiece; l+=13); if (board[l] == wbishop || board[l] == wqueen) return FALSE; } } else if (diagr(from) == diagr(bking_loc)) { if (bking_loc > from) { for (l = bking_loc-11; board[l] == npiece; l-=11); if (board[l] == wbishop || board[l] == wqueen) return FALSE; } else { for (l = bking_loc+11; board[l] == npiece; l+=11); if (board[l] == wbishop || board[l] == wqueen) return FALSE; } } return TRUE; } } if (is_attacked (bking_loc, 1)) return FALSE; else return TRUE; } /* white king: */ else { if (!incheck) { if (moves[m].from == 0) return TRUE; switch (moves[m].promoted ? wpawn : board[target]) { case wpawn: /* pawn moves, it can discover a rank or diagonal check * a capture can also discover a file check */ if (moves[m].captured != npiece) { if (file(from) != file(wking_loc) && rank(from) != rank(wking_loc) && diagl(from) != diagl(wking_loc) && diagr(from) != diagr(wking_loc)) return TRUE; } else { if (rank(from) != rank(wking_loc) && diagl(from) != diagl(wking_loc) && diagr(from) != diagr(wking_loc)) return TRUE; } break; case wknight: /* discovers all */ if (file(from) != file(wking_loc) && rank(from) != rank(wking_loc) && diagl(from) != diagl(wking_loc) && diagr(from) != diagr(wking_loc)) return TRUE; break; case wbishop: /* always discovers file and rank * always discovers one diagonal */ if (file(from) != file(wking_loc) && rank(from) != rank(wking_loc)) { if (diagl(from) == diagl(target)) { /* stays on diag, can only uncover check on * other diag */ if (diagr(from) != diagr(wking_loc)) return TRUE; } else { if (diagl(from) != diagl(wking_loc)) return TRUE; } } break; case wrook: /* discovers diagonal always */ /* one file or rank discovered */ if (diagr(from) != diagr(wking_loc) && diagl(from) != diagl(wking_loc)) { /* rank move ? */ if(rank(from) == rank(target)) { if (file(from) != file(wking_loc)) return TRUE; } else { /* file move */ if (rank(from) != rank(wking_loc)) return TRUE; } } break; case wqueen: /* find out what move it was: ldiag/rdiag/file/rank*/ if (file(from) == file(moves[m].target)) { if (diagr(from) != diagr(wking_loc) && diagl(from) != diagl(wking_loc) && rank(from) != rank(wking_loc)) return TRUE; } else if (rank(from) == rank(target)) { if (diagr(from) != diagr(wking_loc) && file(from) != file(wking_loc) && diagl(from) != diagl(wking_loc)) return TRUE; } else if (diagl(from) == diagl(target)) { if (diagr(from) != diagr(wking_loc) && file(from) != file(wking_loc) && rank(from) != rank(wking_loc)) return TRUE; } else if (diagr(from) == diagr(target)) { if (diagl(from) != diagl(wking_loc) && file(from) != file(wking_loc) && rank(from) != rank(wking_loc)) return TRUE; } break; default: break; } if (board[target] != wking) { if (file(from) == file(wking_loc)) { if (wking_loc > from) { for (l = wking_loc-12; board[l] == npiece; l-=12); if (board[l] == brook || board[l] == bqueen) return FALSE; } else { for (l = wking_loc+12; board[l] == npiece; l+=12); if (board[l] == brook || board[l] == bqueen) return FALSE; } } else if (rank(from) == rank(wking_loc)) { if (wking_loc > from) { for (l = wking_loc-1; board[l] == npiece; l-=1); if (board[l] == brook || board[l] == bqueen) return FALSE; } else { for (l = wking_loc+1; board[l] == npiece; l+=1); if (board[l] == brook || board[l] == bqueen) return FALSE; } } else if (diagl(from) == diagl(wking_loc)) { if (wking_loc > from) { for (l = wking_loc-13; board[l] == npiece; l-=13); if (board[l] == bbishop || board[l] == bqueen) return FALSE; } else { for (l = wking_loc+13; board[l] == npiece; l+=13); if (board[l] == bbishop || board[l] == bqueen) return FALSE; } } else if (diagr(from) == diagr(wking_loc)) { if (wking_loc > from) { for (l = wking_loc-11; board[l] == npiece; l-=11); if (board[l] == bbishop || board[l] == bqueen) return FALSE; } else { for (l = wking_loc+11; board[l] == npiece; l+=11); if (board[l] == bbishop || board[l] == bqueen) return FALSE; } } return TRUE; } } if (is_attacked (wking_loc, 0)) return FALSE; else return TRUE; } /* should never get here .. but just so it will compile :P */ return FALSE; } #define push_slide(t) if (board[(t)] != frame) push_slidE((t)) #define push_knight(t) if (board[(t)] != frame) push_knighT((t)) void gen (move_s moves[]) { /* generate pseudo-legal moves, and place them in the moves array */ int from, a, j, i; kingcap = FALSE; numb_moves = 0; genfor = &moves[0]; if (Variant == Suicide) { captures = FALSE; fcaptures = FALSE; }; restart: /* generate white moves, if it is white to move: */ if (white_to_move) { for (a = 1, j = 1; (a <= piece_count) && (((Variant != Suicide) && !kingcap) || ((Variant == Suicide) && (fcaptures == captures))); j++) { i = pieces[j]; if (!i) continue; else a++; from = i; gfrom = i; switch (board[from]) { case (wpawn): /* pawn moves up one square: */ if (board[from+12] == npiece) { /* only promotions when captures == TRUE */ if (rank (from) == 7 && ((Variant != Suicide) && (Variant != Losers))) { push_pawn (from+12, FALSE); } else if (!captures) { push_pawn (from+12, FALSE); /* pawn moving up two squares on its first move: */ if (rank(from) == 2 && board[from+24] == npiece) push_pawn_simple (from+24); } } /* pawn capturing diagonally: */ if ((board[from+13]&1) == 0 && board[from+13] != frame) push_pawn (from+13, FALSE); /* pawn captruing diagonally: */ if ((board[from+11]&1) == 0 && board[from+11] != frame) push_pawn (from+11, FALSE); /* ep move: */ if (ep_square == from+13) push_pawn (from+13, TRUE); /* ep move: */ else if (ep_square == from+11) push_pawn (from+11, TRUE); break; case (wknight): /* use the knight offsets: */ push_knight (from-25); push_knight (from-23); push_knight (from-14); push_knight (from-10); push_knight (from+10); push_knight (from+14); push_knight (from+23); push_knight (from+25); break; case (wbishop): /* use the bishop offsets: */ push_slide (from-13); push_slide (from-11); push_slide (from+11); push_slide (from+13); break; case (wrook): /* use the rook offsets: */ push_slide (from-12); push_slide (from-1); push_slide (from+1); push_slide (from+12); break; case (wqueen): /* use the queen offsets: */ push_slide (from-13); push_slide (from-12); push_slide (from-11); push_slide (from-1); push_slide (from+1); push_slide (from+11); push_slide (from+12); push_slide (from+13); break; case (wking): /* use the king offsets for 'normal' moves: */ push_king (from-13); push_king (from-12); push_king (from-11); push_king (from-1); push_king (from+1); push_king (from+11); push_king (from+12); push_king (from+13); /* castling moves: */ if (from == 30 && !moved[30] && !captures && (Variant != Suicide || Giveaway == TRUE)) { /* kingside: */ if (!moved[33] && board[33] == wrook) if (board[31] == npiece && board[32] == npiece) push_king_castle (from+2, wck); /* queenside: */ if (!moved[26] && board[26] == wrook) if (board[27] == npiece && board[28] == npiece && board[29] == npiece) push_king_castle (from-2, wcq); } break; default: break; } } } /* generate black moves, if it is black to move: */ else { for (a = 1, j = 1; (a <= piece_count) && (((Variant != Suicide) && !kingcap) || ((Variant == Suicide) && (fcaptures == captures))) ; j++) { i = pieces[j]; if (!i) continue; else a++; from = i; gfrom = i; switch (board[from]) { case (bpawn): /* pawn moves up one square: */ if (board[from-12] == npiece) { /* only promotions when captures == TRUE */ if (rank (from) == 2 && ((Variant != Suicide) && (Variant != Losers))) { push_pawn (from-12, FALSE); } else if (!captures) { push_pawn (from-12, FALSE); /* pawn moving up two squares on its first move: */ if (rank(from) == 7 && board[from-24] == npiece) push_pawn_simple (from-24); } }; /* pawn capturing diagonally: */ if ((board[from-13]&1) == 1 && board[from-13] != npiece) push_pawn (from-13, FALSE); /* pawn capturing diagonally: */ if ((board[from-11]&1) == 1 && board[from-11] != npiece) push_pawn (from-11, FALSE); /* ep move: */ if (ep_square == from-13) push_pawn (from-13, TRUE); /* ep move: */ else if (ep_square == from-11) push_pawn (from-11, TRUE); break; case (bknight): /* use the knight offsets: */ push_knight (from-25); push_knight (from-23); push_knight (from-14); push_knight (from-10); push_knight (from+10); push_knight (from+14); push_knight (from+23); push_knight (from+25); break; case (bbishop): /* use the bishop offsets: */ push_slide (from-13); push_slide (from-11); push_slide (from+11); push_slide (from+13); break; case (brook): /* use the rook offsets: */ push_slide (from-12); push_slide (from-1); push_slide (from+1); push_slide (from+12); break; case (bqueen): /* use the queen offsets: */ push_slide (from-13); push_slide (from-12); push_slide (from-11); push_slide (from-1); push_slide (from+1); push_slide (from+11); push_slide (from+12); push_slide (from+13); break; case (bking): /* use the king offsets for 'normal' moves: */ push_king (from-13); push_king (from-12); push_king (from-11); push_king (from-1); push_king (from+1); push_king (from+11); push_king (from+12); push_king (from+13); /* castling moves: */ if (from == 114 && !moved[114] && !captures && (Variant != Suicide || Giveaway == TRUE)) { /* kingside: */ if (!moved[117] && board[117] == brook) if (board[115] == npiece && board[116] == npiece) push_king_castle (from+2, bck); /* queenside: */ if (!moved[110] && board[110] == brook) if (board[111] == npiece && board[112] == npiece && board[113] == npiece) push_king_castle (from-2, bcq); } break; default: break; } } } if (((Variant == Crazyhouse) || (Variant == Bughouse)) && !captures && !kingcap) { if (white_to_move && (holding[WHITE][wpawn] || holding[WHITE][wknight] || holding[WHITE][wbishop] || holding[WHITE][wqueen] || holding[WHITE][wrook])) { for (from = 26; from < 118; from++) { gfrom = from; switch (board[from]) { case (frame): from += 3; continue; case (npiece): if(holding[WHITE][wpawn]) { if ((rank(from) != 8) && (rank(from) != 1)) { try_drop(wpawn); } } if(holding[WHITE][wknight]) { try_drop(wknight); } if(holding[WHITE][wbishop]) { try_drop(wbishop); } if(holding[WHITE][wrook]) { try_drop(wrook); } if(holding[WHITE][wqueen]) { try_drop(wqueen); } }; } } else if (!white_to_move && (holding[BLACK][bpawn] || holding[BLACK][bknight] || holding[BLACK][bbishop] || holding[BLACK][bqueen] || holding[BLACK][brook])) { for (from = 26; from < 118; from++) { gfrom = from; switch (board[from]) { case (frame): from += 3; continue; case (npiece): if(holding[BLACK][bpawn]) { if ((rank(from) != 8) && (rank(from) != 1)) { try_drop(bpawn); } } if(holding[BLACK][bknight]) { try_drop(bknight); } if(holding[BLACK][bbishop]) { try_drop(bbishop); } if(holding[BLACK][brook]) { try_drop(brook); } if(holding[BLACK][bqueen]) { try_drop(bqueen); } }; }; } } if ((Variant == Suicide) && fcaptures == TRUE && captures == FALSE) { captures = TRUE; numb_moves = 0; goto restart; } if (Variant == Suicide) kingcap = FALSE; } bool in_check (void) { /* return true if the side to move is in check: */ if (Variant == Suicide) return FALSE; if (white_to_move == 1) { if (is_attacked (wking_loc, 0)) { return TRUE; } } else { if (is_attacked (bking_loc, 1)) { return TRUE; } } return FALSE; } bool f_in_check(move_s moves[], int m) { int target = moves[m].target; int from = moves[m].from; int l; static const int knight_o[8] = {10, -10, 14, -14, 23, -23, 25, -25}; if (Variant == Suicide) return FALSE; if (white_to_move == 1) { /* is white king attacked */ /* we are certain the king is not in check already, * as we would capture him in our ply */ /* thus, we need to check if our move could possibly * put the king in check */ /* this can either be a direct check, or a discover */ switch (board[target]) { case bpawn: if (board[target-11] == wking || board[target-13] == wking) return TRUE; break; case bbishop: if (diagl(target) == diagl(wking_loc)) { /* possible left diag check */ if (wking_loc < target) { for (l = wking_loc+13; board[l] == npiece; l +=13); if (l == target) return TRUE; } else { for (l = wking_loc-13; board[l] == npiece; l -=13); if (l == target) return TRUE; } } else if (diagr(target) == diagr(wking_loc)) { if (wking_loc < target) { for (l = wking_loc+11; board[l] == npiece; l +=11); if (l == target) return TRUE; } else { for (l = wking_loc-11; board[l] == npiece; l -=11); if (l == target) return TRUE; } } break; case brook: if (file(target) == file(wking_loc)) { if (wking_loc < target) { for (l = wking_loc+12; board[l] == npiece; l +=12); if (l == target) return TRUE; } else { for (l = wking_loc-12; board[l] == npiece; l -=12); if (l == target) return TRUE; } } else if (rank(target) == rank(wking_loc)) { if (wking_loc < target) { for (l = wking_loc+1; board[l] == npiece; l++); if (l == target) return TRUE; } else { for (l = wking_loc-1; board[l] == npiece; l--); if (l == target) return TRUE; } } break; case bknight: for (l = 0; l < 8; l++) if ((wking_loc + knight_o[l]) == target) return TRUE; break; case bqueen: if (file(target) == file(wking_loc)) { if (wking_loc < target) { for (l = wking_loc+12; board[l] == npiece; l +=12); if (l == target) return TRUE; } else { for (l = wking_loc-12; board[l] == npiece; l -=12); if (l == target) return TRUE; } } else if (rank(target) == rank(wking_loc)) { if (wking_loc < target) { for (l = wking_loc+1; board[l] == npiece; l +=1); if (l == target) return TRUE; } else { for (l = wking_loc-1; board[l] == npiece; l -=1); if (l == target) return TRUE; } } else if (diagl(target) == diagl(wking_loc)) { if (wking_loc < target) { for (l = wking_loc+13; board[l] == npiece; l +=13); if (l == target) return TRUE; } else { for (l = wking_loc-13; board[l] == npiece; l -=13); if (l == target) return TRUE; } } else if (diagr(target) == diagr(wking_loc)) { if (wking_loc < target) { for (l = wking_loc+11; board[l] == npiece; l +=11); if (l == target) return TRUE; } else { for (l = wking_loc-11; board[l] == npiece; l -=11); if (l == target) return TRUE; } } break; case bking: /* can only discover checks */ /* castling is tricky */ if (moves[m].castled) { if (is_attacked (wking_loc, 0)) return TRUE; else return FALSE; } break; } /* drop move can never discover check */ if (from == 0) return FALSE; /* this checks for discovered checks */ if (rank(from) == rank(wking_loc)) { if (wking_loc > from) { for (l = wking_loc-1; board[l] == npiece; l--); if (board[l] == brook || board[l] == bqueen) return TRUE; } else { for (l = wking_loc+1; board[l] == npiece; l++); if (board[l] == brook || board[l] == bqueen) return TRUE; } } else if (file(from) == file(wking_loc)) { if (wking_loc > from) { for (l = wking_loc-12; board[l] == npiece; l-=12); if (board[l] == brook || board[l] == bqueen) return TRUE; } else { for (l = wking_loc+12; board[l] == npiece; l+=12); if (board[l] == brook || board[l] == bqueen) return TRUE; } } else if (diagl(from) == diagl(wking_loc)) { if (wking_loc > from) { for (l = wking_loc-13; board[l] == npiece; l-=13); if (board[l] == bbishop || board[l] == bqueen) return TRUE; } else { for (l = wking_loc+13; board[l] == npiece; l+=13); if (board[l] == bbishop || board[l] == bqueen) return TRUE; } } else if (diagr(from) == diagr(wking_loc)) { if (wking_loc > from) { for (l = wking_loc-11; board[l] == npiece; l-=11); if (board[l] == bbishop || board[l] == bqueen) return TRUE; } else { for (l = wking_loc+11; board[l] == npiece; l+=11); if (board[l] == bbishop || board[l] == bqueen) return TRUE; } } return FALSE; //if (is_attacked (wking_loc, 0)) //return TRUE; } else { /* is black king attacked */ switch (board[target]) { case wpawn: if (board[target+11] == bking || board[target+13] == bking) return TRUE; break; case wbishop: if (diagl(target) == diagl(bking_loc)) { /* possible left diag check */ if (bking_loc < target) { for (l = bking_loc+13; board[l] == npiece; l +=13); if (l == target) return TRUE; } else { for (l = bking_loc-13; board[l] == npiece; l -=13); if (l == target) return TRUE; } } else if (diagr(target) == diagr(bking_loc)) { if (bking_loc < target) { for (l = bking_loc+11; board[l] == npiece; l +=11); if (l == target) return TRUE; } else { for (l = bking_loc-11; board[l] == npiece; l -=11); if (l == target) return TRUE; } } break; case wrook: if (file(target) == file(bking_loc)) { if (bking_loc < target) { for (l = bking_loc+12; board[l] == npiece; l +=12); if (l == target) return TRUE; } else { for (l = bking_loc-12; board[l] == npiece; l -=12); if (l == target) return TRUE; } } else if (rank(target) == rank(bking_loc)) { if (bking_loc < target) { for (l = bking_loc+1; board[l] == npiece; l++); if (l == target) return TRUE; } else { for (l = bking_loc-1; board[l] == npiece; l--); if (l == target) return TRUE; } } break; case wknight: for (l = 0; l < 8; l++) if ((bking_loc + knight_o[l]) == target) return TRUE; break; case wqueen: if (file(target) == file(bking_loc)) { if (bking_loc < target) { for (l = bking_loc+12; board[l] == npiece; l +=12); if (l == target) return TRUE; } else { for (l = bking_loc-12; board[l] == npiece; l -=12); if (l == target) return TRUE; } } else if (rank(target) == rank(bking_loc)) { if (bking_loc < target) { for (l = bking_loc+1; board[l] == npiece; l +=1); if (l == target) return TRUE; } else { for (l = bking_loc-1; board[l] == npiece; l -=1); if (l == target) return TRUE; } } else if (diagl(target) == diagl(bking_loc)) { if (bking_loc < target) { for (l = bking_loc+13; board[l] == npiece; l +=13); if (l == target) return TRUE; } else { for (l = bking_loc-13; board[l] == npiece; l -=13); if (l == target) return TRUE; } } else if (diagr(target) == diagr(bking_loc)) { if (bking_loc < target) { for (l = bking_loc+11; board[l] == npiece; l +=11); if (l == target) return TRUE; } else { for (l = bking_loc-11; board[l] == npiece; l -=11); if (l == target) return TRUE; } } break; case wking: /* can only discover checks */ if (moves[m].castled) { if (is_attacked (bking_loc, 1)) return TRUE; else return FALSE; } break; } if (from == 0) return FALSE; /* this checks for discovered checks */ if (rank(from) == rank(bking_loc)) { if (bking_loc > from) { for (l = bking_loc-1; board[l] == npiece; l--); if (board[l] == wrook || board[l] == wqueen) return TRUE; } else { for (l = bking_loc+1; board[l] == npiece; l++); if (board[l] == wrook || board[l] == wqueen) return TRUE; } } else if (file(from) == file(bking_loc)) { if (bking_loc > from) { for (l = bking_loc-12; board[l] == npiece; l-=12); if (board[l] == wrook || board[l] == wqueen) return TRUE; } else { for (l = bking_loc+12; board[l] == npiece; l+=12); if (board[l] == wrook || board[l] == wqueen) return TRUE; } } else if (diagl(from) == diagl(bking_loc)) { if (bking_loc > from) { for (l = bking_loc-13; board[l] == npiece; l-=13); if (board[l] == wbishop || board[l] == wqueen) return TRUE; } else { for (l = bking_loc+13; board[l] == npiece; l+=13); if (board[l] == wbishop || board[l] == wqueen) return TRUE; } } else if (diagr(from) == diagr(bking_loc)) { if (bking_loc > from) { for (l = bking_loc-11; board[l] == npiece; l-=11); if (board[l] == wbishop || board[l] == wqueen) return TRUE; } else { for (l = bking_loc+11; board[l] == npiece; l+=11); if (board[l] == wbishop || board[l] == wqueen) return TRUE; } } return FALSE; // if (is_attacked (bking_loc, 1)) // display_board(stdout, 1);//return TRUE; } } int extended_in_check(void) { register int sq; static const int knight_o[8] = {10, -10, 14, -14, 23, -23, 25, -25}; if (Variant == Suicide) return 0; if (white_to_move == 1) { sq = board[wking_loc-12]; if (sq == brook || sq == bqueen) return 2; sq = board[wking_loc-1]; if (sq == brook || sq == bqueen) return 2; sq = board[wking_loc+1]; if (sq == brook || sq == bqueen) return 2; sq = board[wking_loc+12]; if (sq == brook || sq == bqueen) return 2; sq = board[wking_loc+13]; if (sq == bbishop || sq == bqueen || sq == bpawn) return 2; sq = board[wking_loc+11]; if (sq == bbishop || sq == bqueen || sq == bpawn) return 2; sq = board[wking_loc-11]; if (sq == bbishop || sq == bqueen) return 2; sq = board[wking_loc-13]; if (sq == bbishop || sq == bqueen) return 2; for (sq = 0; sq < 8; sq++) { if (board[wking_loc + knight_o[sq]] == bknight) return 2; } if (is_attacked (wking_loc, 0)) { if (Variant == Normal || Variant == Losers) return 2; else return 1; } } else { sq = board[bking_loc-12]; if (sq == wrook || sq == wqueen) return 2; sq = board[bking_loc-1]; if (sq == wrook || sq == wqueen) return 2; sq = board[bking_loc+1]; if (sq == wrook || sq == wqueen) return 2; sq = board[bking_loc+12]; if (sq == wrook || sq == wqueen) return 2; sq = board[bking_loc-13]; if (sq == wbishop || sq == wqueen || sq == wpawn) return 2; sq = board[bking_loc-11]; if (sq == wbishop || sq == wqueen || sq == wpawn) return 2; sq = board[bking_loc+11]; if (sq == wbishop || sq == wqueen) return 2; sq = board[bking_loc+13]; if (sq == wbishop || sq == wqueen) return 2; for (sq = 0; sq < 8; sq++) { if (board[bking_loc + knight_o[sq]] == wknight) return 2; } if (is_attacked (bking_loc, 1)) { if (Variant == Normal || Variant == Losers) return 2; else return 1; } } return 0; }; void make (move_s moves[], int i) { /* make a move */ /* rather than writing out from[i].from, from[i].target, etc. all over the place, just make a copy of them here: */ int ep, from, target, captured, promoted, castled, find_slot; ep = moves[i].ep; from = moves[i].from; target = moves[i].target; captured = moves[i].captured; promoted = moves[i].promoted; castled = moves[i].castled; //if ((moves[i].target == 0) || ((moves[i].from != 0) && ((board[moves[i].from] == npiece) || board[moves[i].from] == frame))) // DIE; /* clear the en passant rights: */ path_x[ply].epsq = ep_square; ep_square = 0; /* update the 50 move info: */ path_x[ply].fifty = fifty; /* ignore piece drops...50move draw wont happen anyway */ if (board[from] == wpawn || board[from] == bpawn || board[target] != npiece) { fifty = 0; } else { fifty++; } if (from == 0) { /* drop move */ /* Drop moves are handled fully seperate because we exepect to encouter lots of them and we try to skip as many checks as possible. Note that the critical path for drop moves is very short. Also, we have to handle pieces[] and squares[] specially */ /* new piece on board */ piece_count++; /* find first empty slot in pieces[] */ for(find_slot = 1; (pieces[find_slot] != 0); find_slot++) assert(find_slot < 63); /* add to piece array, set piece-square pointer */ pieces[find_slot] = target; path_x[ply].was_promoted = is_promoted[find_slot]; is_promoted[find_slot] = 0; /* set square->piece pointer */ squares[target] = find_slot; // moved[target] = 1; //if (promoted <= frame || promoted >= npiece) // DIE; assert(promoted > frame && promoted < npiece); DropremoveHolding(promoted, ToMove); /* piece went off holding but onto board */ AddMaterial(promoted); /* put our piece on the board */ board[target] = promoted; Hash(promoted,target); white_to_move ^= 1; ply++; return; } else { path_x[ply].was_promoted = is_promoted[squares[target]]; /* update the "general" pieces[] / squares[] info (special moves need special handling later): */ path_x[ply].cap_num = squares[target]; pieces[squares[target]] = 0; pieces[squares[from]] = target; squares[target] = squares[from]; squares[from] = 0; /* update the piece count & add Holdings */ if (!ep) { switch (board[target]) { case (npiece): break; default: if (Variant == Bughouse || Variant == Crazyhouse) { if (path_x[ply].was_promoted) { addHolding(SwitchPromoted(board[target]), ToMove); } else { addHolding(SwitchColor(board[target]), ToMove); } } RemoveMaterial(board[target]); /* remove captured piece */ Hash(board[target], target); piece_count--; break; } } /* white pawn moves: */ if (board[from] == wpawn) { /* look for a promotion move: */ if (promoted) { board[target] = promoted; board[from] = npiece; moved[target]++; moved[from]++; white_to_move ^= 1; is_promoted[squares[target]] = 1; /* remove pawn */ Hash(wpawn, from); /* add new stuff */ Hash(promoted, target); RemoveMaterial(wpawn); AddMaterial(promoted); ply++; return; } /* look for an en passant move: */ if (ep) { /* remove pawn */ Hash(wpawn, from); /* remove ep pawn */ Hash(bpawn, target-12); /* add target pawn */ Hash(wpawn, target); RemoveMaterial(bpawn); board[target] = wpawn; board[from] = npiece; addHolding(wpawn, WHITE); piece_count--; board[target-12] = npiece; moved[target]++; moved[from]++; moved[target-12]++; white_to_move ^= 1; path_x[ply].cap_num = squares[target-12]; pieces[squares[target-12]] = 0; squares[target-12] = 0; ply++; return; } /* otherwise, we have a "regular" pawn move: */ /* first check to see if we've moved a pawn up 2 squares: */ if (target == from+24) ep_square = from+12; Hash(wpawn, from); Hash(wpawn, target); board[target] = wpawn; board[from] = npiece; moved[target]++; moved[from]++; white_to_move ^= 1; ply++; return; } /* black pawn moves: */ if (board[from] == bpawn) { /* look for a promotion move: */ if (promoted) { board[target] = promoted; board[from] = npiece; moved[target]++; moved[from]++; white_to_move ^= 1; is_promoted[squares[target]] = 1; /* remove pawn */ Hash(bpawn, from); /* add new stuff */ Hash(promoted, target); RemoveMaterial(bpawn); AddMaterial(promoted); ply++; return; } /* look for an en passant move: */ if (ep) { /* remove pawn */ Hash(bpawn, from); /* remove ep pawn */ Hash(wpawn, target+12); /* add target pawn */ Hash(bpawn, target); RemoveMaterial(wpawn); board[target] = bpawn; board[from] = npiece; addHolding(bpawn, BLACK); piece_count--; board[target+12] = npiece; moved[target]++; moved[from]++; moved[target+12]++; white_to_move ^= 1; path_x[ply].cap_num = squares[target+12]; pieces[squares[target+12]] = 0; squares[target+12] = 0; ply++; return; } /* otherwise, we have a "regular" pawn move: */ /* first check to see if we've moved a pawn down 2 squares: */ if (target == from-24) ep_square = from-12; board[target] = bpawn; board[from] = npiece; moved[target]++; moved[from]++; white_to_move ^= 1; Hash(bpawn, from); Hash(bpawn, target); ply++; return; } /* piece moves, other than the king: */ if (board[from] != wking && board[from] != bking) { Hash(board[from], from); Hash(board[from], target); board[target] = board[from]; board[from] = npiece; moved[target]++; moved[from]++; white_to_move ^= 1; ply++; return; } /* otherwise, we have a king move of some kind: */ /* White king moves first: */ if (board[from] == wking) { /* record the new white king location: */ wking_loc = target; /* perform the white king's move: */ board[target] = wking; board[from] = npiece; moved[target]++; moved[from]++; white_to_move ^= 1; Hash(wking, from); Hash(wking, target); /* check for castling: */ /* check for white kingside castling: */ if (castled == wck) { board[33] = npiece; board[31] = wrook; moved[33]++; moved[31]++; white_castled = wck; pieces[squares[33]] = 31; squares[31] = squares[33]; squares[33] = 0; Hash(wrook, 33); Hash(wrook, 31); ply++; return; } /* check for white queenside castling: */ else if (castled == wcq) { board[26] = npiece; board[29] = wrook; moved[26]++; moved[29]++; white_castled = wcq; pieces[squares[26]] = 29; squares[29] = squares[26]; squares[26] = 0; Hash(wrook, 26); Hash(wrook, 29); ply++; return; } ply++; return; } /* now we have only black king moves left: */ else { /* record the new black king location: */ bking_loc = target; /* perform the black king's move: */ board[target] = bking; board[from] = npiece; moved[target]++; moved[from]++; white_to_move ^= 1; Hash(bking, from); Hash(bking, target); /* check for castling: */ /* check for black kingside castling: */ if (castled == bck) { board[117] = npiece; board[115] = brook; moved[117]++; moved[115]++; black_castled = bck; pieces[squares[117]] = 115; squares[115] = squares[117]; squares[117] = 0; Hash(brook, 117); Hash(brook, 115); ply++; return; } /* check for black queenside castling: */ else if (castled == bcq) { board[110] = npiece; board[113] = brook; moved[110]++; moved[113]++; black_castled = bcq; pieces[squares[110]] = 113; squares[113] = squares[110]; squares[110] = 0; Hash(brook, 110); Hash(brook, 113); ply++; return; } } ply++; return; } } void add_move(int Ptarget, int Ppromoted) { genfor[numb_moves].from = gfrom; genfor[numb_moves].target = Ptarget; genfor[numb_moves].captured = npiece; genfor[numb_moves].castled = no_castle; genfor[numb_moves].promoted = Ppromoted; genfor[numb_moves].ep = FALSE; numb_moves++; return; } void add_capture(int Ptarget, int Pcaptured, int Ppromoted, int Pep) { if ((Variant != Suicide) && (Pcaptured == wking || Pcaptured == bking)) { kingcap = TRUE; return; } else if (Pcaptured != npiece) fcaptures = TRUE; genfor[numb_moves].from = gfrom; genfor[numb_moves].target = Ptarget; genfor[numb_moves].captured = Pcaptured; genfor[numb_moves].castled = no_castle; genfor[numb_moves].promoted = Ppromoted; genfor[numb_moves].ep = Pep; numb_moves++; return; } void try_drop (int ptype) { genfor[numb_moves].from = 0; genfor[numb_moves].target = gfrom; genfor[numb_moves].captured = npiece; genfor[numb_moves].castled = no_castle; genfor[numb_moves].promoted = ptype; genfor[numb_moves].ep = FALSE; numb_moves++; return; } void push_king_castle (int Ptarget, int Pcastle_type) { genfor[numb_moves].from = gfrom; genfor[numb_moves].target = Ptarget; genfor[numb_moves].captured = npiece; genfor[numb_moves].castled = Pcastle_type; genfor[numb_moves].promoted = 0; genfor[numb_moves].ep = FALSE; numb_moves++; return; } void push_king (int target) { /* add king moves to the moves array */ /* first see if the move will take the king off the board: */ if (board[target] == frame) return; /* check to see if we have a non capture when in qsearch: */ if (board[target] == npiece && captures) return; /* non-capture, 'normal' king moves: */ if (board[target] == npiece) { add_move(target, 0); return; } /* 'normal' capture moves by the king: */ else if ((board[target]&1) != (board[gfrom]&1)) { add_capture(target, board[target], 0, FALSE); return; } /* no more possible moves for the king, so return: */ return; } void push_knighT (int target) { /* add knight moves to the moves array */ /* check to see if we have a non capture when in qsearch: */ if (board[target] == npiece && captures) return; /* check for a non-capture knight move: */ if (board[target] == npiece) { add_move(target, 0); return; } /* check for a capture knight move: */ else if ((board[target]&1) != (board[gfrom]&1)) { add_capture(target, board[target], 0, FALSE); return; } /* no more possible moves left for the knight, so return: */ return; } void push_pawn (int target, bool is_ep) { /* add pawn moves to the moves array */ int captured_piece; /* check to see if it's an ep move: */ if (is_ep) { if (board[gfrom] == wpawn) { add_capture(target, bpawn, 0, TRUE); return; } else { add_capture(target, wpawn, 0, TRUE); return; } } /* record which piece we are taking, so we don't have to compute it over and over again: */ captured_piece = board[target]; /* look for a white promotion move: */ if (board[gfrom] == wpawn && rank(gfrom) == 7) { add_capture(target, captured_piece, wqueen, FALSE); add_capture(target, captured_piece, wrook, FALSE); add_capture(target, captured_piece, wbishop, FALSE); add_capture(target, captured_piece, wknight, FALSE); if (Variant == Suicide) add_capture(target, captured_piece, wking, FALSE); /* we've finished generating all the promotions: */ return; } /* look for a black promotion move: */ else if (board[gfrom] == bpawn && rank(gfrom) == 2) { add_capture(target, captured_piece, bqueen, FALSE); add_capture(target, captured_piece, brook, FALSE); add_capture(target, captured_piece, bbishop, FALSE); add_capture(target, captured_piece, bknight, FALSE); if (Variant == Suicide) add_capture(target, captured_piece, bking, FALSE); /* we've finished generating all the promotions: */ return; } /* otherwise, we have a normal pawn move: */ else { add_capture(target, captured_piece, 0, FALSE); return; } /* the function should never get here, but just for completeness: */ return; } void push_pawn_simple (int target) { /* add pawn moves to the moves array */ add_move(target, 0); return; } void push_slidE (int target) { /* add moves for sliding pieces to the moves array */ int offset; int mycolor; /* check to see if we have gone off the board first: */ // if (board[target] == frame) // return; /* init variables: */ offset = target - gfrom; mycolor = board[gfrom]&1; /* loop until we hit the edge of the board, or another piece: */ do { /* case when the target is an empty square: */ if (board[target] == npiece) { if (!captures) { add_move(target, 0); } target += offset; } /* case when an enemy piece is hit: */ else if ((board[target]&1) != mycolor) { add_capture(target, board[target], 0, FALSE); break; } /* otherwise, we have hit a friendly piece (or edge of board): */ else break; } while (board[target] != frame); /* we have finished generating all of the sliding moves, so return: */ return; } void unmake (move_s moves[], int i) { /* un-make a move */ /* rather than writing out from[i].from, from[i].target, etc. all over the place, just make a copy of them here: */ int ep, from, target, captured, promoted, castled; ep = moves[i].ep; from = moves[i].from; target = moves[i].target; captured = moves[i].captured; promoted = moves[i].promoted; castled = moves[i].castled; //if ((moves[i].target == 0) || ((moves[i].target != 0) && (board[moves[i].target] == npiece))) // DIE; ply--; //printf("%d ", ply); ep_square = path_x[ply].epsq; /* update the 50 move info: */ fifty = path_x[ply].fifty; if (from == 0) /* drop move */ { /* Drop moves are hanled fully seperate because we exepect to encouter lots of them and we try to skip as many checks as possible. Note that the critical path for drop moves is very short. Also, we have to handle pieces[] and squares[] specially */ /* remove from piece array, unset piece-square pointer */ pieces[squares[target]] = 0; is_promoted[squares[target]] = path_x[ply].was_promoted; /* unset square->piece pointer */ squares[target] = 0; // moved[target] = 0; piece_count--; assert(promoted < npiece && promoted > frame); DropaddHolding(promoted, NotToMove); RemoveMaterial(promoted); /* restore board, either no piece or ep square */ board[target] = captured; Hash(promoted,target); white_to_move ^= 1; return; } else { /* update the "general" pieces[] / squares[] info (special moves need special handling later): */ squares[from] = squares[target]; squares[target] = path_x[ply].cap_num; pieces[squares[target]] = target; pieces[squares[from]] = from; is_promoted[squares[target]] = path_x[ply].was_promoted; /* update the piece count for determining opening/middlegame/endgame stage */ if (!ep) { switch (captured) { case (npiece): break; default: if (Variant == Bughouse || Variant == Crazyhouse) { if (is_promoted[squares[target]]) { removeHolding(SwitchPromoted(captured), NotToMove); } else { removeHolding(SwitchColor(captured), NotToMove); } } Hash(captured, target); AddMaterial(captured); piece_count++; break; } } /* white pawn moves: */ if (board[target] == wpawn) { /* look for an en passant move: */ if (ep) { Hash(wpawn, target); Hash(wpawn, from); Hash(bpawn, target-12); board[target] = npiece; board[from] = wpawn; AddMaterial(bpawn); removeHolding(wpawn, WHITE); piece_count++; board[target-12] = bpawn; moved[target]--; moved[from]--; moved[target-12]--; white_to_move ^= 1; squares[target-12] = path_x[ply].cap_num; pieces[path_x[ply].cap_num] = target-12; squares[target] = 0; return; } /* otherwise, we have a "regular" pawn move: */ Hash(wpawn, from); Hash(wpawn, target); board[target] = captured; board[from] = wpawn; moved[target]--; moved[from]--; white_to_move ^= 1; return; } /* black pawn moves: */ if (board[target] == bpawn) { /* look for an en passant move: */ if (ep) { Hash(bpawn, target); Hash(bpawn, from); Hash(wpawn, target+12); board[target] = npiece; board[from] = bpawn; AddMaterial(wpawn); removeHolding(bpawn, BLACK); piece_count++; board[target+12] = wpawn; moved[target]--; moved[from]--; moved[target+12]--; white_to_move ^= 1; squares[target+12] = path_x[ply].cap_num; pieces[path_x[ply].cap_num] = target+12; squares[target] = 0; return; } Hash(bpawn, from); Hash(bpawn, target); /* otherwise, we have a "regular" pawn move: */ board[target] = captured; board[from] = bpawn; moved[target]--; moved[from]--; white_to_move ^= 1; return; } /* piece moves, other than the king: */ if (board[target] != wking && board[target] != bking && !promoted) { board[from] = board[target]; board[target] = captured; moved[target]--; moved[from]--; white_to_move ^= 1; Hash(board[from], target); Hash(board[from], from); return; } /* look for a promotion move: */ if (promoted) { /* white promotions: */ if (board[target]%2) { board[target] = captured; board[from] = wpawn; moved[target]--; moved[from]--; white_to_move ^= 1; Hash(wpawn, from); Hash(promoted, target); RemoveMaterial(promoted); AddMaterial(wpawn); return; } /* black promotions: */ board[target] = captured; board[from] = bpawn; moved[target]--; moved[from]--; white_to_move ^= 1; Hash(bpawn, from); Hash(promoted, target); RemoveMaterial(promoted); AddMaterial(bpawn); return; } /* otherwise, we have a king move of some kind: */ /* White king moves first: */ if (board[target] == wking) { /* record the new white king location: */ wking_loc = from; /* perform the white king's move: */ board[target] = captured; board[from] = wking; moved[target]--; moved[from]--; white_to_move ^= 1; Hash(wking, from); Hash(wking, target); /* check for castling: */ /* check for white kingside castling: */ if (castled == wck) { board[33] = wrook; board[31] = npiece; moved[33]--; moved[31]--; white_castled = no_castle; squares[33] = squares[31]; squares[31] = 0; pieces[squares[33]] = 33; Hash(wrook, 33); Hash(wrook, 31); return; } /* check for white queenside castling: */ else if (castled == wcq) { board[26] = wrook; board[29] = npiece; moved[26]--; moved[29]--; white_castled = no_castle; squares[26] = squares[29]; squares[29] = 0; pieces[squares[26]] = 26; Hash(wrook, 29); Hash(wrook, 26); return; } return; } /* now we have only black king moves left: */ else { /* record the new black king location: */ bking_loc = from; /* perform the black king's move: */ board[target] = captured; board[from] = bking; moved[target]--; moved[from]--; white_to_move ^= 1; Hash(bking, from); Hash(bking, target); /* check for castling: */ /* check for black kingside castling: */ if (castled == bck) { board[117] = brook; board[115] = npiece; moved[117]--; moved[115]--; black_castled = no_castle; squares[117] = squares[115]; squares[115] = 0; pieces[squares[117]] = 117; Hash(brook, 117); Hash(brook, 115); return; } /* check for black queenside castling: */ else if (castled == bcq) { board[110] = brook; board[113] = npiece; moved[110]--; moved[113]--; black_castled = no_castle; squares[110] = squares[113]; squares[113] = 0; pieces[squares[110]] = 110; Hash(brook, 110); Hash(brook, 113); return; } } } return; } sjeng-11.2.orig/Makefile.am0100644000175000017500000000061407347625653014601 0ustar lukaslukasbin_PROGRAMS = sjeng sjeng_SOURCES = attacks.c crazy.c epd.c learn.c partner.c seval.c \ ttable.c book.c ecache.c eval.c moves.c search.c \ sjeng.c utils.c newbook.c proof.c neval.c rcfile.c\ leval.c draw.c see.c probe.c segtb.c\ protos.h extvars.h sjeng.h squares.h EXTRA_DIST = TODO NEWS ChangeLog COPYING BUGS THANKS blob2.c sjeng.rc SUBDIRS = books tests sjeng-11.2.orig/Makefile.in0100644000175000017500000003201007412717722014575 0ustar lukaslukas# Makefile.in generated automatically by automake 1.4 from Makefile.am # Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. SHELL = @SHELL@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ sbindir = @sbindir@ libexecdir = @libexecdir@ datadir = @datadir@ sysconfdir = @sysconfdir@ sharedstatedir = @sharedstatedir@ localstatedir = @localstatedir@ libdir = @libdir@ infodir = @infodir@ mandir = @mandir@ includedir = @includedir@ oldincludedir = /usr/include DESTDIR = pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = . ACLOCAL = @ACLOCAL@ AUTOCONF = @AUTOCONF@ AUTOMAKE = @AUTOMAKE@ AUTOHEADER = @AUTOHEADER@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ transform = @program_transform_name@ NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : CC = @CC@ CXX = @CXX@ MAKEINFO = @MAKEINFO@ PACKAGE = @PACKAGE@ VERSION = @VERSION@ bin_PROGRAMS = sjeng sjeng_SOURCES = attacks.c crazy.c epd.c learn.c partner.c seval.c ttable.c book.c ecache.c eval.c moves.c search.c sjeng.c utils.c newbook.c proof.c neval.c rcfile.c leval.c draw.c see.c probe.c segtb.c protos.h extvars.h sjeng.h squares.h EXTRA_DIST = TODO NEWS ChangeLog COPYING BUGS THANKS blob2.c sjeng.rc SUBDIRS = books tests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = PROGRAMS = $(bin_PROGRAMS) DEFS = @DEFS@ -I. -I$(srcdir) -I. CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ sjeng_OBJECTS = attacks.o crazy.o epd.o learn.o partner.o seval.o \ ttable.o book.o ecache.o eval.o moves.o search.o sjeng.o utils.o \ newbook.o proof.o neval.o rcfile.o leval.o draw.o see.o probe.o segtb.o sjeng_LDADD = $(LDADD) sjeng_DEPENDENCIES = sjeng_LDFLAGS = CFLAGS = @CFLAGS@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ DIST_COMMON = README ./stamp-h.in AUTHORS COPYING ChangeLog INSTALL \ Makefile.am Makefile.in NEWS THANKS TODO aclocal.m4 config.h.in \ configure configure.in install-sh missing mkinstalldirs DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = tar GZIP_ENV = --best SOURCES = $(sjeng_SOURCES) OBJECTS = $(sjeng_OBJECTS) all: all-redirect .SUFFIXES: .SUFFIXES: .S .c .o .s $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) \ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status $(ACLOCAL_M4): configure.in cd $(srcdir) && $(ACLOCAL) config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) cd $(srcdir) && $(AUTOCONF) config.h: stamp-h @if test ! -f $@; then \ rm -f stamp-h; \ $(MAKE) stamp-h; \ else :; fi stamp-h: $(srcdir)/config.h.in $(top_builddir)/config.status cd $(top_builddir) \ && CONFIG_FILES= CONFIG_HEADERS=config.h \ $(SHELL) ./config.status @echo timestamp > stamp-h 2> /dev/null $(srcdir)/config.h.in: $(srcdir)/stamp-h.in @if test ! -f $@; then \ rm -f $(srcdir)/stamp-h.in; \ $(MAKE) $(srcdir)/stamp-h.in; \ else :; fi $(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && $(AUTOHEADER) @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null mostlyclean-hdr: clean-hdr: distclean-hdr: -rm -f config.h maintainer-clean-hdr: mostlyclean-binPROGRAMS: clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) distclean-binPROGRAMS: maintainer-clean-binPROGRAMS: install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) $(mkinstalldirs) $(DESTDIR)$(bindir) @list='$(bin_PROGRAMS)'; for p in $$list; do \ if test -f $$p; then \ echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ else :; fi; \ done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) list='$(bin_PROGRAMS)'; for p in $$list; do \ rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ done .c.o: $(COMPILE) -c $< .s.o: $(COMPILE) -c $< .S.o: $(COMPILE) -c $< mostlyclean-compile: -rm -f *.o core *.core clean-compile: distclean-compile: -rm -f *.tab.c maintainer-clean-compile: sjeng: $(sjeng_OBJECTS) $(sjeng_DEPENDENCIES) @rm -f sjeng $(LINK) $(sjeng_LDFLAGS) $(sjeng_OBJECTS) $(sjeng_LDADD) $(LIBS) # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. @SET_MAKE@ all-recursive install-data-recursive install-exec-recursive \ installdirs-recursive install-recursive uninstall-recursive \ check-recursive installcheck-recursive info-recursive dvi-recursive: @set fnord $(MAKEFLAGS); amf=$$2; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" mostlyclean-recursive clean-recursive distclean-recursive \ maintainer-clean-recursive: @set fnord $(MAKEFLAGS); amf=$$2; \ dot_seen=no; \ rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ rev="$$subdir $$rev"; \ test "$$subdir" = "." && dot_seen=yes; \ done; \ test "$$dot_seen" = "no" && rev=". $$rev"; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS)'; \ unique=`for i in $$list; do echo $$i; done | \ awk ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ here=`pwd` && cd $(srcdir) \ && mkid -f$$here/ID $$unique $(LISP) TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) $(LISP) tags=; \ here=`pwd`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS)'; \ unique=`for i in $$list; do echo $$i; done | \ awk ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)config.h.in$$unique$(LISP)$$tags" \ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.h.in $$unique $(LISP) -o $$here/TAGS) mostlyclean-tags: clean-tags: distclean-tags: -rm -f TAGS ID maintainer-clean-tags: distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist -rm -rf $(distdir) GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz mkdir $(distdir)/=build mkdir $(distdir)/=inst dc_install_base=`cd $(distdir)/=inst && pwd`; \ cd $(distdir)/=build \ && ../configure --srcdir=.. --prefix=$$dc_install_base \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) dist -rm -rf $(distdir) @banner="$(distdir).tar.gz is ready for distribution"; \ dashes=`echo "$$banner" | sed s/./=/g`; \ echo "$$dashes"; \ echo "$$banner"; \ echo "$$dashes" dist: distdir -chmod -R a+r $(distdir) GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) -rm -rf $(distdir) dist-all: distdir -chmod -R a+r $(distdir) GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) -rm -rf $(distdir) distdir: $(DISTFILES) -rm -rf $(distdir) mkdir $(distdir) -chmod 777 $(distdir) @for file in $(DISTFILES); do \ d=$(srcdir); \ if test -d $$d/$$file; then \ cp -pr $$/$$file $(distdir)/$$file; \ else \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ || cp -p $$d/$$file $(distdir)/$$file || :; \ fi; \ done for subdir in $(SUBDIRS); do \ if test "$$subdir" = .; then :; else \ test -d $(distdir)/$$subdir \ || mkdir $(distdir)/$$subdir \ || exit 1; \ chmod 777 $(distdir)/$$subdir; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \ || exit 1; \ fi; \ done info-am: info: info-recursive dvi-am: dvi: dvi-recursive check-am: all-am check: check-recursive installcheck-am: installcheck: installcheck-recursive all-recursive-am: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive install-exec-am: install-binPROGRAMS install-exec: install-exec-recursive install-data-am: install-data: install-data-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am install: install-recursive uninstall-am: uninstall-binPROGRAMS uninstall: uninstall-recursive all-am: Makefile $(PROGRAMS) config.h all-redirect: all-recursive-am install-strip: $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install installdirs: installdirs-recursive installdirs-am: $(mkinstalldirs) $(DESTDIR)$(bindir) mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) -rm -f config.cache config.log stamp-h stamp-h[0-9]* maintainer-clean-generic: mostlyclean-am: mostlyclean-hdr mostlyclean-binPROGRAMS \ mostlyclean-compile mostlyclean-tags \ mostlyclean-generic mostlyclean: mostlyclean-recursive clean-am: clean-hdr clean-binPROGRAMS clean-compile clean-tags \ clean-generic mostlyclean-am clean: clean-recursive distclean-am: distclean-hdr distclean-binPROGRAMS distclean-compile \ distclean-tags distclean-generic clean-am distclean: distclean-recursive -rm -f config.status maintainer-clean-am: maintainer-clean-hdr maintainer-clean-binPROGRAMS \ maintainer-clean-compile maintainer-clean-tags \ maintainer-clean-generic distclean-am @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." maintainer-clean: maintainer-clean-recursive -rm -f config.status .PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \ mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \ maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \ mostlyclean-compile distclean-compile clean-compile \ maintainer-clean-compile install-data-recursive \ uninstall-data-recursive install-exec-recursive \ uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \ all-recursive check-recursive installcheck-recursive info-recursive \ dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \ maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ distclean-tags clean-tags maintainer-clean-tags distdir info-am info \ dvi-am dvi check check-am installcheck-am installcheck all-recursive-am \ install-exec-am install-exec install-data-am install-data install-am \ install uninstall-am uninstall all-redirect all-am all installdirs-am \ installdirs mostlyclean-generic distclean-generic clean-generic \ maintainer-clean-generic clean mostlyclean distclean maintainer-clean # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: sjeng-11.2.orig/neval.c0100644000175000017500000012271607316704771014021 0ustar lukaslukas/* Sjeng - a chess variants playing program Copyright (C) 2000 Gian-Carlo Pascutto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA File: neval.c Purpose: functions for evaluating positions (standard chess) */ #include "sjeng.h" #include "extvars.h" #include "protos.h" #include "squares.h" /* these tables will be used for positional bonuses: */ static int sbishop[144] = { 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,-2,-2,-2,-2,-2,-2,-2,-2,0,0, 0,0,-2,8,5,5,5,5,8,-2,0,0, 0,0,-2,3,3,5,5,3,3,-2,0,0, 0,0,-2,2,5,4,4,5,2,-2,0,0, 0,0,-2,2,5,4,4,5,2,-2,0,0, 0,0,-2,3,3,5,5,3,3,-2,0,0, 0,0,-2,8,5,5,5,5,8,-2,0,0, 0,0,-2,-2,-2,-2,-2,-2,-2,-2,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0}; static int sknight[144] = { 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,-20,-10,-10,-10,-10,-10,-10,-20,0,0, 0,0,-10,0,0,3,3,0,0,-10,0,0, 0,0,-10,0,5,5,5,5,0,-10,0,0, 0,0,-10,0,5,10,10,5,0,-10,0,0, 0,0,-10,0,5,10,10,5,0,-10,0,0, 0,0,-10,0,5,5,5,5,0,-10,0,0, 0,0,-10,0,0,3,3,0,0,-10,0,0, 0,0,-20,-10,-10,-10,-10,-10,-10,-20,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0}; static long int swhite_pawn[144] = { 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,1,2,3,10,10,3,2,1,0,0, 0,0,2,4,6,12,12,6,4,2,0,0, 0,0,3,6,9,14,14,9,6,3,0,0, 0,0,4,8,12,16,16,12,8,4,0,0, 0,0,5,10,15,20,20,15,10,5,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0}; static int sblack_pawn[144] = { 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,5,10,15,20,20,15,10,5,0,0, 0,0,4,8,12,16,16,12,8,4,0,0, 0,0,3,6,9,14,14,9,6,3,0,0, 0,0,2,4,6,12,12,6,4,2,0,0, 0,0,1,2,3,10,10,3,2,1,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0}; /* to be used during opening and middlegame for white king positioning: */ static int swhite_king[144] = { 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,2,14,0,0,0,9,14,2,0,0, 0,0,-3,-5,-6,-6,-6,-6,-5,-3,0,0, 0,0,-5,-5,-8,-8,-8,-8,-5,-5,0,0, 0,0,-8,-8,-13,-13,-13,-13,-8,-8,0,0, 0,0,-13,-13,-21,-21,-21,-21,-13,-13,0,0, 0,0,-21,-21,-34,-34,-34,-34,-21,-21,0,0, 0,0,-34,-34,-55,-55,-55,-55,-34,-34,0,0, 0,0,-55,-55,-89,-89,-89,-89,-55,-55,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0}; /* to be used during opening and middlegame for black king positioning: */ static int sblack_king[144] = { 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,-55,-55,-89,-89,-89,-89,-55,-55,0,0, 0,0,-34,-34,-55,-55,-55,-55,-34,-34,0,0, 0,0,-21,-21,-34,-34,-34,-34,-21,-21,0,0, 0,0,-13,-13,-21,-21,-21,-21,-13,-13,0,0, 0,0,-8,-8,-13,-13,-13,-13,-8,-8,0,0, 0,0,-5,-5,-8,-8,-8,-8,-5,-5,0,0, 0,0,-3,-5,-6,-6,-6,-6,-5,-3,0,0, 0,0,2,14,0,0,0,9,14,2,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0}; /* to be used for positioning of both kings during the endgame: */ static int send_king[144] = { 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,-5,-3,-1,0,0,-1,-3,-5,0,0, 0,0,-3,10,10,10,10,10,10,-3,0,0, 0,0,-1,10,25,25,25,25,10,-1,0,0, 0,0,0,10,25,30,30,25,10,0,0,0, 0,0,0,10,25,30,30,25,10,0,0,0, 0,0,-1,10,25,25,25,25,10,-1,0,0, 0,0,-3,10,10,10,10,10,10,-3,0,0, 0,0,-5,-3,-1,0,0,-1,-3,-5,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0}; /* utility array to reverse rank: */ static int srev_rank[9] = { 0,8,7,6,5,4,3,2,1}; const int std_p_tropism[9] = { 9999, 15, 10, 7, 2, 0, 0, 0, 9999}; const int std_r_tropism[9] = { 9999, 10, 6, 4, 2, 0, 0, 0, 9999}; const int std_n_tropism[9] = { 9999, 14, 9, 6, 1, 0, 0, 0, 9999}; const int std_q_tropism[9] = { 9999, 16, 12, 7, 2, 0, 0, 0, 9999}; const int std_b_tropism[9] = { 9999, 12, 7, 5, 0, 0, 0, 0, 9999}; static int bishop_mobility(int square) { register int l; register int m = 0; for (l = square-13; board[l] == npiece; l-=13) m++; for (l = square-11; board[l] == npiece; l-=11) m++; for (l = square+11; board[l] == npiece; l+=11) m++; for (l = square+13; board[l] == npiece; l+=13) m++; return m; } long int end_eval (void) { /* return a score for the current endgame position: */ int i, a, pawn_file, pawns[2][11], white_back_pawn[11], black_back_pawn[11], srank, j; long int score = 0; bool isolated, backwards; int in_cache; int wp = 0, bp = 0, wn = 0, bn = 0, wb = 0, bb = 0, wq = 0, bq = 0, wr = 0, br = 0; int fwrook, fbrook, rwrook, rbrook; int wpotential = 0, bpotential = 0, tmp; in_cache = 0; checkECache(&score, &in_cache); if(in_cache) { if (white_to_move == 1) return score; return -score; } /* initialize the pawns array, (files offset by one to use dummy files in order to easier determine isolated status) and also initialize the arrays keeping track of the rank of the most backward pawn: */ memset (pawns, 0, sizeof (pawns)); for (i = 0; i < 11; i++) { white_back_pawn[i] = 7; black_back_pawn[i] = 2; } for (j = 1, a = 1; (a <= piece_count); j++) { i = pieces[j]; if (!i) continue; else a++; assert((i > 0) && (i < 145)); pawn_file = file (i)+1; srank = rank (i); if (board[i] == wpawn) { pawns[1][pawn_file]++; if (srank < white_back_pawn[pawn_file]) { white_back_pawn[pawn_file] = srank; } } else if (board[i] == bpawn) { pawns[0][pawn_file]++; if (srank > black_back_pawn[pawn_file]) { black_back_pawn[pawn_file] = srank; } } } /* loop through the board, adding material value, as well as positional bonuses for all pieces encountered: */ for (j = 1, a = 1; (a <= piece_count); j++) { i = pieces[j]; if (!i) continue; else a++; pawn_file = file (i)+1; srank = rank (i); switch (board[i]) { case (wpawn): isolated = FALSE; backwards = FALSE; score += 100; score += swhite_pawn[i]; wp++; /* in general, bonuses/penalties in the endgame evaluation will be higher, since pawn structure becomes more important for the creation of passed pawns */ /* check for backwards pawns: */ if (white_back_pawn[pawn_file+1] > srank && white_back_pawn[pawn_file-1] > srank) { score -= 8; backwards = TRUE; /* check to see if it is furthermore isolated: */ if (!pawns[1][pawn_file+1] && !pawns[1][pawn_file-1]) { score -= 5; isolated = TRUE; } } /* give weak, exposed pawns a penalty (not as much as in the midgame, since there may be no pieces to take advantage of it): */ if (!pawns[0][pawn_file]) { if (backwards) score -= 3; if (isolated) score -= 5; } /* give doubled, trippled, etc.. pawns a penalty (bigger in the endgame, since they will become big targets): */ if (pawns[1][pawn_file] > 1) score -= 3*(pawns[1][pawn_file]-1); /* give bonuses for passed pawns (bigger in the endgame since passed pawns are what wins the endgame): */ if (!pawns[0][pawn_file] && srank >= black_back_pawn[pawn_file-1] && srank >= black_back_pawn[pawn_file+1]) { score += 30 + 3*swhite_pawn[i]; if (white_to_move) { /* check queening race */ /* tmp = queening square */ tmp = A8 + file(i) - 1; /* king is away how much ?*/ if (max(abs(file(bking_loc)-file(tmp)), abs(rank(bking_loc)-rank(tmp))) > (abs(rank(tmp) - rank(i)))) { wpotential += 800; } } else { /* check queening race */ /* tmp = queening square */ tmp = A8 + file(i) - 1; /* king is away how much ?*/ if ((max(abs(file(bking_loc)-file(tmp)), abs(rank(bking_loc)-rank(tmp)))-1) > (abs(rank(tmp) - rank(i)))) { wpotential += 800; } } /* outside passer ? */ if (file(i) == 1 || file(i) == 8) score += 12 + 2*swhite_pawn[i]; /* give an extra bonus if a connected, passed pawn: */ if (!isolated) { score += 12; /* check whether supporter is passed */ if (pawns[1][pawn_file+1]) { if (!pawns[0][pawn_file+1] && white_back_pawn[pawn_file+1] >= black_back_pawn[pawn_file+2]) { score += 7*rank(i); /* connected on seventh ? */ if (rank(i) == 7 && white_back_pawn[pawn_file+1] >= 6) { score += 50; } } } if (pawns[1][pawn_file-1]) { if (!pawns[0][pawn_file-1] && white_back_pawn[pawn_file+1] >= black_back_pawn[pawn_file-2]) { score += 7*rank(i); /* connected on seventh ? */ if (rank(i) == 7 && white_back_pawn[pawn_file-1] >= 6) { score += 50; } } } } } if (!pawns[1][pawn_file-1]) score -= 7; break; case (bpawn): isolated = FALSE; backwards = FALSE; score -= 100; score -= sblack_pawn[i]; bp++; /* in general, bonuses/penalties in the endgame evaluation will be higher, since pawn structure becomes more important for the creation of passed pawns */ /* check for backwards pawns: */ if (black_back_pawn[pawn_file+1] < srank && black_back_pawn[pawn_file-1] < srank) { score += 8; backwards = TRUE; /* check to see if it is furthermore isolated: */ if (!pawns[0][pawn_file+1] && !pawns[0][pawn_file-1]) { score += 5; isolated = TRUE; } } /* give weak, exposed pawns a penalty (not as much as in the midgame, since there may be no pieces to take advantage of it): */ if (!pawns[1][pawn_file]) { if (backwards) score += 3; if (isolated) score += 5; } /* give doubled, trippled, etc.. pawns a penalty (bigger in the endgame, since they will become big targets): */ if (pawns[0][pawn_file] > 1) score += 3*(pawns[0][pawn_file]-1); /* give bonuses for passed pawns (bigger in the endgame since passed pawns are what wins the endgame): */ if (!pawns[1][pawn_file] && srank <= white_back_pawn[pawn_file-1] && srank <= white_back_pawn[pawn_file+1]) { score -= 30 + 3*sblack_pawn[i]; if (!white_to_move) { /* check queening race */ /* tmp = queening square */ tmp = A1 + file(i) - 1; /* king is away how much ?*/ if (max(abs(file(wking_loc)-file(tmp)), abs(rank(wking_loc)-rank(tmp))) > (abs(rank(tmp) - (rank(i))))) { bpotential -= 800; } } else { /* check queening race */ /* tmp = queening square */ tmp = A1 + file(i) - 1; /* king is away how much ?*/ if ((max(abs(file(wking_loc)-file(tmp)), abs(rank(wking_loc)-rank(tmp)))-1) > abs((rank(tmp) - rank(i)))) { bpotential -= 800; } } /* outside passer ? */ if (file(i) == 1 || file(i) == 8) score -= 12 + 2*sblack_pawn[i]; /* give an extra bonus if a connected, passed pawn: */ if (!isolated) { score -= 12; /* check whether supporter is passed */ if (pawns[0][pawn_file+1]) { if (!pawns[1][pawn_file+1] && black_back_pawn[pawn_file+1] <= white_back_pawn[pawn_file+2]) { score -= 7*(9-rank(i)); /* on seventh and supported ? */ if (rank(i) == 2 && black_back_pawn[pawn_file+1] <= 3) { score -= 50; } } } if (pawns[0][pawn_file-1]) { if (!pawns[1][pawn_file-1] && black_back_pawn[pawn_file-1] <= white_back_pawn[pawn_file-2]) { score -= 7*(9-rank(i)); /* connected on seventh ? */ if (rank(i) == 2 && black_back_pawn[pawn_file-1] <= 3) { score -= 50; } } } } } if (!pawns[0][pawn_file-1]) score += 7; break; case (wrook): score += 500; wr++; if (wr == 1) { fwrook = file(i); rwrook = rank(i); } /* bonus for being on the 7th (a bit bigger bonus in the endgame, b/c a rook on the 7th can be a killer in the endgame): */ if (srank == 7) { score += 12; if (wr == 2 && 7 == rwrook) { score += 10; } } /* give bonuses depending on how open the rook's file is: */ if (!pawns[1][pawn_file]) { /* half open file */ score += 5; if (wr == 2 && file(i) == fwrook) { /* connected on file */ score += 10; } if (!pawns[0][pawn_file]) { /* open file */ score += 3; } } break; case (brook): score -= 500; br++; if (br == 1) { fbrook = file(i); rbrook = rank(i); } /* bonus for being on the 7th (a bit bigger bonus in the endgame, b/c a rook on the 7th can be a killer in the endgame): */ if (srank == 2) { score -= 12; if (br == 2 && 2 == rbrook) { score -= 10; } } /* give bonuses depending on how open the rook's file is: */ if (!pawns[0][pawn_file]) { /* half open file */ score -= 5; if (br == 2 && file(i) == fbrook) { /* connected on file */ score -= 10; } if (!pawns[1][pawn_file]) { /* open file */ score -= 3; } } break; case (wbishop): score += 325; score += sbishop[i]; score += (bishop_mobility(i) << 1) - 15; wb++; break; case (bbishop): score -= 325; score -= sbishop[i]; score -= (bishop_mobility(i) << 1) - 15; bb++; break; case (wknight): score += 310; score += sknight[i]; wn++; break; case (bknight): score -= 310; score -= sknight[i]; bn++; break; case (wqueen): score += 900; wq++; break; case (bqueen): score -= 900; bq++; break; } } /* some static knowledge about drawn endgames */ /* pawn ending detection */ if (!wr && !wq && !wb && !wn) { score += bpotential; } if (!br && !bq && !bb && !bn) { score += wpotential; } /* no more pawns */ if (!wp && !bp) { /* nor heavies */ if (!wr && !br && !wq && !bq) { if (!bb && !wb) { /* only knights */ /* it pretty safe to say this is a draw */ if (wn < 3 && bn < 3) { score = 0; } } else if (!wn && !bn) { /* only bishops */ /* not a draw if one side two other side zero else its always a draw */ if (abs(wb - bb) < 2) { score = 0; } } else if ((wn < 3 && !wb) || (wb == 1 && !wn)) { /* we cant win, but can black? */ if ((bn < 3 && !bb) || (bb == 1 && !bn)) { /* guess not */ score = 0; } } } else if (!wq && !bq) { if (wr == 1 && br == 1) { /* rooks equal */ if ((wn + wb) < 2 && (bn + bb) < 2) { /* one minor difference max */ /* a draw too usually */ score = 0; } } else if (wr == 1 && !br) { /* one rook */ /* draw if no minors to support AND minors to defend */ if ((wn + wb == 0) && (((bn + bb) == 1) || ((bn + bb) == 2))) { score = 0; } } else if (br == 1 && !wr) { /* one rook */ /* draw if no minors to support AND minors to defend */ if ((bn + bb == 0) && (((wn + wb) == 1) || ((wn + wb) == 2))) { score = 0; } } } } else { /* bad trade code, largely based on Crafty's */ /* minors are not equal */ if ((wn + wb) != (bn + bb)) { /* majors are equal */ if ((wq + wr) == (bq + br)) { if ((wn + wb) > (bn + bb)) { /* white is a piece up */ score += 120; } else { /* black is a piece up */ score -= 120; } } else if (abs((wr + wq) - (br + bq)) == 1) { /* one major difference */ if ((wb + wn) > (bb + bn + 1)) { /* two minors for one major */ score += 120; } else if ((bb + bn) > (wb + wn + 1)) { score -= 120; } } else if (abs((wr + wq) - (br + bq)) == 2) { /* two majors difference */ if ((wb + wn) > (bb + bn + 2)) { /* three minors for two majors */ score += 120; } else if ((bb + bn) > (wb + wn + 2)) { score -= 120; } } } else if ((wq + wr) == (bq + br)) { if (wq && !bq) { score += 120; } else if (!wq && bq) { score -= 120; } } } /* the king is safe to come out in the endgame, so we don't check for king safety anymore, and encourage centralization of the king */ score += send_king[wking_loc]; /* the king is safe to come out in the endgame, so we don't check for king safety anymore, and encourage centralization of the king */ score -= send_king[bking_loc]; /* the e/d pawn blockage is not relevant in the endgame, and we don't need to check for king safety due to pawn storms / heavy piece infiltration */ storeECache(score); /* adjust for color: */ if (white_to_move == 1) { return score; } else { return -score; } } void check_phase(void) { int num_pieces = 0; int j, a, i; for (j = 1, a = 1; (a <= piece_count); j++) { i = pieces[j]; if (!i) continue; else a++; if (board[i] != wpawn && board[i] != bpawn && board[i] != npiece && board[i] != frame) { num_pieces++; } }; if ((num_pieces >= 12) /* not both have castled */ && (!white_castled || !black_castled) /* no both lost castling priveledges */ && (board[30] == wking || board[114] == bking)) { phase = Opening; } else if (num_pieces <= 6) { phase = Endgame; } else phase = Middlegame; } long int std_eval (void) { /* select the appropriate eval() routine: */ if (phase == Opening) { return (opn_eval ()); } else if (phase == Endgame) { return (end_eval ()); } else { return (mid_eval ()); } } long int mid_eval (void) { /* return a score for the current middlegame position: */ int i,a, pawn_file, pawns[2][11], white_back_pawn[11], black_back_pawn[11], srank, wking_pawn_file, bking_pawn_file, j; long int score = 0; bool isolated, backwards; int in_cache; int wp = 0, bp = 0, wn = 0, bn = 0, wb = 0, bb = 0, wq = 0, bq = 0, wr = 0, br = 0; int rbrook, fbrook, rwrook,fwrook; in_cache = 0; checkECache(&score, &in_cache); if(in_cache) { if (white_to_move == 1) return score; return -score; } /* initialize the pawns array, (files offset by one to use dummy files in order to easier determine isolated status) and also initialize the arrays keeping track of the rank of the most backward pawn: */ memset (pawns, 0, sizeof (pawns)); for (i = 0; i < 11; i++) { white_back_pawn[i] = 7; black_back_pawn[i] = 2; } for (j = 1, a = 1; (a <= piece_count); j++) { i = pieces[j]; if (!i) continue; else a++; assert((i > 0) && (i < 145)); if (board[i] == wpawn) { pawn_file = file (i)+1; srank = rank (i); pawns[1][pawn_file]++; if (srank < white_back_pawn[pawn_file]) { white_back_pawn[pawn_file] = srank; } } else if (board[i] == bpawn) { pawn_file = file (i)+1; srank = rank (i); pawns[0][pawn_file]++; if (srank > black_back_pawn[pawn_file]) { black_back_pawn[pawn_file] = srank; } } } /* loop through the board, adding material value, as well as positional bonuses for all pieces encountered: */ for (j = 1, a = 1; (a <= piece_count); j++) { i = pieces[j]; if (!i) continue; else a++; pawn_file = file (i)+1; srank = rank (i); switch (board[i]) { case (wpawn): isolated = FALSE; backwards = FALSE; score += 100; score += swhite_pawn[i]; wp++; /* check for backwards pawns: */ if (white_back_pawn[pawn_file+1] > srank && white_back_pawn[pawn_file-1] > srank) { score -= 5; backwards = TRUE; /* check to see if it is furthermore isolated: */ if (!pawns[1][pawn_file+1] && !pawns[1][pawn_file-1]) { score -= 3; isolated = TRUE; } } score += std_p_tropism[max(abs(rank(i) - rank(bking_loc)), abs(file(i) - file(bking_loc)))]; /* give weak, exposed pawns a penalty: */ if (!pawns[0][pawn_file]) { if (backwards) score -= 4; if (isolated) score -= 8; } /* give doubled, trippled, etc.. pawns a penalty: */ if (pawns[1][pawn_file] > 1) score -= 2*(pawns[1][pawn_file]-1); /* give bonuses for passed pawns: */ if (!pawns[0][pawn_file] && srank >= black_back_pawn[pawn_file-1] && srank >= black_back_pawn[pawn_file+1]) { score += 20 + 2*swhite_pawn[i]; /* give an extra bonus if a connected, passed pawn: */ if (!isolated) { score += 10; /* check whether supporter is passed */ if (pawns[1][pawn_file+1]) { if (!pawns[0][pawn_file+1] && white_back_pawn[pawn_file+1] >= black_back_pawn[pawn_file+2]) { score += 7*rank(i); /* connected on seventh ? */ if (rank(i) == 7 && white_back_pawn[pawn_file+1] >= 6) { score += 50; } } } if (pawns[1][pawn_file-1]) { if (!pawns[0][pawn_file-1] && white_back_pawn[pawn_file+1] >= black_back_pawn[pawn_file-2]) { score += 7*rank(i); /* connected on seventh ? */ if (rank(i) == 7 && white_back_pawn[pawn_file-1] >= 6) { score += 50; } } } } } if (!pawns[1][pawn_file-1]) score -= 5; break; case (bpawn): isolated = FALSE; backwards = FALSE; score -= 100; score -= sblack_pawn[i]; bp++; /* check for backwards pawns: */ if (black_back_pawn[pawn_file+1] < srank && black_back_pawn[pawn_file-1] < srank) { score += 5; backwards = TRUE; /* check to see if it is furthermore isolated: */ if (!pawns[0][pawn_file+1] && !pawns[0][pawn_file-1]) { score += 3; isolated = TRUE; } } score -= std_p_tropism[max(abs(rank(i) - rank(wking_loc)), abs(file(i) - file(wking_loc)))]; /* give weak, exposed pawns a penalty: */ if (!pawns[1][pawn_file]) { if (backwards) score += 4; if (isolated) score += 8; } /* give doubled, trippled, etc.. pawns a penalty: */ if (pawns[0][pawn_file] > 1) score += 2*(pawns[0][pawn_file]-1); /* give bonuses for passed pawns: */ if (!pawns[1][pawn_file] && srank <= white_back_pawn[pawn_file-1] && srank <= white_back_pawn[pawn_file+1]) { score -= 20 + 2*sblack_pawn[i]; /* give an extra bonus if a connected, passed pawn: */ if (!isolated) { score -= 10; /* check whether supporter is passed */ if (pawns[0][pawn_file+1]) { if (!pawns[1][pawn_file+1] && black_back_pawn[pawn_file+1] <= white_back_pawn[pawn_file+2]) { score -= 7*(9-rank(i)); /* connected on seventh ? */ if (rank(i) == 2 && black_back_pawn[pawn_file+1] <= 3) { score -= 50; } } } if (pawns[0][pawn_file-1]) { if (!pawns[1][pawn_file-1] && black_back_pawn[pawn_file-1] <= white_back_pawn[pawn_file-2]) { score -= 7*(9-rank(i)); /* connected on seventh ? */ if (rank(i) == 2 && black_back_pawn[pawn_file-1] <= 3) { score -= 50; } } } } } if (!pawns[0][pawn_file-1]) score += 5; break; case (wrook): score += 500; wr++; if (wr == 1) { fwrook = file(i); rwrook = rank(i); } score += std_r_tropism[max(abs(rank(i) - rank(bking_loc)), abs(file(i) - file(bking_loc)))]; /* bonus for being on the 7th: */ if (srank == 7) { score += 8; if (wr == 2 && rwrook == 7) { score += 10; } } /* give bonuses depending on how open the rook's file is: */ if (!pawns[1][pawn_file]) { /* half open file */ score += 5; if (wr == 2 && file(i) == fwrook) { score += 12; } if (!pawns[0][pawn_file]) { /* open file */ score += 3; } } break; case (brook): score -= 500; br++; if (br == 1) { fbrook = file(i); rbrook = rank(i); } score -= std_r_tropism[max(abs(rank(i) - rank(wking_loc)), abs(file(i) - file(wking_loc)))]; /* bonus for being on the 7th: */ if (srank == 2) { score -= 8; if (wr == 2 && rbrook == 2) { score -= 10; } } /* give bonuses depending on how open the rook's file is: */ if (!pawns[0][pawn_file]) { /* half open file */ score -= 5; if (br == 2 && file(i) == fbrook) { score -= 12; } if (!pawns[1][pawn_file]) { /* open file */ score -= 3; } } break; case (wbishop): score += 325; score += sbishop[i]; wb++; score += std_r_tropism[max(abs(rank(i) - rank(bking_loc)), abs(file(i) - file(bking_loc)))]; score += bishop_mobility(i); break; case (bbishop): score -= 325; score -= sbishop[i]; bb++; score -= std_r_tropism[max(abs(rank(i) - rank(wking_loc)), abs(file(i) - file(wking_loc)))]; score -= bishop_mobility(i); break; case (wknight): score += 310; score += sknight[i]; wn++; score += std_n_tropism[max(abs(rank(i) - rank(bking_loc)), abs(file(i) - file(bking_loc)))]; break; case (bknight): score -= 310; score -= sknight[i]; bn++; score -= std_n_tropism[max(abs(rank(i) - rank(wking_loc)), abs(file(i) - file(wking_loc)))]; break; case (wqueen): score += 900; wq++; score += std_q_tropism[max(abs(rank(i) - rank(bking_loc)), abs(file(i) - file(bking_loc)))]; break; case (bqueen): score -= 900; bq++; score -= std_q_tropism[max(abs(rank(i) - rank(wking_loc)), abs(file(i) - file(wking_loc)))]; break; case (wking): score += swhite_king[i]; /* encourage castling, and give a penalty for moving the king without castling */ if (white_castled == wcq) score += 15; else if (white_castled == wck) score += 25; else if (moved[30]) { score -= 10; /* make the penalty bigger if the king is open, leaving the other side a chance to gain tempo with files along the file, as well as building an attack: */ if (!pawns[1][pawn_file]) score -= 15; } /* if the king is behind some pawn cover, give penalties for the pawn cover being far from the king, else give a penalty for the king not having any pawn cover: */ if (file(wking_loc) != 4 && file(wking_loc) != 5) { if (srank < white_back_pawn[pawn_file] && pawns[1][pawn_file]) score -= 9*(white_back_pawn[pawn_file]-srank-1); else score -= 22; if (srank < white_back_pawn[pawn_file+1] && pawns[1][pawn_file+1]) score -= 8*(white_back_pawn[pawn_file+1]-srank-1); else score -= 16; if (srank < white_back_pawn[pawn_file-1] && pawns[1][pawn_file-1]) score -= 8*(white_back_pawn[pawn_file-1]-srank-1); else score -= 16; } else { /* being in center isnt great either, so correct */ score -= 10; } break; case (bking): score -= sblack_king[i]; /* encourage castling, and give a penalty for moving the king without castling */ if (black_castled == bcq) score -= 15; else if (black_castled == bck) score -= 25; else if (moved[114]) { score += 10; /* make the penalty bigger if the king is open, leaving the other side a chance to gain tempo with files along the file, as well as building an attack: */ if (!pawns[0][pawn_file]) score += 15; } /* if the king is behind some pawn cover, give penalties for the pawn cover being far from the king, else give a penalty for the king not having any pawn cover: */ if (file(bking_loc) != 4 && file(bking_loc) != 5) { if (srank > black_back_pawn[pawn_file] && pawns[0][pawn_file]) score += 9*(srev_rank[srank-black_back_pawn[pawn_file]-1]); else score += 22; if (srank > black_back_pawn[pawn_file+1] && pawns[0][pawn_file+1]) score += 8*(srev_rank[srank-black_back_pawn[pawn_file+1]-1]); else score += 16; if (srank > black_back_pawn[pawn_file-1] && pawns[0][pawn_file-1]) score += 8*(srev_rank[srank-black_back_pawn[pawn_file-1]-1]); else score += 16; } else { score += 10; } break; } } /* give penalties for blocking the e/d pawns: */ if (!moved[41] && board[53] != npiece) score -= 5; if (!moved[42] && board[54] != npiece) score -= 5; if (!moved[101] && board[89] != npiece) score += 5; if (!moved[102] && board[90] != npiece) score += 5; /* to be used for pawn storm code: */ wking_pawn_file = file (wking_loc)+1; bking_pawn_file = file (bking_loc)+1; /* if the kings are on opposite wings, or far apart, check for pawn storms, and open lines for heavy pieces: */ if (abs(wking_pawn_file-bking_pawn_file) > 2) { /* black pawn storms: */ score -= 3*(srev_rank[black_back_pawn[wking_pawn_file]]-2); score -= 3*(srev_rank[black_back_pawn[wking_pawn_file+1]]-2); score -= 3*(srev_rank[black_back_pawn[wking_pawn_file-1]]-2); /* white pawn storms: */ /* this has side effects on no pawns, but I guess it wont hurt - GCP */ score += 3*(white_back_pawn[bking_pawn_file]-2); score += 3*(white_back_pawn[bking_pawn_file+1]-2); score += 3*(white_back_pawn[bking_pawn_file-1]-2); /* black opening up lines: */ if (!pawns[0][wking_pawn_file]) score -= 8; if (!pawns[0][wking_pawn_file+1]) score -= 6; if (!pawns[0][wking_pawn_file-1]) score -= 6; /* white opening up lines: */ if (!pawns[1][bking_pawn_file]) score += 8; if (!pawns[1][bking_pawn_file+1]) score += 6; if (!pawns[1][bking_pawn_file-1]) score += 6; } /* bad trade code, largely based on Crafty's */ /* minors are not equal */ if ((wn + wb) != (bn + bb)) { /* majors are equal */ if ((wq + wr) == (bq + br)) { if ((wn + wb) > (bn + bb)) { /* white is a piece up */ score += 120; } else { /* black is a piece up */ score -= 120; } } else if (abs((wr + wq) - (br + bq)) == 1) { /* one major difference */ if ((wb + wn) > (bb + bn + 1)) { /* two minors for one major */ score += 120; } else if ((bb + bn) > (wb + wn + 1)) { score -= 120; } } else if (abs((wr + wq) - (br + bq)) == 2) { /* two majors difference */ if ((wb + wn) > (bb + bn + 2)) { /* three minors for two majors */ score += 120; } else if ((bb + bn) > (wb + wn + 2)) { score -= 120; } } } else if ((wq + wr) == (bq + br)) { if (wq && !bq) { score += 120; } else if (!wq && bq) { score -= 120; } } storeECache(score); /* adjust for color: */ if (white_to_move == 1) { return score; } else { return -score; } } long int opn_eval (void) { /* return a score for the current opening position: */ int i,a, pawn_file, pawns[2][11], white_back_pawn[11], black_back_pawn[11], srank, wking_pawn_file, bking_pawn_file, j; long int score = 0; bool isolated, backwards; int in_cache; int fwrook = 0, fbrook = 0; in_cache = 0; checkECache(&score, &in_cache); if(in_cache) { if (white_to_move == 1) return score; return -score; } /* initialize the pawns array, (files offset by one to use dummy files in order to easier determine isolated status) and also initialize the arrays keeping track of the rank of the most backward pawn: */ memset (pawns, 0, sizeof (pawns)); for (i = 0; i < 11; i++) { white_back_pawn[i] = 7; black_back_pawn[i] = 2; } for (j = 1, a = 1; (a <= piece_count); j++) { i = pieces[j]; if (!i) continue; else a++; if (board[i] == wpawn) { pawn_file = file (i)+1; srank = rank (i); pawns[1][pawn_file]++; if (srank < white_back_pawn[pawn_file]) { white_back_pawn[pawn_file] = srank; } } else if (board[i] == bpawn) { pawn_file = file (i)+1; srank = rank (i); pawns[0][pawn_file]++; if (srank > black_back_pawn[pawn_file]) { black_back_pawn[pawn_file] = srank; } } } /* loop through the board, adding material value, as well as positional bonuses for all pieces encountered: */ for (j = 1, a = 1; (a <= piece_count); j++) { i = pieces[j]; if (!i) continue; else a++; assert((i > 0) && (i < 145)); pawn_file = file (i)+1; srank = rank (i); switch (board[i]) { case (wpawn): isolated = FALSE; backwards = FALSE; score += 100; score += swhite_pawn[i]; /* penalties / bonuses will be in general smaller in the opening, in order to put an emphasis on piece development */ /* check for backwards pawns: */ if (white_back_pawn[pawn_file+1] > srank && white_back_pawn[pawn_file-1] > srank) { /* no penalty in the opening for having a backwards pawn that hasn't moved yet! */ if (srank != 2) score -= 3; backwards = TRUE; /* check to see if it is furthermore isolated: */ if (!pawns[1][pawn_file+1] && !pawns[1][pawn_file-1]) { score -= 2; isolated = TRUE; } } /* give weak, exposed pawns a penalty: */ if (!pawns[0][pawn_file]) { if (backwards) score -= 3; if (isolated) score -= 5; } /* give doubled, trippled, etc.. pawns a penalty: */ if (pawns[1][pawn_file] > 1) score -= 2*(pawns[1][pawn_file]-1); /* give bonuses for passed pawns: */ if (!pawns[0][pawn_file] && srank >= black_back_pawn[pawn_file-1] && srank >= black_back_pawn[pawn_file+1]) { score += 5 + 2*swhite_pawn[i]; /* give an extra bonus if a connected, passed pawn: */ if (!isolated) score += 10; } break; case (bpawn): isolated = FALSE; backwards = FALSE; score -= 100; score -= sblack_pawn[i]; /* penalties / bonuses will be in general smaller in the opening, in order to put an emphasis on piece development */ /* check for backwards pawns: */ if (black_back_pawn[pawn_file+1] < srank && black_back_pawn[pawn_file-1] < srank) { /* no penalty in the opening for having a backwards pawn that hasn't moved yet! */ if (srank != 2) score += 3; backwards = TRUE; /* check to see if it is furthermore isolated: */ if (!pawns[0][pawn_file+1] && !pawns[0][pawn_file-1]) { score += 2; isolated = TRUE; } } /* give weak, exposed pawns a penalty: */ if (!pawns[1][pawn_file]) { if (backwards) score += 3; if (isolated) score += 5; } /* give doubled, trippled, etc.. pawns a penalty: */ if (pawns[0][pawn_file] > 1) score += 2*(pawns[0][pawn_file]-1); /* give bonuses for passed pawns: */ if (!pawns[1][pawn_file] && srank <= white_back_pawn[pawn_file-1] && srank <= white_back_pawn[pawn_file+1]) { score -= 5 + 2*sblack_pawn[i]; /* give an extra bonus if a connected, passed pawn: */ if (!isolated) score -= 10; } break; case (wrook): score += 500; if (!fwrook) fwrook = file(i); else if (file(i) == fwrook) { /* two rooks, file at least halfopen */ if (!pawns[1][pawn_file]) score += 10; } /* bonus for being on the 7th: */ if (srank == 7) score += 8; /* give bonuses depending on how open the rook's file is: */ if (!pawns[1][pawn_file]) { /* half open file */ score += 5; if (!pawns[0][pawn_file]) { /* open file */ score += 3; } } break; case (brook): score -= 500; if (!fbrook) fbrook = file(i); else if (file(i) == fbrook) { /* two rooks, file at least halfopen */ if (!pawns[0][pawn_file]) score -= 10; } /* bonus for being on the 7th: */ if (srank == 2) score -= 8; /* give bonuses depending on how open the rook's file is: */ if (!pawns[0][pawn_file]) { /* half open file */ score -= 5; if (!pawns[1][pawn_file]) { /* open file */ score -= 3; } } break; case (wbishop): score += 325; score += sbishop[i]; score += std_b_tropism[max(abs(rank(i) - rank(bking_loc)), abs(file(i) - file(bking_loc)))]; score += bishop_mobility(i); break; case (bbishop): score -= 325; score -= sbishop[i]; score -= std_b_tropism[max(abs(rank(i) - rank(wking_loc)), abs(file(i) - file(wking_loc)))]; score -= bishop_mobility(i); break; case (wknight): score += 310; score += sknight[i]; score += std_n_tropism[max(abs(rank(i) - rank(bking_loc)), abs(file(i) - file(bking_loc)))]; break; case (bknight): score -= 310; score -= sknight[i]; score -= std_n_tropism[max(abs(rank(i) - rank(wking_loc)), abs(file(i) - file(wking_loc)))]; break; case (wqueen): score += 900; score += std_q_tropism[max(abs(rank(i) - rank(bking_loc)), abs(file(i) - file(bking_loc)))]; /* a small penalty to discourage moving the queen in the opening before the other minors: */ if (i != 29) if (!moved[28] || !moved[27] || !moved[31] || !moved[32]) score -= 10; break; case (bqueen): score -= 900; score -= std_q_tropism[max(abs(rank(i) - rank(wking_loc)), abs(file(i) - file(wking_loc)))]; /* a small penalty to discourage moving the queen in the opening before the other minors: */ if (i != 113) if (!moved[112] || !moved[111] || !moved[115] || !moved[116]) score += 10; break; case (wking): score += swhite_king[i]; /* encourage castling, and give a penalty for moving the king without castling */ if (white_castled == wcq) score += 12; else if (white_castled == wck) score += 20; else if (moved[30]) { score -= 15; /* make the penalty bigger if the king is open, leaving the other side a chance to gain tempo with files along the file, as well as building an attack: */ if (!pawns[1][pawn_file]) score -= 10; } /* in general, in the opening, don't worry quite so much about pawn cover, because sometimes it isn't good for the king to castle */ /* if the king is behind some pawn cover, give penalties for the pawn cover being far from the king, else give a penalty for the king not having any pawn cover: */ /* only worry about cover when castled */ if (file(wking_loc) != 4 && file(wking_loc) != 5) { if (srank < white_back_pawn[pawn_file] && pawns[1][pawn_file]) score -= 7*(white_back_pawn[pawn_file]-srank-1); else score -= 14; if (srank < white_back_pawn[pawn_file+1] && pawns[1][pawn_file+1]) score -= 4*(white_back_pawn[pawn_file+1]-srank-1); else score -= 8; if (srank < white_back_pawn[pawn_file-1] && pawns[1][pawn_file-1]) score -= 4*(white_back_pawn[pawn_file-1]-srank-1); else score -= 8; } else { score -= 7; } break; case (bking): score -= sblack_king[i]; /* encourage castling, and give a penalty for moving the king without castling */ if (black_castled == bcq) score -= 12; else if (black_castled == bck) score -= 20; else if (moved[114]) { score += 15; /* make the penalty bigger if the king is open, leaving the other side a chance to gain tempo with files along the file, as well as building an attack: */ if (!pawns[0][pawn_file]) score += 10; } /* in general, in the opening, don't worry quite so much about pawn cover, because sometimes it isn't good for the king to castle */ /* if the king is behind some pawn cover, give penalties for the pawn cover being far from the king, else give a penalty for the king not having any pawn cover: */ if (file(bking_loc) != 4 && file(bking_loc) != 5) { if (srank > black_back_pawn[pawn_file] && pawns[0][pawn_file]) score += 7*(srev_rank[srank-black_back_pawn[pawn_file]-1]); else score += 14; if (srank > black_back_pawn[pawn_file+1] && pawns[0][pawn_file+1]) score += 4*(srev_rank[srank-black_back_pawn[pawn_file+1]-1]); else score += 8; if (srank > black_back_pawn[pawn_file-1] && pawns[0][pawn_file-1]) score += 4*(srev_rank[srank-black_back_pawn[pawn_file-1]-1]); else score += 8; } else { score += 7; } break; } } /* give bigger penalties for blocking the e/d pawns in the opening, as we want to develop quickly: */ if (!moved[41] && board[53] != npiece) score -= 7; if (!moved[42] && board[54] != npiece) score -= 7; if (!moved[101] && board[89] != npiece) score += 7; if (!moved[102] && board[90] != npiece) score += 7; /* to be used for pawn storm code: */ wking_pawn_file = file[wking_loc]+1; bking_pawn_file = file[bking_loc]+1; /* if the kings are on opposite wings, or far apart, check for pawn storms, and open lines for heavy pieces (bonuses/penalties brought down a bit in the opening, as it isn't a good idea to start pawn storming when the position is still fluid): */ if (abs(bking_pawn_file-wking_pawn_file) > 2) { /* black pawn storms: */ score -= srev_rank[black_back_pawn[wking_pawn_file]] - 2; score -= srev_rank[black_back_pawn[wking_pawn_file+1]] - 2; score -= srev_rank[black_back_pawn[wking_pawn_file-1]] - 2; /* white pawn storms: */ score += white_back_pawn[bking_pawn_file] - 2; score += white_back_pawn[bking_pawn_file+1] - 2; score += white_back_pawn[bking_pawn_file-1] - 2; /* black opening up lines: */ if (!pawns[0][wking_pawn_file]) score -= 6; if (!pawns[0][wking_pawn_file+1]) score -= 4; if (!pawns[0][wking_pawn_file-1]) score -= 4; /* white opening up lines: */ if (!pawns[1][bking_pawn_file]) score += 6; if (!pawns[1][bking_pawn_file+1]) score += 4; if (!pawns[1][bking_pawn_file-1]) score += 4; } storeECache(score); /* adjust for color: */ if (white_to_move == 1) { return score; } else { return -score; } } sjeng-11.2.orig/search.c0100644000175000017500000013156207412717310014146 0ustar lukaslukas/* Sjeng - a chess variants playing program Copyright (C) 2000-2001 Gian-Carlo Pascutto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA File: search.c Purpose: contains functions related to the recursive search */ #include "sjeng.h" #include "extvars.h" #include "protos.h" #include "limits.h" unsigned long FH, FHF; unsigned long razor_drop, razor_material, drop_cuts, ext_recap, ext_onerep; char true_i_depth; int bestmovenum; int ugly_ep_hack; char postpv[STR_BUFF]; char searching_move[20]; int moveleft; int movetotal; int legals; int failed; int extendedtime; int tradefreely; int s_threat; unsigned long rootnodecount[MOVE_BUFF]; bool checks[PV_BUFF]; #define KINGCAP 50000 #define NONE 0 #define SINGLE 1 void order_moves (move_s moves[], long int move_ordering[], long int see_values[], int num_moves, int best) { int promoted, captured; int i, from, target, seev; /* fill the move ordering array: */ /* if searching the pv, give it the highest move ordering, and if not, rely on the other heuristics: */ if (searching_pv) { searching_pv = FALSE; for (i = 0; i < num_moves; i++) { from = moves[i].from; target = moves[i].target; promoted = moves[i].promoted; captured = moves[i].captured; /* give captures precedence in move ordering, and order captures by material gain */ if (captured != npiece) { seev = see(ToMove, target, from); if (seev >= -50) move_ordering[i] = 50000 + seev; else move_ordering[i] = seev; see_values[i] = seev; } else move_ordering[i] = 0; /* make the pv have highest move ordering: */ if (from == pv[1][ply].from && target == pv[1][ply].target && promoted == pv[1][ply].promoted) { searching_pv = TRUE; move_ordering[i] = INF; if (captured != npiece) see_values[i] = see(ToMove, target, from); } else if ((best != -1) && (best != -2) && (i == best)) { move_ordering[i] = INF; if (captured != npiece) see_values[i] = see(ToMove, target, from); } else if (best == -2) { /* we have an iterative deepening move */ if (from == pv[ply+1][ply+1].from && target == pv[ply+1][ply+1].target && promoted == pv[ply+1][ply+1].promoted) { move_ordering[i] = INF; } } /* heuristics other than pv (no need to use them on the pv move - it is already ordered highest) */ else { if (ply != 1 || i_depth < 2) { /* add the history heuristic bonus: */ move_ordering[i] += (history_h[from][target]>>i_depth); /* add the killer move heuristic bonuses: */ if (from == killer1[ply].from && target == killer1[ply].target && promoted == killer1[ply].promoted) move_ordering[i] += 10000; else if (from == killer2[ply].from && target == killer2[ply].target && promoted == killer2[ply].promoted) move_ordering[i] += 5000; else if (from == killer3[ply].from && target == killer3[ply].target && promoted == killer3[ply].promoted) move_ordering[i] += 2500; } else { if ((nodes / 100) > INF) { move_ordering[i] = rootnodecount[i] / 1000; } else { move_ordering[i] = rootnodecount[i] / 100; } } } } } /* if not searching the pv: */ else { for (i = 0; i < num_moves; i++) { from = moves[i].from; target = moves[i].target; promoted = moves[i].promoted; captured = moves[i].captured; /* give captures precedence in move ordering, and order captures by material gain */ if ((best != -1) && (i == best)) { move_ordering[i] = INF; /* make sure we have SEE data */ if (captured != npiece) see_values[i] = see(ToMove, target, from); } else if (best == -2) { /* we have an iterative deepening move */ if (from == pv[ply+1][ply+1].from && target == pv[ply+1][ply+1].target && promoted == pv[ply+1][ply+1].promoted) { move_ordering[i] = INF; if (captured != npiece) see_values[i] = see(ToMove, target, from); } } else if (captured != npiece) { seev = see(ToMove, target, from); if (seev >= -50) move_ordering[i] = 50000 + seev; else move_ordering[i] = seev; see_values[i] = seev; } else move_ordering[i] = 0; /* heuristics other than pv */ /* add the history heuristic bonus: */ move_ordering[i] += (history_h[from][target]>>i_depth); /* add the killer move heuristic bonuses: */ if (from == killer1[ply].from && target == killer1[ply].target && promoted == killer1[ply].promoted) move_ordering[i] += 10000; else if (from == killer2[ply].from && target == killer2[ply].target && promoted == killer2[ply].promoted) move_ordering[i] += 5000; else if (from == killer3[ply].from && target == killer3[ply].target && promoted == killer3[ply].promoted) move_ordering[i] += 2500; } } } void perft (int depth) { move_s moves[MOVE_BUFF]; int num_moves, i; int ic; //ep_temp = ep_square; num_moves = 0; /* return if we are at the maximum depth: */ if (!depth) { raw_nodes++; return; } /* generate the move list: */ gen (&moves[0]); num_moves = numb_moves; ic = in_check(); /* loop through the moves at the current depth: */ for (i = 0; i < num_moves; i++) { make (&moves[0], i); /* check to see if our move is legal: */ if (check_legal (&moves[0], i, ic)) { /* go deeper into the tree recursively, increasing the indent to create the "tree" effect: */ perft (depth-1); } /* unmake the move to go onto the next: */ unmake (&moves[0], i); } //ep_square = ep_temp; } long int qsearch (int alpha, int beta, int depth) { /* perform a quiscense search on the current node using alpha-beta with negamax search */ move_s moves[MOVE_BUFF]; int num_moves, i, j; long int score = -INF, standpat, move_ordering[MOVE_BUFF], see_values[MOVE_BUFF]; bool legal_move, no_moves = TRUE; int sbest, best_score, best, delta, bound; int originalalpha; int oldtime; int seev; pv_length[ply] = ply; /* before we do anything, see if we're out of time: */ if (!(nodes & 8191)) { if (interrupt()) { time_exit = TRUE; return 0; } else if (((rdifftime (rtime (), start_time) >= time_for_move)) && (i_depth > 1)) { if (failed == 1 && !extendedtime && !fixed_time && !go_fast && Variant != Bughouse && (time_left > max(time_for_move*4, 1000))) { extendedtime = 1; oldtime = time_for_move; time_for_move += allocate_time(); printf("Extended from %d to %d, time left %d\n", oldtime, time_for_move, time_left); } else { time_exit = TRUE; return 0; } } } /* return our score if we're at a leaf node: */ if (depth <= 0 || ply > maxdepth) { /* remove leafcounting effect */ qnodes--; nodes--; score = eval (); return score; } originalalpha = alpha; switch (QProbeTT(&bound, alpha, beta, &best)) { case EXACT: return bound; break; case UPPER: if (bound <= alpha) return bound; if (bound < beta) beta = bound; break; case LOWER: if (bound >= beta) return bound; if (bound > alpha) alpha = bound; break; case DUMMY: break; case HMISS: best = -1;; break; }; standpat = eval (); if (standpat >= beta) { /* rem check this */ QStoreTT(standpat, originalalpha, beta, 500); return standpat; } else if (standpat > alpha) { alpha = standpat; } sbest = -1; best_score = -INF; num_moves = 0; delta = alpha-150-standpat; /* generate and order moves: */ gen (&moves[0]); num_moves = numb_moves; if (kingcap) return KINGCAP; order_moves (&moves[0], &move_ordering[0], &see_values[0], num_moves, best); /* loop through the moves at the current node: */ while (remove_one (&i, &move_ordering[0], num_moves)) { legal_move = FALSE; seev = see_values[i]; if (((seev < delta) || (seev < 0)) && !moves[i].promoted) continue; make (&moves[0], i); score = -qsearch (-beta, -alpha, depth-1); if (score != -KINGCAP) { nodes++; qnodes++; legal_move = TRUE; no_moves = FALSE; }; unmake (&moves[0], i); if(score > best_score && legal_move) { best_score = score; }; /* check our current score vs. alpha: */ if (score > alpha && legal_move) { /* don't update the history heuristic scores here, since depth is messed up when qsearch is called */ best = i; /* try for an early cutoff: */ if (score >= beta) { QStoreTT(score, originalalpha, beta, i); return score; } alpha = score; /* update the pv: */ pv[ply][ply] = moves[i];; for (j = ply+1; j < pv_length[ply+1]; j++) pv[ply][j] = pv[ply+1][j]; pv_length[ply] = pv_length[ply+1]; } } /* we don't check for mate / stalemate here, because without generating all of the moves leading up to it, we don't know if the position could have been avoided by one side or not */ if (no_moves) { /* we tried all moves and none were good...sack to alpha */ return standpat; } else { QStoreTT(alpha, originalalpha, beta, best); return alpha; } } bool remove_one (int *marker, long int move_ordering[], int num_moves) { /* a function to give pick the top move order, one at a time on each call. Will return TRUE while there are still moves left, FALSE after all moves have been used */ int i, best = -INF; *marker = -INF; for (i = 0; i < num_moves; i++) { if (move_ordering[i] > best) { *marker = i; best = move_ordering[i]; } } if (*marker > -INF) { move_ordering[*marker] = -INF; return TRUE; } else { return FALSE; } } long int search (int alpha, int beta, int depth, int is_null) { /* search the current node using alpha-beta with negamax search */ move_s moves[MOVE_BUFF]; int num_moves, i, j; long int score = -INF, move_ordering[MOVE_BUFF], see_values[MOVE_BUFF]; bool no_moves, legal_move; int bound, threat, donull, best, sbest, best_score, old_ep; bool incheck, first; int extend, fscore, fmax, selective; move_s kswap; int ksswap; int originalalpha; int afterincheck; int legalmoves; int dropcut; int oldtime; int egscore; static const int rc_index[14] = {0,1,1,2,2,5,5,3,3,4,4,2,2,0}; /* before we do anything, see if we're out of time: */ if (!(nodes & 8191)) { if (interrupt()) { time_exit = TRUE; return 0; } else if (((rdifftime (rtime (), start_time) >= time_for_move)) && (i_depth > 1)) { if (failed == 1 && !extendedtime && !fixed_time && !go_fast && Variant != Bughouse && (time_left > max(time_for_move*4, 1000))) { extendedtime = 1; oldtime = time_for_move; time_for_move += allocate_time(); printf("Extended from %d to %d, time left %d\n", oldtime, time_for_move, time_left); } else { time_exit = TRUE; return 0; } } } originalalpha = alpha; fmax = -INF; threat = 0; extend = 0; pv_length[ply] = ply; if (is_draw ()) { return 0; } if ((path[ply-1].captured != npiece || ply == 2)) { if (piece_count <= EGTBPieces && (Variant == Normal)) { egscore = probe_egtb(); if (egscore != KINGCAP) return egscore; } else if (piece_count <= 3 && (Variant == Suicide) && SEGTB) { EGTBProbes++; egscore = egtb(white_to_move); if (egscore != -128) { EGTBHits++; if (egscore < 0) { return -INF+(129+egscore); } else if (egscore > 0) { return INF-(129-egscore); } else if (egscore == 0) return 0; } } } incheck = checks[ply]; /* perform check extensions if we haven't gone past maxdepth: */ if (ply < maxdepth+1 && incheck && ((ply <= i_depth*2) || (depth == 0))) { depth++; ext_check++; extend++; } else if ((ply < maxdepth+1) && (ply > 2) && (ply < (i_depth*2)) && (depth <= 2) && cfg_recap && (path[ply-1].captured != 13) && (rc_index[path[ply-1].captured] == rc_index[path[ply-2].captured])) { depth++; ext_recap++; extend++; } /* try to find a stable position before passing the position to eval (): */ if (depth <= 0 || ply >= maxdepth) { if (Variant != Suicide && Variant != Losers) { captures = TRUE; score = qsearch (alpha, beta, maxdepth); captures = FALSE; return score; } else { if (Variant == Suicide) { return suicide_eval(); } else if (Variant == Losers) { i = losers_eval(); if (abs(i) == INF) { return ((i > 0) ? INF-ply : -INF+ply); } else { return i; } } } } num_moves = 0; no_moves = TRUE; switch (ProbeTT(&bound, alpha, beta, &best, &threat, &donull, depth)) { case EXACT: return bound; break; case UPPER: if (bound <= alpha) return bound; if (bound < beta) beta = bound; best = -1; break; case LOWER: if (bound >= beta) return bound; if (bound > alpha) alpha = bound; break; case DUMMY: break; case HMISS: best = -1; threat = FALSE; break; }; if (best == 500) best = -1; sbest = -1; best_score = -INF; old_ep = ep_square; legalmoves = 0; if (Variant == Losers) { i = losers_eval(); if (abs(i) == INF) { return (i > 0) ? i-ply : i+ply; } captures = TRUE; gen (&moves[0]); num_moves = numb_moves; captures = FALSE; if (num_moves) { for (i = 0; i < num_moves; i++) { make(&moves[0], i); if (check_legal(&moves[0], i, incheck)) { legalmoves++; } unmake(&moves[0], i); } } if (!legalmoves) { captures = FALSE; gen(&moves[0]); num_moves = numb_moves; }; legalmoves = 0; } if ((is_null == NONE) && ((phase != Endgame) || ((phase == Endgame) && (depth <= 6))) && !incheck && donull && !searching_pv && (threat == FALSE) && (((Variant != Suicide) && (Variant != Losers)) || (Variant == Losers && moves[0].captured == npiece))) { ep_square = 0; white_to_move ^= 1; ply++; fifty++; hash ^= 0xDEADBEEF; /* use R=1 cos R=2 is too dangerous for our ply depths */ if (Variant != Normal && Variant != Losers) score = -search(-beta, -beta+1, ((depth > 3) ? depth-2-1 : depth-1-1), SINGLE); else { if (depth > 11) score = -search(-beta, -beta+1, depth-4-1, SINGLE); else if (depth > 6) score = -search(-beta, -beta+1, depth-3-1, SINGLE); else score = -search(-beta, -beta+1, depth-2-1, SINGLE); }; hash ^= 0xDEADBEEF; fifty--; ply--; white_to_move ^= 1; ep_square = old_ep; if (time_exit) return 0; NTries++; if (score >= beta) { NCuts++; StoreTT(score, alpha, beta, 500, 0, depth); return score; } else if (score < -INF+100) { threat = TRUE; TExt++; depth++; extend++; ext_onerep++; } } else if (threat == TRUE) { TExt++; depth++; extend++; ext_onerep++; } score = -INF; first = TRUE; selective = 0; if (phase != Endgame && (Variant != Suicide) && cfg_futprune) { fscore = (white_to_move ? Material : -Material) + 900; if (!extend && depth == 3 && fscore <= alpha) depth = 2; fscore = (white_to_move ? Material : -Material) + 500; if (!extend && depth == 2 && fscore <= alpha) { selective = 1; best_score = fmax = fscore; } fscore = (white_to_move ? Material : -Material) + ((Variant == Normal) ? 150 : 200); if (!extend && depth == 1 && fscore <= alpha) { selective = 1; best_score = fmax = fscore; } } if (Variant != Losers) { /* generate and order moves: */ gen (&moves[0]); num_moves = numb_moves; } if ((Variant == Suicide) && num_moves == 1) depth++; else if ((Variant == Losers) && legalmoves == 1) depth++; if (num_moves > 0) { order_moves (&moves[0], &move_ordering[0], &see_values[0], num_moves, best); /* loop through the moves at the current node: */ while (remove_one (&i, &move_ordering[0], num_moves)) { make (&moves[0], i); legal_move = FALSE; hash_history[move_number+ply-1] = hash; path[ply-1] = moves[i]; //old_ep = ep_square; extend = 0; /* dont extend twice */ /* go deeper if it's a legal move: */ if (check_legal (&moves[0], i, incheck)) { afterincheck = f_in_check(&moves[0], i); checks[ply] = afterincheck; if (!afterincheck && ((Variant == Normal) || (Variant == Suicide) || (Variant == Losers)) && (depth < 3) && (((board[moves[i].target] == wpawn) && (rank(moves[i].target) >= 6) || ((board[moves[i].target] == bpawn) && (rank(moves[i].target) <= 3))))) { extend++; }; dropcut = 0; /* Razoring of uninteresting drops */ if ((moves[i].from == 0) && (depth > 1) /* more than pre-frontier nodes */ && (afterincheck == 0) /* not a contact checking move */ && (incheck == 0) /* not a check evasion */ && !searching_pv && cfg_razordrop ) { razor_drop++; extend--;} else { if ((moves[i].from == 0) && (depth == 1) && (incheck == 0) && cfg_cutdrop) { if (white_to_move) { dropcut = (calc_attackers(moves[i].target, 1) - calc_attackers(moves[i].target, 0)) > 0; if (dropcut) drop_cuts++; } else { dropcut = (calc_attackers(moves[i].target, 0) - calc_attackers(moves[i].target, 1)) > 0; if (dropcut) drop_cuts++; } } } if (!dropcut && (!selective || (afterincheck != 0) || (fmax + ((abs(material[moves[i].captured]) * ((Variant == Normal || Variant == Losers)?1:2) )) > alpha) || (moves[i].promoted))) { /* we only count the nodes we actually examine */ nodes++; if (first == TRUE) { score = -search (-beta, -alpha, depth+extend-1, NONE); FULL++; } else { score = -search (-alpha-1, -alpha, depth+extend-1, NONE); PVS++; if (score > best_score && !time_exit && score != -KINGCAP) { if ((score > alpha) && (score < beta)) { score = -search(-beta, -score, depth+extend-1, NONE); // ep_square = old_ep; PVSF++; if (score > best_score) best_score = score; } else best_score = score; } } legal_move = TRUE; } else razor_material++; legalmoves++; no_moves = FALSE; } if (score > best_score && legal_move) { best_score = score; }; unmake (&moves[0], i); /* return if we've run out of time: */ if (time_exit) return 0; /* check our current score vs. alpha: */ if (score > alpha && legal_move) { /* try for an early cutoff: */ if (score >= beta) { /* update the history heuristic since we have a cutoff: */ history_h[moves[i].from][moves[i].target] += depth * depth; if (moves[i].captured == npiece) { /* we have a cutoff, so update our killers: */ /* first, check whether it matches one of the known killers */ if (moves[i].from == killer1[ply].from && moves[i].target == killer1[ply].target && moves[i].promoted == killer1[ply].promoted) { killer_scores[ply]++; } else if (moves[i].from == killer2[ply].from && moves[i].target == killer2[ply].target && moves[i].promoted == killer2[ply].promoted) { killer_scores2[ply]++; if (killer_scores2[ply] > killer_scores[ply]) { kswap = killer1[ply]; killer1[ply] = killer2[ply]; killer2[ply] = kswap; ksswap = killer_scores[ply]; killer_scores[ply] = killer_scores2[ply]; killer_scores2[ply] = ksswap; } } else if (moves[i].from == killer3[ply].from && moves[i].target == killer3[ply].target && moves[i].promoted == killer3[ply].promoted) { killer_scores3[ply]++; if (killer_scores3[ply] > killer_scores2[ply]) { kswap = killer2[ply]; killer2[ply] = killer3[ply]; killer3[ply] = kswap; ksswap = killer_scores2[ply]; killer_scores2[ply] = killer_scores3[ply]; killer_scores3[ply] = ksswap; } } /* if not, replace killer3 */ else { killer_scores3[ply] = 1; killer3[ply] = moves[i]; } } if (first == TRUE) FHF++; FH++; StoreTT(score, originalalpha, beta, i, threat, depth); return score; } alpha = score; sbest = i; /* update the pv: */ pv[ply][ply] = moves[i]; for (j = ply+1; j < pv_length[ply+1]; j++) pv[ply][j] = pv[ply+1][j]; pv_length[ply] = pv_length[ply+1]; } if (legal_move) first = FALSE; } if (legalmoves <= 1 && (Variant != Suicide) && cfg_onerep) threat = TRUE; } else { /* no generated moves..only happens in suicide */ StoreTT(INF-ply, originalalpha, beta, 0, threat, depth); return INF-ply; } /* check for mate / stalemate: */ if (no_moves) { if (Variant != Losers && Variant != Suicide) { if (in_check ()) { StoreTT(-INF+ply, originalalpha, beta, 0, threat, depth); return (-INF+ply); } else { StoreTT(0, originalalpha, beta, 0, threat, depth); return 0; } } else { StoreTT(INF-ply, originalalpha, beta, 0, threat, depth); return (INF-ply); } } else { if (fifty > 100) { return 0; } }; /* doesnt seem to have any effect */ if (sbest == -1) sbest = 500; if (best_score <= originalalpha) { if (!selective) StoreTT(best_score, originalalpha, beta, sbest, threat, depth); } else { if (!selective) StoreTT(best_score, originalalpha, beta, sbest, threat, depth); else StoreTT(best_score, -INF, -INF, sbest, threat, depth);/*store lowbound*/ } return best_score; } move_s search_root (int originalalpha, int originalbeta, int depth) { /* search the root node using alpha-beta with negamax search */ move_s moves[MOVE_BUFF], best_move = dummy; int num_moves, i, j; long int root_score = -INF, move_ordering[MOVE_BUFF], see_values[MOVE_BUFF]; bool no_moves, legal_move, first; int alpha, beta; move_s kswap; move_s oldbest; int oldbestnum; int ksswap; int incheck; int mc = 0; int oldnodecount; alpha = originalalpha; beta = originalbeta; num_moves = 0; no_moves = TRUE; ply = 1; searching_pv = TRUE; time_exit = FALSE; time_failure = FALSE; first = TRUE; cur_score = -INF; /* check for a draw by 3 fold repetition: */ if (is_draw ()) { result = draw_by_rep; cur_score = 0; pv_length[ply] = 0; return (dummy); }; pv_length[ply] = ply; // GCP hash_history[move_number+ply-1] = hash; /*check extensions: */ incheck = in_check (); if (incheck) { ext_check++; depth++; }; checks[ply] = incheck; if (Variant == Losers) { legals = 0; captures = TRUE; gen (&moves[0]); num_moves = numb_moves; captures = FALSE; if (num_moves) { for (i = 0; i < num_moves; i++) { make(&moves[0], i); if (check_legal(&moves[0], i, incheck)) { legals++; } unmake(&moves[0], i); } } if (!legals) { captures = FALSE; gen(&moves[0]); num_moves = numb_moves; for (i = 0; i < num_moves; i++) { make(&moves[0], i); if (check_legal(&moves[0], i, incheck)) { legals++; } unmake(&moves[0], i); } }; } else { /* generate and order moves: */ gen (&moves[0]); num_moves = numb_moves; } movetotal = legals; order_moves (&moves[0], &move_ordering[0], &see_values[0], num_moves, -1); /* loop through the moves at the root: */ while (remove_one (&i, &move_ordering[0], num_moves)) { if (!alllosers && rootlosers[i] && ((Variant == Losers) || (Variant == Suicide))) continue; make (&moves[0], i); legal_move = FALSE; hash_history[move_number+ply-1] = hash; path[ply-1] = moves[i]; oldnodecount = nodes; //old_ep = ep_square; /* go deeper if it's a legal move: */ if (check_legal (&moves[0], i, incheck)) { unmake(&moves[0], i); mc++; moveleft = movetotal - mc; comp_to_san(moves[i], searching_move); make(&moves[0], i); nodes++; checks[ply] = f_in_check(&moves[0], i); if ((first == TRUE) || (i_depth < 2)) { root_score = -search (-beta, -alpha, depth-1, NONE); //ep_square = old_ep; if (!time_exit && (post || !xb_mode) && i_depth >= mindepth) { if (root_score >= beta) { /* update the pv: */ pv[ply-1][ply-1] = moves[i]; for (j = ply; j < pv_length[ply]; j++) pv[ply-1][j] = pv[ply][j]; pv_length[ply-1] = pv_length[ply]; post_fh_thinking(root_score, &moves[i]); } else if (root_score <= alpha) { /* update the pv: */ /* maybe not..fail low yields nonsense */ // pv[ply-1][ply-1] = moves[i]; // for (j = ply; j < pv_length[ply]; j++) // pv[ply-1][j] = pv[ply][j]; // pv_length[ply-1] = pv_length[ply]; failed = 1; post_fl_thinking(root_score, &moves[i]); } else { /* update the pv: */ pv[ply-1][ply-1] = moves[i]; for (j = ply; j < pv_length[ply]; j++) pv[ply-1][j] = pv[ply][j]; pv_length[ply-1] = pv_length[ply]; post_thinking(root_score); } if (root_score > cur_score && !time_exit) { cur_score = root_score; bestmovenum = i; best_move = moves[i]; } } } else { root_score = -search (-alpha-1, -alpha, depth-1, NONE); //ep_square = old_ep; if ((root_score > alpha) && (root_score < beta) && !time_exit) { post_fail_thinking(root_score, &moves[i]); oldbest = best_move; oldbestnum = bestmovenum; if (root_score > cur_score && !time_exit) { cur_score = root_score; bestmovenum = i; best_move = moves[i]; } root_score = -search(-beta, -root_score, depth-1, NONE); //ep_square = old_ep; if (root_score > alpha && !time_exit) { failed = 0; cur_score = root_score; bestmovenum = i; best_move = moves[i]; if (i_depth >= mindepth) { /* update the pv: */ pv[ply-1][ply-1] = moves[i]; for (j = ply; j < pv_length[ply]; j++) pv[ply-1][j] = pv[ply][j]; pv_length[ply-1] = pv_length[ply]; } } else {best_move = oldbest; bestmovenum = oldbestnum; }; } if (root_score >= beta && !time_exit) post_fh_thinking(root_score, &moves[i]); } if (root_score > cur_score && !time_exit) { cur_score = root_score; bestmovenum = i; best_move = moves[i]; } /* check to see if we've aborted this search before we found a move: * or a failed search <- removed 2000-5-28 * we should use the fail-highs * and the fail-lows are handled in think */ if (time_exit && (cur_score == -INF)) { if (no_moves) time_failure = TRUE; } no_moves = FALSE; legal_move = TRUE; } unmake (&moves[0], i); /* if we've run out of time, return the best we have so far: */ if (time_exit) return best_move; /* check our current score vs. alpha: */ if (root_score > alpha && legal_move) { /* we have a cutoff, so update our killers: */ /* first, check whether it matches one of the known killers */ if (moves[i].from == killer1[ply].from && moves[i].target == killer1[ply].target && moves[i].promoted == killer1[ply].promoted) { killer_scores[ply]++; } else if (moves[i].from == killer2[ply].from && moves[i].target == killer2[ply].target && moves[i].promoted == killer2[ply].promoted) { killer_scores2[ply]++; if (killer_scores2[ply] > killer_scores[ply]) { kswap = killer1[ply]; killer1[ply] = killer2[ply]; killer2[ply] = kswap; ksswap = killer_scores[ply]; killer_scores[ply] = killer_scores2[ply]; killer_scores2[ply] = ksswap; } } else if (moves[i].from == killer3[ply].from && moves[i].target == killer3[ply].target && moves[i].promoted == killer3[ply].promoted) { killer_scores3[ply]++; if (killer_scores3[ply] > killer_scores2[ply]) { kswap = killer2[ply]; killer2[ply] = killer3[ply]; killer3[ply] = kswap; ksswap = killer_scores2[ply]; killer_scores2[ply] = killer_scores3[ply]; killer_scores3[ply] = ksswap; } } /* if not, replace killer3 */ else { killer_scores3[ply] = 1; killer3[ply] = moves[i]; } /* update the history heuristic since we have a cutoff: */ /* PGC square it */ history_h[moves[i].from][moves[i].target] += depth * depth; alpha = root_score; best_move = moves[i]; bestmovenum = i; cur_score = alpha; /* update the pv: */ pv[ply][ply] = moves[i]; for (j = ply+1; j < pv_length[ply+1]; j++) pv[ply][j] = pv[ply+1][j]; pv_length[ply] = pv_length[ply+1]; if (cur_score >= beta) return best_move; /* print out thinking information: */ if (post && i_depth >= mindepth) { post_thinking (alpha); } } if (legal_move) first = FALSE; rootnodecount[i] = nodes - oldnodecount; } /* check to see if we are mated / stalemated: */ if (no_moves && !is_pondering) { if (Variant != Suicide && Variant != Losers) { if (in_check ()) { if (white_to_move == 1) { result = white_is_mated; } else { result = black_is_mated; } } else { result = stalemate; } } else { if (white_to_move == 1) { result = black_is_mated; } else { result = white_is_mated; } } } else if (!is_pondering) { /* check for draw by the 50 move rule: */ if (fifty > 100) { result = draw_by_fifty; cur_score = 0; pv_length[ply] = 0; return dummy; } } return best_move; } move_s think (void) { /* Perform iterative deepening to go further in the search */ move_s comp_move, temp_move, old_move; int i, j, k; long int elapsed, temp_score, true_score; char postmove[STR_BUFF]; clock_t cpu_start, cpu_end; float et = 0; int alpha, beta; int tmptmp; int rs; move_s moves[MOVE_BUFF]; int l, lastlegal, ic; int pn_restart; int num_moves; char output[8]; userealholdings = 0; pn_restart = 0; restart: nodes = 0; qnodes = 0; ply = 1; EGTBProbes = 0; EGTBHits = 0; ECacheProbes = 0; ECacheHits = 0; TTProbes = 0; TTHits = 0; TTStores = 0; NCuts = 0; NTries = 0; TExt = 0; FH = 0; FHF = 0; PVS = 0; FULL = 0; PVSF = 0; ext_check = 0; ext_recap = 0; ext_onerep = 0; razor_drop = 0; razor_material = 0; drop_cuts = 0; rs = 0; extendedtime = 0; forcedwin = 0; true_i_depth = 0; bestmovenum = -1; /* Don't do anything if the queue isn't clean */ /* PGC: only safe if we're not playing...else partner tells screw us up */ if (interrupt() && (is_analyzing || is_pondering)) return dummy; //ep_temp = ep_square; start_time = rtime (); // we need to know if we must sit or not in bug // legals = 0; if (Variant == Losers) captures = TRUE; else captures = FALSE; gen(&moves[0]); num_moves = numb_moves; ic = in_check(); for (l = 0; l < numb_moves; l++) { make(&moves[0],l); if (check_legal(&moves[0], l, ic)) { legals++; lastlegal = l; } unmake(&moves[0],l); } if (Variant == Losers && legals == 0) { captures = FALSE; num_moves = 0; gen(&moves[0]); num_moves = numb_moves; for (l = 0; l < numb_moves; l++) { make(&moves[0],l); if (check_legal(&moves[0], l, ic)) { legals++; lastlegal = l; } unmake(&moves[0],l); } }; if (Variant != Bughouse && !is_pondering) { if (legals == 1) { time_cushion += (inc*100); return moves[lastlegal]; } } //ep_square = ep_temp; /* before we do anything, check to see if we can make a move from book! */ if (!pn_restart && book_ply < 40 && !is_analyzing && !is_pondering) { comp_move = choose_book_move(); //ep_square = ep_temp; /* if choose_book_move() didn't return a junk move indicating that no book move was found, play the book move! :) */ if (comp_move.target == 0) comp_move = choose_binary_book_move(); //ep_square = ep_temp; if (comp_move.target != 0) { comp_to_san (comp_move, postmove); printf("0 0 0 0 %s (Book Move)\n", postmove); cpu_end = clock (); //ep_square = ep_temp; time_cushion += (inc*100); return comp_move; } } check_phase(); switch(phase) { case Opening : printf("Opening phase.\n"); break; case Middlegame : printf("Middlegame phase.\n"); break; case Endgame : printf("Endgame phase.\n"); break; } /* allocate our time for this move: */ if (!is_pondering) { if (!fixed_time) { if (go_fast) { tmptmp = allocate_time(); if (tmptmp > 40) { time_for_move = 40; } else { time_for_move = tmptmp; } } else { time_for_move = allocate_time (); } } else { time_for_move = fixed_time; } } else { time_for_move = 999999; }; if (pn_restart) time_for_move = (float)time_for_move * (float)2/((float)pn_restart+1.0); printf("Time for move : %d\n", time_for_move); if (time_for_move > 50) LoadLearn(); if (!pn_restart) { clear_dp_tt(); memset(rootlosers, 0, sizeof(rootlosers)); } if (!pn_restart && !is_pondering && ((Variant == Suicide) || (Variant == Losers)) && (piece_count > 3 || (Variant != Suicide))) { pn_time = (int)((float)(time_for_move) * 1.0/3.0); proofnumberscan(); } else if (!pn_restart) pn_move = dummy; if (result && pn_move.target == dummy.target) return pn_move; if ((forcedwin || result) && (pn_move.target != dummy.target) && !is_analyzing) { comp_move = pn_move; } else { /* clear the pv before a new search: */ for (i = 0; i < PV_BUFF; i++) for (j = 0; j < PV_BUFF; j++) pv[i][j] = dummy; /* clear the history heuristic: */ memset (history_h, 0, sizeof (history_h)); /* clear the killer moves: */ for (i = 0; i < PV_BUFF; i++) { killer_scores[i] = 0; killer_scores2[i] = 0; killer_scores3[i] = 0; killer1[i] = dummy; killer2[i] = dummy; killer3[i] = dummy; } memset(rootnodecount, 0, sizeof(rootnodecount)); cpu_start = clock(); temp_score = 0; cur_score = 0; true_score = 0; for (i_depth = 1; i_depth <= maxdepth; i_depth++) { /* don't bother going deeper if we've already used 2/3 of our time, and we haven't finished our mindepth search, since we likely won't finsish */ elapsed = rdifftime (rtime (), start_time); if (elapsed > time_for_move*2.1/3.0 && i_depth > mindepth) break; failed = 0; alpha = temp_score - (Variant == Normal ? 35 : 100); beta = temp_score + (Variant == Normal ? 35 : 100); //ep_square = ep_temp; temp_move = search_root (alpha, beta, i_depth); if (result) break; if (cur_score <= alpha) failed = 1; else failed = 0; if (cur_score <= alpha && !time_exit) /* fail low */ { alpha = cur_score - (Variant == Normal ? 350 : 600); beta = cur_score; rs++; //ep_square = ep_temp; temp_move = search_root (alpha, beta, i_depth); if (cur_score > alpha && !time_exit) failed = 0; if (cur_score <= alpha && !time_exit) { alpha = -(INF+1); beta = cur_score; rs++; //ep_square = ep_temp; temp_move = search_root (alpha, beta, i_depth); if (cur_score > alpha && !time_exit) failed = 0; } else if (cur_score >= beta && !time_exit) { temp_move = search_root (-INF, +INF, i_depth); if (!time_exit) failed = 0; } } else if (cur_score >= beta && !time_exit) /* fail high */ { comp_move = temp_move; temp_score = cur_score; alpha = cur_score - 1; beta = cur_score + (Variant == Normal ? 350 : 600); rs++; //ep_square = ep_temp; temp_move = search_root (alpha, beta, i_depth); if (cur_score >= beta && !time_exit) { comp_move = temp_move; temp_score = cur_score; alpha = cur_score - 1; beta = +(INF+1); rs++; //ep_square = ep_temp; temp_move = search_root (alpha, beta, i_depth); } else if (cur_score <= alpha && !time_exit) { /* fail high then low...do not make it PV */ failed = 1; }; }; //ep_square = ep_temp; if (interrupt() && (i_depth > 1)) { if (is_pondering) return dummy; else if (!go_fast) break; } /* if we haven't aborted our search on time, set the computer's move and post our thinking: */ if (!time_failure && !failed) { /* if our search score suddenly drops, and we ran out of time on the search, just use previous results */ /* GCP except when we found a mate...maybe generalise ? */ /* enabled 2000-5-28 */ // if (time_exit && (cur_score < temp_score-50) && (cur_score > -900000)) // break; /* acidentally pondering if mated */ if (cur_score == -INF) return dummy; comp_move = temp_move; temp_score = cur_score; stringize_pv(postpv); if (!time_exit) { true_i_depth = i_depth; } if (i_depth >= mindepth) post_thinking (cur_score); if (temp_score > 900000 && ((int)(1000000-cur_score) < i_depth)) { break; }; } if (time_exit) break; /* reset the killer scores (we can keep the moves for move ordering for now, but the scores may not be accurate at higher depths, so we need to reset them): */ for (j = 0; j < PV_BUFF; j++) { killer_scores[j] = 0; killer_scores2[j] = 0; killer_scores3[j] = 0; } } } //ep_square = ep_temp; if (!forcedwin) { cpu_end = clock(); et = (cpu_end-cpu_start)/(double) CLOCKS_PER_SEC; old_move = comp_move; if ((Variant == Losers || Variant == Suicide) && !result && !alllosers && !is_pondering) { s_threat = FALSE; comp_move = proofnumbercheck(comp_move); if ((pn_restart < 10) && (s_threat)) { /* a/b loser */ pn_restart++; /* mark loser */ for (i = 0; i < num_moves; i++) { if (moves[i].from == old_move.from && moves[i].target == old_move.target && moves[i].promoted == old_move.promoted) { rootlosers[i] = TRUE; break; } } for (j = 0; j < num_moves; j++) { if (rootlosers[j]) k++; } if (k == legals) alllosers = TRUE; goto restart; } } }; if (alllosers) comp_move = old_move; if (pn_restart != 0 && xb_mode) { comp_to_san(comp_move, output); printf("tellics whisper %d restart(s), ended up with %s\n", pn_restart, output); result = 0; } elapsed = rdifftime (rtime (), start_time); printf("Used time : %d\n", elapsed); /* update our elapsed time_cushion: */ if (moves_to_tc && !is_pondering) { time_cushion += time_for_move-elapsed+inc; } if (temp_score == INF-2 && !is_pondering/* && pn_move.target == dummy.target*/) { if (white_to_move == 1) { result = black_is_mated; } else { result = white_is_mated; } } else if (temp_score == -(INF-2) && !is_pondering/* && pn_move.target == dummy.target*/) { if (white_to_move == 1) { result = white_is_mated; } else { result = black_is_mated; } } if (post && xb_mode && !is_pondering && result != black_is_mated && result != white_is_mated && result != draw_by_fifty && result != draw_by_rep && result != stalemate && !forcedwin) { if (temp_score > INF-400) { if (Variant != Bughouse) { printf("tellics kibitz Mate in %d\n", (int)((1000000-temp_score)/2)); } else { printf("tellics ptell Mate in %d, give him no more pieces.\n", (int)((1000000-temp_score)/2)); } } //comp_to_san (comp_move, postmove); if ((et > 0) && (Variant != Bughouse)) { printf("tellics whisper d%d %+.2f %sn: %ld qp: %.0f%% fh: %.0f%% c-x: %d r-x: %d 1-x: %d egtb: %d time: %.2f nps: %ld\n", true_i_depth, (float)temp_score/100.0, postpv, nodes, (((float)qnodes*100)/((float)nodes+1)), ((float)FHF*100)/((float)(FH+1)), // ((float)PVS*100)/((float)FULL+1), // ((float)PVSF*100)/((float)PVS+1), ext_check, ext_recap, ext_onerep, EGTBHits, ((float)elapsed/100.), (long)((float) nodes/(float) (et))); } } if ((result != white_is_mated) && (result != black_is_mated) && (result != stalemate) && (result != draw_by_fifty) && (result != draw_by_rep) && (true_i_depth >= 3) && pn_move.target == dummy.target && !is_pondering && (Variant != Bughouse)) { if (bestmovenum == -1) DIE; Learn(temp_score, bestmovenum, true_i_depth); } if ((Variant == Bughouse) && temp_score > -999900) { if (tradefreely == 0 && !userealholdings) { tradefreely = 1; printf("tellics ptell You can trade freely.\n"); } } else if ((temp_score < -999900) && (Variant == Bughouse) && pn_move.target == dummy.target) { if (userealholdings) { must_sit = TRUE; } else { userealholdings = 1; ProcessHoldings(realholdings); tradefreely = 0; printf("tellics ptell ---trades\n"); goto restart; } /* shut up if the mate is already played */ if (temp_score > -1000000) { if (partnerdead) { printf("tellics kibitz Both players dead...resigning...\n"); printf("tellics resign\n"); } else { printf("tellics ptell I am forcedly mated (dead). Tell me 'go' to start moving into it.\n"); } } } else if ((temp_score > -60000) && (temp_score < -40000) && (Variant == Bughouse) && !partnerdead && pn_move.target == dummy.target) { must_sit = TRUE; printf("tellics ptell I'll have to sit...(lose piece that mates you)\n"); } return comp_move; } void tree (int depth, int indent, FILE *output, char *disp_b) { move_s moves[MOVE_BUFF]; int num_moves, i, j; int ic; // //ep_temp = ep_square; num_moves = 0; /* return if we are at the maximum depth: */ if (!depth) { return; } /* generate the move list: */ gen (&moves[0]); num_moves = numb_moves; ic = in_check(); /* loop through the moves at the current depth: */ for (i = 0; i < num_moves; i++) { make (&moves[0], i); /* check to see if our move is legal: */ if (check_legal (&moves[0], i, ic)) { /* indent and print out our line: */ for (j = 0; j < indent; j++) { fputc (' ', output); } print_move (&moves[0], i, output); fprintf (output, "\n"); /* display board if desired: */ if (disp_b[0] == 'y') display_board (output, 1); /* go deeper into the tree recursively, increasing the indent to create the "tree" effect: */ tree (depth-1, indent+2, output, disp_b); } /* unmake the move to go onto the next: */ unmake(&moves[0], i); } //ep_square = ep_temp; } sjeng-11.2.orig/config.h.in0100644000175000017500000000217007412717061014553 0ustar lukaslukas/* config.h.in. Generated automatically from configure.in by autoheader. */ /* Define to empty if the keyword does not work. */ #undef const /* Define as the return type of signal handlers (int or void). */ #undef RETSIGTYPE /* Define if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define if you can safely include both and . */ #undef TIME_WITH_SYS_TIME /* Define if you have the ftime function. */ #undef HAVE_FTIME /* Define if you have the gettimeofday function. */ #undef HAVE_GETTIMEOFDAY /* Define if you have the select function. */ #undef HAVE_SELECT /* Define if you have the strstr function. */ #undef HAVE_STRSTR /* Define if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define if you have the header file. */ #undef HAVE_SYS_TIMEB_H /* Define if you have the header file. */ #undef HAVE_UNISTD_H /* Define if you have the gdbm library (-lgdbm). */ #undef HAVE_LIBGDBM /* Define if you have the m library (-lm). */ #undef HAVE_LIBM /* Name of package */ #undef PACKAGE /* Version number of package */ #undef VERSION sjeng-11.2.orig/squares.h0100644000175000017500000000351607273576355014407 0ustar lukaslukas/* Sjeng - a chess variants playing program Copyright (C) 2000-2001 Gian-Carlo Pascutto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA File: squares.h Purpose: contains squares definitions */ #define A1 26 #define B1 27 #define C1 28 #define D1 29 #define E1 30 #define F1 31 #define G1 32 #define H1 33 #define A2 38 #define B2 39 #define C2 40 #define D2 41 #define E2 42 #define F2 43 #define G2 44 #define H2 45 #define A3 50 #define B3 51 #define C3 52 #define D3 53 #define E3 54 #define F3 55 #define G3 56 #define H3 57 #define A4 62 #define B4 63 #define C4 64 #define D4 65 #define E4 66 #define F4 67 #define G4 68 #define H4 69 #define A5 74 #define B5 75 #define C5 76 #define D5 77 #define E5 78 #define F5 79 #define G5 80 #define H5 81 #define A6 86 #define B6 87 #define C6 88 #define D6 89 #define E6 90 #define F6 91 #define G6 92 #define H6 93 #define A7 98 #define B7 99 #define C7 100 #define D7 101 #define E7 102 #define F7 103 #define G7 104 #define H7 105 #define A8 110 #define B8 111 #define C8 112 #define D8 113 #define E8 114 #define F8 115 #define G8 116 #define H8 117 sjeng-11.2.orig/rcfile.c0100644000175000017500000001177107355047246014156 0ustar lukaslukas/* Sjeng - a chess variants playing program Copyright (C) 2000 Gian-Carlo Pascutto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA File: rcfile.c Purpose: Read in config file, allocate hash/caches */ #include "sjeng.h" #include "protos.h" #include "extvars.h" #include "config.h" FILE *rcfile; char line[STR_BUFF]; int TTSize; int ECacheSize; int PBSize; int cfg_booklearn; int cfg_razordrop; int cfg_cutdrop; int cfg_ksafety[15][9]; int cfg_tropism[5][7]; int havercfile; int cfg_futprune; int cfg_devscale; int cfg_onerep; int cfg_recap; int cfg_smarteval; int cfg_attackeval; float cfg_scalefac; void read_rcfile (void) { int i; unsigned int setc; if ((rcfile = fopen ("sjeng.rc", "r")) == NULL) { printf("No configuration file!\n"); TTSize = 300000; ECacheSize = 200000; PBSize = 200000; EGTBCacheSize = 0; strcpy(EGTBDir, "TB"); cfg_devscale = 1; cfg_scalefac = 1.0; cfg_razordrop = 1; cfg_cutdrop = 0; cfg_futprune = 1; cfg_smarteval = 1; cfg_attackeval = 0; havercfile = 0; setc = havercfile + (cfg_devscale << 1) + (((cfg_scalefac == 1.0) ? 1 : 0) << 2) + (cfg_razordrop << 3) + (cfg_cutdrop << 4) + (cfg_futprune << 5) + (cfg_smarteval << 6) + (cfg_attackeval << 7); sprintf(setcode, "%u", setc); initialize_eval(); alloc_hash(); alloc_ecache(); return; } havercfile = 1; /* read in values, possibly seperated by # commented lines */ fgets(line, STR_BUFF, rcfile); while (line[0] == '#') fgets(line, STR_BUFF, rcfile); sscanf(line, "%d", &TTSize); fgets(line, STR_BUFF, rcfile); while (line[0] == '#') fgets(line, STR_BUFF, rcfile); sscanf(line, "%d", &ECacheSize); fgets(line, STR_BUFF, rcfile); while (line[0] == '#') fgets(line, STR_BUFF, rcfile); sscanf(line, "%d", &PBSize); fgets(line, STR_BUFF, rcfile); while (line[0] == '#') fgets(line, STR_BUFF, rcfile); sscanf(line, "%f", &cfg_scalefac); fgets(line, STR_BUFF, rcfile); while (line[0] == '#') fgets(line, STR_BUFF, rcfile); sscanf(line, "%d", &cfg_devscale); fgets(line, STR_BUFF, rcfile); while (line[0] == '#') fgets(line, STR_BUFF, rcfile); sscanf(line, "%d", &cfg_razordrop); fgets(line, STR_BUFF, rcfile); while (line[0] == '#') fgets(line, STR_BUFF, rcfile); sscanf(line, "%d", &cfg_cutdrop); fgets(line, STR_BUFF, rcfile); while (line[0] == '#') fgets(line, STR_BUFF, rcfile); sscanf(line, "%d", &cfg_booklearn); fgets(line, STR_BUFF, rcfile); while (line[0] == '#') fgets(line, STR_BUFF, rcfile); sscanf(line, "%d", &cfg_futprune); fgets(line, STR_BUFF, rcfile); while (line[0] == '#') fgets(line, STR_BUFF, rcfile); sscanf(line, "%d", &cfg_onerep); fgets(line, STR_BUFF, rcfile); while (line[0] == '#') fgets(line, STR_BUFF, rcfile); sscanf(line, "%d", &cfg_recap); fgets(line, STR_BUFF, rcfile); while (line[0] == '#') fgets(line, STR_BUFF, rcfile); sscanf(line, "%d", &cfg_smarteval); fgets(line, STR_BUFF, rcfile); while (line[0] == '#') fgets(line, STR_BUFF, rcfile); sscanf(line, "%d", &cfg_attackeval); fgets(line, STR_BUFF, rcfile); while (line[0] == '#') fgets(line, STR_BUFF, rcfile); for(i = 0; i < 5; i++) { sscanf(line, "%d %d %d %d %d %d %d", &cfg_tropism[i][0], &cfg_tropism[i][1], &cfg_tropism[i][2],&cfg_tropism[i][3], &cfg_tropism[i][4], &cfg_tropism[i][5], &cfg_tropism[i][6]); do { fgets(line, STR_BUFF, rcfile);} while (line[0] == '#'); } for(i = 0; i < 15; i++) { sscanf(line, "%d %d %d %d %d %d %d %d %d", &cfg_ksafety[i][0], &cfg_ksafety[i][1],&cfg_ksafety[i][2],&cfg_ksafety[i][3], &cfg_ksafety[i][4], &cfg_ksafety[i][5],&cfg_ksafety[i][6],&cfg_ksafety[i][7], &cfg_ksafety[i][8]); do {fgets(line, STR_BUFF, rcfile);} while ((line[0] == '#') && !feof(rcfile)); } setc = havercfile + (cfg_devscale << 1) + (((cfg_scalefac == 1.0) ? 1 : 0) << 2) + (cfg_razordrop << 3) + (cfg_cutdrop << 4) + (cfg_futprune << 5) + (cfg_smarteval << 6) + (cfg_attackeval << 7); sprintf(setcode, "%u", setc); initialize_eval(); alloc_hash(); alloc_ecache(); return; } sjeng-11.2.orig/stamp-h.in0100644000175000017500000000001207412717725014431 0ustar lukaslukastimestamp sjeng-11.2.orig/AUTHORS0100644000175000017500000000017507307525236013607 0ustar lukaslukasSjeng is written by Gian-Carlo Pascutto (gcp@sjeng.org), based on work done by Adrien Regimbald (adrien@gpu.srv.ualberta.ca) sjeng-11.2.orig/utils.c0100644000175000017500000007507207323621630014044 0ustar lukaslukas/* Sjeng - a chess variants playing program Copyright (C) 2000-2001 Gian-Carlo Pascutto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA File: utils.c Purpose: misc. functions used throughout the program */ #include "config.h" #include "sjeng.h" #include "extvars.h" #include "protos.h" #include "limits.h" #ifdef HAVE_SELECT #include #include #include fd_set read_fds; struct timeval timeout = { 0, 0 }; #else #ifdef _WIN32 #undef frame #include #include #define frame 0 #endif #endif /* Random number generator stuff */ #define N (624) #define M (397) #define K (0x9908B0DFU) #define hiBit(u) ((u) & 0x80000000U) #define loBit(u) ((u) & 0x00000001U) #define loBits(u) ((u) & 0x7FFFFFFFU) #define mixBits(u, v) (hiBit(u)|loBits(v)) static unsigned long state[N+1]; static unsigned long *next; int left = -1; long int allocate_time (void) { /* calculate the ammount of time the program can use in its search, measured in centi-seconds (calculate everything in float for more accuracy as we go, and return the result as a long int) */ float allocated_time = 0.0, move_speed = 20.0; /* sudden death time allocation: */ if (!moves_to_tc) { /* calculate move speed. The idea is that if we are behind, we move faster, and if we have < 1 min left and a small increment, we REALLY need to start moving fast. Also, if we aren't in a super fast game, don't worry about being behind on the clock at the beginning, because some players will make instant moves in the opening, and Sjeng will play poorly if it tries to do the same. */ /* check to see if we're behind on time and need to speed up: */ if ((min_per_game < 6 && !inc) || time_left < (((min_per_game*6000) + (sec_per_game*100))*4.0/5.0)) { if ((opp_time-time_left) > (opp_time/5.0) && xb_mode) move_speed = 40.0; else if ((opp_time-time_left) > (opp_time/10.0) && xb_mode) move_speed = 30.0; else if ((opp_time-time_left) > (opp_time/20.0) && xb_mode) move_speed = 25.0; } if ((Variant != Suicide) && (Variant != Losers)) { if ((time_left-opp_time) > (time_left/5.0) && xb_mode) move_speed -= 10; else if ((time_left-opp_time) > (time_left/10.0) && xb_mode) move_speed -= 5; } else if (Variant == Suicide) { move_speed -= 10; } else if (Variant == Losers) { move_speed -= 5; } /* allocate our base time: */ allocated_time = time_left/move_speed; /* add our increment if applicable: */ if (inc) { if (time_left-allocated_time-inc > 500) { allocated_time += inc; } else if (time_left-allocated_time-(inc*2.0/3.0) > 100) { allocated_time += inc*2.0/3.0; } } } /* conventional clock time allocation: */ else { allocated_time = (((float)min_per_game * 6000. + (float)sec_per_game * 100.)/(float)moves_to_tc) - 100.; /* if we've got extra time, use some of it: */ if (time_cushion) { allocated_time += time_cushion*2.1/3.0; time_cushion -= time_cushion*2.1/3.0; } } if (Variant == Bughouse) { allocated_time *= 1./4.; if ((opp_time > time_left) || (opp_time < 1500)) { /* behind on time or blitzing out */ allocated_time *= 1./2.; } } return ((long int) allocated_time); } void comp_to_san (move_s move, char str[]) { move_s moves[MOVE_BUFF]; move_s evade_moves[MOVE_BUFF]; char type_to_char[] = { 'F', 'P', 'P', 'N', 'N', 'K', 'K', 'R', 'R', 'Q', 'Q', 'B', 'B', 'E' }; int i, num_moves, evasions, ambig, mate; int f_rank, t_rank, converter; char f_file, t_file; int ic; //eps = ep_square; f_rank = rank (move.from); t_rank = rank (move.target); converter = (int) 'a'; f_file = file (move.from)+converter-1; t_file = file (move.target)+converter-1; if (move.from == 0) { sprintf (str, "%c@%c%d", type_to_char[move.promoted], t_file, t_rank); } else if ((board[move.from] == wpawn) || (board[move.from] == bpawn)) { if (board[move.target] == npiece && !move.ep) { if(!move.promoted) { sprintf (str, "%c%d", t_file, t_rank); } else { sprintf (str, "%c%d=%c", t_file, t_rank, type_to_char[move.promoted]); } } else { if (!move.promoted) { sprintf (str, "%cx%c%d", f_file, t_file, t_rank); } else { sprintf (str, "%cx%c%d=%c", f_file, t_file, t_rank, type_to_char[move.promoted]); } } } else if (move.castled != no_castle) { if (move.castled == wck || move.castled == bck) { sprintf (str, "O-O"); } else { sprintf(str, "O-O-O"); } } else { ambig = -1; num_moves = 0; gen(&moves[0]); num_moves = numb_moves; ic = in_check(); /* check whether there is another, identical piece that could also move to this square */ for(i = 0; i < num_moves; i++) { if ((moves[i].target == move.target) && (board[moves[i].from] == board[move.from]) && (moves[i].from != move.from)) { /* would it be a legal move ? */ make(&moves[0], i); if (check_legal(&moves[0], i, ic)) { unmake(&moves[0], i); ambig = i; break; } unmake(&moves[0], i); } } if (ambig != -1) { if (board[move.target] == npiece) { if (file(moves[ambig].from) != file(move.from)) sprintf(str, "%c%c%c%d", type_to_char[board[move.from]], f_file, t_file, t_rank); else sprintf(str, "%c%d%c%d", type_to_char[board[move.from]], f_rank, t_file, t_rank); } else { if (file(moves[ambig].from) != file(move.from)) sprintf(str, "%c%cx%c%d", type_to_char[board[move.from]], f_file, t_file, t_rank); else sprintf(str, "%c%dx%c%d", type_to_char[board[move.from]], f_rank, t_file, t_rank); } } else { if (board[move.target] == npiece) { sprintf(str, "%c%c%d", type_to_char[board[move.from]], t_file, t_rank); } else { sprintf(str, "%cx%c%d", type_to_char[board[move.from]], t_file, t_rank); } } } //ep_square = eps; make(&move, 0); if (!check_legal(&move, 0, 1)) { strcpy(str, "illg"); unmake(&move, 0); return; } if (in_check()) { mate = TRUE; evasions = 0; gen(&evade_moves[0]); evasions = numb_moves; for (i = 0; i < evasions; i++) { make(&evade_moves[0], i); if (check_legal(&evade_moves[0], i, TRUE)) { mate = FALSE; unmake(&evade_moves[0], i); break; } unmake(&evade_moves[0], i); } if (mate == TRUE) strcat(str, "#"); else strcat(str, "+"); } unmake(&move, 0); } void comp_to_coord (move_s move, char str[]) { /* convert a move_s internal format move to coordinate notation: */ int prom, from, target, f_rank, t_rank, converter; char f_file, t_file; char type_to_char[] = { 'F', 'P', 'p', 'N', 'n', 'K', 'k', 'R', 'r', 'Q', 'q', 'B', 'b', 'E' }; prom = move.promoted; from = move.from; target = move.target; f_rank = rank (from); t_rank = rank (target); converter = (int) 'a'; f_file = file (from)+converter-1; t_file = file (target)+converter-1; if (from == 0) { sprintf (str, "%c@%c%d", type_to_char[prom], t_file, t_rank); } else { /* "normal" move: */ if (!prom) { sprintf (str, "%c%d%c%d", f_file, f_rank, t_file, t_rank); } /* promotion move: */ else { if (prom == wknight || prom == bknight) { sprintf (str, "%c%d%c%dn", f_file, f_rank, t_file, t_rank); } else if (prom == wrook || prom == brook) { sprintf (str, "%c%d%c%dr", f_file, f_rank, t_file, t_rank); } else if (prom == wbishop || prom == bbishop) { sprintf (str, "%c%d%c%db", f_file, f_rank, t_file, t_rank); } else if (prom == wking || prom == bking) { sprintf (str, "%c%d%c%dk", f_file, f_rank, t_file, t_rank); } else { sprintf (str, "%c%d%c%dq", f_file, f_rank, t_file, t_rank); } } } } void display_board (FILE *stream, int color) { /* prints a text-based representation of the board: */ char *line_sep = "+----+----+----+----+----+----+----+----+"; char *piece_rep[14] = {"!!", " P", "*P", " N", "*N", " K", "*K", " R", "*R", " Q", "*Q", " B", "*B", " "}; int a,b,c; if (color % 2) { fprintf (stream, " %s\n", line_sep); for (a = 1; a <= 8; a++) { fprintf (stream, "%d |", 9 - a); for (b = 0; b <= 11; b++) { c = 120 - a*12 + b; if (board[c] != 0) fprintf (stream, " %s |", piece_rep[board[c]]); } fprintf (stream, "\n %s\n", line_sep); } fprintf (stream, "\n a b c d e f g h\n\n"); } else { fprintf (stream, " %s\n", line_sep); for (a = 1; a <= 8; a++) { fprintf (stream, "%d |", a); for (b = 0; b <= 11; b++) { c = 24 + a*12 -b; if (board[c] != 0) fprintf (stream, " %s |", piece_rep[board[c]]); } fprintf (stream, "\n %s\n", line_sep); } fprintf (stream, "\n h g f e d c b a\n\n"); } } void init_game (void) { /* set up a new game: */ int init_board[144] = { 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,7,3,11,9,5,11,3,7,0,0, 0,0,1,1,1,1,1,1,1,1,0,0, 0,0,13,13,13,13,13,13,13,13,0,0, 0,0,13,13,13,13,13,13,13,13,0,0, 0,0,13,13,13,13,13,13,13,13,0,0, 0,0,13,13,13,13,13,13,13,13,0,0, 0,0,2,2,2,2,2,2,2,2,0,0, 0,0,8,4,12,10,6,12,4,8,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0 }; memcpy (board, init_board, sizeof (init_board)); memset (moved, 0, sizeof(moved)); white_to_move = 1; ep_square = 0; wking_loc = 30; bking_loc = 114; white_castled = no_castle; black_castled = no_castle; result = no_result; captures = FALSE; piece_count = 32; Material = 0; memset(is_promoted, 0, sizeof(is_promoted)); memset(holding, 0, sizeof(holding)); white_hand_eval = 0; black_hand_eval = 0; reset_piece_square (); bookidx = 0; book_ply = 0; fifty = 0; ply = 0; phase = Opening; } bool is_move (char str[]) { /* check to see if the input string is a move or not. Returns true if it is in a move format supported by Sjeng. */ if (isalpha (str[0]) && isdigit (str[1]) && isalpha (str[2]) && isdigit (str[3])) { return TRUE; } else if (isalpha(str[0]) && str[1] == '@' && isalpha(str[2]) && isdigit(str[3])) { return TRUE; } else { return FALSE; } } void perft_debug (void) { /* A function to debug the move gen by doing perft's, showing the board, and accepting move input */ char input[STR_BUFF], *p; move_s move; int depth; init_game (); /* go into a loop of doing a perft(), then making the moves the user inputs until the user enters "exit" or "quit" */ while (TRUE) { /* get the desired depth to generate to: */ printf ("\n\nPlease enter the desired depth for perft():\n"); rinput (input, STR_BUFF, stdin); depth = atoi (input); /* print out the number of raw nodes for this depth: */ raw_nodes = 0; perft (depth); printf ("\n\nRaw nodes for depth %d: %ld\n\n", depth, raw_nodes); /* print out the board: */ display_board (stdout, 1); printf ("\nPlease input a move/command:\n"); rinput (input, STR_BUFF, stdin); /* check to see if we have an exit/quit: */ for (p = input; *p; p++) *p = tolower (*p); if (!strcmp (input, "exit") || !strcmp (input, "quit")) { exit (EXIT_SUCCESS); } if (!verify_coord (input, &move)) { /* loop until we get a legal move or an exit/quit: */ do { printf ("\nIllegal move/command! Please input a new move/command:\n"); rinput (input, STR_BUFF, stdin); /* check to see if we have an exit/quit: */ for (p = input; *p; p++) *p = tolower (*p); if (!strcmp (input, "exit") || !strcmp (input, "quit")) { exit (EXIT_SUCCESS); } } while (!verify_coord (input, &move)); } make (&move, 0); } } void hash_extract_pv(int level, char str[]) { int dummy, bm; move_s moves[MOVE_BUFF]; int num_moves; char output[STR_BUFF]; /* avoid loop on repetitions */ level--; if (!level) return; if(ProbeTT(&dummy, 0, 0, &bm, &dummy, &dummy, 0) != HMISS) { gen(&moves[0]); num_moves = numb_moves; if ((bm >= 0) && (bm < num_moves)) { comp_to_san(moves[bm], output); make(&moves[0], bm); if (check_legal(&moves[0], bm, 1)) { /* only print move AFTER legal check is done */ strcat(str, "<"); strcat(str, output); strcat(str, "> "); hash_extract_pv(level, str); } unmake(&moves[0], bm); } } } void stringize_pv (char str[]) { char output[STR_BUFF]; int i; memset(str, 0, STR_BUFF); for (i = 1; i < pv_length[1]; i++) { comp_to_san (pv[1][i], output); make(&pv[1][i], 0); strcat (str, output); strcat (str, " "); } hash_extract_pv(7, str); for (i = (pv_length[1]-1); i > 0; i--) { unmake(&pv[1][i], 0); } } void post_thinking (long int score) { /* post our thinking output: */ int i, remake = 0; long int elapsed; char output[STR_BUFF]; char hashpv[STR_BUFF]; /* in xboard mode, follow xboard conventions for thinking output, otherwise output the iterative depth, human readable score, and the pv */ /* if (xb_mode) {*/ elapsed = rdifftime (rtime (), start_time); printf ("%2d %7ld %5ld %8ld ", i_depth, score, elapsed, nodes); /* if root move is already/still played, back it up */ /* 25-06-2000 our en passant info is unrecoverable here so we cannot gen.... */ if (((pv[1][1].from != 0) && (board[pv[1][1].from] == npiece)) || ((pv[1][1].from == 0) && (board[pv[1][1].target] != npiece))) { unmake(&pv[1][1], 0); remake = 1; } for (i = 1; i < pv_length[1]; i++) { comp_to_san (pv[1][i], output); make(&pv[1][i], 0); printf ("%s ", output); } memset(hashpv, 0, sizeof(hashpv)); hash_extract_pv(7, hashpv); printf("%s", hashpv); for (i = (pv_length[1]-1); i > 0; i--) { unmake(&pv[1][i], 0); } if (remake) make(&pv[1][1], 0); printf ("\n"); } void post_fail_thinking(long int score, move_s *failmove) { /* post our thinking output: */ long int elapsed; char output[STR_BUFF]; /* in xboard mode, follow xboard conventions for thinking output, otherwise output the iterative depth, human readable score, and the pv */ elapsed = rdifftime (rtime (), start_time); printf ("%2d %7ld %5ld %8ld ", i_depth, score, elapsed, nodes); unmake(failmove, 0); comp_to_san (*failmove, output); make(failmove, 0); printf ("%s !", output); printf ("\n"); } void post_fh_thinking(long int score, move_s *failmove) { /* post our thinking output: */ long int elapsed; char output[STR_BUFF]; /* in xboard mode, follow xboard conventions for thinking output, otherwise output the iterative depth, human readable score, and the pv */ elapsed = rdifftime (rtime (), start_time); printf ("%2d %7ld %5ld %8ld ", i_depth, score, elapsed, nodes); unmake(failmove, 0); comp_to_san (*failmove, output); make(failmove, 0); printf ("%s !!", output); printf ("\n"); } void post_fl_thinking(long int score, move_s *failmove) { /* post our thinking output: */ long int elapsed; char output[STR_BUFF]; /* in xboard mode, follow xboard conventions for thinking output, otherwise output the iterative depth, human readable score, and the pv */ elapsed = rdifftime (rtime (), start_time); printf ("%2d %7ld %5ld %8ld ", i_depth, score, elapsed, nodes); unmake(failmove, 0); comp_to_san (*failmove, output); make(failmove, 0); printf ("%s ??", output); printf ("\n"); } void post_stat_thinking(void) { /* post our thinking output: */ long int elapsed; elapsed = rdifftime (rtime (), start_time); if (xb_mode == 1) { printf ("stat01: %ld %ld %d %d %d\n", elapsed, nodes, i_depth, moveleft, movetotal); } else if (xb_mode == 2) { printf ("stat01: %ld %ld %d %d %d %s\n", elapsed, nodes, i_depth, moveleft, movetotal, searching_move); } } void print_move (move_s moves[], int m, FILE *stream) { /* print out a move */ char move[STR_BUFF]; comp_to_san (moves[m], move); fprintf (stream, "%s", move); } void rdelay (int time_in_s) { /* My delay function to cause a delay of time_in_s seconds */ rtime_t time1, time2; long int timer = 0; time1 = rtime (); while (timer/100 < time_in_s) { time2 = rtime (); timer = rdifftime (time2, time1); } } long int rdifftime (rtime_t end, rtime_t start) { /* determine the time taken between start and the current time in centi-seconds */ /* using ftime(): */ #if defined(HAVE_SYS_TIMEB_H) && (defined(HAVE_FTIME) || defined(HAVE_GETTIMEOFDAY)) return ((end.time-start.time)*100 + (end.millitm-start.millitm)/10); /* -------------------------------------------------- */ /* using time(): */ #else return (100*(long int) difftime (end, start)); #endif } void check_piece_square (void) { int i; for (i = 1; i <= piece_count; i++) { if (squares[pieces[i]] != i && pieces[i] != 0) { printf("Piece->square->piece inconsistency\n"); display_board(stdout, 0); DIE; } if (board[pieces[i]] == npiece && pieces[i] != 0) { printf("Board/Piece->square inconsistency\n"); display_board(stdout, 0); DIE; } if (pieces[i] == 0 && squares[pieces[i]] != 0) { printf("Zero-ed piece inconsistency\n"); display_board(stdout, 0); DIE; } } for (i = 0; i < 144; i++) { if ((board[i] == npiece || board[i] == frame) && squares[i] != 0) { printf("Empty square has piece pointer\n"); display_board(stdout, 0); DIE; } if (board[i] != npiece && board[i] != frame && squares[i] == 0) { printf("Filled square %d has no piece pointer\n", i); display_board(stdout, 0); DIE; } if (pieces[squares[i]] != i && squares[i] != 0) { printf("Square->piece->square inconsistency\n"); display_board(stdout, 0); DIE; } } } void reset_piece_square (void) { /* we use piece number 0 to show a piece taken off the board, so don't use that piece number for other things: */ /* reset the piece / square tables: */ int i, promoted_board[144]; memset(promoted_board, 0, sizeof(promoted_board)); /* save our promoted info as we cant determine it from the board */ for (i = 1; i <= piece_count; i++) if(is_promoted[i]) promoted_board[pieces[i]] = 1; Material = 0; piece_count = 0; memset(pieces, 0, sizeof(pieces)); memset(is_promoted, 0, sizeof(is_promoted)); pieces[0] = 0; for (i = 26; i < 118; i++) if (board[i] && (board[i] < npiece)) { AddMaterial(board[i]); piece_count += 1; pieces[piece_count] = i; squares[i] = piece_count; /* restored promoted info */ if (promoted_board[i]) is_promoted[piece_count] = 1; } else squares[i] = 0; } void rinput (char str[], int n, FILE *stream) { /* My input function - reads in up to n-1 characters from stream, or until we encounter a \n or an EOF. Appends a null character at the end of the string, and stores the string in str[] */ int ch, i = 0; while ((ch = getc (stream)) != (int) '\n' && ch != EOF) { if (i < n-1) { str[i++] = ch; } } str [i] = '\0'; } rtime_t rtime (void) { /* using ftime(): */ #if defined(HAVE_FTIME) && defined(HAVE_SYS_TIMEB_H) rtime_t temp; ftime(&temp); return (temp); /* -------------------------------------------------- */ /* gettimeofday replacement by Daniel Clausen */ #else #if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIMEB_H) rtime_t temp; struct timeval tmp; gettimeofday(&tmp, NULL); temp.time = tmp.tv_sec; temp.millitm = tmp.tv_usec / 1000; temp.timezone = 0; temp.dstflag = 0; return (temp); #else return (time (0)); #endif #endif } void start_up (void) { /* things to do on start up of the program */ printf("\nSjeng version " VERSION ", Copyright (C) 2000-2001 Gian-Carlo Pascutto\n\n" "Sjeng comes with ABSOLUTELY NO WARRANTY; for details type 'warranty'\n" "This is free software, and you are welcome to redistribute it\n" "under certain conditions; type 'distribution'\n\n"); } void toggle_bool (bool *var) { /* toggle FALSE -> TRUE, TRUE -> FALSE */ if (*var) { *var = FALSE; } else { *var = TRUE; } } void tree_debug (void) { /* A function to make a tree of output at a certain depth and print out the number of nodes: */ char input[STR_BUFF]; FILE *stream; int depth; init_game (); /* get the desired depth to generate to: */ printf ("\nPlease enter the desired depth:\n"); rinput (input, STR_BUFF, stdin); depth = atoi (input); /* does the user want to output tree () ? */ printf ("\nDo you want tree () output? (y/n)\n"); rinput (input, STR_BUFF, stdin); if (input[0] == 'y') { /* get our output file: */ printf ("\nPlease enter the name of the output file for tree ():\n"); rinput (input, STR_BUFF, stdin); if ((stream = fopen (input, "w")) == NULL) { fprintf (stderr, "Couldn't open file %s\n", input); } /* does the user want to output diagrams? */ printf ("\nDo you want to output diagrams? (y/n)\n"); rinput (input, STR_BUFF, stdin); tree (depth, 0, stream, input); } /* print out the number of raw nodes for this depth: */ raw_nodes = 0; perft (depth); printf ("\n\n%s\nRaw nodes for depth %d: %ld\n%s\n\n", divider, depth, raw_nodes, divider); } bool verify_coord (char input[], move_s *move) { /* checks to see if the move the user entered was legal or not, returns true if the move was legal, and stores the legal move inside move */ move_s moves[MOVE_BUFF]; int num_moves, i; char comp_move[6]; bool legal = FALSE; bool mate; if (Variant == Losers) { captures = TRUE; num_moves = 0; gen (&moves[0]); num_moves = numb_moves; captures = FALSE; mate = TRUE; for (i = 0; i < num_moves; i++) { make (&moves[0], i); /* check to see if our move is legal: */ if (check_legal (&moves[0], i, TRUE)) { mate = FALSE; unmake(&moves[0], i); break; }; unmake(&moves[0], i); } if (mate == TRUE) { /* no legal capture..do non-captures */ captures = FALSE; num_moves = 0; gen (&moves[0]); num_moves = numb_moves; } } else { gen (&moves[0]); num_moves = numb_moves; } /* compare user input to the generated moves: */ for (i = 0; i < num_moves; i++) { comp_to_coord (moves[i], comp_move); if (!strcasecmp (input, comp_move)) { make (&moves[0], i); if (check_legal (&moves[0], i, TRUE)) { legal = TRUE; *move = moves[i]; } unmake (&moves[0], i); } } return (legal); } int interrupt(void) { int c; #ifdef HAVE_SELECT FD_ZERO(&read_fds); FD_SET(0,&read_fds); timeout.tv_sec = timeout.tv_usec = 0; select(1,&read_fds,NULL,NULL,&timeout); if(FD_ISSET(0,&read_fds)) { c = getc(stdin); if (c == '?') /*Move now*/ { return 1; } else if (c == '.') /* Stat request */ { getc(stdin); post_stat_thinking(); return 0; } ungetc(c, stdin); if (!is_pondering && (Variant == Bughouse || Variant == Crazyhouse)) return 0; return 1; } else return 0; #else #ifdef _WIN32 static int init = 0, pipe; static HANDLE inh; DWORD dw; if(xb_mode) { /* winboard interrupt code taken from crafty */ if (!init) { init = 1; inh = GetStdHandle(STD_INPUT_HANDLE); pipe = !GetConsoleMode(inh, &dw); if (!pipe) { SetConsoleMode(inh, dw & ~(ENABLE_MOUSE_INPUT|ENABLE_WINDOW_INPUT)); FlushConsoleInputBuffer(inh); } } if(pipe) { if(!PeekNamedPipe(inh, NULL, 0, NULL, &dw, NULL)) { c = getc(stdin); if (c == '?') /*Move now*/ { return 1; } else if (c == '.') /* Stat request */ { getc(stdin); post_stat_thinking(); return 0; } ungetc(c, stdin); if (!is_pondering && (Variant == Bughouse || Variant == Crazyhouse)) return 0; return 1; } if (dw) { c = getc(stdin); if (c == '?') /*Move now*/ { return 1; } else if (c == '.') /* Stat request */ { getc(stdin); post_stat_thinking(); return 0; } ungetc(c, stdin); if (!is_pondering && (Variant == Bughouse || Variant == Crazyhouse)) return 0; return 1; } else return 0; } else { GetNumberOfConsoleInputEvents(inh, &dw); if (dw <= 1) { return 0; } else { c = getc(stdin); if (c == '?') /*Move now*/ { return 1; } else if (c == '.') /* Stat request */ { getc(stdin); post_stat_thinking(); return 0; } ungetc(c, stdin); if (!is_pondering && (Variant == Bughouse || Variant == Crazyhouse)) return 0; return 1; }; } } #else #endif #endif return 0; } void PutPiece(int color, char piece, char pfile, int prank) { int converterf = (int) 'a'; int converterr = (int) '1'; int norm_file, norm_rank, norm_square; norm_file = pfile - converterf; norm_rank = prank - converterr; norm_square = ((norm_rank * 12) + 26) + (norm_file); if (color == WHITE) { switch (piece) { case 'p': board[norm_square] = wpawn; break; case 'n': board[norm_square] = wknight; break; case 'b': board[norm_square] = wbishop; break; case 'r': board[norm_square] = wrook; break; case 'q': board[norm_square] = wqueen; break; case 'k': board[norm_square] = wking; break; case 'x': board[norm_square] = npiece; break; } } else if (color == BLACK) { switch (piece) { case 'p': board[norm_square] = bpawn; break; case 'n': board[norm_square] = bknight; break; case 'b': board[norm_square] = bbishop; break; case 'r': board[norm_square] = brook; break; case 'q': board[norm_square] = bqueen; break; case 'k': board[norm_square] = bking; break; case 'x': board[norm_square] = npiece; break; } } return; } void reset_board (void) { /* set up an empty game: */ int i; int init_board[144] = { 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,13,13,13,13,13,13,13,13,0,0, 0,0,13,13,13,13,13,13,13,13,0,0, 0,0,13,13,13,13,13,13,13,13,0,0, 0,0,13,13,13,13,13,13,13,13,0,0, 0,0,13,13,13,13,13,13,13,13,0,0, 0,0,13,13,13,13,13,13,13,13,0,0, 0,0,13,13,13,13,13,13,13,13,0,0, 0,0,13,13,13,13,13,13,13,13,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0 }; memcpy (board, init_board, sizeof (init_board)); for (i = 0; i <= 143; i++) moved[i] = 0; ep_square = 0; piece_count = 0; Material = 0; memset(is_promoted, 0, sizeof(is_promoted)); memset(holding, 0, sizeof(holding)); white_hand_eval = 0; black_hand_eval = 0; bookidx = 0; fifty = 0; reset_piece_square (); } void speed_test(void) { move_s moves[MOVE_BUFF]; int i, j; clock_t cpu_start, cpu_end; float et; int ic; /* LCT2 Pos 1 */ setup_epd_line("r3kb1r/3n1pp1/p6p/2pPp2q/Pp2N3/3B2PP/1PQ2P2/R3K2R w KQkq"); cpu_start = clock (); for (i = 0; i < 5000000; i++) { gen (&moves[0]); } cpu_end = clock (); et = (cpu_end-cpu_start)/(double) CLOCKS_PER_SEC; printf("Movegen speed: %d/s\n", (int)(5000000.0/et)); j = 0; cpu_start = clock (); for (i = 0; i < 50000000; i++) { make (&moves[0], j); unmake (&moves[0], j); if ((j+1) < numb_moves) j++; else j = 0; } cpu_end = clock (); et = (cpu_end-cpu_start)/(double) CLOCKS_PER_SEC; printf("Make+unmake speed: %d/s\n", (int)(50000000.0/et)); j = 0; ic = in_check(); cpu_start = clock (); for (i = 0; i < 50000000; i++) { make (&moves[0], j); check_legal(&moves[0], j, ic); unmake (&moves[0], j); if ((j+1) < numb_moves) j++; else j = 0; } cpu_end = clock (); et = (cpu_end-cpu_start)/(double) CLOCKS_PER_SEC; printf("Movecycle speed: %d/s\n", (int)(50000000.0/et)); reset_ecache(); cpu_start = clock (); for (i = 0; i < 10000000; i++) { eval(); /* invalidate the ecache */ hash = (++hash) % ULONG_MAX; } cpu_end = clock (); et = (cpu_end-cpu_start)/(double) CLOCKS_PER_SEC; printf("Eval speed: %d/s\n", (int)(10000000.0/et)); /* restore the hash */ initialize_hash(); } /* Mersenne Twister */ void seedMT(unsigned long seed) { register unsigned long x = (seed | 1U) & 0xFFFFFFFFU, *s = state; register int j; for(left=0, *s++=x, j=N; --j; *s++ = (x*=69069U) & 0xFFFFFFFFU); } unsigned long reloadMT(void) { register unsigned long *p0=state, *p2=state+2, *pM=state+M, s0, s1; register int j; if(left < -1) seedMT(4357U); left=N-1, next=state+1; for(s0=state[0], s1=state[1], j=N-M+1; --j; s0=s1, s1=*p2++) *p0++ = *pM++ ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U); for(pM=state, j=M; --j; s0=s1, s1=*p2++) *p0++ = *pM++ ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U); s1=state[0], *p0 = *pM ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U); s1 ^= (s1 >> 11); s1 ^= (s1 << 7) & 0x9D2C5680U; s1 ^= (s1 << 15) & 0xEFC60000U; return(s1 ^ (s1 >> 18)); } unsigned long randomMT(void) { unsigned long y; if(--left < 0) return(reloadMT()); y = *next++; y ^= (y >> 11); y ^= (y << 7) & 0x9D2C5680U; y ^= (y << 15) & 0xEFC60000U; return(y ^ (y >> 18)); } sjeng-11.2.orig/ecache.c0100644000175000017500000000415107412717720014107 0ustar lukaslukas/* Sjeng - a chess variants playing program Copyright (C) 2000 Gian-Carlo Pascutto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA File: ecache.c Purpose: handling of the evaluation cache */ #include "sjeng.h" #include "protos.h" #include "extvars.h" typedef struct { unsigned long stored_hash; unsigned long hold_hash; unsigned int score; } ECacheType; /*ECacheType ECache[ECACHESIZE];*/ ECacheType *ECache; unsigned long ECacheProbes; unsigned long ECacheHits; void storeECache(long int score) { int index; index = hash % ECacheSize; ECache[index].stored_hash = hash; ECache[index].hold_hash = hold_hash; ECache[index].score = score; } void checkECache(long int *score, int *in_cache) { int index; ECacheProbes++; index = hash % ECacheSize; if(ECache[index].stored_hash == hash && ECache[index].hold_hash == hold_hash) { ECacheHits++; *in_cache = 1; *score = ECache[index].score; } } void reset_ecache(void) { memset(ECache, 0, sizeof(ECache)); return; } void alloc_ecache(void) { ECache = (ECacheType*)malloc(sizeof(ECacheType)*ECacheSize); if (ECache == NULL) { printf("Out of memory allocating ECache.\n"); exit(EXIT_FAILURE); } printf("Allocated %lu eval cache entries, totalling %lu bytes.\n", ECacheSize, sizeof(ECacheType)*ECacheSize); return; } void free_ecache(void) { free(ECache); return; } sjeng-11.2.orig/newbook.c0100644000175000017500000003503707307525327014355 0ustar lukaslukas/* Sjeng - a chess variants playing program Copyright (C) 2000 Gian-Carlo Pascutto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA File: newbook.c Purpose: general function concerning the binary hashed book */ #include "sjeng.h" #include "protos.h" #include "extvars.h" #include "gdbm.h" #include #include #define BUILDTHRESHOLD 2 #define PLAYTHRESHOLD 3 #ifndef HAVE_LIBGDBM #error You need the GNU DBM library (GDBM). Go to ftp.gnu.org #endif typedef struct { unsigned long hashkey; } hashkey_t; typedef struct { unsigned long played; signed long score; } posinfo_t; typedef struct { int result; /* 0: 1-0 1:1/2 2:0-1 3:? */ } pgn_header_t; unsigned long kksize; unsigned char *keycache; unsigned long bookpos[400], booktomove[400], bookidx; int gamenum; void get_header(FILE *pgnbook, pgn_header_t *pgn_header) { int ch; char buff[STR_BUFF]; int b; int terminate = FALSE; memset(pgn_header, 0, sizeof(pgn_header_t)); while(!terminate) { ch = getc(pgnbook); if (ch == EOF) break; /* beginning of a header field */ if (ch == '[') { b = 0; memset(buff, 0, sizeof(buff)); while(((buff[b++] = getc(pgnbook)) != ']') && (b < STR_BUFF)); buff[--b] = '\0'; /* buff now contains the field, minus the [] */ /* file position is just after ] */ //printf ("Read header: -%s-\n", buff); if (!strncmp("Result", buff, 6)) { if (strstr(buff+6, "1-0")) pgn_header->result = 0; else if (strstr(buff+6, "1/2-1/2")) pgn_header->result = 1; else if (strstr(buff+6, "0-1")) pgn_header->result = 2; else if (strstr(buff+6, "*")) pgn_header->result = 3; } } /* space or newlines between headers */ else if (ch == ' ' || ch == '\n' || ch == '\r'); else /* no more headers, put back last char */ { //printf("End of header: -%c-\n", ch); terminate = TRUE; ungetc(ch, pgnbook); } } } void add_current(GDBM_FILE binbook, pgn_header_t pgn_header) { hashkey_t key; posinfo_t posinfo; posinfo_t *pst; datum index; datum data; int win = 0, loss = 0; int ret; /* fill in the key field */ key.hashkey = (hash ^ ToMove); if (keycache[key.hashkey % kksize] >= BUILDTHRESHOLD) { index.dptr = (char*) &key; index.dsize = sizeof(key); posinfo.played = 2; posinfo.score = 0; data.dptr = (char*) &posinfo; data.dsize = sizeof(posinfo); ret = gdbm_store(binbook, index, data, GDBM_INSERT); if (ret == 1) { data = gdbm_fetch(binbook, index); pst = (posinfo_t *) data.dptr; pst->played++; gdbm_store(binbook, index, data, GDBM_REPLACE); free(data.dptr); } } else keycache[key.hashkey % kksize]++; } void replay_game(FILE *pgnbook, GDBM_FILE binbook, pgn_header_t pgn_header) { int ch, xch; char movebuff[STR_BUFF], sjmove[STR_BUFF]; int ms; int brackets = 0, braces = 0; int gameend = FALSE; move_s moves[MOVE_BUFF]; int match, num_moves, i; int limit = 0; int ic; /* reset board */ init_game(); initialize_hash(); putchar('.'); while (!gameend) { ch = getc(pgnbook); if (ch == EOF) return; if (ch == ' ' || ch == '\n') { /* just skip and go on */ } else if (ch == '{') { brackets++; /* we want to skip everything till we get brackets * and braces back to 0 */ while (brackets > 0 || braces > 0) { xch = getc(pgnbook); if (xch == '}') brackets--; else if (xch == '{') brackets++; else if (xch == '[') braces++; else if (xch == ']') braces--; else if (xch == EOF) break; } } else if (ch == '[') { braces++; while (brackets > 0 || braces > 0) { xch = getc(pgnbook); if (xch == '}') brackets--; else if (xch == '{') brackets++; else if (xch == '[') braces++; else if (xch == ']') braces--; else if (xch == EOF) break; } } else if (ch == '*') { /* result string: unfinished game */ /* seek next header */ while (((ch = getc(pgnbook)) != '[') && !feof(pgnbook)); ungetc(ch, pgnbook); gameend = TRUE; } else if (isdigit(ch)) { xch = getc(pgnbook); if (xch == EOF) { return; } /* either a move number or a result string */ else if (isdigit(xch)) /* 2 digits...must be move number */ { while(((ch = getc(pgnbook)) != '.') && !feof(pgnbook)); } else if (xch != '.') { /* not a move numer, must be result */ /* seek to next header */ while (((ch = getc(pgnbook)) != '[') && !feof(pgnbook)); ungetc(ch, pgnbook); gameend = TRUE; } } else if (isalpha(ch)) { /* parse one move */ ms = 0; movebuff[ms++] = ch; while(movebuff[ms-1] != ' ' && movebuff[ms-1] != '\n') { movebuff[ms++] = getc(pgnbook); } movebuff[--ms] = '\0'; /* scratch last bogus char */ /* movebuff now contains -hopefully- the move in SAN */ // printf("Read move: -%s- ", &movebuff); /* now, generate all moves from the current pos and try * to get a match */ match = FALSE; num_moves = 0; // 21-3 ply = 0; gen (&moves[0]); num_moves = numb_moves; ic = in_check(); for (i = 0; i < num_moves; i++) { comp_to_san(moves[i], sjmove); if (!strcmp(movebuff, sjmove)) { /* moves matched !*/ make(&moves[0], i); match = TRUE; if (check_legal(&moves[0], i, ic)) { break; } else { printf("Illegal move from PGN!\n"); printf("Game: %d Move: %s\n", gamenum, movebuff); break; } } } limit++; if (match == FALSE || limit > 40) { if (match == FALSE) printf("No move match! -%s-\n", movebuff); /* skip junk game */ while (((ch = getc(pgnbook)) != '[') && !feof(pgnbook)); ungetc(ch, pgnbook); gameend = TRUE; } else { add_current(binbook, pgn_header); } } } } void weed_book(GDBM_FILE binbook) { datum data; datum index; datum nextkey; posinfo_t *ps; int weeds; int positions; do { weeds = 0; positions = 0; index = gdbm_firstkey(binbook); while (index.dptr) { positions++; nextkey = gdbm_nextkey (binbook, index); data = gdbm_fetch(binbook, index); ps = (posinfo_t *) data.dptr; if ((ps->played) < PLAYTHRESHOLD) { gdbm_delete(binbook, index); free(index.dptr); weeds++; } free(data.dptr); index = nextkey; } printf("Weeded %d moves.\n", weeds); } while (weeds > 0); printf("%d unique positions.\n", positions); printf("Reorganizing BinBook.\n"); gdbm_reorganize(binbook); printf("Done.\n"); } void build_book (void) { FILE *pgnbook; GDBM_FILE binbook; pgn_header_t pgn_header; char bookname[FILENAME_MAX], kks[STR_BUFF]; printf("\nName of PGN book: "); rinput(bookname, STR_BUFF, stdin); pgnbook = fopen(bookname, "r"); if (pgnbook == NULL) { printf("PGN book not found!\n"); exit(EXIT_FAILURE); } if (Variant == Normal) binbook = gdbm_open("nbook.bin", 16384, GDBM_NEWDB | GDBM_FAST, 00664, NULL); else if (Variant == Suicide) binbook = gdbm_open("sbook.bin", 16384, GDBM_NEWDB | GDBM_FAST, 00664, NULL); else if (Variant == Losers) binbook = gdbm_open("lbook.bin", 16384, GDBM_NEWDB | GDBM_FAST, 00664, NULL); else binbook = gdbm_open("zbook.bin", 16384, GDBM_NEWDB | GDBM_FAST, 00664, NULL); if (binbook == NULL) { printf("Error opening binbook.\n"); exit(EXIT_FAILURE); } printf("\nSize of KeyCache (bytes): "); rinput(kks, STR_BUFF, stdin); kksize = atol(kks); printf("Freeing hash and eval cache\n"); free_hash(); free_ecache(); printf("Allocating keycache\n"); keycache = (unsigned char *) calloc(kksize, sizeof(unsigned char)); if (keycache == NULL) { printf("Not enough RAM!\n"); exit(EXIT_FAILURE); } printf("Building"); gamenum = 0; while (!feof(pgnbook)) { gamenum++; get_header(pgnbook, &pgn_header); replay_game(pgnbook, binbook, pgn_header); }; free(keycache); printf("\nWeeding book moves.\n"); weed_book(binbook); fclose(pgnbook); gdbm_close(binbook); alloc_hash(); alloc_ecache(); } move_s choose_binary_book_move (void) { GDBM_FILE binbook; hashkey_t key; posinfo_t *ps; datum index; datum data; move_s moves[MOVE_BUFF], bestmove; move_s bookmoves[MOVE_BUFF]; int num_bookmoves; int raw; int num_moves, i; char output[6]; signed long scores[MOVE_BUFF], best_score = 0; srand(time(0)); if (Variant == Normal) binbook = gdbm_open("nbook.bin", 16384, GDBM_READER, 0, NULL); else if (Variant == Suicide) binbook = gdbm_open("sbook.bin", 16384, GDBM_READER, 0, NULL); else if (Variant == Losers) binbook = gdbm_open("lbook.bin", 16384, GDBM_READER, 0, NULL); else binbook = gdbm_open("zbook.bin", 16384, GDBM_READER, 0, NULL); if (binbook == NULL) { printf("No BinBook found.\n"); return dummy; } num_moves = 0; raw = 0; num_bookmoves = 0; gen(&moves[0]); num_moves = numb_moves; for (i = 0; i < num_moves; i++) { make(&moves[0], i); if (check_legal(&moves[0], i, TRUE)) { if (is_draw()) { /* ok this is fishy: we can get a draw-by-rep * while still in book. let the search take over. * this prevents a trick where the player simply * retreats his knights and Sjeng does the same */ book_ply = 50; printf("Anti-book-rep-trick...\n"); unmake(&moves[0], i); gdbm_close(binbook); return dummy; } key.hashkey = (hash ^ ToMove); index.dptr = (char*) &key; index.dsize = sizeof(key); data = gdbm_fetch(binbook, index); if (data.dptr != NULL) { ps = (posinfo_t *) data.dptr; raw++; comp_to_coord(moves[i], output); printf("Move %s: %ld times played, %d learned\n", output, ps->played, ps->score); if ((ps->played + ps->score) >= PLAYTHRESHOLD) { scores[num_bookmoves] = ps->played + ps->score; bookmoves[num_bookmoves] = moves[i]; num_bookmoves++; } free(data.dptr); } } unmake(&moves[0], i); } gdbm_close(binbook); printf("Book moves: raw: %d cut : %d\n", raw, num_bookmoves); if (!num_bookmoves) return dummy; /* find the top frequency: */ for (i = 0; i < num_bookmoves; i++) { if (scores[i] > best_score) { best_score = scores[i]; } } /* add some randomness to each frequency: */ for (i = 0; i < num_bookmoves; i++) { /* weed out very rare lines */ if (scores[i] * 15 > best_score) { scores[i] += (int) ((float)(((float)(rand())/RAND_MAX)) * ((float)best_score*1.35)); } else { scores[i] = 0; } } /* now pick our best move: */ best_score = 0; for (i = 0; i < num_bookmoves; i++) { if (scores[i] > best_score) { best_score = scores[i]; bestmove = bookmoves[i]; } } /* we need to find the hash here so learning will * be correct */ make(&bestmove, 0); bookpos[bookidx] = hash; booktomove[bookidx++] = ToMove; unmake(&bestmove, 0); return bestmove; } void book_learning(int result) { GDBM_FILE binbook; hashkey_t key; posinfo_t *ps; datum index; datum data; float playinc; float factor; int pi; int iters; static const float factortable[] = {1.0, 0.5, 0.25, 0.12, 0.08, 0.05, 0.03}; if (bookidx == 0) return; if (Variant == Normal) binbook = gdbm_open("nbook.bin", 16384, GDBM_WRITER, 0, NULL); else if (Variant == Suicide) binbook = gdbm_open("sbook.bin", 16384, GDBM_WRITER, 0, NULL); else if (Variant == Losers) binbook = gdbm_open("lbook.bin", 16384, GDBM_WRITER, 0, NULL); else if (Variant == Crazyhouse) binbook = gdbm_open("zbook.bin", 16384, GDBM_WRITER, 0, NULL); else if (Variant == Bughouse) return; if (binbook == NULL) { printf("No BinBook found, not learning.\n"); return; } iters = 0; while ((iters < 7) && ((bookidx - iters) > 0)) { iters++; factor = factortable[iters-1]; key.hashkey = (bookpos[bookidx-iters] ^ booktomove[bookidx-iters]); index.dptr = (char*) &key; index.dsize = sizeof(key); data = gdbm_fetch(binbook, index); if (data.dptr != NULL) { ps = (posinfo_t *) data.dptr; playinc = 0; if (result == WIN) { if (my_rating <= opp_rating) playinc = 0.5 * factor; else playinc = 0.25 * factor; } else if (result == LOSS) { if (my_rating >= opp_rating) playinc = -0.5 * factor; else playinc = -0.25 * factor; } else { if (my_rating >= opp_rating) playinc = -0.3 * factor; else playinc = 0.3 * factor; } if (fabs((double)((ps->played + ps->score)) * playinc) < 1.0) { pi = (int)(playinc * 10.0); } else { pi = (int)((float)(ps->played + ps->score)*(float)playinc); } /* don't 'overlearn' */ if (abs((ps->score)+pi) < (ps->played*5)) { printf("Learning opening %lu, played %lu, old score %ld, new score %ld\n", bookpos[bookidx-iters], ps->played, ps->score, (ps->score)+pi); ps->score += pi; gdbm_store(binbook, index, data, GDBM_REPLACE); } free(data.dptr); } else { printf("No hit in hashed book, not learning.\n"); } } gdbm_close(binbook); return; }; sjeng-11.2.orig/INSTALL0100644000175000017500000000465307114425132013563 0ustar lukaslukasBasic Installation ================== These are generic installation instructions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, a file `config.cache' that saves the results of its tests to speed up reconfiguring, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.in' is used to create `configure' by a program called `autoconf'. You only need `configure.in' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. If you're using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes awhile. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package. 4. Type `make install' to install the programs and any data files and documentation. 5. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. sjeng-11.2.orig/protos.h0100644000175000017500000001206507325162241014230 0ustar lukaslukas/* Sjeng - a chess variants playing program Copyright (C) 2000 Gian-Carlo Pascutto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA File: protos.h Purpose: function prototypes */ #ifndef PROTOS_H #define PROTOS_H long int allocate_time (void); bool check_legal (move_s moves[], int m, int incheck); void comp_to_coord (move_s move, char str[]); void display_board (FILE *stream, int color); long int end_eval (void); long int seval(void); long int std_eval (void); long int suicide_eval (void); long int losers_eval (void); long int eval (void); void gen (move_s moves[]); void ics_game_end (void); bool in_check (void); bool f_in_check (move_s moves[], int m); int extended_in_check (void); void init_game (void); bool is_attacked (int square, int color); bool nk_attacked (int square, int color); bool is_move (char str[]); void make (move_s moves[], int i); void order_moves (move_s moves[], long int move_ordering[], long int see_values[], int num_moves, int best); long int mid_eval (void); long int opn_eval (void); long int suicide_mid_eval(void); void check_phase(void); void perft (int depth); void speed_test(void); void perft_debug (void); void post_thinking (long int score); void post_fl_thinking (long int score, move_s *failmove); void post_fh_thinking (long int score, move_s *failmove); void post_fail_thinking(long int score, move_s *failmove); void print_move (move_s moves[], int m, FILE *stream); void push_pawn (int target, bool is_ep); void push_king_castle (int target, int castle_type); void push_pawn_simple (int target); void push_king (int target); void push_knighT (int target); void try_drop (int ptype); void push_slidE (int target); long int qsearch (int alpha, int beta, int depth); void rdelay (int time_in_s); long int rdifftime (rtime_t end, rtime_t start); bool remove_one (int *marker, long int move_ordering[], int num_moves); void reset_piece_square (void); void check_piece_square (void); void rinput (char str[], int n, FILE *stream); rtime_t rtime (void); long int search (int alpha, int beta, int depth, int is_null); move_s search_root (int alpha, int beta, int depth); void start_up (void); move_s think (void); void toggle_bool (bool *var); void tree (int depth, int indent, FILE *output, char *disp_b); void tree_debug (void); void unmake (move_s moves[], int i); bool verify_coord (char input[], move_s *move); bool is_draw(void); void ProcessHoldings(char line[]); void addHolding(int what, int who); void removeHolding(int what, int who); void DropaddHolding(int what, int who); void DropremoveHolding(int what, int who); void printHolding(void); int SwitchColor(int piece); int SwitchPromoted(int piece); int evalHolding(void); void initialize_zobrist(void); void initialize_hash(void); void initialize_eval(void); void checkECache(long int *score, int *in_cache); void storeECache(long int score); int init_book(void); move_s choose_book_move(void); move_s choose_binary_book_move(void); void StoreTT(int score, int alpha, int beta, int best , int threat, int depth); void QStoreTT(int score, int alpha, int beta, int best); int ProbeTT(int *score, int alpha, int beta, int *best, int *threat, int *donull, int depth); int QProbeTT(int *score, int alpha, int beta, int *best); void LearnStoreTT(int score, unsigned nhash, unsigned hhash, int tomove, int best, int depth); void LoadLearn(void); void Learn(int score, int best, int depth); void pinput (int n, FILE *stream); int calc_attackers(int square, int color); int interrupt(void); void PutPiece(int color, char piece, char file, int rank); void reset_board(void); void reset_ecache(void); void HandlePartner(char *input); void HandlePtell(char *input); void BegForPartner(void); void CheckBadFlow(bool reset); void run_epd_testsuite(void); void ResetHandValue(void); void build_book(void); void comp_to_san (move_s move, char str[]); void stringize_pv (char str[]); void clear_tt(void); void clear_dp_tt(void); move_s proofnumbercheck(move_s compmove); void proofnumbersearch(void); void proofnumberscan(void); void alloc_hash(void); void alloc_ecache(void); void free_hash(void); void free_ecache(void); void read_rcfile(void); void book_learning(int result); void seedMT(unsigned long seed); unsigned long randomMT(void); void setup_epd_line(char* inbuff); int see(int color, int square, int from); void init_egtb(void); int probe_egtb(void); void gen_all_tables(void); int egtb(int s); #endif sjeng-11.2.orig/blob2.c0100644000175000017500000000077507301300731013672 0ustar lukaslukas/* Compile this file for a faster Sjeng */ /* e.g. gcc -O9 -lgdbm -o sjeng blob2.c */ #include "rcfile.c" #include "attacks.c" #include "book.c" #include "crazy.c" #include "epd.c" #include "learn.c" #include "newbook.c" #include "partner.c" #include "moves.c" #include "ttable.c" #include "ecache.c" #include "draw.c" #include "see.c" #include "search.c" #include "seval.c" #include "neval.c" #include "eval.c" #include "sjeng.c" #include "utils.c" #include "proof.c" #include "probe.c" #include "leval.c" sjeng-11.2.orig/ChangeLog0100644000175000017500000002351007307525245014307 0ustar lukaslukas2001-06-06 Gian-Carlo Pascutto * Released 10.0 2001-04-05 Gian-Carlo Pascutto * Released 9.0 2001-01-02 Gian-Carlo Pascutto * Released 8.0 * lots of changes, see NEWS (sorry...didnt have time to update changelog) 2000-12-07 Gian-Carlo Pascutto * Released 7.5.1 * newbook.c: BUILDTHRESHOLD, PLAYTHRESHOLD added * sjeng.h: smaller movedate (int->unsig char) * sjeng.c: (main): recognize 'variant giveaway' * seval.c: (suicide_mid_eval): smaller king centralisation bonus * search.c: (order_captures): fix MVV/LVA (qsearch): slightly smaller futility cutoff (search): more cautious check extension trigger (search): no nullmove in endgames (search): R=4 if depth > 12 (search): passed pawn extensions * protos.h: add new functions * proof.c: (suicide_pn_eval): add early exit condition * moves.c: use global from variable (gen): remove 'from' in calls (gen): use push_king_castle (push_king_castle): added (push_king): remove castling condition (add_move): use global from * eval.c: tweaked some piece-square tables rewrote the (disabled) FULLEVAL code 2000-10-24 Gian-Carlo Pascutto * Released 7.4.3 * utils.c: (interrupt): return 0 on fallthrough * epd.c: (run_epd_testsuite): do not report pn-time if no pn-search was run (run_epd_testsuite): use FILENAME_MAX (check_solution): return FALSE on fallthrough * newbook.c: (*): use exit(EXIT_FAILURE) (build_book): use FILENAME_MAX * search.c: (think): short circuit if result var set (think): add time cushion on book move (think): do not exit without returning a var (search): enfore greater or equal to 0 depth before extending * proof.c: (proofnumbersearch): output game result 2000-10-22 Gian-Carlo Pascutto * Released 7.4.2 * blob2.c: fix neval/seval/eval.c * proof.c: (develop_node): handle suicide 'stalemates' * seval.c: lower queen value remove srev_rank to prevent blob2.c conflict * search.c: (order_moves): lower queen value (qsearch): do legality check anyway * utils.c: (comp_to_coord): king promotions in suicide * moves.c: (gen): fixes to promotions in suicide 2000-10-20 Gian-Carlo Pascutto * Released 7.4.1 * proof.c: (proofnumbersearch): only kibitz in xb_mode Use SAFETY margin for node buffer allocation * sjeng.c: (main): ask for time with 'prove' * README: MVV/LVA typo * moves.c: (push_pawn): add king promotions in suicide * Released 7.4 * learn.c: avoid code duplication via pointers * blob2.c: added * proof.c: added 2000-10-19 Gian-Carlo Pascutto * utils.c: (verify_coord): use strncasecmp * ttable.c: use 2-level tables * moves.c: (gen): break on king-capture * search.c: (qsearch): do not check for legality but check for kingcapture instead (ALL) imported suicide support from experimental versions 2000-07-23 Gian-Carlo Pascutto * search.c: (search): do not apply limited razoring if we are in check 2000-07-23 Gian-Carlo Pascutto * moves.c: (gen): optimized pawn-movegeneration (gen): split up movegen in drop and nondrop part (push_slide): optimized with macro (ALL) replaced instances of %2 with &1 (ALL) removed moves[] parameters 2000-07-22 Gian-Carlo Pascutto * Released 7.3 * book.c: (choose_book_move): cleanups * extvars.h: opening_history made larger * epd.c (setup_epd_line): avoid use of 'rank' * moves.c (add_move): added (try_drop): use add_move (push_*): use add_move * search.c: (search): use original alpha when storing into TTable (qsearch): no new best score if move was illegal (search): no new best score if move was illegal (search_root): handle fail-high cases immediately (think): return immediately if we are going to be interrupted on first call * sjeng.h: no more bitfields for movedata (breaks GCC) * utils.c: (post_*_thinking): reverted to comp_to_coord (allocate_time): use more time if we have an increment * newbook.c: (build_book) zh/bug book support (choose_binary_book_move) zh/bug book support * sjeng.c: (main): added 'speed' option * utils.c: (speed_test): added 2000-07-03 Gian-Carlo Pascutto * utils.c (comp_to_san): use new movegen calling format (init_game): reset phase (hash_extract_pv): use new movegen calling format (hash_extract_pv): indicate brokenness and ugly_ep_hack (speed_test): added * ttable.c (initialize_hash): set hold_hash (fixes learning) * sjeng.h: changed some move structure data in bitfields for -maybe- faster access * ttable.c: (clear_tt): added * sjeng.c: (main): call clear_tt on variant-switch (main): 'book' and 'speed' commands added * epd.c: (run_epd_testsuite): call clear_tt * seval.c: changes to piece-square tables (end_eval): keep piece counters (end_eval): bad trade and drawn engame code (end_eval): relocated king position bonusses (end_eval): larger bonusses for passed pawns (check_phase): added (seval): use phase var rather than on-the-fly check (mid_eval): keep piece counters (mid_eval): bad trade code (mid_eval): kingsafety bugfixes (mid_eval): tweaked bonusses (opn_eval): tweaked bonusses * search.c: added ugly_ep_hack (order_moves): ifdef'ed EXTRAKILLERS (perft): updated for new movegen calling format (qsearch): updated for new movegen calling format (search): disable Extended Futility Pruning in endgames (search): updated for new movegen calling format (search): better(?) killer replacement code (search_root): use ugly_ep_hack (search_root): better killer replacement code (search_root): update bestmovenum on fail-high (think): use new book code (think): update and print game phase (think): removed bogus cpu_start update (think): new fail-low handling code (tree): use new movegen calling format * extvars.h: added phase, numb_moves, ugly_ep_hack * partner.c (CheckBadFlow): adapted for new movegen calling format * newbook.c: new file * moves.c: (gen) changed calling sequence to eliminate num_moves indirections (try_drop): removed num_moves parameter (push_king): removed num_moves parameter (push_knight): removed num_moves parameter (push_pawn): removed num_moves parameter (push_slide): removed num_moves parameter * book.c: (choose_book_move): do not fix first move for any variant (choose_book_move): adapted for new movegen calling format 2000-06-01 Gian-Carlo Pascutto * moves.c: (gen): use 'else if' for second case in ep move testing (push_slide): use break instead of set/test (try_drop): piece drop has always npiece captured 2000-05-29 Gian-Carlo Pascutto * ttable.c: (initialize_hash): reset hash before rebuilding 2000-05-28 Gian-Carlo Pascutto * search.c (search_root): time_failure only on no_moves (think): use partial search results * WAC, 486DX33 5sec: 176/300 * search.c (search): removed NDCuts/NDTries counting (search): No nullmoves on the PV. This seems to increase tactical awareness a bit as well as a few PV-backup problems. * extvars.h: removed NDCuts/NDTries display * sjeng.c (main): removed NDCuts/NDTries display * epd.c: (run_epd_testsuite): use rinput rather than scanf (run_epd_testsuite): removed NDCuts/NDTries display use check_solution and print results (check_solution): added 2000-05-26 Gian-Carlo Pascutto * utils.c (post_fail_thinking) print ?? instead of -- removed some obsolete references to Faile (comp_to_san): new function (hash_extract_pv): new function (post_thinking): use comp_to_san and hash_extract_pv (post_fail_thinking): use comp_to_san (post_fh_thinking): use comp_to_san (post_fl_thiking): use comp_to_san 2000-05-20 Gian-Carlo Pascutto * search.c: (search) disable nullmove if fewer than 14 pieces (search): only use check extensions near leaves (search): fixed: double queen and rook futility margins (search): razor first moves, except if PV (search): removed DPVS * search.c: (think) removed: printing of RS (think): count researches and display on whisper (think): only learn if depth is at least 3 * search.c: (qsearch) removed lazy evaluation 2000-04-22 Gian-Carlo Pascutto * Released 7.2 * NEWS: updated * README: added remark about _WIN32 * utils.c: (rdifftime): use precise function if HAVE_GETTIMEOFDAY or HAVE_FTIME * sjeng.h: don't use timeb if !HAVE_GETTIMEOFDAY and !HAVE_FTIME * utils.c: (interrupt): check for _WIN32 if !HAVE_SELECT * added THANKS * utils.c: (rtime): use gettimeofday if ftime is not available * configure.in: added check for gettimeofday AM_INIT_AUTOMAKE: updated version number * eval.c: (initialize_eval): last fix was not sufficent increased dimension of pre_tropism arrays 2000-04-18 Gian-Carlo Pascutto * eval.c: (initialize_eval): fix out-of-bounds error 2000-04-16 Gian-Carlo Pascutto * Released 7.1 * sjeng.c: (main) updated version output * configure.in: updated AC_OUTPUT AM_INIT_AUTOMAKE: updated version number * tests/Makefile.am: file added * books/Makefile.am: file added * Makefile.am: added SUBDIRS 2000-04-12 Gian-Carlo Pascutto * Released 7.0 * Added/renamed files to comply with GNU standards (NEWS,BUGS,...) * Added automake/autoconf/autoheader/etc... support sjeng-11.2.orig/extvars.h0100644000175000017500000001113707412717216014402 0ustar lukaslukas/* Sjeng - a chess variants playing program Copyright (C) 2000 Gian-Carlo Pascutto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA File: extvars.h Purpose: global data definitions */ extern char divider[50]; extern int board[144], moved[144], ep_square, white_to_move, wking_loc, bking_loc, white_castled, black_castled, result, ply, pv_length[PV_BUFF], squares[144], num_pieces, i_depth, comp_color, fifty, piece_count; extern long int nodes, raw_nodes, qnodes, killer_scores[PV_BUFF], killer_scores2[PV_BUFF], killer_scores3[PV_BUFF], moves_to_tc, min_per_game, sec_per_game, inc, time_left, opp_time, time_cushion, time_for_move, cur_score; extern unsigned long history_h[144][144]; extern bool captures, searching_pv, post, time_exit, time_failure; extern int xb_mode, maxdepth; extern move_s pv[PV_BUFF][PV_BUFF], dummy, killer1[PV_BUFF], killer2[PV_BUFF], killer3[PV_BUFF]; extern move_x path_x[PV_BUFF]; extern move_s path[PV_BUFF]; extern rtime_t start_time; extern int holding[2][16]; extern int num_holding[2]; extern int white_hand_eval; extern int black_hand_eval; extern int drop_piece; extern int pieces[62]; extern int is_promoted[62]; extern int num_makemoves; extern int num_unmakemoves; extern int num_playmoves; extern int num_pieceups; extern int num_piecedowns; extern int max_moves; /* piece types range form 0..16 */ extern unsigned long zobrist[17][144]; extern unsigned long hash; extern unsigned long ECacheProbes; extern unsigned long ECacheHits; extern unsigned long TTProbes; extern unsigned long TTHits; extern unsigned long TTStores; extern unsigned long hold_hash; extern char book[4000][161]; extern int num_book_lines; extern int book_ply; extern int use_book; extern char opening_history[STR_BUFF]; extern unsigned long bookpos[400], booktomove[400], bookidx; extern int Material; extern int material[17]; extern int zh_material[17]; extern int std_material[17]; extern int suicide_material[17]; extern int losers_material[17]; extern int NTries, NCuts, TExt; extern char ponder_input[STR_BUFF]; extern bool is_pondering; extern unsigned long FH, FHF, PVS, FULL, PVSF; extern unsigned long ext_check, ext_recap, ext_onerep; extern unsigned long razor_drop, razor_material; extern unsigned long total_moves; extern unsigned long total_movegens; extern const int rank[144], file[144], diagl[144], diagr[144], sqcolor[144]; extern int Variant; extern int Giveaway; extern int forcedwin; extern bool is_analyzing; extern char my_partner[STR_BUFF]; extern bool have_partner; extern bool must_sit; extern int must_go; extern bool go_fast; extern bool piecedead; extern bool partnerdead; extern int tradefreely; extern char true_i_depth; extern long fixed_time; extern int hand_value[]; extern int numb_moves; extern int phase; FILE *lrn_standard; FILE *lrn_zh; FILE *lrn_suicide; FILE *lrn_losers; extern int bestmovenum; extern int ugly_ep_hack; extern int root_to_move; extern int kingcap; extern int pn_time; extern move_s pn_move; extern move_s pn_saver; extern bool kibitzed; extern int rootlosers[PV_BUFF]; extern int alllosers; extern int s_threat; extern int cfg_booklearn; extern int cfg_devscale; extern int cfg_razordrop; extern int cfg_cutdrop; extern int cfg_futprune; extern int cfg_onerep; extern int cfg_recap; extern int cfg_smarteval; extern int cfg_attackeval; extern float cfg_scalefac; extern int cfg_ksafety[15][9]; extern int cfg_tropism[5][7]; extern int havercfile; extern int TTSize; extern int PBSize; extern int ECacheSize; extern int my_rating, opp_rating; extern int userealholdings; extern char realholdings[255]; extern int move_number; extern unsigned long hash_history[600]; extern int moveleft; extern int movetotal; extern char searching_move[20]; extern char setcode[30]; extern int cbEGTBCompBytes; extern int EGTBProbes; extern int EGTBHits; extern int EGTBPieces; extern int EGTBCacheSize; extern char EGTBDir[STR_BUFF]; extern int SEGTB; sjeng-11.2.orig/COPYING0100644000175000017500000004312707307525257013601 0ustar lukaslukas GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. sjeng-11.2.orig/attacks.c0100644000175000017500000003260307307525427014340 0ustar lukaslukas/* Sjeng - a chess variants playing program Copyright (C) 2000 Gian-Carlo Pascutto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA File: attacks.c Purpose: calculate attack information */ #include "sjeng.h" #include "extvars.h" int calc_attackers (int square, int color) { /* this function calculates attack information for a square */ static const int rook_o[4] = {12, -12, 1, -1}; static const int bishop_o[4] = {11, -11, 13, -13}; static const int knight_o[8] = {10, -10, 14, -14, 23, -23, 25, -25}; int a_sq, i; int attackers = 0; if (board[square] == frame) return 0; /* white attacker: */ if (color%2) { /* rook-style moves: */ for (i = 0; i < 4; i++) { a_sq = square + rook_o[i]; /* the king can attack from one square away: */ if (board[a_sq] == wking) { attackers++; break; } else { /* otherwise, check for sliding pieces: */ while (board[a_sq] != frame) { if (board[a_sq] == wrook || board[a_sq] == wqueen) { attackers++; break; } else if (board[a_sq] != npiece) break; a_sq += rook_o [i]; } } } /* bishop-style moves: */ for (i = 0; i < 4; i++) { a_sq = square + bishop_o[i]; /* check for pawn attacks: */ if (board[a_sq] == wpawn && i%2) { attackers++; break; } /* the king can attack from one square away: */ else if (board[a_sq] == wking) { attackers++; break; } else { while (board[a_sq] != frame) { if (board[a_sq] == wbishop || board[a_sq] == wqueen) { attackers++; break; } else if (board[a_sq] != npiece) break; a_sq += bishop_o [i]; } } } /* knight-style moves: */ for (i = 0; i < 8; i++) { a_sq = square + knight_o[i]; if (board[a_sq] == wknight) attackers++; } /* if we haven't hit a white attacker by now, there are none: */ } /* black attacker: */ else { /* rook-style moves: */ for (i = 0; i < 4; i++) { a_sq = square + rook_o[i]; /* the king can attack from one square away: */ if (board[a_sq] == bking) { attackers++; break; } /* otherwise, check for sliding pieces: */ else { while (board[a_sq] != frame) { if (board[a_sq] == brook || board[a_sq] == bqueen) { attackers++; break; }; if (board[a_sq] != npiece) break; a_sq += rook_o [i]; } } } /* bishop-style moves: */ for (i = 0; i < 4; i++) { a_sq = square + bishop_o[i]; /* check for pawn attacks: */ if (board[a_sq] == bpawn && !(i%2)) { attackers++; break; } /* the king can attack from one square away: */ else if (board[a_sq] == bking) { attackers++; break; } else { while (board[a_sq] != frame) { if (board[a_sq] == bbishop || board[a_sq] == bqueen) { attackers++; break; } else if (board[a_sq] != npiece) break; a_sq += bishop_o [i]; } } } /* knight-style moves: */ for (i = 0; i < 8; i++) { a_sq = square + knight_o[i]; if (board[a_sq] == bknight) attackers++; } /* if we haven't hit a black attacker by now, there are none: */ } return attackers; } #if 0 bool is_attacked (int square, int color) { int a, j, dir, i, l; for (a = 1, j = 1; (a <= piece_count); j++) { i = pieces[j]; if (!i) continue; else a++; if ((color&1) != (board[i]&1)) continue; if (color & 1) { switch (board[i]) { case (wpawn): if ((i+13) == square || (i+11) == square) return TRUE; break; case (wknight): if ((i - 25) == square || (i-23) == square || (i-14) == square || (i-10) == square || (i+10) == square || (i+14) == square || (i+23) == square || (i+25) == square) return TRUE; break; case (wbishop): dir = abs(i - square); if ((dir % 13) == 0) { dir = (i - square > 0) ? 13 : -13; for (l = square+dir;(board[l] == npiece) && (l != i);l += dir); if (i == l) return TRUE; } else if ((dir % 11) == 0) { dir = (i - square > 0) ? 11 : -11; for (l = square+dir;(board[l] == npiece) && (l != i);l += dir); if (i == l) return TRUE; } break; case (wrook): if (file(i) == file(square)) { dir = (i - square > 0) ? 12 : -12; for (l = square+dir;(board[l] == npiece) && (l != i); l += dir); if (i == l) return TRUE; } else if (rank(i) == rank(square)) { dir = (i - square > 0) ? 1 : -1; for (l = square+dir;(board[l] == npiece) && (l != i); l += dir); if (i == l) return TRUE; } break; case (wqueen): dir = abs(i - square); if ((dir % 13) == 0) { dir = (i - square > 0) ? 13 : -13; for (l = square+dir;(board[l] == npiece) && (l != i);l += dir); if (i == l) return TRUE; } else if ((dir % 11) == 0) { dir = (i - square > 0) ? 11 : -11; for (l = square+dir;(board[l] == npiece) && (l != i);l += dir); if (i == l) return TRUE; } else if (file(i) == file(square)) { dir = (i - square > 0) ? 12 : -12; for (l = square+dir;(board[l] == npiece) && (l != i); l += dir); if (i == j) return TRUE; } else if (rank(i) == rank(square)) { dir = (i - square > 0) ? 1 : -1; for (l = square+dir;(board[l] == npiece) && (l != i); l += dir); if (i == l) return TRUE; } break; case (wking): if ( (abs(rank(i) - rank(square)) <= 1) && (abs(file(i) - file(square)) <= 1)) return TRUE; break; } } else { switch(board[i]) { case (bpawn): if ((i-13) == square || (i-11) == square) return TRUE; break; case (bknight): if ((i - 25) == square || (i-23) == square || (i-14) == square || (i-10) == square || (i+10) == square || (i+14) == square || (i+23) == square || (i+25) == square) return TRUE; break; case (bbishop): dir = abs(i - square); if ((dir % 13) == 0) { dir = (i - square > 0) ? 13 : -13; for (l = square+dir;(board[l] == npiece) && (l != i);l += dir); if (i == l) return TRUE; } else if ((dir % 11) == 0) { dir = (i - square > 0) ? 11 : -11; for (l = square+dir;(board[l] == npiece) && (l != i);l += dir); if (i == l) return TRUE; } break; case (brook): if (file(i) == file(square)) { dir = (i - square > 0) ? 12 : -12; for (l = square+dir;(board[l] == npiece) && (l != i); l += dir); if (i == l) return TRUE; } else if (rank(i) == rank(square)) { dir = (i - square > 0) ? 1 : -1; for (l = square+dir;(board[l] == npiece) && (l != i); l += dir); if (i == l) return TRUE; } break; case (bqueen): dir = abs(i - square); if ((dir % 13) == 0) { dir = (i - square > 0) ? 13 : -13; for (l = square+dir;(board[l] == npiece) && (l != i);l += dir); if (i == l) return TRUE; } else if ((dir % 11) == 0) { dir = (i - square > 0) ? 11 : -11; for (l = square+dir;(board[l] == npiece) && (l != i);l += dir); if (i == l) return TRUE; } else if (file(i) == file(square)) { dir = (i - square > 0) ? 12 : -12; for (l = square+dir;(board[l] == npiece) && (l != i); l += dir); if (i == l) return TRUE; } else if (rank(i) == rank(square)) { dir = (i - square > 0) ? 1 : -1; for (l = square+dir;(board[l] == npiece) && (l != i); l += dir); if (i == l) return TRUE; } break; case (bking): if ( (abs(rank(i) - rank(square)) <= 1) && (abs(file(i) - file(square)) <= 1)) return TRUE; break; } } } return FALSE; } #endif bool is_attacked (int square, int color) { /* this function will return TRUE if square "square" is attacked by a piece of color "color", and return FALSE otherwise */ static const int rook_o[4] = {12, -12, 1, -1}; static const int bishop_o[4] = {11, -11, 13, -13}; static const int knight_o[8] = {10, -10, 14, -14, 23, -23, 25, -25}; register int ndir, a_sq; register int basq, i; /* white attacker: */ if (color&1) { /* bishop-style moves: */ for (i = 0; i < 4; i++) { ndir = bishop_o[i]; a_sq = square+ndir; basq = board[a_sq]; /* check for pawn attacks: */ if (basq == wpawn && (i&1)) return TRUE; /* the king can attack from one square away: */ if (basq == wking) return TRUE; while (basq != frame) { if (basq == wbishop || basq == wqueen) return TRUE; if (basq != npiece) break; a_sq += ndir; basq = board[a_sq]; } } /* knight-style moves: */ for (i = 0; i < 8; i++) { if (board[square + knight_o[i]] == wknight) return TRUE; } /* rook-style moves: */ for (i = 0; i < 4; i++) { ndir = rook_o[i]; a_sq = square + ndir; basq = board[a_sq]; /* the king can attack from one square away: */ if (basq == wking) return TRUE; /* otherwise, check for sliding pieces: */ while (basq != frame) { if (basq == wrook || basq == wqueen) return TRUE; if (basq != npiece) break; a_sq += ndir; basq = board[a_sq]; } } /* if we haven't hit a white attacker by now, there are none: */ return FALSE; } /* black attacker: */ else { /* bishop-style moves: */ for (i = 0; i < 4; i++) { ndir = bishop_o[i]; a_sq = square + ndir; basq = board[a_sq]; /* check for pawn attacks: */ if (basq == bpawn && !(i&1)) return TRUE; /* the king can attack from one square away: */ if (basq == bking) return TRUE; while (basq != frame) { if (basq == bbishop || basq == bqueen) return TRUE; if (basq != npiece) break; a_sq += ndir; basq = board[a_sq]; } } /* knight-style moves: */ for (i = 0; i < 8; i++) { if (board[square + knight_o[i]] == bknight) return TRUE; } /* rook-style moves: */ for (i = 0; i < 4; i++) { ndir = rook_o[i]; a_sq = square + rook_o[i]; basq = board[a_sq]; /* the king can attack from one square away: */ if (basq == bking) return TRUE; /* otherwise, check for sliding pieces: */ while (basq != frame) { if (basq == brook || basq == bqueen) return TRUE; if (basq != npiece) break; a_sq += ndir; basq = board[a_sq]; } } /* if we haven't hit a black attacker by now, there are none: */ return FALSE; } } bool nk_attacked (int square, int color) { /* this function will return TRUE if square "square" is attacked by a piece of color "color", and return FALSE otherwise */ static const int rook_o[4] = {12, -12, 1, -1}; static const int bishop_o[4] = {11, -11, 13, -13}; static const int knight_o[8] = {10, -10, 14, -14, 23, -23, 25, -25}; register int ndir, a_sq; register int basq, i; /* white attacker: */ if (color&1) { /* bishop-style moves: */ for (i = 0; i < 4; i++) { ndir = bishop_o[i]; a_sq = square+ndir; basq = board[a_sq]; /* check for pawn attacks: */ if (basq == wpawn && (i&1)) return TRUE; /* the king can attack from one square away: */ while (basq != frame) { if (basq == wbishop || basq == wqueen) return TRUE; if (basq != npiece) break; a_sq += ndir; basq = board[a_sq]; } } /* knight-style moves: */ for (i = 0; i < 8; i++) { if (board[square + knight_o[i]] == wknight) return TRUE; } /* rook-style moves: */ for (i = 0; i < 4; i++) { ndir = rook_o[i]; a_sq = square + ndir; basq = board[a_sq]; /* otherwise, check for sliding pieces: */ while (basq != frame) { if (basq == wrook || basq == wqueen) return TRUE; if (basq != npiece) break; a_sq += ndir; basq = board[a_sq]; } } /* if we haven't hit a white attacker by now, there are none: */ return FALSE; } /* black attacker: */ else { /* bishop-style moves: */ for (i = 0; i < 4; i++) { ndir = bishop_o[i]; a_sq = square + ndir; basq = board[a_sq]; /* check for pawn attacks: */ if (basq == bpawn && !(i&1)) return TRUE; /* the king can attack from one square away: */ while (basq != frame) { if (basq == bbishop || basq == bqueen) return TRUE; if (basq != npiece) break; a_sq += ndir; basq = board[a_sq]; } } /* knight-style moves: */ for (i = 0; i < 8; i++) { if (board[square + knight_o[i]] == bknight) return TRUE; } /* rook-style moves: */ for (i = 0; i < 4; i++) { ndir = rook_o[i]; a_sq = square + rook_o[i]; basq = board[a_sq]; /* otherwise, check for sliding pieces: */ while (basq != frame) { if (basq == brook || basq == bqueen) return TRUE; if (basq != npiece) break; a_sq += ndir; basq = board[a_sq]; } } /* if we haven't hit a black attacker by now, there are none: */ return FALSE; } } sjeng-11.2.orig/probe.c0100644000175000017500000001437307347625262014023 0ustar lukaslukas/* Sjeng - a chess variants playing program Copyright (C) 2000-2001 Gian-Carlo Pascutto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA As a special exception, Gian-Carlo Pascutto gives permission to link this program with the Nalimov endgame database access code. See the Copying/Distribution section in the README file for more details. File: probe.c Purpose: access Nalimov endgame databases */ #include "sjeng.h" #include "protos.h" #include "extvars.h" #undef USE_EGTB #define XX 127 #define KINGCAP 50000 typedef unsigned int INDEX; typedef int square; #if defined (_MSC_VER) #define TB_FASTCALL __fastcall #else #define TB_FASTCALL #endif typedef int color; #define x_colorWhite 0 #define x_colorBlack 1 #define x_colorNeutral 2 #define COLOR_DECLARED typedef int piece; #define x_pieceNone 0 #define x_piecePawn 1 #define x_pieceKnight 2 #define x_pieceBishop 3 #define x_pieceRook 4 #define x_pieceQueen 5 #define x_pieceKing 6 #define PIECES_DECLARED typedef signed char tb_t; #define pageL 65536 #define tbbe_ssL ((pageL-4)/2) #define bev_broken (tbbe_ssL+1) /* illegal or busted */ #define bev_mi1 tbbe_ssL /* mate in 1 move */ #define bev_mimin 1 /* mate in max moves */ #define bev_draw 0 /* draw */ #define bev_limax (-1) /* mated in max moves */ #define bev_li0 (-tbbe_ssL) /* mated in 0 moves */ typedef INDEX (TB_FASTCALL * PfnCalcIndex) (square*, square*, square, int fInverse); extern int IDescFindFromCounters (int*); extern int FRegisteredFun (int, color); extern PfnCalcIndex PfnIndCalcFun (int, color); extern int TB_FASTCALL L_TbtProbeTable (int, color, INDEX); extern int IInitializeTb (char*); extern int FTbSetCacheSize(void *pv, unsigned long cbSize); #define PfnIndCalc PfnIndCalcFun #define FRegistered FRegisteredFun int EGTBProbes; int EGTBHits; int EGTBPieces; int EGTBCacheSize; char EGTBDir[STR_BUFF]; void init_egtb(void) { #ifdef USE_EGTB void *buffer; buffer = malloc(EGTBCacheSize); if (buffer == NULL && (EGTBCacheSize != 0)) { printf("Could not allocate EGTB buffer.\n"); exit(EXIT_FAILURE); }; EGTBPieces = IInitializeTb (EGTBDir); printf("%d piece endgame tablebases found\n", EGTBPieces); printf("Allocated %dKb for indices and tables.\n",((cbEGTBCompBytes+1023)/1024)); if(FTbSetCacheSize (buffer, EGTBCacheSize) == FALSE && (EGTBCacheSize != 0)) { printf("Could not enable EGTB buffer.\n"); exit(EXIT_FAILURE); }; return; #else return; #endif } const static int EGTranslate(int sqidx) { int r; r = (((rank(sqidx)-1)*8)+(file(sqidx)-1)); return r; } int probe_egtb(void) { #ifdef USE_EGTB int *psqW, *psqB; int rgiCounters[10] = {0,0,0,0,0,0,0,0,0,0}; int side; int fInvert; int sqEnP; int wi = 1, W[8] = {6,0,0,0,0,0}; int bi = 1, B[8] = {6,0,0,0,0,0}; int tbScore; INDEX ind; int j, a, i; int iTb; EGTBProbes++; W[4] = EGTranslate(wking_loc); B[4] = EGTranslate(bking_loc); for (j = 1, a = 1;(a <= piece_count); j++) { i = pieces[j]; if (!i) continue; else a++; switch(board[i]) { case wpawn: rgiCounters[0]++; W[wi] = 1; W[wi+4] = EGTranslate(i); wi++; break; case wknight: rgiCounters[1]++; W[wi] = 2; W[wi+4] = EGTranslate(i); wi++; break; case wbishop: rgiCounters[2]++; W[wi] = 3; W[wi+4] = EGTranslate(i); wi++; break; case wrook: rgiCounters[3]++; W[wi] = 4; W[wi+4] = EGTranslate(i); wi++; break; case wqueen: rgiCounters[4]++; W[wi] = 5; W[wi+4] = EGTranslate(i); wi++; break; case bpawn: rgiCounters[5]++; B[bi] = 1; B[bi+4] = EGTranslate(i); bi++; break; case bknight: rgiCounters[6]++; B[bi] = 2; B[bi+4] = EGTranslate(i); bi++; break; case bbishop: rgiCounters[7]++; B[bi] = 3; B[bi+4] = EGTranslate(i); bi++; break; case brook: rgiCounters[8]++; B[bi] = 4; B[bi+4] = EGTranslate(i); bi++; break; case bqueen: rgiCounters[9]++; B[bi] = 5; B[bi+4] = EGTranslate(i); bi++; break; } } /* more than 4 pieces for one side: not a class we can index */ if (wi >= 4 || bi >= 4) { return KINGCAP; } iTb = IDescFindFromCounters (rgiCounters); if (0 == iTb) { return KINGCAP; } else if (iTb > 0) { /* white = 0*/ side = !white_to_move; fInvert = 0; psqW = W; psqB = B; } else { side = white_to_move; fInvert = 1; psqW = B; psqB = W; iTb = -iTb; } if (!FRegistered(iTb, side)) return KINGCAP; if (ep_square == 0) { sqEnP = XX; } else { if (white_to_move) { if (board[ep_square - 11] == wpawn || board[ep_square - 13] == wpawn) sqEnP = EGTranslate(ep_square); else sqEnP = XX; } else { if (board[ep_square + 11] == bpawn || board[ep_square + 13] == bpawn) sqEnP = EGTranslate(ep_square); else sqEnP = XX; } } ind = PfnIndCalc(iTb, side) (psqW, psqB, sqEnP, fInvert); tbScore = L_TbtProbeTable( iTb, side, ind); if (tbScore == bev_broken) return KINGCAP; EGTBHits++; if (tbScore > 0) { return ((tbScore-bev_mi1)*2+INF-ply-1); } else if (tbScore < 0) { return ((tbScore+bev_mi1)*2-INF+ply); } return 0; #else return KINGCAP; #endif } sjeng-11.2.orig/proof.c0100644000175000017500000007161407412723037014032 0ustar lukaslukas/* Sjeng - a chess variants playing program Copyright (C) 2000-2001 Gian-Carlo Pascutto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA File: proof.c Purpose: contains functions related to the pn-search */ #include "sjeng.h" #include "extvars.h" #include "protos.h" #include "limits.h" #include "math.h" #define FALSE 0 #define TRUE 1 #define UNKNOWN 2 #define STALEMATE 3 /* special case because pn-search only assumes 1/0 */ #define PN_INF 100000000 /* we can exceed PBSize before exiting the main search loop */ #define SAFETY 10000 /* define this to use the pn^2 search */ #undef PN2 int nodecount; int nodecount2; int pn2; long frees; int iters; int forwards; int maxply; int ply; int pn_time; move_s pn_move; move_s pn_saver; bool kibitzed; int forcedwin; int rootlosers[PV_BUFF]; int alllosers; typedef struct node { unsigned char value; unsigned char num_children; unsigned char expanded; unsigned char evaluated; int proof; int disproof; struct node **children; struct node *parent; move_s move; } node_t; void pn2_eval (node_t *node); void suicide_pn_eval (node_t *this); void std_pn_eval (node_t *this); void losers_pn_eval (node_t *this); unsigned char *membuff; int bufftop = 0; void* Xmalloc(int size) { int oldtop = bufftop; bufftop += size; return (&membuff[oldtop]); }; void Xfree(void) { bufftop = 0; }; void freenodes (node_t * node) { int i; if (!node) return; if (node->children) { if (node->num_children > 0) { for (i = 0; i < (node->num_children); i++) { if (node->children[i] != 0) { freenodes (node->children[i]); }; }; free (node->children); } }; free (node); }; void pn_eval(node_t * this) { if (Variant == Suicide) { suicide_pn_eval(this); } else if (Variant == Losers) { losers_pn_eval(this); } else { std_pn_eval(this); } } void std_pn_eval (node_t * this) { int num_moves; move_s moves[MOVE_BUFF]; int mate; int i; this->evaluated = TRUE; //ep_temp = ep_square; if ((white_to_move && is_attacked (wking_loc, WHITE)) || (!white_to_move && is_attacked (bking_loc, BLACK))) { num_moves = 0; gen (&moves[0]); num_moves = numb_moves; mate = TRUE; for (i = 0; i < num_moves; i++) { make (&moves[0], i); /* check to see if our move is legal: */ if (check_legal (&moves[0], i, TRUE)) { mate = FALSE; unmake (&moves[0], i); break; }; unmake (&moves[0], i); } if (mate == TRUE) { /* proven or disproven */ if (ToMove == root_to_move) { /* root mover is mated-> disproven */ this->value = FALSE; } else { this->value = TRUE; }; } else { this->value = UNKNOWN; }; } else { this->value = UNKNOWN; }; //ep_square = ep_temp; }; void suicide_pn_eval(node_t *this) { int j, a, i; int wp = 0, bp = 0; int egscore; this->evaluated = TRUE; if (piece_count <= 3 && (Variant == Suicide) && SEGTB) { egscore = egtb(white_to_move); if (egscore != -128) { if (egscore > 0) { if (ToMove == root_to_move) { this->value = TRUE; return; } else { this->value = FALSE; return; } } else if (egscore < 0) { if (ToMove == root_to_move) { this->value = FALSE; return; } else { this->value = TRUE; return; } } else { this->value = UNKNOWN; return; } } } for (j = 1, a = 1; (a <= piece_count); j++) { i = pieces[j]; if (!i) continue; else a++; switch (board[i]) { case wpawn: case wbishop: case wrook: case wking: case wqueen: case wknight: wp++; break; case bpawn: case bbishop: case brook: case bking: case bqueen: case bknight: bp++; break; } if (wp && bp) break; } if (!wp) { /* white has no pieces */ /* proven or disproven */ if (!root_to_move) { /* root mover is mated-> proven */ this->value = TRUE; } else { this->value = FALSE; }; } else if (!bp) { /* black has no pieces */ if (!root_to_move) { /* root mover is mated-> disproven */ this->value = FALSE; } else { this->value = TRUE; }; } else { this->value = UNKNOWN; }; }; void losers_pn_eval(node_t *this) { int num_moves; move_s moves[MOVE_BUFF]; int mate; int i; int j, a; int wp = 0, bp = 0; this->evaluated = TRUE; //ep_temp = ep_square; for (j = 1, a = 1; (a <= piece_count); j++) { i = pieces[j]; if (!i) continue; else a++; switch (board[i]) { case wpawn: case wbishop: case wrook: case wqueen: case wknight: wp++; break; case bpawn: case bbishop: case brook: case bqueen: case bknight: bp++; break; } if (wp && bp) break; } if (!wp) { /* proven or disproven */ if (!root_to_move) { /* root mover is mated-> disproven */ this->value = TRUE; } else { this->value = FALSE; }; return; } else if (!bp) { if (root_to_move) { /* root mover is mated-> disproven */ this->value = TRUE; } else { this->value = FALSE; }; return; } if ((white_to_move && is_attacked(wking_loc, WHITE)) || (!white_to_move && is_attacked(bking_loc, BLACK))) { captures = TRUE; num_moves = 0; gen (&moves[0]); num_moves = numb_moves; captures = FALSE; mate = TRUE; for (i = 0; i < num_moves; i++) { make (&moves[0], i); /* check to see if our move is legal: */ if (check_legal (&moves[0], i, TRUE)) { mate = FALSE; unmake(&moves[0], i); break; }; unmake(&moves[0], i); } if (mate == TRUE) { /* no legal capture..do non-captures */ captures = FALSE; num_moves = 0; gen (&moves[0]); num_moves = numb_moves; for (i = 0; i < num_moves; i++) { make (&moves[0], i); /* check to see if our move is legal: */ if (check_legal (&moves[0], i, TRUE)) { mate = FALSE; unmake(&moves[0], i); break; }; unmake(&moves[0], i); } } if (mate == TRUE) { /* proven or disproven */ if (ToMove == root_to_move) { /* root mover is mated-> disproven */ this->value = TRUE; } else { this->value = FALSE; }; } else { this->value = UNKNOWN; }; } else { this->value = UNKNOWN; }; //ep_square = ep_temp; }; node_t *select_most_proving (node_t * node) { int i; node_t *tnode; tnode = node; while (tnode->expanded) { if (ToMove == root_to_move) { i = 0; while (tnode->children[i]->proof != tnode->proof) { i++; }; } else { i = 0; while (tnode->children[i]->disproof != tnode->disproof) { i++; }; }; tnode = tnode->children[i]; hash_history[move_number+ply-1] = hash; make (&tnode->move, 0); if (ply > maxply) maxply = ply; }; return tnode; }; void set_proof_and_disproof_numbers (node_t * node) { int proof; int disproof; int i; move_s moves[MOVE_BUFF]; int l, num_moves; int reploop; int ic; if (node->expanded) { if (ToMove != root_to_move) { proof = 0; disproof = +PN_INF; for (i = 0; i < node->num_children; i++) { proof += node->children[i]->proof; if (proof > PN_INF) proof = PN_INF; if (node->children[i]->disproof < disproof) { disproof = node->children[i]->disproof; } } if ((proof == 0) || (disproof == PN_INF)) { forwards++; StoreTT(+INF-500, +INF, -INF, -1, 0, 200); } else if ((disproof == 0) || (proof == PN_INF)) { forwards++; StoreTT(-INF+500, +INF, -INF, -1, 0, 200); } } else { disproof = 0; proof = +PN_INF; for (i = 0; i < node->num_children; i++) { disproof += node->children[i]->disproof; if (disproof > PN_INF) disproof = PN_INF; if (node->children[i]->proof < proof) { proof = node->children[i]->proof; } } if ((proof == 0) || (disproof == PN_INF)) { forwards++; StoreTT(+INF-500, +INF, -INF, -1, 0, 200); } else if ((disproof == 0) || (proof == PN_INF)) { forwards++; StoreTT(-INF+500, +INF, -INF, -1, 0, 200); } } hash_history[move_number+ply-1] = hash; node->proof = proof; node->disproof = disproof; } else if (node->evaluated) { if (node->value == UNKNOWN) { hash_history[move_number+ply-1] = hash; if (is_draw() || ply > 200) { node->proof = 50000; node->disproof = 50000; return; } //ept = ep_square; if (Variant != Losers) { num_moves = 0; gen (&moves[0]); num_moves = numb_moves; ic = in_check(); if (Variant != Suicide) { l = 0; for (i = 0; i < num_moves; i++) { make (&moves[0], i); /* check to see if our move is legal: */ if (check_legal (&moves[0], i, ic)) { l++; } unmake (&moves[0], i); }; } else { l = numb_moves; }; } else { /* Losers...this a bit more messy */ l = 0; captures = TRUE; num_moves = 0; gen (&moves[0]); num_moves = numb_moves; captures = FALSE; ic = in_check(); if (num_moves) { for (i = 0; i < num_moves; i++) { make(&moves[0], i); if (check_legal(&moves[0], i, ic)) { l++; } unmake(&moves[0], i); } } // //ep_square = ept; if (!l) { captures = FALSE; num_moves = 0; gen(&moves[0]); num_moves = numb_moves; for (i = 0; i < num_moves; i++) { make(&moves[0], i); if (check_legal(&moves[0], i, ic)) { l++; } unmake(&moves[0], i); } }; } if (l == 0) { /* might be stalemate too */ node->proof = 1; node->disproof = 1; } else if (ToMove == root_to_move) /* OR */ { if ((Variant != Suicide) && (Variant != Losers)) { node->proof = 1 + floor(ply / 50); node->disproof = l + floor(ply / 50); } else { if (Variant == Losers) { /* this is probably a bogus line, so breathen the tree */ if (phase == Endgame) { node->proof = 1 + floor(ply / 30); node->disproof = l + floor(ply / 30); } else { node->proof = 1 + floor(ply / 80); node->disproof = l + floor(ply / 80); } } else { node->proof = 1 + floor(ply / 150); node->disproof = l + floor(ply / 150); } } } else { if ((Variant != Suicide) && (Variant != Losers)) { node->proof = l + floor(ply / 50); node->disproof = 1 + floor(ply / 50); } else { if (Variant == Losers) { if (phase == Endgame) { node->proof = l + floor(ply/30); node->disproof = 1 + floor(ply/30); } else { node->proof = l + floor(ply/80); node->disproof = 1 + floor(ply/80); } } else { node->proof = l + floor(ply / 150); node->disproof = 1 + floor(ply / 150); } } } //ep_square = ept; } else if (node->value == FALSE) { node->proof = +PN_INF; node->disproof = 0; } else if (node->value == TRUE) { node->proof = 0; node->disproof = +PN_INF; } else if (node->value == STALEMATE) { /* don't look at this node, its a dead-end */ node->proof = 50000; node->disproof = 50000; }; } else { node->proof = node->disproof = 1; } } void develop_node (node_t * node) { int num_moves; move_s moves[MOVE_BUFF]; int i, l; node_t *newnode; #ifdef PN2 node_t **newchildren; #endif int leg; int ic; //ept = ep_square; #ifdef PN2 if (!pn2) pn2_eval(node); #endif ic = in_check(); if (Variant != Losers) { num_moves = 0; gen (&moves[0]); num_moves = numb_moves; } else { captures = TRUE; leg = FALSE; num_moves = 0; gen (&moves[0]); num_moves = numb_moves; captures = FALSE; for (i = 0; i < num_moves; i++) { make (&moves[0], i); /* check to see if our move is legal: */ if (check_legal (&moves[0], i, ic)) { leg = TRUE; unmake(&moves[0], i); break; }; unmake(&moves[0], i); } if (leg == FALSE) { captures = FALSE; num_moves = 0; gen (&moves[0]); num_moves = numb_moves; } } #ifdef PN2 if (pn2) #endif node->children = (node_t **) Xmalloc (num_moves * sizeof (node_t **)); #ifdef PN2 else newchildren = (node_t **) malloc (num_moves * sizeof (node_t **)); #endif l = 0; for (i = 0; i < num_moves; i++) { hash_history[move_number+ply-1] = hash; make (&moves[0], i); /* check to see if our move is legal: */ if (check_legal (&moves[0], i, ic)) { #ifdef PN2 if (pn2) #endif newnode = (node_t *) Xmalloc (sizeof (node_t)); #ifdef PN2 else newnode = (node_t *) malloc (sizeof (node_t)); #endif newnode->value = 0; #ifdef PN2 if (!pn2) { newnode->proof = node->children[l]->proof; newnode->disproof = node->children[l]->disproof; } else { #endif newnode->proof = newnode->disproof = 1; #ifdef PN2 }; #endif newnode->num_children = 0; newnode->parent = node; newnode->evaluated = FALSE; newnode->expanded = FALSE; newnode->move = moves[i]; #ifdef PN2 if (!pn2) newchildren[l] = newnode; else #endif node->children[l] = newnode; l++; #ifdef PN2 if (pn2 == FALSE) /*use delayed eval */; else if (pn2) #endif pn_eval (newnode); #ifdef PN2 if (pn2) #endif set_proof_and_disproof_numbers (newnode); unmake (&moves[0], i); } else unmake (&moves[0], i); }; node->expanded = TRUE; node->num_children = l; #ifdef PN2 if (!pn2) node->children = newchildren; #endif /* account for stalemate ! */ if (node->num_children == 0) { node->expanded = FALSE; node->evaluated = TRUE; if (Variant != Suicide && Variant != Losers) { node->value = STALEMATE; } else { if (ToMove == root_to_move) { node->value = TRUE; } else { node->value = FALSE; } }; }; #ifdef PN2 if (pn2) nodecount2 += num_moves; else #endif nodecount += num_moves; frees += num_moves; //ep_square = ept; #ifdef PN2 if (!pn2) Xfree(); #endif }; void update_ancestors (node_t * node) { node_t *tnode, *prevnode; tnode = node; prevnode = node; while (tnode != 0) { set_proof_and_disproof_numbers (tnode); prevnode = tnode; if (tnode->move.target != 0) { /* traverse */ unmake (&tnode->move, 0); } tnode = tnode->parent; }; if (prevnode->move.target != 0) { make (&prevnode->move, 0); } return; }; void pn2_eval (node_t * root) { node_t *mostproving; #ifdef PN2 node_t *newroot; #endif node_t *currentnode; node_t *oldparent; nodecount2 = 0; pn2 = TRUE; oldparent = root->parent; root->parent = 0; pn_eval (root); set_proof_and_disproof_numbers (root); currentnode = root; while (root->proof != 0 && root->disproof != 0 && nodecount2 < nodecount ) { mostproving = select_most_proving (root); develop_node (mostproving); update_ancestors (mostproving); }; root->expanded = FALSE; root->num_children = 0; root->parent = oldparent; pn2 = FALSE; }; void proofnumberscan (void) { move_s moves[MOVE_BUFF]; int islegal[MOVE_BUFF]; int nodesspent[MOVE_BUFF]; int i, l, legal; int num_moves; rtime_t xstart_time; node_t *root; node_t *mostproving; node_t *currentnode; int leastlooked, leastlooked_l, leastlooked_i; int losers; int xnodecount; int firsts, alternates; char output[8]; int ic; float bdp; int altlosers; xstart_time = rtime (); membuff = (unsigned char *) calloc(PBSize, sizeof(node_t)); root = (node_t *) calloc (1, sizeof (node_t)); gen (&moves[0]); num_moves = numb_moves; alllosers = FALSE; memset(rootlosers, 0, sizeof(rootlosers)); memset(nodesspent, 0, sizeof(nodesspent)); pn_move = dummy; legal = 0; ic = in_check(); for (i = 0; i < num_moves; i++) { make (&moves[0], i); /* check to see if our move is legal: */ if (check_legal (&moves[0], i, ic)) { legal++; islegal[i] = 1; } else { islegal[i] = 0; }; unmake(&moves[0], i); } if (legal == 0) { Xfree(); free(membuff); free(root); return; } losers = 0; nodecount = 1; iters = 0; maxply = 0; forwards = 0; firsts = 0; alternates = 0; hash_history[move_number+ply-1] = hash; root_to_move = ToMove; pn_eval (root); if (root->value == TRUE || root->value == FALSE) { Xfree(); free(membuff); free(root); pn_move = dummy; return; } set_proof_and_disproof_numbers (root); while ((rdifftime (rtime (), xstart_time) < pn_time) && !interrupt() && (bufftop < ((PBSize-SAFETY) * sizeof(node_t))) && root->proof != 0 && root->disproof != 0) { iters++; xnodecount = nodecount; if ((nodecount % 100) < 66) { firsts++; /* pick normal pn move */ currentnode = root; mostproving = select_most_proving (currentnode); develop_node (mostproving); update_ancestors (mostproving); /* what was the mostproving node ? */ i = 0; while (root->children[i]->proof != root->proof) i++; nodesspent[i] += nodecount - xnodecount; if (root->proof == 0 && root->disproof == PN_INF) { forcedwin = TRUE; if (!kibitzed) { kibitzed = TRUE; printf("tellics kibitz Forced win!\n"); } pn_move = root->children[i]->move; } else if (root->disproof == 0 && root->proof == PN_INF) { pn_move = dummy; losers++; } } else { /* pick alternate move */ alternates++; leastlooked = PN_INF; l = 0; for (i = 0; i < num_moves; i++) { if ((nodesspent[i] < leastlooked) && islegal[i] && !rootlosers[i]) { leastlooked = nodesspent[i]; leastlooked_i = i; leastlooked_l = l; } if (islegal[i]) l++; } if (leastlooked == PN_INF) { /* could not find a nonlosing legal move */ nodecount += 30; continue; } make(&moves[0], leastlooked_i); currentnode = root->children[leastlooked_l]; mostproving = select_most_proving (currentnode); develop_node (mostproving); update_ancestors (mostproving); nodesspent[leastlooked_i] += nodecount - xnodecount; /* should be back at root now */ if (root->children[leastlooked_l]->proof == 0 && root->children[leastlooked_l]->disproof == PN_INF) { /* alternate move was forced win */ forcedwin = TRUE; if (!kibitzed) { kibitzed = TRUE; printf("tellics kibitz Forced win! (alt)\n"); } pn_move = root->children[leastlooked_l]->move; } else if (root->children[leastlooked_l]->disproof == 0 && root->children[leastlooked_l]->proof == PN_INF) { /* alternate move loses */ rootlosers[leastlooked_i] = 1; losers++; } } }; l = 0; bdp = -1; altlosers = 0; if (root->expanded) { for (i = 0; i < num_moves; i++) { if (islegal[i]) { comp_to_san(moves[i], output); //printf("checked %s, nodes: %d, pn: %d, dp: %d\n", // output, nodesspent[i], root->children[l]->proof, root->children[l]->disproof); if (root->children[l]->proof != 0) { if (((float)root->children[l]->disproof / (float)root->children[l]->proof) > bdp) { bdp = ((float)root->children[l]->disproof / (float)root->children[l]->proof); pn_move = root->children[l]->move; } if ((root->children[l]->disproof == 0) && (root->children[l]->proof == PN_INF)) { altlosers++; make(&moves[0], i); Learn(-INF+500, 255, 200); unmake(&moves[0], i); } } else { forcedwin = TRUE; pn_move = root->children[l]->move; bdp = PN_INF; } l++; } } } comp_to_san(pn_move, output); if (xb_mode && post) printf ("tellics whisper proof %d, disproof %d, %d losers, highest depth %d, primary %d, secondary %d\n", root->proof, root->disproof, altlosers, maxply, firsts, alternates); #if 0 if (forcedwin && maxply == 0) { if (root_to_move == WHITE) { result = black_is_mated; } else { result = white_is_mated; } } #endif if (altlosers == (legal - 1)) { printf("tellics whisper Forced reply\n"); for (i = 0; i < num_moves; i++) { if (!rootlosers[i] && islegal[i]) { /* not really forced win but setting this flag * just means 'blindy trust pnsearch' */ forcedwin = TRUE; pn_move = moves[i]; break; } } } if (altlosers == legal) { alllosers = TRUE; } Xfree(); free(membuff); free(root); return; }; void proofnumbersearch (void) { node_t *root; node_t *mostproving; node_t *currentnode; rtime_t xstart_time; char output[8192]; char PV[8192]; int i; float bdp; int oldply; nodecount = 1; iters = 0; frees = 0; ply = 1; maxply = 0; forwards = 0; hash_history[move_number+ply-1] = hash; root_to_move = ToMove; //eps = ep_square; xstart_time = rtime (); root = (node_t *) calloc (1, sizeof (node_t)); membuff = (unsigned char *) calloc(PBSize, sizeof(node_t)); pn_eval (root); if (root->value == FALSE) { pn_move = dummy; Xfree(); free(root); free(membuff); return; } set_proof_and_disproof_numbers (root); currentnode = root; while (root->proof != 0 && root->disproof != 0 && (bufftop < ((PBSize-SAFETY) * sizeof(node_t)))) { mostproving = select_most_proving (currentnode); develop_node (mostproving); update_ancestors (mostproving); iters++; #ifdef PN2 if (iters) #else if ((iters % 32) == 0) #endif { #ifdef PN2 printf("P: %d D: %d N: %d S: %d Mem: %2.2fM Iters: %d ", root->proof, root->disproof, nodecount, frees, (((nodecount) * sizeof(node_t) / (float)(1024*1024))), iters); printf ("PV: "); memset (output, 0, sizeof (output)); memset (PV, 0, sizeof (PV)); //currentnode = root; ply = 1; while (currentnode->expanded) { if (ToMove == root_to_move) { i = 0; while (currentnode->children[i]->proof != currentnode->proof) { i++; }; } else { i = 0; while (currentnode->children[i]->disproof != currentnode->disproof) { i++; } }; currentnode = currentnode->children[i]; comp_to_coord (currentnode->move, output); printf ("%s ", output); strcat (PV, output); strcat (PV, " "); make (¤tnode->move, 0); }; while (currentnode != root) { unmake (¤tnode->move, 0); currentnode = currentnode->parent; }; printf("\n"); #endif if ((rdifftime (rtime (), xstart_time) > pn_time) && !interrupt()) break; } }; printf ("P: %d D: %d N: %d S: %d Mem: %2.2fM Iters: %d MaxDepth: %d\n", root->proof, root->disproof, nodecount, frees, (((nodecount) * sizeof (node_t) / (float) (1024 * 1024))), iters,maxply); if (xb_mode && post) printf ("tellics whisper proof %d, disproof %d, %d nodes, %d forwards, %d iters, highest depth %d\n", root->proof, root->disproof, nodecount, forwards, iters, maxply); if (!xb_mode) printf("Time : %f\n", (float)rdifftime(rtime(), xstart_time)/100.); while (currentnode != root) { unmake (¤tnode->move, 0); currentnode = currentnode->parent; }; if (root->proof == 0) { root->value = TRUE; printf ("This position is WON.\n"); printf ("PV: "); memset (output, 0, sizeof (output)); memset (PV, 0, sizeof (PV)); //currentnode = root; ply = 1; while (currentnode->expanded) { if (ToMove == root_to_move) { i = 0; while (currentnode->children[i]->proof != currentnode->proof) { i++; }; } else { i = 0; while (currentnode->children[i]->disproof != currentnode->disproof) { i++; } }; currentnode = currentnode->children[i]; comp_to_coord (currentnode->move, output); printf ("%s ", output); strcat (PV, output); strcat (PV, " "); make (¤tnode->move, 0); if (ply == 1) pn_move = currentnode->move; forcedwin = TRUE; }; oldply = ply; while (currentnode != root) { unmake (¤tnode->move, 0); currentnode = currentnode->parent; }; if (!kibitzed && xb_mode && post) { kibitzed = TRUE; printf ("\ntellics kibitz Forced win in %d moves.\n", oldply/2); } if (oldply == 1 && (root->proof == 0 || root->disproof == 0)) { if (root_to_move == WHITE) { printf("\n1-0 {White mates}\n"); result = black_is_mated; } else { printf("\n0-1 {Black mates}\n"); result = white_is_mated; } } printf ("\n"); } else if (root->disproof == 0) { root->value = FALSE; printf ("This position is LOST.\n"); pn_move = dummy; } else { root->value = UNKNOWN; printf ("This position is UNKNOWN.\n"); pn_move = dummy; }; /* find the move which is least likely to lose */ bdp = -1; for (i = 0; i < root->num_children; i++) { if (root->children[i]->proof != 0) { if (((float)(root->children[i]->disproof) / (float)(root->children[i]->proof)) > bdp) { bdp = (float)root->children[i]->disproof / (float)(root->children[i]->proof); pn_move = root->children[i]->move; } } else { pn_move = root->children[i]->move; break; } }; pn_saver = pn_move; free(root); Xfree(); free(membuff); //ep_square = eps; return; } move_s proofnumbercheck(move_s compmove) { node_t* root; node_t *mostproving; node_t *currentnode; rtime_t xstart_time; move_s resmove; if (piece_count <= 3 && (Variant == Suicide)) { return compmove; } nodecount = 0; iters = 0; frees = 0; ply = 1; maxply = 0; /* make our move to check */ make(&compmove, 0); hash_history[move_number+ply-1] = hash; root_to_move = ToMove; //eps = ep_square; xstart_time = rtime(); root = (node_t *) calloc(1, sizeof(node_t)); membuff = (unsigned char *) calloc(PBSize, sizeof(node_t)); pn_eval(root); set_proof_and_disproof_numbers(root); currentnode = root; while (root->proof != 0 && root->disproof != 0 && (bufftop < ((PBSize-SAFETY) * sizeof(node_t)))) { mostproving = select_most_proving(currentnode); develop_node(mostproving); update_ancestors(mostproving); iters++; if ((iters % 32) == 0) { // printf("P: %d D: %d N: %d S: %d Mem: %2.2fM Iters: %d\n", root->proof, root->disproof, nodecount, frees, (((nodecount) * sizeof(node_t) / (float)(1024*1024))), iters); if ((rdifftime (rtime (), xstart_time) > pn_time)) break; } }; printf("P: %d D: %d N: %d S: %d Mem: %2.2fM Iters: %d\n", root->proof, root->disproof, nodecount, frees, (((nodecount) * sizeof(node_t) / (float)(1024*1024))), iters); while(currentnode != root) { unmake(¤tnode->move, 0); currentnode = currentnode->parent; }; unmake(&compmove, 0); if (root->proof == 0) { /* ok big problem our ab move loses */ root->value = TRUE; /* use best disprover instead */ resmove = pn_move; s_threat = TRUE; } else if (root->disproof == 0) { /* ab move wins...unlikely due to earlier pnsearch */ root->value = FALSE; resmove = compmove; } else { root->value = UNKNOWN; resmove = compmove; }; Xfree(); free(root); free(membuff); //ep_square = eps; return resmove; } sjeng-11.2.orig/standard.lrn0100644000175000017500000000031007473542762015052 0ustar lukaslukas ÿ÷ƒÕ5¨Àÿîÿÿÿ÷ ]diÜÀÿî ü›<ÌÀÿîZð‚UÀÿîd0®#Àÿî ÖËÀÿî ú…¼ÖÀÿî&'¿ñÀÿî&Õ¼+Àÿîlí ÀÿîÐF+ÀÿîqÀxö¶Àÿîqsjeng-11.2.orig/bug.lrn0100644000175000017500000000000007473542467014025 0ustar lukaslukassjeng-11.2.orig/suicide.lrn0100644000175000017500000000000007473542467014675 0ustar lukaslukassjeng-11.2.orig/losers.lrn0100644000175000017500000000000007473542467014557 0ustar lukaslukas