#ifndef _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE 1
#endif
#include
<iostream>
#include
"defines.h"
#include
"protos.h"
#include
"extglobals.h"
#include
"board.h"
#include "timer.h"
void readCommands()
{
int nextc;
if (board.nextMove
== WHITE_MOVE)
{
std::cout
<< "wt> ";
}
else
{
std::cout
<< "bl> ";
}
std::cout.flush();
//
===========================================================================
// Read a command and call doCommand:
//
===========================================================================
while ((nextc
= getc(stdin)) != EOF)
{
if (nextc
== '\n')
{
CMD_BUFF[CMD_BUFF_COUNT] = '\0';
while (CMD_BUFF_COUNT)
{
if
(!doCommand(CMD_BUFF)) return;
}
if (board.nextMove
== WHITE_MOVE)
{
std::cout << "wt> ";
}
else
{
std::cout << "bl> ";
}
std::cout.flush();
}
else
{
if (CMD_BUFF_COUNT
>= MAX_CMD_BUFF-1)
{
std::cout << "Warning: command
buffer full !! " << std::endl;
CMD_BUFF_COUNT = 0;
}
CMD_BUFF[CMD_BUFF_COUNT++] =
nextc;
}
}
}
BOOLTYPE doCommand(const
char
*buf)
{
Move move;
Timer timer;
U64 msStart;
U64 msStop;
U64 perftcount;
char
userinput[80];
int i,
number;
//
=================================================================
// return when command buffer is empty
//
=================================================================
if (!strcmp(buf,
""))
{
CMD_BUFF_COUNT =
'\0';
return
true;
}
//
=================================================================
// help, h, or ?: show this help
//
=================================================================
if ((!strcmp(buf,
"help"))
|| (!strcmp(buf, "h"))
|| (!strcmp(buf, "?")))
{
std::cout <<
std::endl << "help:"
<< std::endl;
std::cout <<
"black : BLACK to
move" << std::endl;
std::cout <<
"cc : play
computer-to-computer " << std::endl;
std::cout <<
"d : display
board " << std::endl;
std::cout <<
"exit : exit
program " << std::endl;
std::cout <<
"eval : show
static evaluation of this position" <<
std::endl;
std::cout <<
"game : show game
moves " << std::endl;
std::cout <<
"go : computer
next move " << std::endl;
std::cout <<
"help, h, or ? : show this
help " << std::endl;
std::cout <<
"info : display
variables (for testing purposes)" <<
std::endl;
std::cout <<
"move e2e4, or h7h8q : enter a
move (use this format)" << std::endl;
std::cout <<
"moves : show all
legal moves" << std::endl;
std::cout <<
"new : start new
game" << std::endl;
std::cout <<
"perf : benchmark
a number of key functions" << std::endl;
std::cout <<
"perft n : calculate
raw number of nodes from here, depth n "
<< std::endl;
std::cout <<
"quit : exit
program " << std::endl;
std::cout <<
"r : rotate
board " << std::endl;
std::cout <<
"readfen filename n : reads #-th
FEN position from filename" <<
std::endl;
std::cout <<
"sd n : set the
search depth to n" << std::endl;
std::cout <<
"setup : setup
board... " << std::endl;
std::cout <<
"undo : take back
last move" << std::endl;
std::cout <<
"white : WHITE to
move" << std::endl;
std::cout << std::endl;
CMD_BUFF_COUNT =
'\0';
return
true;
}
//
=================================================================
// black: black to move
//
=================================================================
if
(!strcmp(buf, "black"))
{
board.nextMove = BLACK_MOVE;
CMD_BUFF_COUNT =
'\0';
return
true;
}
//
=================================================================
// d: display board
//
=================================================================
if (!strcmp(buf,
"d"))
{
board.display();
CMD_BUFF_COUNT =
'\0';
return
true;
}
//
=================================================================
// exit or quit: exit program
//
=================================================================
if ((!strcmp(buf,
"exit"))
|| (!strcmp(buf, "quit")))
{
CMD_BUFF_COUNT =
'\0';
return
false;
}
//
=================================================================
// info: display variables (for testing purposes)
//
=================================================================
if (!strcmp(buf,
"info"))
{
info();
CMD_BUFF_COUNT =
'\0';
return
true;
}
//
=================================================================
// game: show game moves
//
=================================================================
if (!strcmp(buf,
"game"))
{
if (board.endOfGame)
{
for
(i = 0 ; i < board.endOfGame ; i++)
{
std::cout << i+1 <<
". ";
displayMove(board.gameLine[i].move);
std::cout <<std::endl;
}
}
else
{
std::cout <<
"there are no game moves" <<
std::endl;
}
CMD_BUFF_COUNT =
'\0';
return
true;
}
//
=================================================================
// moves: show all legal moves
//
=================================================================
if (!strcmp(buf,
"moves"))
{
board.moveBufLen[0] = 0;
board.moveBufLen[1] =
movegen(board.moveBufLen[0]);
std::cout << std::endl <<
"moves from this position:" <<
std::endl;
for (i =
board.moveBufLen[0]; i < board.moveBufLen[1]; i++)
{
makeMove(board.moveBuffer[i]);
if
(isOtherKingAttacked())
{
unmakeMove(board.moveBuffer[i]);
}
else
{
std::cout << i+1 <<
". " ;
displayMove(board.moveBuffer[i]);
std::cout << std::endl;
unmakeMove(board.moveBuffer[i]);
}
}
CMD_BUFF_COUNT =
'\0';
return
true;
}
//
=================================================================
// move (do a move) [console mode only]
//
=================================================================
if (!strncmp(buf,
"move", 4))
{
sscanf(buf+4,"%s",userinput);
// generate
the pseudo-legal move list
board.moveBufLen[0] = 0;
board.moveBufLen[1] =
movegen(board.moveBufLen[0]);
if (isValidTextMove(userinput,
move)) // check to see if the user
move is also found in the pseudo-legal move list
{
makeMove(move);
if
(isOtherKingAttacked()) //
post-move check to see if we are leaving our king in check
{
unmakeMove(move);
std::cout <<
" invalid move, leaving king in
check: " << userinput << std::endl;
}
else
{
board.endOfGame++;
board.endOfSearch =
board.endOfGame;
board.display();
}
}
else
{
std::cout <<
" move is invalid or not recognized:
" << userinput << std::endl;
}
CMD_BUFF_COUNT =
'\0';
return
true;
}
//
=================================================================
// new: start new game
//
=================================================================
if (!strcmp(buf,
"new"))
{
dataInit();
board.init();
board.display();
CMD_BUFF_COUNT =
'\0';
return
true;
}
//
=================================================================
// perft n : calculate raw number of
nodes from here, depth n
//
=================================================================
if (!strncmp(buf,
"perft", 5))
{
sscanf(buf+5,"%d",
&number);
std::cout <<
" starting perft " << number
<< "..." << std::endl;
timer.init();
board.moveBufLen[0] = 0;
#ifdef WINGLET_DEBUG_PERFT
ICAPT = 0;
IEP = 0;
IPROM = 0;
ICASTLOO = 0;
ICASTLOOO = 0;
ICHECK = 0;
#endif
msStart = timer.getms();
perftcount = perft(0, number);
msStop = timer.getms();
std::cout <<
"nodes = " << perftcount
<< ", " << msStop - msStart <<
" ms, ";
if ((msStop
- msStart) > 0)
std::cout << (perftcount/(msStop
- msStart)) << " knods/s";
std::cout << std::endl;
CMD_BUFF_COUNT =
'\0';
#ifdef WINGLET_DEBUG_PERFT
std::cout <<
"captures = " << ICAPT <<
std::endl;
std::cout <<
"en-passant = " << IEP <<
std::endl;
std::cout <<
"castlings = " << ICASTLOO +
ICASTLOOO << std::endl;
std::cout <<
"promotions = " << IPROM <<
std::endl;
std::cout <<
"checks = " << ICHECK <<
std::endl;
#endif
return
true;
}
//
=================================================================
// r: rotate board
//
=================================================================
if (!strcmp(buf,
"r"))
{
board.viewRotated = !board.viewRotated;
board.display();
CMD_BUFF_COUNT =
'\0';
return
true;
}
//
=================================================================
// readfen filename n : reads #-th FEN position from filename
//
=================================================================
if (!strncmp(buf,
"readfen",
7))
{
sscanf(buf+7,"%s
%d", userinput, &number);
board.init();
readFen(userinput, number);
board.display();
CMD_BUFF_COUNT =
'\0';
return
true;
}
//
=================================================================
// setup : setup board...
//
=================================================================
if (!strncmp(buf,
"setup",
5))
{
setup();
CMD_BUFF_COUNT =
'\0';
return
true;
}
//
=================================================================
// undo: take back last move
//
=================================================================
if (!strcmp(buf,
"undo"))
{
if (board.endOfGame)
{
unmakeMove(board.gameLine[--board.endOfGame].move);
board.endOfSearch =
board.endOfGame;
board.display();
}
else
{
std::cout <<
"already at start of game" <<
std::endl;
}
CMD_BUFF_COUNT =
'\0';
return
true;
}
//
=================================================================
// white: white to move
//
=================================================================
if (!strcmp(buf,
"white"))
{
board.nextMove = WHITE_MOVE;
CMD_BUFF_COUNT =
'\0';
return
true;
}
//
=================================================================
// unknown command
//
=================================================================
std::cout <<
" command not implemented: "
<< buf << ", type 'help' for
more info" << std::endl;
CMD_BUFF_COUNT =
'\0';
return
true;
}
#ifndef WINGLET_DEFINES_H
#define WINGLET_DEFINES_H
#define WINGLET_PROG_VERSION
"winglet 0.0, Copyright (C) 2011, Stef Luijten"
//#define WINGLET_DEBUG_PERFT
//#define WINGLET_DEBUG_MOVES
typedef
unsigned
long
long
U64;
typedef
unsigned
long
long
BitMap;
typedef
short SHORTINT;
typedef
unsigned
short USHORTINT;
typedef
int BOOLTYPE;
#define MAX_CMD_BUFF 256
//
Console command input buffer
#define MAX_MOV_BUFF 4096
//
Number of moves that we can store (all plies)
#define MAX_PLY 64
// Search depth
#define MAX_GAME_LINE 1024
// Number of moves in the (game + search) line that we can store
#endif
#ifndef WINGLET_PROTOS_H
#define WINGLET_PROTOS_H
#include "board.h"
#include
"move.h"
unsigned
int bitCnt(BitMap);
void dataInit();
void displayBitmap(BitMap);
void displayMove(Move &);
BOOLTYPE doCommand(const
char *);
unsigned
int
firstOne(BitMap);
void info();
BOOLTYPE isAttacked(BitMap &,
const
unsigned
char &);
BOOLTYPE isValidTextMove(char
*, Move &);
BOOLTYPE isOtherKingAttacked();
BOOLTYPE isOwnKingAttacked();
unsigned
int lastOne(BitMap);
void makeBlackPromotion(unsigned
int,
unsigned int &);
void makeCapture(unsigned
int &,
unsigned int &);
void makeMove(Move &);
void makeWhitePromotion(unsigned
int,
unsigned int &);
void movegen();
U64 perft(int,
int);
void readCommands();
BOOLTYPE readFen(char
*, int);
void setup();
void setupFen(char *,
char *,
char *,
char *,
int ,
int
);
void unmakeBlackPromotion(unsigned
int,
unsigned int &);
void unmakeCapture(unsigned
int &,
unsigned int &);
void unmakeMove(Move &);
void unmakeWhitePromotion(unsigned
int,
unsigned int &);
#endif

√
try "perft n", use small values of n (4 to 6).
Here are some test positions with results.
√
try making moves with the "move" command, for
instance "move e2e4".
√
this is also a good time to try out different compile
options, or compare 32-bit with 64-bit executables (in case
you have a 64-bit machine). Perft will give you an
indication of the differences in speed for movegen and (un)makemove.
And if you're adventurous you can try out different ways of
storing moves.
|
|