#ifndef _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE
#endif
#include
<conio.h>
#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, dummy;
char
sanMove[12];
Timer timer;
U64 msStart;
U64 msStop;
U64 perftcount;
char
userinput[80];
int i, j,
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 <<
"time s : time per move in
seconds" << 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"))
{
if (board.nextMove
== WHITE_MOVE)
{
board.endOfSearch = 0;
board.endOfGame = 0;
}
board.nextMove = BLACK_MOVE;
CMD_BUFF_COUNT =
'\0';
return
true;
}
//
=================================================================
// cc: play computer-to-computer
//
=================================================================
if (!strcmp(buf,
"cc"))
{
while
(!_kbhit() && !board.isEndOfgame(i, dummy))
{
move = board.think();
if
(move.moveInt)
{
makeMove(move);
board.endOfGame++;
board.endOfSearch =
board.endOfGame;
board.display();
}
else
{
CMD_BUFF_COUNT =
'\0';
return true;
}
}
CMD_BUFF_COUNT =
'\0';
return
true;
}
// =================================================================
// d: display board
// =================================================================
if (!strcmp(buf,
"d"))
{
board.display();
CMD_BUFF_COUNT =
'\0';
return
true;
}
// =================================================================
// eval (do a static evaluation of the board)
// =================================================================
if (!strcmp(buf,
"eval"))
{
number = board.eval();
std::cout <<
"eval score = "
<< number << std::endl;
#ifdef
WINGLET_DEBUG_EVAL
board.mirror();
board.display();
i = board.eval();
std::cout
<< "eval score = "
<< i << std::endl;
board.mirror();
if (number
!= i) std::cout << "evaluation
is not symmetrical! " << number <<
std::endl;
else
std::cout << "evaluation is
symmetrical" << std::endl;
#endif
CMD_BUFF_COUNT =
'\0';
return
true;
}
// =================================================================
// exit or quit: exit program
// =================================================================
if ((!strcmp(buf,
"exit"))
|| (!strcmp(buf, "quit")))
{
CMD_BUFF_COUNT =
'\0';
return
false;
}
//
=================================================================
// game: show game moves
//
=================================================================
if (!strcmp(buf,
"game"))
{
if (board.endOfGame)
{
//
make a temporary copy of board.gameLine[];
number = board.endOfGame;
GameLineRecord *tmp =
new GameLineRecord[number];
memcpy(tmp, board.gameLine,
number * sizeof(GameLineRecord));
//
unmake all moves:
for
(i = number-1 ; i >= 0 ; i--)
{
unmakeMove(tmp[i].move);
board.endOfSearch = --board.endOfGame;
}
//
redo all moves:
j = board.nextMove;
for
(i = 0 ; i < number; i++)
{
// move numbering:
if (!((i+j+2)%2)) std::cout << (i+2*j+2)/2 <<
". ";
else if (!i) std::cout <<
"1. ... ";
// construct the move string
toSan(tmp[i].move,
sanMove);
std::cout << sanMove;
// output CRLF, or space:
if (!((i+j+1)%2)) std::cout << std::endl;
else std::cout << " ";
// make the move:
makeMove(tmp[i].move);
board.endOfSearch = ++board.endOfGame;
}
std::cout << std::endl;
//
delete the temporary copy:
delete[]
tmp;
}
else
{
std::cout <<
"there are no game moves" <<
std::endl;
}
CMD_BUFF_COUNT =
'\0';
return
true;
}
//
=================================================================
// go: computer next move
//
=================================================================
if (!strcmp(buf,
"go"))
{
if (!board.isEndOfgame(i,
dummy))
{
move = board.think();
if
(move.moveInt)
{
makeMove(move);
board.endOfGame++;
board.endOfSearch =
board.endOfGame;
}
board.display();
board.isEndOfgame(i, dummy);
CMD_BUFF_COUNT =
'\0';
return
true;
}
else
{
board.display();
CMD_BUFF_COUNT =
'\0';
return
true;
}
}
// =================================================================
// info: display variables (for testing purposes)
// =================================================================
if (!strcmp(buf,
"info"))
{
info();
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;
number = 0;
for (i
= board.moveBufLen[0]; i < board.moveBufLen[1]; i++)
{
makeMove(board.moveBuffer[i]);
if
(isOtherKingAttacked())
{
unmakeMove(board.moveBuffer[i]);
}
else
{
unmakeMove(board.moveBuffer[i]);
toSan(board.moveBuffer[i],
sanMove);
std::cout << ++number <<
". " << sanMove << std::endl;
}
}
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"))
{
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;
}
// =================================================================
// sd n: set the search depth to n
// =================================================================
if
(!strncmp(buf, "sd",
2))
{
sscanf(buf+2,"%d",
&board.searchDepth);
std::cout <<
"winglet> search depth "
<< board.searchDepth << std::endl;
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"))
{
if (board.nextMove
== BLACK_MOVE)
{
board.endOfSearch = 0;
board.endOfGame = 0;
}
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;
}
(...)
//
===========================================================================
// Initialize MIRRORed data:
//
===========================================================================
// Data is supplied as mirrored for
WHITE, so it's ready for BLACK to use:
for
(square = 0; square < 64; square++)
{
PAWNPOS_B[square] = PAWNPOS_W[square];
KNIGHTPOS_B[square] =
KNIGHTPOS_W[square];
BISHOPPOS_B[square] =
BISHOPPOS_W[square];
ROOKPOS_B[square] = ROOKPOS_W[square];
QUEENPOS_B[square] = QUEENPOS_W[square];
KINGPOS_B[square] = KINGPOS_W[square];
KINGPOS_ENDGAME_B[square] =
KINGPOS_ENDGAME_W[square];
}
// Complete missing mirrored data:
for (i =
0; i < 64; i++)
{
PAWNPOS_W[i] = PAWNPOS_B[MIRROR[i]];
KNIGHTPOS_W[i] = KNIGHTPOS_B[MIRROR[i]];
BISHOPPOS_W[i] = BISHOPPOS_B[MIRROR[i]];
ROOKPOS_W[i] = ROOKPOS_B[MIRROR[i]];
QUEENPOS_W[i] = QUEENPOS_B[MIRROR[i]];
KINGPOS_W[i] = KINGPOS_B[MIRROR[i]];
KINGPOS_ENDGAME_W[i] =
KINGPOS_ENDGAME_B[MIRROR[i]];
for
(square = 0; square < 64; square ++)
{
// PASSED_BLACK bitmaps (mirror of
PASSED_WHITE bitmaps):
if (PASSED_WHITE[i]
& BITSET[square]) PASSED_BLACK[MIRROR[i]] |= BITSET[MIRROR[square]];
// ISOLATED_BLACK bitmaps (mirror of
ISOLATED_WHITE bitmaps):
if (ISOLATED_WHITE[i]
& BITSET[square]) ISOLATED_BLACK[MIRROR[i]] |= BITSET[MIRROR[square]];
// BACKWARD_BLACK bitmaps (mirror of
BACKWARD_WHITE bitmaps):
if (BACKWARD_WHITE[i]
& BITSET[square]) BACKWARD_BLACK[MIRROR[i]] |= BITSET[MIRROR[square]];
// KINGSHIELD_STRONG_B bitmaps (mirror
of KINGSHIELD_STRONG_W bitmaps):
if (KINGSHIELD_STRONG_W[i]
& BITSET[square]) KINGSHIELD_STRONG_B[MIRROR[i]] |=
BITSET[MIRROR[square]];
// KINGSHIELD_WEAK_B bitmaps (mirror
of KINGSHIELD_WEAK_W bitmaps):
if (KINGSHIELD_WEAK_W[i]
& BITSET[square]) KINGSHIELD_WEAK_B[MIRROR[i]] |=
BITSET[MIRROR[square]];
}
}
NOMOVE.moveInt = 0;
return;
}
void info()
{
// your playground... display
variables - meant for testing/verification purposes only
std::cout << std::endl
<< "============ info start
==============" << std::endl;
std::cout <<
"size of board, in bytes = "
<< sizeof(board)
<< std::endl;
std::cout <<
"Material value = "
<< board.Material << std::endl;
std::cout <<
"White castling rights = "
<< int(board.castleWhite)
<< std::endl;
std::cout <<
"Black castling rights = "
<< int(board.castleBlack)
<< std::endl;
std::cout <<
"En-passant square = "
<< board.epSquare << std::endl;
std::cout <<
"Fifty move count = "
<< board.fiftyMove << std::endl;
std::cout <<
"bitCnt of white pawns = "
<< bitCnt(board.whitePawns) << std::endl;
std::cout << std::endl
<< "bitmap of blackKnights |
board.whitePawns:" << std::endl;
displayBitmap(board.blackKnights |
board.whitePawns);
std::cout <<
"============ info end
================" << std::endl <<
std::endl;
return;
}
|