| 
							- //
 - // "$Id: checkers.cxx 8168 2011-01-02 03:55:23Z matt $"
 - //
 - // Checkers game for the Fast Light Tool Kit (FLTK).
 - //
 - // Hours of fun: the FLTK checkers game!
 - // Based on a very old algorithm, but it still works!
 - //
 - // Copyright 1998-2010 by Bill Spitzak and others.
 - //
 - // This library is free software; you can redistribute it and/or
 - // modify it under the terms of the GNU Library General Public
 - // License as published by the Free Software Foundation; either
 - // version 2 of the License, or (at your option) any later version.
 - //
 - // This library 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
 - // Library General Public License for more details.
 - //
 - // You should have received a copy of the GNU Library General Public
 - // License along with this library; if not, write to the Free Software
 - // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 - // USA.
 - //
 - // Please report all bugs and problems on the following page:
 - //
 - //     http://www.fltk.org/str.php
 - //
 - 
 - const char* copyright = 
 - "Checkers game\n"
 - "Copyright (C) 1997-2010 Bill Spitzak    spitzak@d2.com\n"
 - "Original Pascal code:\n"
 - "Copyright 1978, Oregon Minicomputer Software, Inc.\n"
 - "2340 SW Canyon Road, Portland, Oregon 97201\n"
 - "Written by Steve Poulsen 18-Jan-79\n"
 - "\n"
 - "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.\n"
 - "\n"
 - "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.\n"
 - "\n"
 - "You should have received a copy of the GNU Library General Public "
 - "License along with this library; if not, write to the Free Software "
 - "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 "
 - "USA.";
 - 
 - // Define FLTK to get the fltk interface
 - // Define VT100 to get the VT100 interface
 - // Define both to get a program that takes a -t switch
 - 
 - #define FLTK
 - //#define VT100
 - 
 - #undef check
 - 
 - #include <string.h>
 - #include <stdlib.h>
 - #include <stdio.h>
 - #include <stdarg.h>
 - #include <time.h>
 - 
 - #ifdef VT100
 - #include <ctype.h>	// toupper
 - #endif
 - 
 - ////////////////////////////////////////////////////////////////
 - // The algorithim:
 - 
 - int maxevaluate=2500;		// max number of moves to examine on a turn
 - int maxnodes = 2500;		// maximum number of nodes in search tree
 - int maxply = 20;		// maximum depth to look ahead
 - char forcejumps = 1;		// is forced jumps rule in effect?
 - 
 - // scoring parameters: (all divided by 5 from original code)
 - // some signs seem to be backwards, marked them with (-) in comment
 - const int spiece = 800;		// value of a piece
 - const int sking = 1200;		// value of a king
 - const int sadvan = 160;		// value of mypieces/theirpieces-1
 - // const int smobil = ?		// moves *enemy* can make w/o being jumped
 - const int sallpin = 80;		// mobil == 0
 - const int sdeny = 10;		// moves enemy can make that will be jumped
 - const int spin = 32;		// enemy pieces that have no move except jumped
 - const int sthreat = -10;	// enemy pieces we can jump if not moved (-)
 - const int sgrad = 1;		// score of piece positions
 - const int sback = 10;		// back row occupied so enemy can't make king
 - const int smoc2 = 200;		// more mobility, more center
 - const int smoc3 = -8;		// less mobility, less center
 - const int smoc4 = -80;		// more mobility, less center
 - const int smode2 = -14;		// less mobility, less denied
 - const int smode3 = -40;		// more mobility, more denied (-)
 - const int sdemmo = -20;		// more denied, more moves (-)
 - const int scent = 10;		// pieces in center
 - const int skcent = 100;		// kings in center
 - 
 - const int depthpenalty=4;	// guess
 - const int noise=2;		// values less or eq to this apart are eq
 - 
 - // const int sattackking = 4;	// not used
 - // const int sattackpiece = 3;
 - 
 - struct node {
 -   node *father;
 -   node *son;		// best son
 -   node *brother;	// next brother
 -   short int value;	// value of this board position to player making move
 -   unsigned char from,to; // the move to reach this board
 -   long int jump;	// bit map of locations jumped
 -   unsigned char mobil;
 -   unsigned char deny;
 -   unsigned char pin;
 -   unsigned char threat;
 -   short int gradient;
 -   unsigned who:1;	// 0 = black's move, 1 = white's move
 -   unsigned king:1;	// 1 = move causes piece to be kinged
 -   unsigned back:1;
 -   unsigned moc2:1;
 -   unsigned moc3:1;
 -   unsigned moc4:1;
 -   unsigned mode2:1;
 -   unsigned mode3:1;
 -   unsigned demmo:1;
 - };
 - 
 - int nodes;		// count of nodes
 - 
 - /*	Board positions:	Border positions:
 - 
 - 	      WHITE		  00  01  02  03  04
 - 	  05  06  07  08	04  XX  XX  XX  XX
 - 	09  10  11  12		  XX  XX  XX  XX  13
 - 	  14  15  16  17	13  XX  XX  XX  XX
 - 	18  19  20  21		  XX  XX  XX  XX  22
 - 	  23  24  25  26	22  XX  XX  XX  XX
 - 	27  28  29  30		  XX  XX  XX  XX  31
 - 	  32  33  34  36	31  XX  XX  XX  XX
 - 	36  37  38  39		  XX  XX  XX  XX  40
 - 	      BLACK		40  41  42  43  44
 - 
 - */
 - 
 - typedef char piece;
 - 
 - // Piece values so that BLACK and WHITE are bit flags:
 - #define EMPTY 0
 - #define BLACK 1
 - #define WHITE 2
 - #define KING 4
 - #define BLACKKING 5
 - #define WHITEKING 6
 - #define BLUE 8
 - 
 - const piece flip[9] = {
 -   EMPTY, WHITE, BLACK, 0, 0, WHITEKING, BLACKKING, 0, BLUE};
 - 
 - const int offset[9][4] = {	// legal move directions
 -   {0,0,0,0},
 -   {-5,-4,0,0},
 -   {4,5,0,0},
 -   {0,0,0,0},
 -   {0,0,0,0},
 -   {4,5,-4,-5},
 -   {4,5,-4,-5},
 -   {0,0,0,0},
 -   {0,0,0,0}
 - };
 - 
 - piece b[45];		// current board position being considered
 - 
 - int evaluated;		// number of moves evaluated this turn
 - 
 - char centralsquares[45];
 - char is_protected[45];
 - 
 - piece flipboard[45];	// swapped if enemy is black
 - piece *tb;		// pointer to real or swapped board
 - #define FRIEND BLACK
 - #define FRIENDKING BLACKKING
 - #define ENEMY WHITE
 - #define ENEMYKING WHITEKING
 - 
 - char check(int target,int direction) {
 -   // see if enemy at target can be jumped from direction by our piece
 -   int dst = target-direction;
 -   if (tb[dst]) return(0);
 -   int src = target+direction;
 -   if (tb[src] == FRIENDKING);
 -   else if (direction < 0 || tb[src] != FRIEND) return(0);
 -   piece aa = tb[target]; piece bb = tb[src];
 -   tb[target] = EMPTY; tb[src] = EMPTY;
 -   int safe =
 -     (   (tb[src-4]&FRIEND && tb[src-8]&ENEMY)
 -      || (tb[src-5]&FRIEND && tb[src-10]&ENEMY)
 -      || (tb[dst-4]&ENEMY && !tb[dst+4])
 -      || (tb[dst-5]&ENEMY && !tb[dst+5])
 -      || (tb[src+4]&FRIEND && tb[src+8]==ENEMYKING)
 -      || (tb[src+5]&FRIEND && tb[src+10]==ENEMYKING)
 -      || (tb[dst+4]==ENEMYKING && !tb[dst-4])
 -      || (tb[dst+5]==ENEMYKING && !tb[dst-5]));
 -   tb[target] = aa; tb[src] = bb;
 -   return(safe);
 - }
 - 
 - int deniedmoves,undeniedmoves;
 - void analyzemove(int direction,int src) {
 -   int target = src+direction;
 -   if (!tb[target]) {
 -     if (!tb[target+direction]) is_protected[target] = 1;
 -     piece a = tb[src]; tb[src] = EMPTY;
 -     if (check(target,4) || check(target,5) ||
 - 	check(target,-4) || check(target,-5) ||
 - 	(tb[src+4]&ENEMY && check(src+4,4)) ||
 - 	(tb[src+5]&ENEMY && check(src+5,5)) ||
 - 	(tb[src-4]&ENEMY && check(src-4,-4)) ||
 - 	(tb[src-5]&ENEMY && check(src-5,-5)))
 -       deniedmoves++;
 -     else undeniedmoves++;
 -     tb[src] = a;
 -   }
 - }
 - 
 - void evaluateboard(node *n,int print) {
 - 
 -   if (!n->who) tb = b;	// move was black's
 -   else {
 -     for (int i=0; i<45; i++) flipboard[44-i] = flip[(int)b[i]];
 -     tb = flipboard;
 -   }
 - 
 -   memset(is_protected,0,sizeof(is_protected));
 -   int friendpieces = 0;
 -   int enemypieces = 0;
 -   int friendkings = 0;
 -   int enemykings = 0;
 -   int friendkcent = 0;
 -   int friendcent = 0;
 -   int enemykcent = 0;
 -   int enemycent = 0;
 -   n->mobil = n->deny = n->pin = n->threat = 0;
 - 
 -   int i;
 -   for (i=5; i<40; i++) switch(tb[i]) {
 -   case ENEMYKING:
 -     enemykings++;
 -     enemykcent += centralsquares[i];
 -     deniedmoves = 0;
 -     undeniedmoves = 0;
 -     if (i>8) {
 -       analyzemove(-4,i);
 -       analyzemove(-5,i);
 -     }
 -     goto J1;
 -   case ENEMY:
 -     deniedmoves = 0;
 -     undeniedmoves = 0;
 -   J1:	enemypieces++;
 -     enemycent += centralsquares[i];
 -     if (i<36) {
 -       analyzemove(4,i);
 -       analyzemove(5,i);
 -     }
 -     if (deniedmoves && !undeniedmoves) n->pin++;
 -     n->deny += deniedmoves;
 -     n->mobil += undeniedmoves;
 -     break;
 -   case FRIENDKING:
 -     friendkings++;
 -     friendkcent += centralsquares[i];
 -     if (tb[i+4]&ENEMY && !tb[i+8] && !(tb[i+4]==ENEMYKING && !tb[i-4]))
 -       n->threat++;
 -     if (tb[i+5]&ENEMY && !tb[i+10] && !(tb[i+5]==ENEMYKING && !tb[i-5]))
 -       n->threat++;
 -   case FRIEND:
 -     friendpieces++;
 -     friendcent += centralsquares[i];
 -     if (tb[i-4]&ENEMY && !tb[i-8] && tb[i+4]) n->threat++;
 -     if (tb[i-5]&ENEMY && !tb[i-10] && tb[i+5]) n->threat++;
 -     break;
 -   }
 - 
 -   int gradient[40];
 -   for (i=4; i<9; i++) gradient[i] = tb[i] ? 0 : 32;
 -   int total = 0;
 -   for (i=9; i<40; i++) {
 -     int x = (gradient[i-4]+gradient[i-5])/2;
 -     if (tb[i]==FRIEND) total += x;
 -     gradient[i] = (tb[i]&FRIEND || (!tb[i] && !is_protected[i])) ? x : 0;
 -   }
 -   n->gradient = total;
 - 
 -   n->back = tb[39]==FRIEND && tb[37]==FRIEND && !enemykings;
 - 
 -   node* f = n->father;
 - 
 -   n->moc2 = f->mobil>n->mobil && friendcent>enemycent;
 -   n->moc3 = f->mobil<=n->mobil && friendcent<enemycent;
 -   n->moc4 = f->mobil>n->mobil && friendcent<enemycent;
 -   n->mode2 = f->mobil<=n->mobil && n->deny<f->deny;
 -   n->mode3 = f->mobil>n->mobil && n->deny>f->deny;
 -   n->demmo = n->deny>f->deny && f->deny+f->mobil>n->deny+n->mobil;
 - 
 -   total =
 -     spiece	* (friendpieces - enemypieces) +
 -     (sking-spiece) * (friendkings	- enemykings) +
 -     //	mobil?
 -     sdeny	* (n->deny	- f->deny) +
 -     spin	* (n->pin	- f->pin) +
 -     sthreat	* (n->threat	- f->threat) +
 -     sgrad	* (n->gradient	- f->gradient) +
 -     sback	* (n->back	- f->back) +
 -     smoc2	* (n->moc2	- f->moc2) +
 -     smoc3	* (n->moc3	- f->moc3) +
 -     smoc4	* (n->moc4	- f->moc4) +
 -     smode2	* (n->mode2	- f->mode2) +
 -     smode3	* (n->mode3	- f->mode3) +
 -     sdemmo	* (n->demmo	- f->demmo) +
 -     scent	* (friendcent	- enemycent) +
 -     (skcent-scent) * (friendkcent	- enemykcent);
 -   if (!n->mobil) total += sallpin;
 - 
 -   if (!enemypieces) total = 30000;
 -   else if (friendpieces > enemypieces)
 -     total += (sadvan*friendpieces)/enemypieces-sadvan;
 -   else total -= (sadvan*enemypieces)/friendpieces-sadvan;
 - 
 -   if (print) {
 -     printf("\tParent\tNew\tScore\n");
 -     printf("pieces\t%d\t%d\t%d\n",enemypieces,friendpieces,
 - 	   spiece*(friendpieces-enemypieces));
 -     printf("kings\t%d\t%d\t%d\n",enemykings,friendkings,
 - 	   (sking-spiece)*(friendkings-enemykings));
 -     printf("mobil\t%d\t%d\n",f->mobil,n->mobil);
 -     printf("deny\t%d\t%d\t%d\n",f->deny,n->deny,sdeny*(n->deny-f->deny));
 -     printf("pin\t%d\t%d\t%d\n",f->pin,n->pin,spin*(n->pin-f->pin));
 -     printf("threat\t%d\t%d\t%d\n",f->threat,n->threat,sthreat*(n->threat-f->threat));
 -     printf("grad\t%d\t%d\t%d\n",f->gradient,n->gradient,sgrad*(n->gradient-f->gradient));
 -     printf("back\t%d\t%d\t%d\n",f->back,n->back,sback*(n->back-f->back));
 -     printf("moc2\t%d\t%d\t%d\n",f->moc2,n->moc2,smoc2*(n->moc2-f->moc2));
 -     printf("moc3\t%d\t%d\t%d\n",f->moc3,n->moc3,smoc3*(n->moc3-f->moc3));
 -     printf("moc4\t%d\t%d\t%d\n",f->moc4,n->moc4,smoc4*(n->moc4-f->moc4));
 -     printf("mode2\t%d\t%d\t%d\n",f->mode2,n->mode2,smode2*(n->mode2-f->mode2));
 -     printf("mode3\t%d\t%d\t%d\n",f->mode3,n->mode3,smode3*(n->mode3-f->mode3));
 -     printf("demmo\t%d\t%d\t%d\n",f->demmo,n->demmo,sdemmo*(n->demmo-f->demmo));
 -     printf("cent\t%d\t%d\t%dn",enemycent,friendcent,scent*(friendcent-enemycent));
 -     printf("kcent\t%d\t%d\t%d\n",enemykcent,friendkcent,skcent*(friendkcent-enemykcent));
 -     printf("total:\t\t\t%d\n",total);
 -   }
 -   else {
 -     n->value = total;
 -     evaluated++;
 -   }
 - }	// end of evaluateboard
 - 
 - // --------------------- Tree management -----------------
 - 
 - node *freelist;
 - 
 - node *newnode(void) {
 -   node *n;
 -   if (freelist) {
 -     n = freelist;
 -     freelist = n->brother;
 -   }
 -   else n = (node *)malloc(sizeof(node));
 -   memset(n,0,sizeof(node));
 -   nodes++;
 -   return(n);
 - }
 - 
 - void extract(node *n) {
 -   node* i = n->father;
 -   if (i) {
 -     node* j = i->son;
 -     if (j==n) i->son = n->brother;
 -     else while (j) {
 -       i = j; j = j->brother;
 -       if (j==n) {i->brother = n->brother; break;}
 -     }
 -   }
 -   n->brother = 0;
 - }
 - 
 - void killnode(node *x) {
 -   if (!x) return;
 -   node *y;
 -   for (y = x; ; y = y->brother) {
 -     nodes--;
 -     killnode(y->son); y->son = 0;
 -     if (!y->brother) break;
 -   }
 -   y->brother = freelist;
 -   freelist = x;
 - }
 - 
 - int seed;		// current random number
 - 
 - void insert(node *n) {
 -   int val = n->value;
 -   node **pp;
 -   for (pp = &(n->father->son); *pp; pp = &((*pp)->brother)) {
 -     int val1 = (*pp)->value;
 -     if (abs(val-val1) <= noise) {
 -       seed = (seed*13077+5051)%0100000;
 -       if ((seed & 070) >= 060) break;
 -     }
 -     else if (val > val1) break;
 -   }
 -   n->brother = *pp;
 -   *pp = n;
 - }
 - 
 - // --------------------------------------------------------------
 - 
 - void movepiece(node* f, int i, node* jnode) {
 -   static char jumphappened;
 - 
 -   for (int k=0; k<4; k++) {
 -     int direction = offset[(int)b[i]][k];
 -     if (!direction) break;
 -     int j = i+direction;
 -     if (b[j] == EMPTY) {
 -       if (!jnode && (!forcejumps || !f->son || !f->son->jump)) {
 - 	node* n = newnode();
 - 	n->father = f;
 - 	n->who = !f->who;
 - 	n->from = i;
 - 	n->to = j;
 - 	piece oldpiece = b[i]; b[i] = EMPTY;
 - 	if (!(oldpiece&KING) && n->who ? (j>=36) : (j<=8)) {
 - 	  n->king = 1;
 - 	  b[j] = oldpiece|KING;
 - 	}
 - 	else b[j] = oldpiece;
 - 	evaluateboard(n,0);
 - 	insert(n);
 - 	b[i] = oldpiece; b[j] = EMPTY;
 -       }
 -     } else if (((b[j]^b[i])&(WHITE|BLACK))==(WHITE|BLACK) && !b[j+direction]) {
 -       if (forcejumps && f->son && !f->son->jump) {
 - 	killnode(f->son);
 - 	f->son = 0;
 -       }
 -       int jumploc = j;
 -       j += direction;
 -       node* n = newnode();
 -       n->father = f;
 -       n->who = !f->who;
 -       n->from = i;
 -       n->to = j;
 -       n->jump = (1<<(jumploc-10));
 -       piece oldpiece = b[i]; b[i] = EMPTY;
 -       if (!(oldpiece&KING) && n->who ? (j>=36) : (j<=8)) {
 - 	n->king = 1;
 - 	b[j] = oldpiece|KING;
 -       }
 -       else b[j] = oldpiece;
 -       if (jnode) {
 - 	n->from = jnode->from;
 - 	n->jump |= jnode->jump;
 - 	n->king |= jnode->king;
 -       }
 -       piece jumpedpiece = b[jumploc];
 -       b[jumploc] = EMPTY;
 -       jumphappened = 0;
 -       movepiece(f,j,n);
 -       if (forcejumps && jumphappened) killnode(n);
 -       else {evaluateboard(n,0); insert(n);}
 -       b[i] = oldpiece; b[j] = EMPTY;
 -       b[jumploc] = jumpedpiece;
 -       jumphappened = 1;
 -     }
 -   }
 - }
 - 
 - void expandnode(node *f) {
 -   if (f->son || f->value > 28000) return;	// already done
 -   piece turn = f->who ? BLACK : WHITE;
 -   for (int i=5; i<40; i++) if (b[i]&turn) movepiece(f,i,0);
 -   if (f->son) {
 -     f->value = -f->son->value;
 -     if (f->brother) f->value -= depthpenalty;
 -   }
 -   else f->value = 30000;
 - }
 - 
 - void makemove(node *n) {
 -   b[n->to] = b[n->from];
 -   if (n->king) b[n->to] |= KING;
 -   b[n->from] = EMPTY;
 -   if (n->jump) for(int i=0; i<32; i++) {
 -     if (n->jump & (1<<i)) b[10+i] = EMPTY;
 -   }
 - }
 - 
 - int didabort(void);
 - 
 - int fullexpand(node *f, int level) {
 -   if (didabort() || nodes > maxnodes-(maxply*10) || evaluated > maxevaluate) return(0);
 -   expandnode(f);
 -   if (!f->son) return(1);
 -   piece oldboard[45];
 -   memmove(oldboard,b,sizeof(b));
 -   node* n = f->son;
 -   if (!n->jump && n->brother) {if (level<1) return(1); level--;}
 -   int i;
 -   node* sons[32]; for (i=0; (sons[i++] = n); n = n->brother);
 -   int ret = 1;
 -   for (i=0; ret && (n = sons[i++]);) {
 -     makemove(n);
 -     ret = fullexpand(n,level);
 -     memmove(b,oldboard,sizeof(b));
 -     extract(n);
 -     insert(n);
 -   }
 -   f->value = -f->son->value;
 -   return(ret);
 - }
 - 
 - int descend(node *f) {
 -   static int depth;
 -   if (didabort() || nodes > maxnodes || depth >= maxply) return(0);
 -   if (f->son) {
 -     node* n = f->son;
 -     makemove(n);
 -     depth++;
 -     int ret = descend(n);
 -     depth--;
 -     extract(n);
 -     insert(n);
 -     f->value = -f->son->value;
 -     return(ret);
 -   }
 -   else {expandnode(f); return(1);}
 - }
 - 
 - char debug;
 - 
 - node *calcmove(node *root) {	// return best move after root
 -   expandnode(root);
 -   if (!root->son) return(0);	// no move due to loss
 -   if (debug) printf("calcmove() initial nodes = %d\n",nodes);
 -   evaluated = 0;
 -   if (root->son->brother) {
 -     int x;
 -     for (x = 1; abs(root->value)<28000 && fullexpand(root,x); x++);
 -     piece saveboard[45]; memmove(saveboard,b,sizeof(b));
 -     while (abs(root->value)<28000) {
 -       x = descend(root);
 -       memmove(b,saveboard,sizeof(b));
 -       if (!x) break;
 -     }
 -   }
 -   if (debug) printf(" evaluated %d, nodes = %d\n", evaluated, nodes);
 -   return(root->son);
 - }
 - 
 - // the actual game state ----------------
 - 
 - node *root,*undoroot;
 - 
 - piece jumpboards[24][45];	// saved boards for undoing jumps
 - int nextjump;
 - 
 - char user;	// 0 = black, 1 = white
 - char playing;
 - char autoplay;
 - 
 - void newgame(void) {
 - 
 -   int n;
 -   for (n=0; n<5; n++) b[n] = BLUE;
 -   for (n=5; n<18; n++) b[n] = WHITE;
 -   for (n=18; n<27; n++) b[n] = EMPTY;
 -   for (n=27; n<40; n++) b[n] = BLACK;
 -   for (n=40; n<45; n++) b[n] = BLUE;
 -   b[13] = b[22] = b[31] = BLUE;
 - 
 -   centralsquares[15] = centralsquares[16] =
 -     centralsquares[19] = centralsquares[20] =
 -     centralsquares[24] = centralsquares[25] =
 -     centralsquares[28] = centralsquares[29] = 1;
 - 
 -   // set up initial search tree:
 -   nextjump = 0;
 -   killnode(undoroot);
 -   undoroot = root = newnode();
 - 
 -   // make it white's move, so first move is black:
 -   root->who = 1;
 -   user = 0;
 -   playing = 1;
 - }
 - 
 - void domove(node* move) {
 -   if (move->jump) memmove(jumpboards[nextjump++],b,sizeof(b));
 -   makemove(move);
 -   extract(move);
 -   killnode(root->son);
 -   root->son = move;
 -   root = move;
 -   if (debug) evaluateboard(move,1);
 - }
 - 
 - node* undomove() {
 -   node *n = root;
 -   if (n == undoroot) return 0; // no more undo possible
 -   if (n->jump) memmove(b,jumpboards[--nextjump],sizeof(b));
 -   else {
 -     b[n->from] = b[n->to];
 -     if (n->king) b[n->from] &= (WHITE|BLACK);
 -     b[n->to] = EMPTY;
 -   }
 -   root = n->father;
 -   killnode(n);
 -   root->son = 0;
 -   root->value = 0;	// prevent it from thinking game is over
 -   playing = 1;
 -   if (root == undoroot) user = 0;
 -   return n;
 - }
 - 
 - const char _usermoves[] =
 - "B1D1F1H1A2C2E2G2??B3D3F3H3A4C4E4G4??B5D5F5H5A6C6E6G6??B7D7F7H7A8C8E8G8??";
 - #define usermoves(x,y) _usermoves[2*((x)-5)+(y)-1]
 - 
 - void dumpnode(node *n, int help) {
 -   int x = n->from;
 -   int y = n->to;
 -   if (help) printf("%c%c %c%c\t- ",
 - 		   usermoves(x,1),usermoves(x,2),
 - 		   usermoves(y,1),usermoves(y,2));
 -   printf("%s %ss from %c%c to %c%c",
 - 	 n->who ? "White" : "Black",
 - 	 n->jump ? "jump" : "move",
 - 	 usermoves(x,1),usermoves(x,2),
 - 	 usermoves(y,1),usermoves(y,2));
 -   if (n->jump) {
 -     for (int i=0; i<32; i++) if (n->jump & (1<<i))
 -       printf(", %c%c",usermoves(10+i,1),usermoves(10+i,2));
 -     printf(" removed");
 -   }
 -   printf(" (%+d).\n",n->value);
 - }
 - 
 - int abortflag;
 - 
 - ////////////////////////////////////////////////////////////////
 - // VT100 Interface:
 - #ifdef VT100
 - 
 - void positioncursor(int i) {
 -   printf("\033[%d;%dH",
 - 	 usermoves(i,2)-'0'+1,
 - 	 2*(usermoves(i,1)-'A')+1);
 - }
 - 
 - void outpiecename(piece n) {
 -   printf(n&BLACK ? "\033[1;7m" : "\033[1m");
 -   putchar(" BW??BW??"[n]);
 -   putchar(" BW??KK??"[n]);
 -   printf("\033[0m");
 - }
 - 
 - void VT100board(void) {
 -   printf("\033<\033[H\033[J\033[10r");
 -   int l = 0;
 -   puts(" A B C D E F G H");
 -   for (int i=0; i<4; i++) {
 -     int j = 9*i+5;
 -     int k;
 -     for (k=0; k<4; k++) {
 -       printf("\033[7m  \033[0m");
 -       outpiecename(b[j+k]);
 -     }
 -     l++;
 -     printf("%d\n",l);
 -     j += 4;
 -     for (k=0; k<4; k++) {
 -       outpiecename(b[j+k]);
 -       printf("\033[7m  \033[0m");
 -     }
 -     l++;
 -     printf("%d\n",l);
 -   }
 - }
 - 
 - void VT100move(node *n, int) {
 -   if (!n) return;
 -   printf("\0337");
 -   positioncursor(n->from);
 -   outpiecename(b[n->from]);
 -   positioncursor(n->to);
 -   outpiecename(b[n->to]);
 -   if (n->jump) for(int i=0; i<32; i++) {
 -     if (n->jump & (1<<i)) {
 -       positioncursor(10+i);
 -       outpiecename(b[10+i]);
 -     }
 -   }
 -   printf("\0338");
 - }
 - 
 - int decode(char *m) {
 -   int i;
 -   for(i=5; i<=40; i++)
 -     if (toupper(m[0])==usermoves(i,1) && m[1]==usermoves(i,2)) return(i);
 -   return(0);
 - }
 - 
 - #include <signal.h>
 - 
 - static void sigint(...) {
 -   abortflag = 1;
 -   signal(SIGINT,sigint);
 - }
 - 
 - void fixexit(int x) {
 -   printf("\0337\033[r\0338");
 -   exit(x);
 - }
 - 
 - // Returns a son, or 0 if no move specified, or root to cause "help"
 - node *getusermove(void) {
 -   int i,j;
 -   node *t;
 -   char line[100],*m1,*m2;
 - 
 -   if (playing)
 -     printf("\033[1m%s's move?\033[0m ",root->who ? "Black" : "White");
 -   else
 -     printf("\033[1mCommand?\033[0m ");
 -   abortflag = 0;
 -   if (!fgets(line, sizeof(line), stdin)) {
 -     putchar('\n');
 -     if (feof(stdin)) fixexit(0);
 -     return 0;
 -   }
 -   for (m1 = line; *m1 && *m1<=' '; m1++);
 -   if (!*m1) return(0);
 -   m2 = m1+1;
 -   if (*m2) m2++;
 -   for (; *m2 && *m2<'0'; m2++);
 -   if (playing && m1[1]>='0' && m1[1]<='9') {
 -     i = decode(m1);
 -     j = decode(m2);
 -     if (i && j) for (t = root->son; t; t = t->brother)
 -       if (t->from == i && t->to == j) return(t);
 -     puts("Valid moves are:");
 -     m1[0] = 'L';
 -   }
 -   switch(toupper(m1[0])) {
 -   case 0: return(0);
 -   case 'A':
 -     if (playing) autoplay = 1;
 -     return(root);
 -   case 'C':
 -     puts(copyright);
 -     break;
 -   case 'D':
 -     debug = !debug;
 -     printf("Debug is now %s.", debug ? "on" : "off");
 -     break;
 -   case 'F':
 -     forcejumps = !forcejumps;
 -     printf("Forced jumps rule is now %s.",forcejumps ? "on" : "off");
 -     killnode(root->son); root->son = 0;
 -     return(0);
 -   case 'L':
 -     expandnode(root);
 -     if (playing) for (t = root->son; t; t = t->brother) dumpnode(t,1);
 -     break;
 -   case 'M':
 -     return(playing ? root : 0);
 -   case 'N':
 -     newgame();
 -     VT100board();
 -     return(0);
 -   case 'P':
 -     printf("I expect the following moves:\n");
 -     for (t = root->son; t; t = t->son) dumpnode(t,0);
 -     break;
 -   case 'Q':
 -     fixexit(0);
 -   case 'R':
 -     VT100board();
 -     break;
 -   case 'S':
 -     user = !user;
 -     return(root);
 -   case 'U':
 -     VT100move(undomove(),1);
 -     VT100move(undomove(),1);
 -     return(0);
 -   case '+':
 -     maxevaluate = maxnodes = 2*maxevaluate;
 -     goto J2;
 -   case '-':
 -     if (maxevaluate > 1)
 -       maxevaluate = maxnodes = maxevaluate/2;
 -   J2: printf("Moves evaluated set to %d.",maxevaluate);
 -     break;
 -   default:
 -     puts(
 - 	 "A(utoplay)\n"
 - 	 "C(opyright)\n"
 - 	 "D(ebug on/off)\n"
 - 	 "F(orce jumps rule on/off)\n"
 - 	 "L(ist legal moves)\n"
 - 	 "M(ake a move for me)\n"
 - 	 "N(ew game)\n"
 - 	 "P(redict next few moves)\n"
 - 	 "Q(uit)\n"
 - 	 "R(edraw screen)\n"
 - 	 "S(witch sides)\n"
 - 	 "U(ndo)\n"
 - 	 "+	- smarter\n"
 - 	 "-	- stupider");
 -     expandnode(root);
 -     for (t = root->son; t; t = t->brother) dumpnode(t,1);
 -   }
 -   return(0);
 - }
 - 
 - int VT100main() {
 -   signal(SIGINT,sigint);
 -   VT100board();
 -   for (;;) {
 -     if (playing) {
 -       expandnode(root);
 -       if (!root->son) {
 - 	printf("%s has no move.  Game over.",root->who ? "Black" : "White");
 - 	playing = autoplay = 0;
 -       }
 -     }
 -     node* move;
 -     if (playing && (autoplay || root->who == user)) {
 -       move = calcmove(root);
 -       if (move->value <= -30000) {
 -  	printf("%s resigns.", move->who ? "White" : "Black");
 -  	move = 0;
 -  	playing = autoplay = 0;
 -       }
 -     } else {
 -       move = getusermove();
 -       if (move == root) move = calcmove(root);
 -     }
 -     if (move) {
 -       dumpnode(move,0);
 -       domove(move);
 -       VT100move(move,0);
 -     }
 -   }
 - }
 - 
 - #endif
 - 
 - ////////////////////////////////////////////////////////////////
 - // fltk interface:
 - #ifdef FLTK
 - 
 - #include <FL/Fl.H>
 - #include <FL/Fl_Double_Window.H>
 - #include <FL/Fl_Bitmap.H>
 - #include <FL/fl_draw.H>
 - #include <FL/Fl_Menu_Item.H>
 - #include <FL/fl_ask.H>
 - 
 - //----------------------------------------------------------------
 - // old 4-level NeXT images have been seperated into bitmaps so they
 - // can be drawn with arbitrary colors and real transparency.  This is
 - // rather tedious and perhaps fltk should provide a direct support
 - // to do this:
 - 
 - #include "pixmaps/black_1.xbm"
 - #include "pixmaps/black_2.xbm"
 - #include "pixmaps/black_3.xbm"
 - #include "pixmaps/black_4.xbm"
 - #include "pixmaps/white_1.xbm"
 - #include "pixmaps/white_2.xbm"
 - #include "pixmaps/white_3.xbm"
 - #include "pixmaps/white_4.xbm"
 - #include "pixmaps/blackking_1.xbm"
 - #include "pixmaps/blackking_2.xbm"
 - #include "pixmaps/blackking_3.xbm"
 - #include "pixmaps/blackking_4.xbm"
 - #include "pixmaps/whiteking_1.xbm"
 - #include "pixmaps/whiteking_2.xbm"
 - #include "pixmaps/whiteking_3.xbm"
 - #include "pixmaps/whiteking_4.xbm"
 - 
 - Fl_Bitmap *bm[4][4];
 - 
 - void make_bitmaps() {
 -   if (bm[0][0]) return;
 -   bm[0][0] = new Fl_Bitmap(black_1_bits, black_1_width, black_1_height);
 -   bm[0][1] = new Fl_Bitmap(black_2_bits, black_1_width, black_1_height);
 -   bm[0][2] = new Fl_Bitmap(black_3_bits, black_1_width, black_1_height);
 -   bm[0][3] = new Fl_Bitmap(black_4_bits, black_1_width, black_1_height);
 -   bm[1][0] = new Fl_Bitmap(white_1_bits, black_1_width, black_1_height);
 -   bm[1][1] = new Fl_Bitmap(white_2_bits, black_1_width, black_1_height);
 -   bm[1][2] = new Fl_Bitmap(white_3_bits, black_1_width, black_1_height);
 -   bm[1][3] = new Fl_Bitmap(white_4_bits, black_1_width, black_1_height);
 -   bm[2][0] = new Fl_Bitmap(blackking_1_bits, black_1_width, black_1_height);
 -   bm[2][1] = new Fl_Bitmap(blackking_2_bits, black_1_width, black_1_height);
 -   bm[2][2] = new Fl_Bitmap(blackking_3_bits, black_1_width, black_1_height);
 -   bm[2][3] = new Fl_Bitmap(blackking_4_bits, black_1_width, black_1_height);
 -   bm[3][0] = new Fl_Bitmap(whiteking_1_bits, black_1_width, black_1_height);
 -   bm[3][1] = new Fl_Bitmap(whiteking_2_bits, black_1_width, black_1_height);
 -   bm[3][2] = new Fl_Bitmap(whiteking_3_bits, black_1_width, black_1_height);
 -   bm[3][3] = new Fl_Bitmap(whiteking_4_bits, black_1_width, black_1_height);
 - }
 - 
 - #define ISIZE black_1_width
 - 
 - void draw_piece(int which, int x, int y) {
 -   if (!fl_not_clipped(x,y,ISIZE,ISIZE)) return;
 -   switch (which) {
 -   case BLACK: which = 0; break;
 -   case WHITE: which = 1; break;
 -   case BLACKKING: which = 2; break;
 -   case WHITEKING: which = 3; break;
 -   default: return;
 -   }
 -   fl_color(FL_BLACK); bm[which][0]->draw(x, y);
 -   fl_color(FL_INACTIVE_COLOR); bm[which][1]->draw(x, y);
 -   fl_color(FL_SELECTION_COLOR); bm[which][2]->draw(x, y);
 -   fl_color(FL_WHITE); bm[which][3]->draw(x, y);
 - }
 - 
 - //----------------------------------------------------------------
 - 
 - class Board : public Fl_Double_Window {
 -   void draw();
 -   int handle(int);
 - public:
 -   void drag_piece(int, int, int);
 -   void drop_piece(int);
 -   void animate(node* move, int backwards);
 -   void computer_move(int);
 -   Board(int w, int h) : Fl_Double_Window(w,h) {color(15);}
 - };
 - 
 - #define BOXSIZE 52
 - #define BORDER 4
 - #define BOARDSIZE (8*BOXSIZE+BORDER)
 - #define BMOFFSET 5
 - 
 - static int erase_this;  // real location of dragging piece, don't draw it
 - static int dragging;	// piece being dragged
 - static int dragx;	// where it is
 - static int dragy;
 - static int showlegal;	// show legal moves
 - 
 - int squarex(int i) {return (usermoves(i,1)-'A')*BOXSIZE+BMOFFSET;}
 - int squarey(int i) {return (usermoves(i,2)-'1')*BOXSIZE+BMOFFSET;}
 - 
 - void Board::draw() {
 -   make_bitmaps();
 -   // -- draw the board itself
 -   fl_draw_box(box(),0,0,w(),h(),color());
 -   // -- draw all dark tiles
 -   fl_color((Fl_Color)10 /*107*/);
 -   int x; for (x=0; x<8; x++) for (int y=0; y<8; y++) {
 -     if (!((x^y)&1)) fl_rectf(BORDER+x*BOXSIZE, BORDER+y*BOXSIZE,
 - 			     BOXSIZE-BORDER, BOXSIZE-BORDER);
 -   }
 -   // -- draw outlines around the fileds
 -   fl_color(FL_DARK3);
 -   for (x=0; x<9; x++) {
 -     fl_rectf(x*BOXSIZE,0,BORDER,h());
 -     fl_rectf(0,x*BOXSIZE,w(),BORDER);
 -   }
 -   for (int j = 5; j < 40; j++) if (j != erase_this) {
 -     draw_piece(b[j], squarex(j), squarey(j));
 -   }
 -   if (showlegal) {
 -     fl_color(FL_WHITE);
 -     node* n;
 -     for (n = root->son; n; n = showlegal==2 ? n->son : n->brother) {
 -       int x1 = squarex(n->from)+BOXSIZE/2-5;
 -       int y1 = squarey(n->from)+BOXSIZE/2-5;
 -       int x2 = squarex(n->to)+BOXSIZE/2-5;
 -       int y2 = squarey(n->to)+BOXSIZE/2-5;
 -       fl_line(x1,y1,x2,y2);
 -       fl_push_matrix();
 -       fl_mult_matrix(x2-x1,y2-y1,y1-y2,x2-x1,x2,y2);
 -       fl_begin_polygon();
 -       fl_vertex(0,0);
 -       fl_vertex(-.3, .1);
 -       fl_vertex(-.3, -.1);
 -       fl_end_polygon();
 -       fl_pop_matrix();
 -     }
 -     int num = 1;
 -     fl_color(FL_BLACK);
 -     fl_font(FL_BOLD,10);
 -     for (n = root->son; n; n = showlegal==2 ? n->son : n->brother) {
 -       int x1 = squarex(n->from)+BOXSIZE/2-5;
 -       int y1 = squarey(n->from)+BOXSIZE/2-5;
 -       int x2 = squarex(n->to)+BOXSIZE/2-5;
 -       int y2 = squarey(n->to)+BOXSIZE/2-5;
 -       char buf[20]; sprintf(buf,"%d",num);
 -       fl_draw(buf, x1+int((x2-x1)*.85)-3, y1+int((y2-y1)*.85)+5);
 -       num++;
 -     }
 -   }
 -   if (dragging) draw_piece(dragging, dragx, dragy);
 - }
 - 
 - // drag the piece on square i to dx dy, or undo drag if i is zero:
 - void Board::drag_piece(int j, int dx, int dy) {
 -   dy = (dy&-2) | (dx&1); // make halftone shadows line up
 -   if (j != erase_this) drop_piece(erase_this); // should not happen
 -   if (!erase_this) { // pick up old piece
 -     dragx = squarex(j); dragy = squarey(j);
 -     erase_this = j;
 -     dragging = b[j];
 -   }
 -   if (dx != dragx || dy != dragy) {
 -     damage(FL_DAMAGE_ALL, dragx, dragy, ISIZE, ISIZE);
 -     damage(FL_DAMAGE_ALL, dx, dy, ISIZE, ISIZE);
 -   }
 -   dragx = dx;
 -   dragy = dy;
 - }
 - 
 - // drop currently dragged piece on square i
 - void Board::drop_piece(int j) {
 -   if (!erase_this) return; // should not happen!
 -   erase_this = 0;
 -   dragging = 0;
 -   int x = squarex(j);
 -   int y = squarey(j);
 -   if (x != dragx || y != dragy) {
 -     damage(4, dragx, dragy, ISIZE, ISIZE);
 -     damage(4, x, y, ISIZE, ISIZE);
 -   }
 - }
 - 
 - // show move (call this *before* the move, *after* undo):
 - void Board::animate(node* move, int backwards) {
 -   if (showlegal) {showlegal = 0; redraw();}
 -   if (!move) return;
 -   int f = move->from;
 -   int t = move->to;
 -   if (backwards) {int x = f; f = t; t = x;}
 -   int x1 = squarex(f);
 -   int y1 = squarey(f);
 -   int x2 = squarex(t);
 -   int y2 = squarey(t);
 -   const int STEPS=35;
 -   for (int j=0; j<STEPS; j++) {
 -     int x = x1+(x2-x1)*j/STEPS;
 -     int y = y1+(y2-y1)*j/STEPS;
 -     drag_piece(move->from,x,y);
 -     Fl::flush();
 -   }
 -   drop_piece(t);
 -   if (move->jump) redraw();
 - }
 - 
 - int busy; // causes pop-up abort menu
 - 
 - void Board::computer_move(int help) {
 -   if (!playing) return;
 -   cursor(FL_CURSOR_WAIT);
 -   Fl::flush();
 -   busy = 1; abortflag = 0;
 -   node* move = calcmove(root);
 -   busy = 0;
 -   if (move) {
 -     if (!help && move->value <= -30000) {
 -       fl_message("%s resigns", move->who ? "White" : "Black");
 -       playing = autoplay = 0;
 -       cursor(FL_CURSOR_DEFAULT);
 -       return;
 -     }
 -     animate(move,0);
 -     domove(move);
 -   }
 -   expandnode(root);
 -   if (!root->son) {
 -     fl_message("%s has no move", root->who ? "Black" : "White");
 -     playing = autoplay = 0;
 -   }
 -   if (!autoplay) cursor(FL_CURSOR_DEFAULT);
 - }
 - 
 - extern Fl_Menu_Item menu[];
 - extern Fl_Menu_Item busymenu[];
 - 
 - int Board::handle(int e) {
 -   if (busy) {
 -     const Fl_Menu_Item* m;
 -     switch(e) {
 -     case FL_PUSH:
 -       m = busymenu->popup(Fl::event_x(), Fl::event_y(), 0, 0, 0);
 -       if (m) m->do_callback(this, (void*)m);
 -       return 1;
 -     case FL_SHORTCUT:
 -       m = busymenu->test_shortcut();
 -       if (m) {m->do_callback(this, (void*)m); return 1;}
 -       return 0;
 -     default:
 -       return 0;
 -     }
 -   }
 -   node *t, *n;
 -   static int deltax, deltay;
 -   int dist;
 -   const Fl_Menu_Item* m;
 -   switch (e) {
 -   case FL_PUSH:
 -     if (Fl::event_button() > 1) {
 -       m = menu->popup(Fl::event_x(), Fl::event_y(), 0, 0, 0);
 -       if (m) m->do_callback(this, (void*)m);
 -       return 1;
 -     }
 -     if (playing) {
 -       expandnode(root);
 -       for (t = root->son; t; t = t->brother) {
 - 	int x = squarex(t->from);
 - 	int y = squarey(t->from);
 - 	if (Fl::event_inside(x,y,BOXSIZE,BOXSIZE)) {
 - 	  deltax = Fl::event_x()-x;
 - 	  deltay = Fl::event_y()-y;
 - 	  drag_piece(t->from,x,y);
 - 	  return 1;
 - 	}
 -       }
 -     }
 -     return 0;
 -   case FL_SHORTCUT:
 -     m = menu->test_shortcut();
 -     if (m) {m->do_callback(this, (void*)m); return 1;}
 -     return 0;
 -   case FL_DRAG:
 -     drag_piece(erase_this, Fl::event_x()-deltax, Fl::event_y()-deltay);
 -     return 1;
 -   case FL_RELEASE:
 -     // find the closest legal move he dropped it on:
 -     dist = 50*50; n = 0;
 -     for (t = root->son; t; t = t->brother) if (t->from==erase_this) {
 -       int d1 = Fl::event_x()-deltax-squarex(t->to);
 -       int d = d1*d1;
 -       d1 = Fl::event_y()-deltay-squarey(t->to);
 -       d += d1*d1;
 -       if (d < dist) {dist = d; n = t;}
 -     }
 -     if (!n) {drop_piece(erase_this); return 1;} // none found
 -     drop_piece(n->to);
 -     domove(n);
 -     if (showlegal) {showlegal = 0; redraw();}
 -     if (n->jump) redraw();
 -     computer_move(0);
 -     return 1;
 -   default:
 -     return 0;
 -   }
 - }
 - 
 - void quit_cb(Fl_Widget*, void*) {exit(0);}
 - 
 - int FLTKmain(int argc, char** argv) {
 -   Fl::visual(FL_DOUBLE|FL_INDEX);
 -   Board b(BOARDSIZE,BOARDSIZE);
 -   b.color(FL_BACKGROUND_COLOR);
 -   b.callback(quit_cb);
 -   b.show(argc,argv);
 -   return Fl::run();
 - } 
 - 
 - void autoplay_cb(Fl_Widget*bp, void*) {
 -   if (autoplay) {autoplay = 0; return;}
 -   if (!playing) return;
 -   Board* b = (Board*)bp;
 -   autoplay = 1;
 -   while (autoplay) {b->computer_move(0); b->computer_move(0);}
 - }
 - 
 - #include <FL/Fl_Box.H>
 - Fl_Window *copyright_window;
 - void copyright_cb(Fl_Widget*, void*) {
 -   if (!copyright_window) {
 -     copyright_window = new Fl_Window(400,270,"Copyright");
 -     copyright_window->color(FL_WHITE);
 -     Fl_Box *b = new Fl_Box(20,0,380,270,copyright);
 -     b->labelsize(10);
 -     b->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE|FL_ALIGN_WRAP);
 -     copyright_window->end();
 -   }
 -   copyright_window->hotspot(copyright_window);
 -   copyright_window->set_non_modal();
 -   copyright_window->show();
 - }
 - 
 - void debug_cb(Fl_Widget*, void*v) {
 -   debug = !debug;
 -   ((Fl_Menu_Item*)v)->flags =
 -     debug ? FL_MENU_TOGGLE|FL_MENU_VALUE : FL_MENU_TOGGLE;
 - }
 - 
 - void forced_cb(Fl_Widget*b, void*v) {
 -   forcejumps = !forcejumps;
 -   ((Fl_Menu_Item*)v)->flags =
 -     forcejumps ? FL_MENU_TOGGLE|FL_MENU_VALUE : FL_MENU_TOGGLE;
 -   killnode(root->son); root->son = 0;
 -   if (showlegal) {expandnode(root); b->redraw();}
 - }
 - 
 - void move_cb(Fl_Widget*pb, void*) {
 -   Board* b = (Board*)pb;
 -   if (playing) b->computer_move(1);
 -   if (playing) b->computer_move(0);
 - }
 - 
 - void newgame_cb(Fl_Widget*b, void*) {
 -   showlegal = 0;
 -   newgame();
 -   b->redraw();
 - }
 - 
 - void legal_cb(Fl_Widget*pb, void*) {
 -   if (showlegal == 1) {showlegal = 0; ((Board*)pb)->redraw(); return;}
 -   if (!playing) return;
 -   expandnode(root);
 -   showlegal = 1; ((Board*)pb)->redraw();
 - }
 - 
 - void predict_cb(Fl_Widget*pb, void*) {
 -   if (showlegal == 2) {showlegal = 0; ((Board*)pb)->redraw(); return;}
 -   if (playing) expandnode(root);
 -   showlegal = 2; ((Board*)pb)->redraw();
 - }
 - 
 - void switch_cb(Fl_Widget*pb, void*) {
 -   user = !user;
 -   ((Board*)pb)->computer_move(0);
 - }
 - 
 - void undo_cb(Fl_Widget*pb, void*) {
 -   Board* b = (Board*)pb;
 -   b->animate(undomove(),1);
 -   b->animate(undomove(),1);
 - }
 - 
 - //--------------------------
 - 
 - #include <FL/Fl_Slider.H>
 - #include <FL/Fl_Value_Output.H>
 - 
 - Fl_Window *intel_window;
 - Fl_Value_Output *intel_output;
 - 
 - void intel_slider_cb(Fl_Widget*w, void*) {
 -   double v = ((Fl_Slider*)w)->value();
 -   int n = int(v*v);
 -   intel_output->value(n);
 -   maxevaluate = maxnodes = n;
 - }
 - 
 - void intel_cb(Fl_Widget*, void*) {
 -   if (!intel_window) {
 -     intel_window = new Fl_Window(200,25,"Checkers Intelligence");
 -     Fl_Slider* s = new Fl_Slider(60,0,140,25);
 -     s->type(FL_HOR_NICE_SLIDER);
 -     s->minimum(1); s->maximum(500); s->value(50);
 -     s->callback(intel_slider_cb);
 -     intel_output = new Fl_Value_Output(0,0,60,25);
 -     intel_output->value(maxevaluate);
 -     intel_window->resizable(s);
 -   }
 -   intel_window->hotspot(intel_window);
 -   intel_window->set_non_modal();
 -   intel_window->show();
 - }
 - 
 - //---------------------------
 - 
 - void stop_cb(Fl_Widget*, void*) {abortflag = 1;}
 - 
 - void continue_cb(Fl_Widget*, void*) {}
 - 
 - Fl_Menu_Item menu[] = {
 -   {"Autoplay", 'a', autoplay_cb},
 -   {"Legal moves", 'l', legal_cb},
 -   {"Move for me", 'm', move_cb},
 -   {"New game", 'n', newgame_cb},
 -   {"Predict", 'p', predict_cb},
 -   {"Switch sides", 's', switch_cb},
 -   {"Undo", 'u', undo_cb, 0, FL_MENU_DIVIDER},
 -   {"Forced jumps rule", 'f', forced_cb, 0, FL_MENU_TOGGLE|FL_MENU_VALUE},
 -   {"Debug", 'd', debug_cb, (void *)"d", FL_MENU_TOGGLE},
 -   {"Intelligence...", 'i', intel_cb, 0, FL_MENU_DIVIDER},
 -   {"Copyright", 'c', copyright_cb},
 -   {"Quit", 'q', quit_cb},
 -   {0}};
 - 
 - Fl_Menu_Item busymenu[] = {
 -   {"Stop", '.', stop_cb},
 -   {"Autoplay", 'a', autoplay_cb},
 -   {"Continue", 0, continue_cb},
 -   {"Debug", 'd', debug_cb, (void *)"d", FL_MENU_TOGGLE},
 -   {"Intelligence...", 'i', intel_cb},
 -   {"Copyright", 'c', copyright_cb},
 -   {"Quit", 'q', quit_cb},
 -   {0}};
 - 
 - #endif
 - 
 - ////////////////////////////////////////////////////////////////
 - // parts shared by both interface:
 - 
 - #ifdef FLTK
 - #ifdef VT100
 - #define BOTH
 - #endif
 - #endif
 - 
 - #ifdef BOTH
 - int terminal;
 - int arg(int, char **argv, int &i) {
 -   if (argv[i][1] == 't') {terminal = 1; i++; return 1;}
 -   return 0;
 - }
 - #endif
 - 
 - int didabort(void) {
 - #ifdef FLTK
 - #ifdef BOTH
 -   if (!terminal)
 - #endif
 -     Fl::check();
 - #endif
 -   if (abortflag) {
 -     autoplay = 0;
 -     abortflag = 0;
 -     return 1;
 -   }
 -   return(0);
 - }
 - 
 - int main(int argc, char **argv) {
 -   seed = time(0);
 -   newgame();
 - #ifdef BOTH
 -   int i = 1;
 -   if (Fl::args(argc, argv, i, arg) < argc) {
 -     fprintf(stderr," -t : use VT100 display\n", Fl::help);
 -     exit(1);
 -   }
 -   if (!getenv("DISPLAY")) terminal = 1;
 -   if (!terminal)
 - #endif
 - #ifdef FLTK
 -     return FLTKmain(argc,argv);
 - #endif
 - #ifdef VT100
 -   return VT100main();
 - #endif
 - }
 - 
 - //
 - // End of "$Id: checkers.cxx 8168 2011-01-02 03:55:23Z matt $".
 - //
 
 
  |