/* Protector -- a UCI chess engine Copyright (C) 2009-2010 Raimund Heid (Raimund_Heid@yahoo.com) 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 3 of the License, or (at your option) any later version. 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. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include "io.h" #include "pgn.h" char pieceSymbol[16]; char pieceName[16]; static char *logfileName = "protector.log"; int getKeyStroke() { logDebug("\nProgram halted. Hit RETURN to continue."); return getchar(); } void getSquareName(Square square, char name[3]) { name[0] = (char) fileName(file(square)); name[1] = (char) rankName(rank(square)); name[2] = '\0'; } void getMoveDump(const Move move, char *buffer) { char from[3], to[3]; getSquareName(getFromSquare(move), from); getSquareName(getToSquare(move), to); if (getNewPiece(move) == NO_PIECE) { sprintf(buffer, "%s-%s", from, to); } else { sprintf(buffer, "%s-%s=%c", from, to, pieceSymbol[getNewPiece(move)]); } } static void getMovelistDump(const Movelist * movelist, char *buffer) { int i; char movebuffer[128]; buffer[0] = '\0'; sprintf(buffer + strlen(buffer), "\nmoves:\n"); for (i = 0; i < movelist->numberOfMoves; i++) { getMoveDump(movelist->moves[i], movebuffer); sprintf(buffer + strlen(buffer), "%d. %s (%d)\n", i + 1, movebuffer, getMoveValue(movelist->moves[i])); } sprintf(buffer + strlen(buffer), "bad captures\n"); for (i = 0; i < movelist->numberOfBadCaptures; i++) { getMoveDump(movelist->badCaptures[i], movebuffer); sprintf(buffer + strlen(buffer), "%d. %s (%d)\n", i + 1, movebuffer, getMoveValue(movelist->badCaptures[i])); } } static void formatTime(long sec, char *buffer) { long seconds = sec % 60; long minutes = (sec / 60) % 60; long hours = (sec / 3600) % 60; sprintf(buffer, "%02ld:%02ld:%02ld", hours, minutes, seconds); } void formatLongInteger(UINT64 n, char *buffer) { char tmp[32], *pBuffer, *fmt = "%llu"; int i, j = 1, ol; sprintf(tmp, fmt, n); ol = (int) strlen(tmp); pBuffer = buffer + ol + (ol - 1) / 3; *pBuffer-- = '\0'; for (i = ol - 1; i >= 0; i--) { assert(pBuffer >= buffer); *pBuffer-- = tmp[i]; if (j++ % 3 == 0 && i > 0) { assert(pBuffer >= buffer); *pBuffer-- = ','; } } } static void formatCentipawnValue(int centipawnValue, char *buffer) { float value = (float) centipawnValue; if (abs(centipawnValue) <= 20000) { sprintf(buffer, "%.2f", value / 100.0); } else { if (centipawnValue > 0) { sprintf(buffer, "#%d", (1 - VALUE_MATED - centipawnValue) / 2); } else { sprintf(buffer, "-#%d", (centipawnValue - VALUE_MATED) / 2); } } } void formatUciValue(const int centipawnValue, char *buffer) { if (abs(centipawnValue) <= -VALUE_ALMOST_MATED) { sprintf(buffer, "cp %d", centipawnValue); } else { if (centipawnValue > 0) { sprintf(buffer, "mate %d", (1 - VALUE_MATED - centipawnValue) / 2); } else { sprintf(buffer, "mate -%d", (centipawnValue - VALUE_MATED) / 2); } } } static void getBoardDump(const Position * position, char *buffer) { int file, rank; Square square; Piece piece; for (rank = RANK_8; rank >= RANK_1; rank--) { for (file = FILE_A; file <= FILE_H; file++) { square = getSquare(file, rank); piece = position->piece[square]; *buffer++ = pieceName[piece]; } *buffer++ = '\n'; } *buffer = '\0'; if (position->activeColor == WHITE) { strcat(buffer, "White to move"); } else { strcat(buffer, "Black to move"); } } void dumpSquare(const Square square) { char buffer[3]; getSquareName(square, buffer); logDebug("%s\n", buffer); } void dumpMove(const Move move) { char buffer[128]; getMoveDump(move, buffer); logDebug("%s (%d)\n", buffer, getMoveValue(move)); } void dumpMovelist(const Movelist * movelist) { char buffer[4096]; getMovelistDump(movelist, buffer); logDebug("%s\n", buffer); } void dumpPv(int depth, long timestamp, const char *moves, int value, UINT64 nodes, const Color activeColor) { char ts[32], ns[32], vs[32]; formatTime(timestamp / 1000, ts); formatLongInteger(nodes, ns); if (activeColor == BLACK && value > 20000) { value--; } formatCentipawnValue((activeColor == WHITE ? value : -value), vs); logReport("%d: %s %s (%s) %s\n", depth, ts, moves, vs, ns); } void logPosition(const Position * position) { char buffer[1024]; getBoardDump(position, buffer); logReport("%s\n", buffer); } void dumpPosition(const Position * position) { logPosition(position); getKeyStroke(); } void dumpVariation(const Variation * variation) { char buffer[1024], moveBuffer[16]; int ply; getBoardDump(&variation->singlePosition, buffer); strcat(buffer, "\n"); for (ply = 0; ply < variation->ply; ply++) { getMoveDump(variation->plyInfo[ply].currentMove, moveBuffer); strcat(buffer, moveBuffer); strcat(buffer, " "); } logReport("%s\nnodeCount: %llu hashValue: %llu", buffer, variation->nodes, variation->singlePosition.hashValue); getKeyStroke(); } static void bitboard2String(Bitboard bitboard, char *title, char *buffer) { int file, rank; for (rank = RANK_8; rank >= RANK_1; rank = (Rank) (rank - 1)) { for (file = FILE_A; file <= FILE_H; file = (File) (file + 1)) { Square square = getSquare(file, rank); *buffer++ = (testSquare(bitboard, square) ? '*' : '0'); } *buffer++ = '\n'; } sprintf(buffer, "%s", title); } void dumpBitboard(Bitboard bitboard, char *title) { char buffer[128]; bitboard2String(bitboard, title, buffer); logDebug("\n%s\n\n", buffer); } void logDebug(const char *fmt, ...) { va_list args; /* fprintf(logfile,"%lu: ",getTimestamp()); */ va_start(args, fmt); if (commandlineOptions.xboardMode == FALSE) { vprintf(fmt, args); } else { logReport(fmt, args); } va_end(args); } void logReport(const char *fmt, ...) { char buffer[1024]; FILE *logfile = fopen(logfileName, "a"); va_list args; va_start(args, fmt); vsprintf(buffer, fmt, args); va_end(args); if (commandlineOptions.xboardMode == FALSE) { printf("%s", buffer); } if (logfile != NULL) { fprintf(logfile, "%s", buffer); if (fclose(logfile) != 0) { printf("Could not close file '%s'.", logfileName); } } else { printf("Could not open file '%s'.", logfileName); } } int initializeModuleIo() { FILE *logfile; pieceSymbol[KING] = 'K'; pieceSymbol[QUEEN] = 'Q'; pieceSymbol[ROOK] = 'R'; pieceSymbol[BISHOP] = 'B'; pieceSymbol[KNIGHT] = 'N'; pieceSymbol[PAWN] = 'P'; pieceName[NO_PIECE] = '*'; pieceName[WHITE_KING] = 'K'; pieceName[WHITE_QUEEN] = 'Q'; pieceName[WHITE_ROOK] = 'R'; pieceName[WHITE_BISHOP] = 'B'; pieceName[WHITE_KNIGHT] = 'N'; pieceName[WHITE_PAWN] = 'P'; pieceName[BLACK_KING] = 'k'; pieceName[BLACK_QUEEN] = 'q'; pieceName[BLACK_ROOK] = 'r'; pieceName[BLACK_BISHOP] = 'b'; pieceName[BLACK_KNIGHT] = 'n'; pieceName[BLACK_PAWN] = 'p'; if ((logfile = fopen(logfileName, "w")) != NULL) { fclose(logfile); } return 0; } int testModuleIo() { char buffer[32]; formatLongInteger(123, buffer); assert(strcmp(buffer, "123") == 0); formatLongInteger(1234, buffer); assert(strcmp(buffer, "1,234") == 0); formatLongInteger(1234567, buffer); assert(strcmp(buffer, "1,234,567") == 0); return 0; }