[go: up one dir, main page]

Menu

Diff of /io.c [000000] .. [r1]  Maximize  Restore

Switch to side-by-side view

--- a
+++ b/io.c
@@ -0,0 +1,397 @@
+/*
+    Protector -- a UCI chess engine
+
+    Copyright (C) 2008 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 <http://www.gnu.org/licenses/>.
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <assert.h>
+#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;
+}