home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD Direkt: Spezial 1
/
CDD_SPIELE_.ISO
/
wingames
/
chess_1
/
search.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-08-16
|
45KB
|
1,670 lines
/*
C source for GNU CHESS
Revision: 1990-12-26
Modified by Daryl Baker for use in MS WINDOWS environment
Copyright (C) 1986, 1987, 1988, 1989, 1990 Free Software Foundation, Inc.
Copyright (c) 1988, 1989, 1990 John Stanback
This file is part of CHESS.
CHESS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY. No author or distributor accepts responsibility to anyone for
the consequences of using it or for whether it serves any particular
purpose or works at all, unless he says so in writing. Refer to the CHESS
General Public License for full details.
Everyone is granted permission to copy, modify and redistribute CHESS, but
only under the conditions described in the CHESS General Public License.
A copy of this license is supposed to have been given to you along with
CHESS so you can know your rights and responsibilities. It should be in a
file named COPYING. Among other things, the copyright notice and this
notice must be preserved on all copies.
*/
#define NOATOM
#define NOCLIPBOARD
#define NOCREATESTRUCT
#define NOFONT
#define NOREGION
#define NOSOUND
#define NOWH
#define NOWINOFFSETS
#define NOCOMM
#define NOKANJI
#include <windows.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <malloc.h>
#include <stdio.h>
#include "gnuchess.h"
#include "defs.h"
#if ttblsz
extern unsigned long hashkey, hashbd;
/*extern struct hashval hashcode[2][7][64];*/
/*extern struct hashentry huge ttable[2][ttblsz];*/
extern struct hashval far *hashcode;
extern struct hashentry far *ttable;
#endif /* ttblsz */
/*extern unsigned char history[8192];*/
extern unsigned char far * history;
extern short rpthash[2][256];
/*extern unsigned char nextpos[8][64][64];*/
/*extern unsigned char nextdir[8][64][64];*/
extern unsigned char far *nextpos;
extern unsigned char far *nextdir;
extern short FROMsquare, TOsquare, Zscore, zwndw;
extern unsigned short PV, Swag0, Swag1, Swag2, Swag3, Swag4;
extern unsigned short killr0[maxdepth], killr1[maxdepth];
extern unsigned short killr2[maxdepth], killr3[maxdepth];
extern short Pscore[maxdepth], Tscore[maxdepth];
extern unsigned long hashkey, hashbd;
extern short ChkFlag[maxdepth], CptrFlag[maxdepth], PawnThreat[maxdepth];
extern short mtl[2], pmtl[2], emtl[2], hung[2];
extern short player, xwndw, rehash;
extern short PieceCnt[2];
extern long NodeCnt, ETnodes, EvalNodes, HashCnt, FHashCnt, HashCol;
extern short HasKnight[2], HasBishop[2], HasRook[2], HasQueen[2];
extern short Pindex[64];
static short _based(_segname("_CODE")) rank7[3] = {6, 1, 0};
static short _based(_segname("_CODE")) kingP[3] = {4, 60, 0};
static short _based(_segname("_CODE")) value[7] =
{0, valueP, valueN, valueB, valueR, valueQ, valueK};
static short _based(_segname("_CODE")) sweep[8] =
{false, false, false, true, true, true, false, false};
static short _based(_segname("_CODE")) ptype[2][8] = {
no_piece, pawn, knight, bishop, rook, queen, king, no_piece,
no_piece, bpawn, knight, bishop, rook, queen, king, no_piece};
static short _based(_segname("_CODE")) control[7] =
{0, ctlP, ctlN, ctlB, ctlR, ctlQ, ctlK};
/* ............ MOVE GENERATION & SEARCH ROUTINES .............. */
void
pick (short int p1, short int p2)
/*
Find the best move in the tree between indexes p1 and p2. Swap the best
move into the p1 element.
*/
{
register short p, s;
short p0, s0;
struct leaf temp;
s0 = Tree[p1].score;
p0 = p1;
for (p = p1 + 1; p <= p2; p++)
if ((s = Tree[p].score) > s0)
{
s0 = s;
p0 = p;
}
if (p0 != p1)
{
temp = Tree[p1];
Tree[p1] = Tree[p0];
Tree[p0] = temp;
}
}
void
SelectMove (HWND hWnd, short int side, short int iop)
/*
Select a move by calling function search() at progressively deeper ply
until time is up or a mate or draw is reached. An alpha-beta window of -90
to +90 points is set around the score returned from the previous
iteration. If Sdepth != 0 then the program has correctly predicted the
opponents move and the search will start at a depth of Sdepth+1 rather
than a depth of 1.
*/
{
static short i, tempb, tempc, tempsf, tempst, xside, rpt;
static short alpha, beta, score;
flag.timeout = false;
xside = otherside[side];
if (iop != 2)
player = side;
if (TCflag)
{
if ((TimeControl.moves[side] + 3) != 0)
ResponseTime = (TimeControl.clock[side]) /
(TimeControl.moves[side] + 3) -
OperatorTime;
else
ResponseTime = 0;
ResponseTime += (ResponseTime * TimeControl.moves[side]) / (2 * TCmoves + 1);
}
else
ResponseTime = Level;
if (iop == 2)
ResponseTime = 99999;
if (Sdepth > 0 && root->score > Zscore - zwndw)
ResponseTime -= ft;
else if (ResponseTime < 1)
ResponseTime = 1;
ExtraTime = 0;
ExaminePosition ();
ScorePosition (side, &score);
/* Pscore[0] = -score; */
ShowSidetoMove ();
if (Sdepth == 0)
{
#if ttblsz
/* ZeroTTable (); */
#endif /* ttblsz */
SearchStartStuff (side);
#ifdef NOMEMSET
for (i = 0; i < 8192; i++)
/* history[i] = 0; */
*(history+i) = 0;
#else
_fmemset ( history, 0, 8192 * sizeof (char));
#endif /* NOMEMSET */
FROMsquare = TOsquare = -1;
PV = 0;
if (iop != 2)
hint = 0;
for (i = 0; i < maxdepth; i++)
PrVar[i] = killr0[i] = killr1[i] = killr2[i] = killr3[i] = 0;
alpha = score - 90;
beta = score + 90;
rpt = 0;
TrPnt[1] = 0;
root = &Tree[0];
MoveList (side, 1);
for (i = TrPnt[1]; i < TrPnt[2]; i++)
pick (i, TrPnt[2] - 1);
if (Book != NULL)
OpeningBook (&hint);
if (Book != NULL)
flag.timeout = true;
NodeCnt = ETnodes = EvalNodes = HashCnt = FHashCnt = HashCol = 0;
Zscore = 0;
zwndw = 20;
}
while (!flag.timeout && Sdepth < MaxSearchDepth)
{
Sdepth++;
ShowDepth (' ');
score = search (hWnd, side, 1, Sdepth, alpha, beta, PrVar, &rpt);
for (i = 1; i <= Sdepth; i++)
killr0[i] = PrVar[i];
if (score < alpha)
{
ShowDepth ('\xbb' /*'-'*/);
ExtraTime = 10 * ResponseTime;
/* ZeroTTable (); */
score = search (hWnd, side, 1, Sdepth, -9000, score, PrVar, &rpt);
}
if (score > beta && !(root->flags & exact))
{
ShowDepth ('\xab' /*'+'*/);
ExtraTime = 0;
/* ZeroTTable (); */
score = search (hWnd, side, 1, Sdepth, score, 9000, PrVar, &rpt);
}
score = root->score;
if (!flag.timeout)
for (i = TrPnt[1] + 1; i < TrPnt[2]; i++)
pick (i, TrPnt[2] - 1);
ShowResults (score, PrVar, '\xb7' /*'.'*/);
for (i = 1; i <= Sdepth; i++)
killr0[i] = PrVar[i];
if (score > Zscore - zwndw && score > Tree[1].score + 250)
ExtraTime = 0;
else if (score > Zscore - 3 * zwndw)
ExtraTime = ResponseTime;
else
ExtraTime = 3 * ResponseTime;
if (root->flags & exact)
flag.timeout = true;
if (Tree[1].score < -9000)
flag.timeout = true;
if (4 * et > 2 * ResponseTime + ExtraTime)
flag.timeout = true;
if (!flag.timeout)
{
Tscore[0] = score;
if (Zscore == 0)
Zscore = score;
else
Zscore = (Zscore + score) / 2;
}
zwndw = 20 + abs (Zscore / 12);
beta = score + Bwindow;
if (Zscore < score)
alpha = Zscore - Awindow - zwndw;
else
alpha = score - Awindow - zwndw;
}
score = root->score;
if (rpt >= 2 || score < -12000)
root->flags |= draw;
if (iop == 2)
return;
if (Book == NULL)
hint = PrVar[2];
ElapsedTime (1);
if (score > -9999 && rpt <= 2)
{
MakeMove (side, root, &tempb, &tempc, &tempsf, &tempst, &INCscore);