Subversion Repositories Games.Chess Giants

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
112 pmbaty 1
/*
2
    Protector -- a UCI chess engine
3
 
4
    Copyright (C) 2009-2010 Raimund Heid (Raimund_Heid@yahoo.com)
5
 
6
    This program is free software: you can redistribute it and/or modify
7
    it under the terms of the GNU General Public License as published by
8
    the Free Software Foundation, either version 3 of the License, or
9
    (at your option) any later version.
10
 
11
    This program is distributed in the hope that it will be useful,
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
    GNU General Public License for more details.
15
 
16
    You should have received a copy of the GNU General Public License
17
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
 
19
*/
20
 
21
#include <stdio.h>
22
#include <stdlib.h>
23
#include <string.h>
24
#include <stdarg.h>
25
#include <assert.h>
26
#include "io.h"
27
#include "pgn.h"
28
#include "position.h"
29
 
30
char pieceSymbol[16];
31
char pieceName[16];
32
 
33
static char *logfileName = "protector.log";
34
 
35
int getKeyStroke()
36
{
37
   logDebug("\nProgram halted. Hit RETURN to continue.");
38
 
39
   return getchar();
40
}
41
 
42
void getSquareName(Square square, char name[3])
43
{
44
   name[0] = (char) fileName(file(square));
45
   name[1] = (char) rankName(rank(square));
46
   name[2] = '\0';
47
}
48
 
49
void getMoveDump(const Move move, char *buffer)
50
{
51
   char from[3], to[3];
52
 
53
   getSquareName(getFromSquare(move), from);
54
   getSquareName(getToSquare(move), to);
55
 
56
   if (getNewPiece(move) == NO_PIECE)
57
   {
58
      sprintf(buffer, "%s-%s", from, to);
59
   }
60
   else
61
   {
62
      sprintf(buffer, "%s-%s=%c", from, to, pieceSymbol[getNewPiece(move)]);
63
   }
64
}
65
 
66
static void getMovelistDump(const Movelist * movelist, char *buffer)
67
{
68
   int i;
69
   char movebuffer[128];
70
 
71
   buffer[0] = '\0';
72
 
73
   sprintf(buffer + strlen(buffer), "\nmoves:\n");
74
 
75
   for (i = 0; i < movelist->numberOfMoves; i++)
76
   {
77
      getMoveDump(movelist->moves[i], movebuffer);
78
      sprintf(buffer + strlen(buffer), "%d. %s (%d)\n", i + 1, movebuffer,
79
              getMoveValue(movelist->moves[i]));
80
   }
81
 
82
   sprintf(buffer + strlen(buffer), "bad captures\n");
83
 
84
   for (i = 0; i < movelist->numberOfBadCaptures; i++)
85
   {
86
      getMoveDump(movelist->badCaptures[i], movebuffer);
87
      sprintf(buffer + strlen(buffer), "%d. %s (%d)\n", i + 1, movebuffer,
88
              getMoveValue(movelist->badCaptures[i]));
89
   }
90
}
91
 
92
static void formatTime(long sec, char *buffer)
93
{
94
   long seconds = sec % 60;
95
   long minutes = (sec / 60) % 60;
96
   long hours = (sec / 3600) % 60;
97
 
98
   sprintf(buffer, "%02ld:%02ld:%02ld", hours, minutes, seconds);
99
}
100
 
101
void formatLongInteger(UINT64 n, char *buffer)
102
{
103
   char tmp[32], *pBuffer, *fmt = "%llu";
104
   int i, j = 1, ol;
105
 
106
   sprintf(tmp, fmt, n);
107
   ol = (int) strlen(tmp);
108
   pBuffer = buffer + ol + (ol - 1) / 3;
109
   *pBuffer-- = '\0';
110
 
111
   for (i = ol - 1; i >= 0; i--)
112
   {
113
      assert(pBuffer >= buffer);
114
 
115
      *pBuffer-- = tmp[i];
116
 
117
      if (j++ % 3 == 0 && i > 0)
118
      {
119
         assert(pBuffer >= buffer);
120
         *pBuffer-- = ',';
121
      }
122
   }
123
}
124
 
125
static void formatCentipawnValue(int centipawnValue, char *buffer)
126
{
127
   float value = (float) centipawnValue;
128
 
129
   if (abs(centipawnValue) <= -(VALUE_MATED + 500))
130
   {
131
      sprintf(buffer, "%.2f", value / 100.0);
132
   }
133
   else
134
   {
135
      if (centipawnValue > 0)
136
      {
137
         sprintf(buffer, "#%d", (1 - VALUE_MATED - centipawnValue) / 2);
138
      }
139
      else
140
      {
141
         sprintf(buffer, "-#%d", (centipawnValue - VALUE_MATED) / 2);
142
      }
143
   }
144
}
145
 
146
void formatUciValue(const int centipawnValue, char *buffer)
147
{
148
   if (abs(centipawnValue) <= -(VALUE_MATED + 500))
149
   {
150
      sprintf(buffer, "cp %d", centipawnValue);
151
   }
152
   else
153
   {
154
      if (centipawnValue > 0)
155
      {
156
         sprintf(buffer, "mate %d", (1 - VALUE_MATED - centipawnValue) / 2);
157
      }
158
      else
159
      {
160
         sprintf(buffer, "mate -%d", (centipawnValue - VALUE_MATED) / 2);
161
      }
162
   }
163
}
164
 
165
static void getBoardDump(const Position * position, char *buffer)
166
{
167
   int file, rank;
168
   Square square;
169
   Piece piece;
170
 
171
   for (rank = RANK_8; rank >= RANK_1; rank--)
172
   {
173
      for (file = FILE_A; file <= FILE_H; file++)
174
      {
175
         square = getSquare(file, rank);
176
         piece = position->piece[square];
177
         *buffer++ = pieceName[piece];
178
      }
179
 
180
      *buffer++ = '\n';
181
   }
182
 
183
   *buffer = '\0';
184
 
185
   if (position->activeColor == WHITE)
186
   {
187
      strcat(buffer, "White to move");
188
   }
189
   else
190
   {
191
      strcat(buffer, "Black to move");
192
   }
193
}
194
 
195
void dumpSquare(const Square square)
196
{
197
   char buffer[3];
198
 
199
   getSquareName(square, buffer);
200
 
201
   logDebug("%s\n", buffer);
202
}
203
 
204
void dumpMove(const Move move)
205
{
206
   char buffer[128];
207
 
208
   getMoveDump(move, buffer);
209
 
210
   logDebug("%s (%d)\n", buffer, getMoveValue(move));
211
}
212
 
213
void logMove(const Move move)
214
{
215
   char buffer[128];
216
 
217
   getMoveDump(move, buffer);
218
 
219
   logReport("%s (%d)\n", buffer, getMoveValue(move));
220
}
221
 
222
void dumpMovelist(const Movelist * movelist)
223
{
224
   char buffer[4096];
225
 
226
   getMovelistDump(movelist, buffer);
227
 
228
   logDebug("%s\n", buffer);
229
}
230
 
231
void dumpPv(int depth, long timestamp,
232
            const char *moves, int value, UINT64 nodes,
233
            const Color activeColor)
234
{
235
   char ts[32], ns[32], vs[32];
236
 
237
   formatTime(timestamp / 1000, ts);
238
   formatLongInteger(nodes, ns);
239
 
240
   if (activeColor == BLACK && value > 20000)
241
   {
242
      value--;
243
   }
244
 
245
   formatCentipawnValue((activeColor == WHITE ? value : -value), vs);
246
   logReport("%d: %s %s (%s) %s\n", depth, ts, moves, vs, ns);
247
}
248
 
249
void logPosition(const Position * position)
250
{
251
   char buffer[1024];
252
 
253
   getBoardDump(position, buffer);
254
 
255
   logReport("%s\n", buffer);
256
}
257
 
258
void dumpPosition(const Position * position)
259
{
260
   logPosition(position);
261
   getKeyStroke();
262
}
263
 
264
void dumpVariation(const Variation * variation)
265
{
266
   char buffer[1024], moveBuffer[16];
267
   int ply;
268
 
269
   getBoardDump(&variation->singlePosition, buffer);
270
   strcat(buffer, "\n");
271
 
272
   for (ply = 0; ply < variation->ply; ply++)
273
   {
274
      getMoveDump(variation->plyInfo[ply].currentMove, moveBuffer);
275
      strcat(buffer, moveBuffer);
276
      strcat(buffer, " ");
277
   }
278
 
279
   logReport("%s\nnodeCount: %llu hashKey: %llu", buffer, variation->nodes,
280
             variation->singlePosition.hashKey);
281
   getKeyStroke();
282
}
283
 
284
void reportVariation(const Variation * variation)
285
{
286
   char buffer[1024], moveBuffer[16];
287
   int ply;
288
 
289
   getBoardDump(&variation->startPosition, buffer);
290
   strcat(buffer, "\n");
291
 
292
   for (ply = 0; ply < variation->ply; ply++)
293
   {
294
      getMoveDump(variation->plyInfo[ply].currentMove, moveBuffer);
295
      strcat(buffer, moveBuffer);
296
      strcat(buffer, " ");
297
   }
298
 
299
   logReport("%s\nnodeCount: %llu hashKey: %llu\nbest move=", buffer,
300
             variation->nodes, variation->singlePosition.hashKey);
301
   logMove(variation->bestBaseMove);
302
}
303
 
304
static void bitboard2String(Bitboard bitboard, char *title, char *buffer)
305
{
306
   int file, rank;
307
 
308
   for (rank = RANK_8; rank >= RANK_1; rank = (Rank) (rank - 1))
309
   {
310
      for (file = FILE_A; file <= FILE_H; file = (File) (file + 1))
311
      {
312
         Square square = getSquare(file, rank);
313
 
314
         *buffer++ = (testSquare(bitboard, square) ? '*' : '0');
315
      }
316
 
317
      *buffer++ = '\n';
318
   }
319
 
320
   sprintf(buffer, "%s", title);
321
}
322
 
323
void dumpBitboard(Bitboard bitboard, char *title)
324
{
325
   char buffer[128];
326
 
327
   bitboard2String(bitboard, title, buffer);
328
 
329
   logDebug("\n%s\n\n", buffer);
330
}
331
 
332
void dumpBalance(const INT32 balance)
333
{
334
   int opValue = getOpeningValue(balance);
335
   int egValue = getEndgameValue(balance);
336
 
337
   logDebug("op=%d eg=%d\n", opValue, egValue);
338
}
339
 
340
static void boardValues2String(const int value[64], char *buffer)
341
{
342
   int file, rank;
343
   char valueBuffer[64];
344
 
345
   for (rank = RANK_8; rank >= RANK_1; rank = (Rank) (rank - 1))
346
   {
347
      for (file = FILE_A; file <= FILE_H; file = (File) (file + 1))
348
      {
349
         Square square = getSquare(file, rank);
350
 
351
         sprintf(valueBuffer, "%i ", value[square]);
352
         sprintf(buffer, "%s", valueBuffer);
353
         buffer += strlen(valueBuffer);
354
      }
355
 
356
      *buffer++ = '\n';
357
   }
358
 
359
   *buffer++ = '\0';
360
}
361
 
362
void dumpBoardValues(const int value[64])
363
{
364
   char buffer[1024];
365
 
366
   boardValues2String(value, buffer);
367
 
368
   logDebug("\n%s\n\n", buffer);
369
}
370
 
371
void logDebug(const char *fmt, ...)
372
{
373
   va_list args;
374
 
375
   va_start(args, fmt);
376
 
377
   if (commandlineOptions.xboardMode == FALSE)
378
   {
379
      vprintf(fmt, args);
380
   }
381
   else
382
   {
383
      FILE *logfile = fopen(logfileName, "a");
384
 
385
      fprintf(logfile, "%lu: ", getTimestamp());
386
      vfprintf(logfile, fmt, args);
387
      fflush(logfile);
388
 
389
      if (fclose(logfile) != 0)
390
      {
391
         printf("Could not close file '%s'.", logfileName);
392
      }
393
   }
394
 
395
   va_end(args);
396
}
397
 
398
void logReport(const char *fmt, ...)
399
{
400
   char buffer[1024];
401
   FILE *logfile = fopen(logfileName, "a");
402
   va_list args;
403
 
404
   va_start(args, fmt);
405
   vsprintf(buffer, fmt, args);
406
   va_end(args);
407
 
408
   if (commandlineOptions.xboardMode == FALSE)
409
   {
410
      printf("%s", buffer);
411
   }
412
 
413
   if (logfile != NULL)
414
   {
415
      fprintf(logfile, "%s", buffer);
416
 
417
      if (fclose(logfile) != 0)
418
      {
419
         printf("Could not close file '%s'.", logfileName);
420
      }
421
   }
422
   else
423
   {
424
      printf("Could not open file '%s'.", logfileName);
425
   }
426
}
427
 
428
void writeTableToFile(UINT64 * table, const int tablesize,
429
                      const char *fileName, const char *tableName)
430
{
431
   FILE *file = fopen(fileName, "w");
432
   int i;
433
   const char *format = "%llullu, ";
434
 
435
   fprintf(file, "#include \"protector.h\"\n\n");
436
   fprintf(file, "UINT64 %s[%d] = {\n", tableName, tablesize);
437
 
438
   for (i = 0; i < tablesize; i++)
439
   {
440
      fprintf(file, format, table[i]);
441
 
442
      if ((i % 4) == 3)
443
      {
444
         fprintf(file, "\n");
445
      }
446
   }
447
 
448
   fclose(file);
449
}
450
 
451
int initializeModuleIo()
452
{
453
   pieceSymbol[KING] = 'K';
454
   pieceSymbol[QUEEN] = 'Q';
455
   pieceSymbol[ROOK] = 'R';
456
   pieceSymbol[BISHOP] = 'B';
457
   pieceSymbol[KNIGHT] = 'N';
458
   pieceSymbol[PAWN] = 'P';
459
 
460
   pieceName[NO_PIECE] = '*';
461
   pieceName[WHITE_KING] = 'K';
462
   pieceName[WHITE_QUEEN] = 'Q';
463
   pieceName[WHITE_ROOK] = 'R';
464
   pieceName[WHITE_BISHOP] = 'B';
465
   pieceName[WHITE_KNIGHT] = 'N';
466
   pieceName[WHITE_PAWN] = 'P';
467
   pieceName[BLACK_KING] = 'k';
468
   pieceName[BLACK_QUEEN] = 'q';
469
   pieceName[BLACK_ROOK] = 'r';
470
   pieceName[BLACK_BISHOP] = 'b';
471
   pieceName[BLACK_KNIGHT] = 'n';
472
   pieceName[BLACK_PAWN] = 'p';
473
 
474
   return 0;
475
}
476
 
477
int testModuleIo()
478
{
479
   char buffer[32];
480
 
481
   formatLongInteger(123, buffer);
482
   assert(strcmp(buffer, "123") == 0);
483
   formatLongInteger(1234, buffer);
484
   assert(strcmp(buffer, "1,234") == 0);
485
   formatLongInteger(1234567, buffer);
486
   assert(strcmp(buffer, "1,234,567") == 0);
487
 
488
   return 0;
489
}