Blame test/checkers.cxx

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