Subversion Repositories Games.Chess Giants

Rev

Rev 33 | Rev 154 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 33 Rev 108
Line 27... Line 27...
27
 *   on a single cache line rather than being split across two, assuming the   *
27
 *   on a single cache line rather than being split across two, assuming the   *
28
 *   structure is 64 bytes or less of course.                                  *
28
 *   structure is 64 bytes or less of course.                                  *
29
 *                                                                             *
29
 *                                                                             *
30
 *******************************************************************************
30
 *******************************************************************************
31
 */
31
 */
32
 
-
 
33
void AlignedMalloc(void **pointer, int alignment, size_t size) {
32
void AlignedMalloc(void **pointer, int alignment, size_t size) {
34
  segments[nsegments][0] = malloc(size + alignment - 1);
33
  segments[nsegments][0] = malloc(size + alignment - 1);
35
  segments[nsegments][1] =
34
  segments[nsegments][1] =
36
      (void *) (((uintptr_t) segments[nsegments][0] + alignment -
35
      (void *) (((uintptr_t) segments[nsegments][0] + alignment -
37
          1) & ~(alignment - 1));
36
          1) & ~(alignment - 1));
Line 40... Line 39...
40
}
39
}
41
 
40
 
42
/*
41
/*
43
 *******************************************************************************
42
 *******************************************************************************
44
 *                                                                             *
43
 *                                                                             *
45
 *   atoiKM() is used to read in an integer value that can have a "K" or "M"   *
44
 *   atoiKMB() is used to read in an integer value that can have a "K" or "M"  *
46
 *   appended to it to multiply by 1024 or 1024*1024.  It returns a 64 bit     *
45
 *   appended to it to multiply by 1024 or 1024*1024.  It returns a 64 bit     *
47
 *   value since memory sizes can exceed 4gb on modern hardware.               *
46
 *   value since memory sizes can exceed 4gb on modern hardware.               *
48
 *                                                                             *
47
 *                                                                             *
49
 *******************************************************************************
48
 *******************************************************************************
50
 */
49
 */
51
 
-
 
52
uint64_t atoiKM(char *input) {
50
uint64_t atoiKMB(char *input) {
53
  uint64_t size;
51
  uint64_t size;
54
 
52
 
55
  size = atoi(input);
53
  size = atoi(input);
56
  if (strchr(input, 'K') || strchr(input, 'k'))
54
  if (strchr(input, 'K') || strchr(input, 'k'))
57
    size *= 1 << 10;
55
    size *= 1 << 10;
58
  if (strchr(input, 'M') || strchr(input, 'm'))
56
  if (strchr(input, 'M') || strchr(input, 'm'))
59
    size *= 1 << 20;
57
    size *= 1 << 20;
-
 
58
  if (strchr(input, 'B') || strchr(input, 'b') || strchr(input, 'G') ||
-
 
59
      strchr(input, 'g'))
-
 
60
    size *= 1 << 30;
60
  return size;
61
  return size;
61
}
62
}
62
 
63
 
63
/*
64
/*
64
 *******************************************************************************
65
 *******************************************************************************
Line 66... Line 67...
66
 *   AlignedRemalloc() is used to change the size of a memory block that has   *
67
 *   AlignedRemalloc() is used to change the size of a memory block that has   *
67
 *   previously been allocated using AlignedMalloc().                          *
68
 *   previously been allocated using AlignedMalloc().                          *
68
 *                                                                             *
69
 *                                                                             *
69
 *******************************************************************************
70
 *******************************************************************************
70
 */
71
 */
71
 
-
 
72
void AlignedRemalloc(void **pointer, int alignment, size_t size) {
72
void AlignedRemalloc(void **pointer, int alignment, size_t size) {
73
  int i;
73
  int i;
-
 
74
 
74
  for (i = 0; i < nsegments; i++)
75
  for (i = 0; i < nsegments; i++)
75
    if (segments[i][1] == *pointer)
76
    if (segments[i][1] == *pointer)
76
      break;
77
      break;
77
  if (i == nsegments) {
78
  if (i == nsegments) {
78
    Print(4095, "ERROR  AlignedRemalloc() given an invalid pointer\n");
79
    Print(4095, "ERROR  AlignedRemalloc() given an invalid pointer\n");
Line 94... Line 95...
94
 *   without any endian issues.                                                *
95
 *   without any endian issues.                                                *
95
 *                                                                             *
96
 *                                                                             *
96
 *******************************************************************************
97
 *******************************************************************************
97
 */
98
 */
98
void BookClusterIn(FILE * file, int positions, BOOK_POSITION * buffer) {
99
void BookClusterIn(FILE * file, int positions, BOOK_POSITION * buffer) {
99
  char file_buffer[BOOK_CLUSTER_SIZE * BOOK_POSITION_SIZE];
-
 
100
  int i;
100
  int i;
-
 
101
  char file_buffer[BOOK_CLUSTER_SIZE * sizeof(BOOK_POSITION)];
101
 
102
 
102
  fread(file_buffer, positions, BOOK_POSITION_SIZE, file);
103
  i = fread(file_buffer, positions, sizeof(BOOK_POSITION), file);
-
 
104
  if (i <= 0)
-
 
105
    perror("BookClusterIn fread error: ");
103
  for (i = 0; i < positions; i++) {
106
  for (i = 0; i < positions; i++) {
104
    buffer[i].position =
107
    buffer[i].position =
105
        BookIn64((unsigned char *) (file_buffer + i * BOOK_POSITION_SIZE));
108
        BookIn64((unsigned char *) (file_buffer + i * sizeof(BOOK_POSITION)));
106
    buffer[i].status_played =
109
    buffer[i].status_played =
107
        BookIn32((unsigned char *) (file_buffer + i * BOOK_POSITION_SIZE +
110
        BookIn32((unsigned char *) (file_buffer + i * sizeof(BOOK_POSITION) +
108
            8));
111
            8));
109
    buffer[i].learn =
112
    buffer[i].learn =
110
        BookIn32f((unsigned char *) (file_buffer + i * BOOK_POSITION_SIZE +
113
        BookIn32f((unsigned char *) (file_buffer + i * sizeof(BOOK_POSITION) +
111
            12));
114
            12));
112
  }
115
  }
113
}
116
}
114
 
117
 
115
/*
118
/*
Line 120... Line 123...
120
 *   Endian-independent.                                                       *
123
 *   Endian-independent.                                                       *
121
 *                                                                             *
124
 *                                                                             *
122
 *******************************************************************************
125
 *******************************************************************************
123
 */
126
 */
124
void BookClusterOut(FILE * file, int positions, BOOK_POSITION * buffer) {
127
void BookClusterOut(FILE * file, int positions, BOOK_POSITION * buffer) {
125
  char file_buffer[BOOK_CLUSTER_SIZE * BOOK_POSITION_SIZE];
-
 
126
  int i;
128
  int i;
-
 
129
  char file_buffer[BOOK_CLUSTER_SIZE * sizeof(BOOK_POSITION)];
127
 
130
 
128
  for (i = 0; i < positions; i++) {
131
  for (i = 0; i < positions; i++) {
129
    memcpy(file_buffer + i * BOOK_POSITION_SIZE,
132
    memcpy(file_buffer + i * sizeof(BOOK_POSITION),
130
        BookOut64(buffer[i].position), 8);
133
        BookOut64(buffer[i].position), 8);
131
    memcpy(file_buffer + i * BOOK_POSITION_SIZE + 8,
134
    memcpy(file_buffer + i * sizeof(BOOK_POSITION) + 8,
132
        BookOut32(buffer[i].status_played), 4);
135
        BookOut32(buffer[i].status_played), 4);
133
    memcpy(file_buffer + i * BOOK_POSITION_SIZE + 12,
136
    memcpy(file_buffer + i * sizeof(BOOK_POSITION) + 12,
134
        BookOut32f(buffer[i].learn), 4);
137
        BookOut32f(buffer[i].learn), 4);
135
  }
138
  }
136
  fwrite(file_buffer, positions, BOOK_POSITION_SIZE, file);
139
  fwrite(file_buffer, positions, sizeof(BOOK_POSITION), file);
137
}
140
}
138
 
141
 
139
/*
142
/*
140
 *******************************************************************************
143
 *******************************************************************************
141
 *                                                                             *
144
 *                                                                             *
142
 *   BookIn32f() is used to convert 4 bytes from the book file into a valid 32 *
145
 *   BookIn32f() is used to convert 4 bytes from the book file into a valid 32 *
143
 *   bit binary value.  this eliminates endian worries that make the binary    *
146
 *   bit binary value.  This eliminates endian worries that make the binary    *
144
 *   book non-portable across many architectures.                              *
147
 *   book non-portable across many architectures.                              *
145
 *                                                                             *
148
 *                                                                             *
146
 *******************************************************************************
149
 *******************************************************************************
147
 */
150
 */
148
float BookIn32f(unsigned char *ch) {
151
float BookIn32f(unsigned char *ch) {
Line 263... Line 266...
263
  int i;
266
  int i;
264
  static int init = 0, pipe;
267
  static int init = 0, pipe;
265
  static HANDLE inh;
268
  static HANDLE inh;
266
  DWORD dw;
269
  DWORD dw;
267
 
270
 
268
  if (!xboard && !_isatty(_fileno(stdin))) // Pierre-Marie Baty -- use ISO C++ conformant names
271
  if (!xboard && !_isatty(_fileno(stdin))) // Pierre-Marie Baty -- ISO C++ names fix
269
    return 0;
272
    return 0;
270
  if (batch_mode)
273
  if (batch_mode)
271
    return 0;
274
    return 0;
272
  if (strchr(cmd_buffer, '\n'))
275
  if (strchr(cmd_buffer, '\n'))
273
    return 1;
276
    return 1;
Line 333... Line 336...
333
 *   search path information in it.                                            *
336
 *   search path information in it.                                            *
334
 *                                                                             *
337
 *                                                                             *
335
 *******************************************************************************
338
 *******************************************************************************
336
 */
339
 */
337
void ClearHashTableScores(void) {
340
void ClearHashTableScores(void) {
338
  size_t i; // Pierre-Marie Baty -- fixed type
341
  int i;
339
 
342
 
340
  if (trans_ref)
343
  if (hash_table)
341
    for (i = 0; i < hash_table_size; i++) {
344
    for (i = 0; i < (int)hash_table_size; i++) { // Pierre-Marie Baty -- added type cast
342
      (trans_ref + i)->word2 ^= (trans_ref + i)->word1;
345
      (hash_table + i)->word2 ^= (hash_table + i)->word1;
343
      (trans_ref + i)->word1 =
346
      (hash_table + i)->word1 =
344
          ((trans_ref + i)->word1 & mask_clear_entry) | (uint64_t) 65536;
347
          ((hash_table + i)->word1 & mask_clear_entry) | (uint64_t) 65536;
345
      (trans_ref + i)->word2 ^= (trans_ref + i)->word1;
348
      (hash_table + i)->word2 ^= (hash_table + i)->word1;
346
    }
349
    }
347
}
350
}
348
 
351
 
349
/* last modified 02/28/14 */
352
/* last modified 02/28/14 */
350
/*
353
/*
Line 467... Line 470...
467
 */
470
 */
468
void CraftyExit(int exit_type) {
471
void CraftyExit(int exit_type) {
469
  int proc;
472
  int proc;
470
 
473
 
471
  for (proc = 1; proc < CPUS; proc++)
474
  for (proc = 1; proc < CPUS; proc++)
472
    thread[proc].tree = (TREE *) - 1;
475
    thread[proc].terminate = 1;
473
  while (smp_threads);
476
  while (smp_threads);
474
  exit(exit_type);
477
  exit(exit_type);
475
}
478
}
476
 
479
 
477
/*
480
/*
Line 601... Line 604...
601
 
604
 
602
  for (i = 56; i >= 0; i -= 8) {
605
  for (i = 56; i >= 0; i -= 8) {
603
    x = (board >> i) & 255;
606
    x = (board >> i) & 255;
604
    for (j = 1; j < 256; j = j << 1)
607
    for (j = 1; j < 256; j = j << 1)
605
      if (x & j)
608
      if (x & j)
606
        printf("X ");
609
        Print(4095, "X ");
607
      else
610
      else
608
        printf("- ");
611
        Print(4095, "- ");
609
    printf("\n");
612
    Print(4095, "\n");
610
  }
613
  }
611
}
614
}
612
 
615
 
613
/*
616
/*
614
 *******************************************************************************
617
 *******************************************************************************
Line 649... Line 652...
649
 *   is nearly ready for display as is.                                        *
652
 *   is nearly ready for display as is.                                        *
650
 *                                                                             *
653
 *                                                                             *
651
 *******************************************************************************
654
 *******************************************************************************
652
 */
655
 */
653
void DisplayChessBoard(FILE * display_file, POSITION pos) {
656
void DisplayChessBoard(FILE * display_file, POSITION pos) {
654
  int display_board[64];
657
  int display_board[64], i, j;
655
  static const char display_string[16][4] =
658
  static const char display_string[16][4] =
656
      { "<K>", "<Q>", "<R>", "<B>", "<N>", "<P>", "   ",
659
      { "<K>", "<Q>", "<R>", "<B>", "<N>", "<P>", "   ",
657
    "-P-", "-N-", "-B-", "-R-", "-Q-", "-K-", " . "
660
    "-P-", "-N-", "-B-", "-R-", "-Q-", "-K-", " . "
658
  };
661
  };
659
  int i, j;
-
 
660
 
662
 
661
/*
663
/*
662
 ************************************************************
664
 ************************************************************
663
 *                                                          *
665
 *                                                          *
664
 *  First, convert square values to indices to the proper   *
666
 *  First, convert square values to indices to the proper   *
Line 688... Line 690...
688
      fprintf(display_file, "|%s", display_string[display_board[i * 8 + j]]);
690
      fprintf(display_file, "|%s", display_string[display_board[i * 8 + j]]);
689
    fprintf(display_file, "|\n");
691
    fprintf(display_file, "|\n");
690
    fprintf(display_file, "       +---+---+---+---+---+---+---+---+\n");
692
    fprintf(display_file, "       +---+---+---+---+---+---+---+---+\n");
691
  }
693
  }
692
  fprintf(display_file, "         a   b   c   d   e   f   g   h\n\n");
694
  fprintf(display_file, "         a   b   c   d   e   f   g   h\n\n");
-
 
695
}
-
 
696
 
-
 
697
/*
-
 
698
 *******************************************************************************
-
 
699
 *                                                                             *
-
 
700
 *   DisplayChessMove() is a debugging function that displays a chess move in  *
-
 
701
 *   a very simple (non-algebraic) form.                                       *
-
 
702
 *                                                                             *
-
 
703
 *******************************************************************************
-
 
704
 */
-
 
705
void DisplayChessMove(char *title, int move) {
-
 
706
  Print(4095, "%s  piece=%d, from=%d, to=%d, captured=%d, promote=%d\n",
-
 
707
      title, Piece(move), From(move), To(move), Captured(move),
-
 
708
      Promote(move));
693
}
709
}
694
 
710
 
695
/*
711
/*
696
 *******************************************************************************
712
 *******************************************************************************
697
 *                                                                             *
713
 *                                                                             *
Line 700... Line 716...
700
 *   look nice and aligned.                                                    *
716
 *   look nice and aligned.                                                    *
701
 *                                                                             *
717
 *                                                                             *
702
 *******************************************************************************
718
 *******************************************************************************
703
 */
719
 */
704
char *DisplayEvaluation(int value, int wtm) {
720
char *DisplayEvaluation(int value, int wtm) {
705
  static char out[10];
-
 
706
  int tvalue;
721
  int tvalue;
-
 
722
  static char out[10];
707
 
723
 
708
  tvalue = (wtm) ? value : -value;
724
  tvalue = (wtm) ? value : -value;
709
  if (!MateScore(value))
725
  if (!MateScore(value))
710
    sprintf_s(out, sizeof (out), "%7.2f", ((float) tvalue) / 100.0); // Pierre-Marie Baty -- use safe version
726
    sprintf(out, "%7.2f", ((float) tvalue) / 100.0);
711
  else if (Abs(value) > MATE) {
727
  else if (Abs(value) > MATE) {
712
    if (tvalue < 0)
728
    if (tvalue < 0)
713
      sprintf_s(out, sizeof (out), " -infnty"); // Pierre-Marie Baty -- use safe version
729
      sprintf(out, " -infnty");
714
    else
730
    else
715
      sprintf_s(out, sizeof (out), " +infnty"); // Pierre-Marie Baty -- use safe version
731
      sprintf(out, " +infnty");
716
  } else if (value == MATE - 2 && wtm)
732
  } else if (value == MATE - 2 && wtm)
717
    sprintf_s(out, sizeof (out), "   Mate"); // Pierre-Marie Baty -- use safe version
733
    sprintf(out, "   Mate");
718
  else if (value == MATE - 2 && !wtm)
734
  else if (value == MATE - 2 && !wtm)
719
    sprintf_s(out, sizeof (out), "  -Mate"); // Pierre-Marie Baty -- use safe version
735
    sprintf(out, "  -Mate");
720
  else if (value == -(MATE - 1) && wtm)
736
  else if (value == -(MATE - 1) && wtm)
721
    sprintf_s(out, sizeof (out), "  -Mate"); // Pierre-Marie Baty -- use safe version
737
    sprintf(out, "  -Mate");
722
  else if (value == -(MATE - 1) && !wtm)
738
  else if (value == -(MATE - 1) && !wtm)
723
    sprintf_s(out, sizeof (out), "   Mate"); // Pierre-Marie Baty -- use safe version
739
    sprintf(out, "   Mate");
724
  else if (value > 0 && wtm)
740
  else if (value > 0 && wtm)
725
    sprintf_s(out, sizeof (out), "  Mat%.2d", (MATE - value) / 2); // Pierre-Marie Baty -- use safe version
741
    sprintf(out, "  Mat%.2d", (MATE - value) / 2);
726
  else if (value > 0 && !wtm)
742
  else if (value > 0 && !wtm)
727
    sprintf_s(out, sizeof (out), " -Mat%.2d", (MATE - value) / 2); // Pierre-Marie Baty -- use safe version
743
    sprintf(out, " -Mat%.2d", (MATE - value) / 2);
728
  else if (wtm)
744
  else if (wtm)
729
    sprintf_s(out, sizeof (out), " -Mat%.2d", (MATE - Abs(value)) / 2); // Pierre-Marie Baty -- use safe version
745
    sprintf(out, " -Mat%.2d", (MATE - Abs(value)) / 2);
730
  else
746
  else
731
    sprintf_s(out, sizeof (out), "  Mat%.2d", (MATE - Abs(value)) / 2); // Pierre-Marie Baty -- use safe version
747
    sprintf(out, "  Mat%.2d", (MATE - Abs(value)) / 2);
732
  return out;
748
  return out;
733
}
749
}
734
 
750
 
735
/*
751
/*
736
 *******************************************************************************
752
 *******************************************************************************
Line 740... Line 756...
740
 *   whispers will look nicer.                                                 *
756
 *   whispers will look nicer.                                                 *
741
 *                                                                             *
757
 *                                                                             *
742
 *******************************************************************************
758
 *******************************************************************************
743
 */
759
 */
744
char *DisplayEvaluationKibitz(int value, int wtm) {
760
char *DisplayEvaluationKibitz(int value, int wtm) {
745
  static char out[10];
-
 
746
  int tvalue;
761
  int tvalue;
-
 
762
  static char out[10];
747
 
763
 
748
  tvalue = (wtm) ? value : -value;
764
  tvalue = (wtm) ? value : -value;
749
  if (!MateScore(value))
765
  if (!MateScore(value))
750
    sprintf_s(out, sizeof (out), "%+.2f", ((float) tvalue) / 100.0); // Pierre-Marie Baty -- use safe version
766
    sprintf(out, "%+.2f", ((float) tvalue) / 100.0);
751
  else if (Abs(value) > MATE) {
767
  else if (Abs(value) > MATE) {
752
    if (tvalue < 0)
768
    if (tvalue < 0)
753
      sprintf_s(out, sizeof (out), "-infnty"); // Pierre-Marie Baty -- use safe version
769
      sprintf(out, "-infnty");
754
    else
770
    else
755
      sprintf_s(out, sizeof (out), "+infnty"); // Pierre-Marie Baty -- use safe version
771
      sprintf(out, "+infnty");
756
  } else if (value == MATE - 2 && wtm)
772
  } else if (value == MATE - 2 && wtm)
757
    sprintf_s(out, sizeof (out), "Mate"); // Pierre-Marie Baty -- use safe version
773
    sprintf(out, "Mate");
758
  else if (value == MATE - 2 && !wtm)
774
  else if (value == MATE - 2 && !wtm)
759
    sprintf_s(out, sizeof (out), "-Mate"); // Pierre-Marie Baty -- use safe version
775
    sprintf(out, "-Mate");
760
  else if (value == -(MATE - 1) && wtm)
776
  else if (value == -(MATE - 1) && wtm)
761
    sprintf_s(out, sizeof (out), "-Mate"); // Pierre-Marie Baty -- use safe version
777
    sprintf(out, "-Mate");
762
  else if (value == -(MATE - 1) && !wtm)
778
  else if (value == -(MATE - 1) && !wtm)
763
    sprintf_s(out, sizeof (out), "Mate"); // Pierre-Marie Baty -- use safe version
779
    sprintf(out, "Mate");
764
  else if (value > 0 && wtm)
780
  else if (value > 0 && wtm)
765
    sprintf_s(out, sizeof (out), "Mat%.2d", (MATE - value) / 2); // Pierre-Marie Baty -- use safe version
781
    sprintf(out, "Mat%.2d", (MATE - value) / 2);
766
  else if (value > 0 && !wtm)
782
  else if (value > 0 && !wtm)
767
    sprintf_s(out, sizeof (out), "-Mat%.2d", (MATE - value) / 2); // Pierre-Marie Baty -- use safe version
783
    sprintf(out, "-Mat%.2d", (MATE - value) / 2);
768
  else if (wtm)
784
  else if (wtm)
769
    sprintf_s(out, sizeof (out), "-Mat%.2d", (MATE - Abs(value)) / 2); // Pierre-Marie Baty -- use safe version
785
    sprintf(out, "-Mat%.2d", (MATE - Abs(value)) / 2);
770
  else
786
  else
771
    sprintf_s(out, sizeof (out), "Mat%.2d", (MATE - Abs(value)) / 2); // Pierre-Marie Baty -- use safe version
787
    sprintf(out, "Mat%.2d", (MATE - Abs(value)) / 2);
772
  return out;
788
  return out;
-
 
789
}
-
 
790
 
-
 
791
/*
-
 
792
 *******************************************************************************
-
 
793
 *                                                                             *
-
 
794
 *   DisplayPath() is used to display a PV during the root move search.        *
-
 
795
 *                                                                             *
-
 
796
 *******************************************************************************
-
 
797
 */
-
 
798
char *DisplayPath(TREE * RESTRICT tree, int wtm, PATH * pv) {
-
 
799
  static char buffer[4096];
-
 
800
  int i, t_move_number;
-
 
801
 
-
 
802
/*
-
 
803
 ************************************************************
-
 
804
 *                                                          *
-
 
805
 *  Initialize.                                             *
-
 
806
 *                                                          *
-
 
807
 ************************************************************
-
 
808
 */
-
 
809
  t_move_number = move_number;
-
 
810
  sprintf(buffer, " %d.", move_number);
-
 
811
  if (!wtm)
-
 
812
    sprintf(buffer + strlen(buffer), " ...");
-
 
813
  for (i = 1; i < (int) pv->pathl; i++) {
-
 
814
    if (i > 1 && wtm)
-
 
815
      sprintf(buffer + strlen(buffer), " %d.", t_move_number);
-
 
816
    sprintf(buffer + strlen(buffer), " %s", OutputMove(tree, i, wtm,
-
 
817
            pv->path[i]));
-
 
818
    MakeMove(tree, i, wtm, pv->path[i]);
-
 
819
    wtm = Flip(wtm);
-
 
820
    if (wtm)
-
 
821
      t_move_number++;
-
 
822
  }
-
 
823
  if (pv->pathh == 1)
-
 
824
    sprintf(buffer + strlen(buffer), " <HT>             ");
-
 
825
  else if (pv->pathh == 2)
-
 
826
    sprintf(buffer + strlen(buffer), " <EGTB>           ");
-
 
827
  else if (pv->pathh == 3)
-
 
828
    sprintf(buffer + strlen(buffer), " <3-fold>         ");
-
 
829
  else if (pv->pathh == 4)
-
 
830
    sprintf(buffer + strlen(buffer), " <50-move>        ");
-
 
831
  if (strlen(buffer) < 30)
-
 
832
    for (i = 0; i < 30 - (int) strlen(buffer); i++) // Pierre-Marie Baty -- added type cast
-
 
833
      strcat(buffer, " ");
-
 
834
  strcpy(kibitz_text, buffer);
-
 
835
  for (i = pv->pathl - 1; i > 0; i--) {
-
 
836
    wtm = Flip(wtm);
-
 
837
    UnmakeMove(tree, i, wtm, pv->path[i]);
-
 
838
  }
-
 
839
  return buffer;
-
 
840
}
-
 
841
 
-
 
842
/*
-
 
843
 *******************************************************************************
-
 
844
 *                                                                             *
-
 
845
 *   DisplayFail() is used to display a PV (moves only) during the search.     *
-
 
846
 *                                                                             *
-
 
847
 *******************************************************************************
-
 
848
 */
-
 
849
void DisplayFail(TREE * RESTRICT tree, int type, int level, int wtm, int time,
-
 
850
    int move, int value, int force) {
-
 
851
  char buffer[4096], *fh_indicator;
-
 
852
 
-
 
853
/*
-
 
854
 ************************************************************
-
 
855
 *                                                          *
-
 
856
 *  If we have not used "noise_level" units of time, we     *
-
 
857
 *  return immediately.  Otherwise we add the fail high/low *
-
 
858
 *  indicator (++/--) and then display the times.           *
-
 
859
 *                                                          *
-
 
860
 ************************************************************
-
 
861
 */
-
 
862
  if (time < (int) noise_level) // Pierre-Marie Baty -- added type cast
-
 
863
    return;
-
 
864
  if (type == 1)
-
 
865
    fh_indicator = (wtm) ? "++" : "--";
-
 
866
  else
-
 
867
    fh_indicator = (wtm) ? "--" : "++";
-
 
868
  Print(4, "         %2i   %s     %2s   ", iteration,
-
 
869
      Display2Times(end_time - start_time), fh_indicator);
-
 
870
/*
-
 
871
 ************************************************************
-
 
872
 *                                                          *
-
 
873
 *  If we are pondering, we need to add the (ponder-move)   *
-
 
874
 *  to the front of the buffer, correcting the move number  *
-
 
875
 *  if necessary.  Then fill in the move number and the     *
-
 
876
 *  fail high/low bound.                                    *
-
 
877
 *                                                          *
-
 
878
 ************************************************************
-
 
879
 */
-
 
880
  if (!pondering) {
-
 
881
    sprintf(buffer, "%d.", move_number);
-
 
882
    if (!wtm)
-
 
883
      sprintf(buffer + strlen(buffer), " ...");
-
 
884
  } else {
-
 
885
    if (wtm)
-
 
886
      sprintf(buffer, "%d. ... (%s) %d.", move_number - 1, ponder_text,
-
 
887
          move_number);
-
 
888
    else
-
 
889
      sprintf(buffer, "%d. (%s)", move_number, ponder_text);
-
 
890
  }
-
 
891
  sprintf(buffer + strlen(buffer), " %s%c", OutputMove(tree, 1, wtm, move),
-
 
892
      (type == 1) ? '!' : '?');
-
 
893
  strcpy(kibitz_text, buffer);
-
 
894
  if (time >= (int) noise_level || force) { // Pierre-Marie Baty -- added type cast
-
 
895
    noise_block = 0;
-
 
896
    Lock(lock_io);
-
 
897
    Print(4, "%s", buffer);
-
 
898
    Unlock(lock_io);
-
 
899
    if (type == 1)
-
 
900
      Print(4, " (%c%s)                   \n", (wtm) ? '>' : '<',
-
 
901
          DisplayEvaluationKibitz(value, wtm));
-
 
902
    else
-
 
903
      Print(4, " (%c%s)                   \n", (wtm) ? '<' : '>',
-
 
904
          DisplayEvaluationKibitz(value, wtm));
-
 
905
  }
773
}
906
}
774
 
907
 
775
/*
908
/*
776
 *******************************************************************************
909
 *******************************************************************************
777
 *                                                                             *
910
 *                                                                             *
778
 *   DisplayPV() is used to display a PV during the search.                    *
911
 *   DisplayPV() is used to display a PV during the search.                    *
779
 *                                                                             *
912
 *                                                                             *
780
 *******************************************************************************
913
 *******************************************************************************
781
 */
914
 */
782
void DisplayPV(TREE * RESTRICT tree, int level, int wtm, int time, PATH * pv) {
915
void DisplayPV(TREE * RESTRICT tree, int level, int wtm, int time, PATH * pv,
-
 
916
    int force) {
783
  char buffer[4096], *buffp, *bufftemp;
917
  char buffer[4096], *buffp, *bufftemp;
784
  int /*i, */t_move_number, type;
-
 
785
  unsigned int i, buflen; // Pierre-Marie Baty -- fixed type
918
  char blanks[40] = { "                                        " };
786
  int nskip = 0, twtm = wtm, pv_depth = pv->pathd;;
919
  int i, len, t_move_number, nskip = 0, twtm = wtm, pv_depth = pv->pathd;;
-
 
920
  unsigned int idle_time;
787
 
921
 
788
/*
922
/*
789
 ************************************************************
923
 ************************************************************
790
 *                                                          *
924
 *                                                          *
791
 *  Initialize.                                             *
925
 *  Initialize.                                             *
792
 *                                                          *
926
 *                                                          *
793
 ************************************************************
927
 ************************************************************
794
 */
928
 */
795
  for (i = 0; i < (unsigned int) n_root_moves; i++) // Pierre-Marie Baty -- part of type fix
929
  for (i = 0; i < n_root_moves; i++)
796
    if (!(root_moves[i].status & 8) && !(root_moves[i].status & 4))
930
    if (root_moves[i].status & 4)
797
      nskip++;
931
      nskip++;
798
  if (level == 5)
932
  for (i = 0; i < 4096; i++)
799
    type = 4;
933
    buffer[i] = ' ';
800
  else
-
 
801
    type = 2;
-
 
802
  t_move_number = move_number;
934
  t_move_number = move_number;
803
  if (display_options & 64)
935
  if (!pondering || analyze_mode) {
804
    sprintf_s(buffer, sizeof (buffer), " %d.", move_number); // Pierre-Marie Baty -- use safe version
936
    sprintf(buffer, "%d.", move_number);
-
 
937
    if (!wtm)
-
 
938
      sprintf(buffer + strlen(buffer), " ...");
805
  else
939
  } else {
806
    buffer[0] = 0;
940
    if (wtm)
807
  if ((display_options & 64) && !wtm)
-
 
808
    strcat_s(buffer, sizeof (buffer), " ..."); // Pierre-Marie Baty -- use safe version
941
      sprintf(buffer, "%d. ... (%s) %d.", move_number - 1, ponder_text,
809
  for (i = 1; i < (unsigned int) pv->pathl; i++) { // Pierre-Marie Baty -- part of type fix
-
 
810
    if ((display_options & 64) && i > 1 && wtm) {
942
          move_number);
811
      buflen = strlen (buffer);
943
    else
812
      sprintf_s(buffer + buflen, sizeof (buffer) - buflen, " %d.", t_move_number); // Pierre-Marie Baty -- use safe version
944
      sprintf(buffer, "%d. (%s)", move_number, ponder_text);
813
    }
945
  }
-
 
946
  for (i = 1; i < (int) pv->pathl; i++) {
814
    buflen = strlen (buffer);
947
    if (i > 1 && wtm)
-
 
948
      sprintf(buffer + strlen(buffer), " %d.", t_move_number);
815
    sprintf_s(buffer + buflen, sizeof (buffer) - buflen, " %s", OutputMove(tree, pv->path[i], i, // Pierre-Marie Baty -- use safe version
949
    sprintf(buffer + strlen(buffer), " %s", OutputMove(tree, i, wtm,
816
            wtm));
950
            pv->path[i]));
817
    MakeMove(tree, i, pv->path[i], wtm);
951
    MakeMove(tree, i, wtm, pv->path[i]);
818
    wtm = Flip(wtm);
952
    wtm = Flip(wtm);
819
    if (wtm)
953
    if (wtm)
820
      t_move_number++;
954
      t_move_number++;
821
  }
955
  }
822
  if (pv->pathh == 1)
956
  if (pv->pathh == 1)
823
    strcat_s(buffer, sizeof (buffer), " <HT>           "); // Pierre-Marie Baty -- use safe version
957
    sprintf(buffer + strlen(buffer), " <HT>");
824
  else if (pv->pathh == 2)
958
  else if (pv->pathh == 2)
825
    strcat_s(buffer, sizeof (buffer), " <EGTB>         "); // Pierre-Marie Baty -- use safe version
959
    sprintf(buffer + strlen(buffer), " <EGTB>");
826
  if (strlen(buffer) < 30)
960
  else if (pv->pathh == 3)
827
    for (i = 0; i < 30 - strlen(buffer); i++)
961
    sprintf(buffer + strlen(buffer), " <3-fold>");
828
      strcat_s(buffer, sizeof (buffer), " "); // Pierre-Marie Baty -- use safe version
962
  else if (pv->pathh == 3)
829
  strcpy_s(kibitz_text, sizeof (kibitz_text), buffer); // Pierre-Marie Baty -- use safe version
963
    sprintf(buffer + strlen(buffer), " <50-move>");
830
  if (nskip > 1 && smp_max_threads > 1) {
964
  if (nskip > 1 && smp_max_threads > 1)
-
 
965
    sprintf(buffer + strlen(buffer), " (s=%d)", nskip);
-
 
966
  if (strlen(buffer) < 30) {
831
    buflen = strlen (buffer);
967
    len = 30 - strlen(buffer);
-
 
968
    for (i = 0; i < len; i++)
832
    sprintf_s(buffer + buflen, sizeof (buffer) - buflen, " (s=%d)", nskip); // Pierre-Marie Baty -- use safe version
969
      strcat(buffer, " ");
833
  }
970
  }
834
  if (tree->nodes_searched > noise_level) {
971
  strcpy(kibitz_text, buffer);
-
 
972
  if (time >= (int) noise_level || force) { // Pierre-Marie Baty -- added type cast
835
    noise_block = 0;
973
    noise_block = 0;
836
    Lock(lock_io);
974
    Lock(lock_io);
837
    Print(type, "         ");
975
    Print(2, "         ");
838
    if (level == 6)
976
    if (level == 6)
839
      Print(type, "%2i   %s%s   ", pv_depth, Display2Times(time),
977
      Print(2, "%2i   %s%s   ", pv_depth, Display2Times(time),
840
          DisplayEvaluation(pv->pathv, twtm));
978
          DisplayEvaluation(pv->pathv, twtm));
841
    else
979
    else
842
      Print(type, "%2i-> %s%s   ", pv_depth, Display2Times(time)
980
      Print(2, "%2i-> %s%s   ", pv_depth, Display2Times(time)
843
          , DisplayEvaluation(pv->pathv, twtm));
981
          , DisplayEvaluation(pv->pathv, twtm));
844
    buffp = buffer + 1;
982
    buffp = buffer;
845
    do {
983
    do {
846
      if ((int) strlen(buffp) > line_length - 42)
984
      if ((int) strlen(buffp) > line_length - 38) {
847
        bufftemp = strchr(buffp + line_length - 42, ' ');
985
        bufftemp = buffp + line_length - 38;
-
 
986
        while (*bufftemp != ' ')
-
 
987
          bufftemp--;
-
 
988
        if (*(bufftemp - 1) == '.')
-
 
989
          while (*(--bufftemp) != ' ');
848
      else
990
      } else
849
        bufftemp = 0;
991
        bufftemp = 0;
850
      if (bufftemp)
992
      if (bufftemp)
851
        *bufftemp = 0;
993
        *bufftemp = 0;
852
      Print(type, "%s\n", buffp);
994
      Print(2, "%s\n", buffp);
853
      buffp = bufftemp + 1;
995
      buffp = bufftemp + 1;
854
      if (bufftemp)
996
      if (bufftemp)
-
 
997
        if (!strncmp(buffp, blanks, strlen(buffp)))
-
 
998
          bufftemp = 0;
-
 
999
      if (bufftemp)
855
        Print(type, "                                     ");
1000
        Print(2, "                                     ");
856
    } while (bufftemp);
1001
    } while (bufftemp);
-
 
1002
    idle_time = 0;
-
 
1003
    for (i = 0; i < (int) smp_max_threads; i++) // Pierre-Marie Baty -- added type cast
-
 
1004
      idle_time += thread[i].idle;
857
    idle_percent =
1005
    busy_percent =
858
        100 - Min(100,
1006
        100 - Min(100,
859
        100 * idle_time / (smp_max_threads * (end_time - start_time) + 1));
1007
        100 * idle_time / (smp_max_threads * (end_time - start_time) + 1));
860
    Kibitz(level, twtm, pv_depth, end_time - start_time, pv->pathv,
1008
    Kibitz(level, twtm, pv_depth, end_time - start_time, pv->pathv,
861
        tree->nodes_searched, idle_percent, tree->egtb_probes_successful,
1009
        tree->nodes_searched, busy_percent, (int) tree->egtb_hits, kibitz_text); // Pierre-Marie Baty -- added type cast
862
        kibitz_text);
-
 
863
    Unlock(lock_io);
1010
    Unlock(lock_io);
864
  }
1011
  }
865
  for (i = pv->pathl - 1; i > 0; i--) {
1012
  for (i = pv->pathl - 1; i > 0; i--) {
866
    wtm = Flip(wtm);
1013
    wtm = Flip(wtm);
867
    UnmakeMove(tree, i, pv->path[i], wtm);
1014
    UnmakeMove(tree, i, wtm, pv->path[i]);
868
  }
1015
  }
869
}
1016
}
870
 
1017
 
871
/*
1018
/*
872
 *******************************************************************************
1019
 *******************************************************************************
Line 876... Line 1023...
876
 *   just nnn.n seconds.                                                       *
1023
 *   just nnn.n seconds.                                                       *
877
 *                                                                             *
1024
 *                                                                             *
878
 *******************************************************************************
1025
 *******************************************************************************
879
 */
1026
 */
880
char *DisplayHHMMSS(unsigned int time) {
1027
char *DisplayHHMMSS(unsigned int time) {
881
  static char out[10];
1028
  static char out[32];
882
 
1029
 
883
  time = time / 100;
1030
  time = time / 100;
884
  sprintf_s(out, sizeof (out), "%3u:%02u:%02u", time / 3600, time / 60, time % 60); // Pierre-Marie Baty -- use safe version
1031
  sprintf(out, "%3u:%02u:%02u", time / 3600, (time % 3600) / 60, time % 60);
885
  return out;
1032
  return out;
886
}
1033
}
887
 
1034
 
888
/*
1035
/*
889
 *******************************************************************************
1036
 *******************************************************************************
Line 896... Line 1043...
896
 */
1043
 */
897
char *DisplayHHMM(unsigned int time) {
1044
char *DisplayHHMM(unsigned int time) {
898
  static char out[10];
1045
  static char out[10];
899
 
1046
 
900
  time = time / 6000;
1047
  time = time / 6000;
901
  sprintf_s(out, sizeof (out), "%3u:%02u", time / 60, time % 60); // Pierre-Marie Baty -- use safe version
1048
  sprintf(out, "%3u:%02u", time / 60, time % 60);
902
  return out;
1049
  return out;
903
}
1050
}
904
 
1051
 
905
/*
1052
/*
906
 *******************************************************************************
1053
 *******************************************************************************
907
 *                                                                             *
1054
 *                                                                             *
908
 *   DisplayKMB() takes an integer value that represents nodes per second, or  *
1055
 *   DisplayKMB() takes an integer value that represents nodes per second, or  *
909
 *   just total nodes, and converts it into a more compact form, so that       *
1056
 *   just total nodes, and converts it into a more compact form, so that       *
910
 *   instead of nps=57200931, we get nps=57M.                                  *
1057
 *   instead of nps=57200931, we get nps=57.2M.  We use units of "K", "M",     *
-
 
1058
 *   "B" and "T".  If type==0, K=1000, etc.  If type=1, K=1024, etc.           *
911
 *                                                                             *
1059
 *                                                                             *
912
 *******************************************************************************
1060
 *******************************************************************************
913
 */
1061
 */
914
char *DisplayKMB(uint64_t val) {
1062
char *DisplayKMB(uint64_t val, int type) {
915
  static char out[10];
1063
  static char out[10];
916
 
1064
 
-
 
1065
  if (type == 0) {
917
  if (val < 1000)
1066
    if (val < 1000)
918
    sprintf_s(out, sizeof (out), "%" PRIu64, val); // Pierre-Marie Baty -- use safe version
1067
      sprintf(out, "%" PRIu64, val);
919
  else if (val < 1000000)
1068
    else if (val < 1000000)
920
    sprintf_s(out, sizeof (out), "%.1fK", (double) (val + 500) / 1000); // Pierre-Marie Baty -- use safe version
1069
      sprintf(out, "%.1fK", (double) val / 1000);
921
  else if (val < 1000000000)
1070
    else if (val < 1000000000)
922
    sprintf_s(out, sizeof (out), "%.1fM", (double) (val + 500000) / 1000000); // Pierre-Marie Baty -- use safe version
1071
      sprintf(out, "%.1fM", (double) val / 1000000);
923
  else
1072
    else
924
    sprintf_s(out, sizeof (out), "%.1fB", (double) (val + 500000000) / 1000000000); // Pierre-Marie Baty -- use safe version
1073
      sprintf(out, "%.1fB", (double) val / 1000000000);
-
 
1074
  } else {
-
 
1075
    if (val > 0 && !(val & 0x000000003fffffffULL))
-
 
1076
      sprintf(out, "%dG", (int) (val / (1 << 30)));
-
 
1077
    else if (val > 0 && !(val & 0x00000000000fffffULL))
-
 
1078
      sprintf(out, "%dM", (int) (val / (1 << 20)));
-
 
1079
    else if (val > 0 && !(val & 0x00000000000003ffULL))
-
 
1080
      sprintf(out, "%dK", (int) (val / (1 << 10)));
-
 
1081
    else
-
 
1082
      sprintf(out, "%" PRIu64, val);
-
 
1083
  }
925
  return out;
1084
  return out;
926
}
1085
}
927
 
1086
 
928
/*
1087
/*
929
 *******************************************************************************
1088
 *******************************************************************************
Line 939... Line 1098...
939
 */
1098
 */
940
char *DisplayTime(unsigned int time) {
1099
char *DisplayTime(unsigned int time) {
941
  static char out[10];
1100
  static char out[10];
942
 
1101
 
943
  if (time < 6000)
1102
  if (time < 6000)
944
    sprintf_s(out, sizeof (out), "%6.2f", (float) time / 100.0); // Pierre-Marie Baty -- use safe version
1103
    sprintf(out, "%6.2f", (float) time / 100.0);
945
  else {
1104
  else {
946
    time = time / 100;
1105
    time = time / 100;
947
    sprintf_s(out, sizeof (out), "%3u:%02u", time / 60, time % 60); // Pierre-Marie Baty -- use safe version
1106
    sprintf(out, "%3u:%02u", time / 60, time % 60);
948
  }
1107
  }
949
  return out;
1108
  return out;
950
}
1109
}
951
 
1110
 
952
/*
1111
/*
Line 964... Line 1123...
964
 *   roughly when the move will be announced.                                  *
1123
 *   roughly when the move will be announced.                                  *
965
 *                                                                             *
1124
 *                                                                             *
966
 *******************************************************************************
1125
 *******************************************************************************
967
 */
1126
 */
968
char *Display2Times(unsigned int time) {
1127
char *Display2Times(unsigned int time) {
-
 
1128
  int ttime, c, spaces;
969
  static char out[20], tout[10];
1129
  static char out[20], tout[10];
970
  int ttime;
-
 
971
  int c, spaces;
-
 
972
 
1130
 
973
  if (time < 6000)
1131
  if (time < 6000)
974
    sprintf_s(out, sizeof (out), "%6.2f", (float) time / 100.0); // Pierre-Marie Baty -- use safe version
1132
    sprintf(out, "%6.2f", (float) time / 100.0);
975
  else {
1133
  else {
976
    time = time / 100;
1134
    time = time / 100;
977
    sprintf_s(out, sizeof (out), "%3u:%02u", time / 60, time % 60); // Pierre-Marie Baty -- use safe version
1135
    sprintf(out, "%3u:%02u", time / 60, time % 60);
978
  }
1136
  }
979
  if (search_time_limit)
1137
  if (search_time_limit)
980
    ttime = search_time_limit;
1138
    ttime = search_time_limit;
981
  else
1139
  else
982
    ttime = difficulty * time_limit / 100;
1140
    ttime = difficulty * time_limit / 100;
983
  if (ttime < 360000) {
1141
  if (ttime < 360000) {
984
    if (ttime < 6000)
1142
    if (ttime < 6000)
985
      sprintf_s(tout, sizeof (tout), "%6.2f", (float) ttime / 100.0); // Pierre-Marie Baty -- use safe version
1143
      sprintf(tout, "%6.2f", (float) ttime / 100.0);
986
    else {
1144
    else {
987
      ttime = ttime / 100;
1145
      ttime = ttime / 100;
988
      sprintf_s(tout, sizeof (tout), "%3u:%02u", ttime / 60, ttime % 60); // Pierre-Marie Baty -- use safe version
1146
      sprintf(tout, "%3u:%02u", ttime / 60, ttime % 60);
989
    }
1147
    }
990
    c = strspn(tout, " ");
1148
    c = strspn(tout, " ");
991
    strcat_s(out, sizeof (out), "/"); // Pierre-Marie Baty -- use safe version
1149
    strcat(out, "/");
992
    strcat_s(out, sizeof (out), tout + c); // Pierre-Marie Baty -- use safe version
1150
    strcat(out, tout + c);
993
  }
1151
  }
994
  spaces = 13 - strlen(out);
1152
  spaces = 13 - strlen(out);
995
  for (c = 0; c < spaces; c++)
1153
  for (c = 0; c < spaces; c++)
996
    strcat_s(out, sizeof (out), " "); // Pierre-Marie Baty -- use safe version
1154
    strcat(out, " ");
997
  return out;
1155
  return out;
998
}
1156
}
999
 
1157
 
1000
/*
1158
/*
1001
 *******************************************************************************
1159
 *******************************************************************************
Line 1008... Line 1166...
1008
 */
1166
 */
1009
char *DisplayTimeKibitz(unsigned int time) {
1167
char *DisplayTimeKibitz(unsigned int time) {
1010
  static char out[10];
1168
  static char out[10];
1011
 
1169
 
1012
  if (time < 6000)
1170
  if (time < 6000)
1013
    sprintf_s(out, sizeof (out), "%.2f", (float) time / 100.0); // Pierre-Marie Baty -- use safe version
1171
    sprintf(out, "%.2f", (float) time / 100.0);
1014
  else {
1172
  else {
1015
    time = time / 100;
1173
    time = time / 100;
1016
    sprintf_s(out, sizeof (out), "%u:%02u", time / 60, time % 60); // Pierre-Marie Baty -- use safe version
1174
    sprintf(out, "%u:%02u", time / 60, time % 60);
1017
  }
1175
  }
1018
  return out;
1176
  return out;
1019
}
-
 
1020
 
-
 
1021
/*
-
 
1022
 *******************************************************************************
-
 
1023
 *                                                                             *
-
 
1024
 *   DisplayTreeState() is a debugging procedure used to provide some basic    *
-
 
1025
 *   information about how the parallel search is progressing.  It is invoked  *
-
 
1026
 *   by typing a "." (no quotes) while in console mode.                        *
-
 
1027
 *                                                                             *
-
 
1028
 *******************************************************************************
-
 
1029
 */
-
 
1030
void DisplayTreeState(TREE * RESTRICT tree, int sply, int spos, int maxply) {
-
 
1031
  int left, i, *mvp, parallel = 0;
-
 
1032
  char buf[1024];
-
 
1033
 
-
 
1034
  buf[0] = 0;
-
 
1035
  if (sply == 1) {
-
 
1036
    left = 0;
-
 
1037
    for (i = 0; i < n_root_moves; i++)
-
 
1038
      if (!(root_moves[i].status & 8))
-
 
1039
        left++;
-
 
1040
    sprintf_s(buf, sizeof (buf), "%d:%d/%d  ", 1, left, n_root_moves); // Pierre-Marie Baty -- use safe version
-
 
1041
  } else {
-
 
1042
    for (i = 0; i < spos - 6; i++)
-
 
1043
      strcat_s(buf, sizeof (buf), " "); // Pierre-Marie Baty -- use safe version
-
 
1044
    sprintf(buf + strlen(buf), "[p%2d] ", tree->thread_id);
-
 
1045
  }
-
 
1046
  for (i = Max(sply, 2); i <= maxply; i++) {
-
 
1047
    left = 0;
-
 
1048
    for (mvp = tree->last[i - 1]; mvp < tree->last[i]; mvp++)
-
 
1049
      if (*mvp)
-
 
1050
        left++;
-
 
1051
    sprintf(buf + strlen(buf), "%d:%d/%d  ", i, left,
-
 
1052
        (int) (tree->last[i] - tree->last[i - 1]));
-
 
1053
    if (!(i % 8))
-
 
1054
      strcat_s(buf, sizeof (buf), "\n"); // Pierre-Marie Baty -- use safe version
-
 
1055
    if (tree->nprocs > 1 && tree->ply == i) {
-
 
1056
      parallel = strlen(buf);
-
 
1057
      break;
-
 
1058
    }
-
 
1059
    if (sply > 1)
-
 
1060
      break;
-
 
1061
  }
-
 
1062
  printf("%s\n", buf);
-
 
1063
  if (sply == 1 && tree->nprocs) {
-
 
1064
    for (i = 0; i < smp_max_threads; i++)
-
 
1065
      if (tree->siblings[i])
-
 
1066
        DisplayTreeState(tree->siblings[i], tree->ply + 1, parallel, maxply);
-
 
1067
  }
-
 
1068
}
-
 
1069
 
-
 
1070
/*
-
 
1071
 *******************************************************************************
-
 
1072
 *                                                                             *
-
 
1073
 *   DisplayType3() prints personality parameters that use an 8x8 board for    *
-
 
1074
 *   their base values.  This prints them side by side with rank/file labels   *
-
 
1075
 *   to make it easier to read.                                                *
-
 
1076
 *                                                                             *
-
 
1077
 *******************************************************************************
-
 
1078
 */
-
 
1079
void DisplayType3(int *array, int *array2) {
-
 
1080
  int i, j;
-
 
1081
 
-
 
1082
  printf("    ----------- Middlegame -----------   ");
-
 
1083
  printf("    ------------- Endgame -----------\n");
-
 
1084
  for (i = 0; i < 8; i++) {
-
 
1085
    printf("    ");
-
 
1086
    for (j = 0; j < 8; j++)
-
 
1087
      printf("%3d ", array[64 + (7 - i) * 8 + j]);
-
 
1088
    printf("  |  %d  |", 8 - i);
-
 
1089
    printf("  ");
-
 
1090
    for (j = 0; j < 8; j++)
-
 
1091
      printf("%3d ", array2[64 + (7 - i) * 8 + j]);
-
 
1092
    printf("\n");
-
 
1093
  }
-
 
1094
  printf
-
 
1095
      ("    ----------------------------------       ---------------------------------\n");
-
 
1096
  printf("      a   b   c   d   e   f   g   h        ");
-
 
1097
  printf("      a   b   c   d   e   f   g   h\n");
-
 
1098
}
-
 
1099
 
-
 
1100
/*
-
 
1101
 *******************************************************************************
-
 
1102
 *                                                                             *
-
 
1103
 *   DisplayType4() prints personality parameters that use an 8x8 board for    *
-
 
1104
 *   their base values.  This prints them side by side with rank/file labels   *
-
 
1105
 *   to make it easier to read.                                                *
-
 
1106
 *                                                                             *
-
 
1107
 *******************************************************************************
-
 
1108
 */
-
 
1109
void DisplayType4(int *array, int *array2) {
-
 
1110
  int i, j;
-
 
1111
 
-
 
1112
  printf("    ----------- Middlegame -----------   ");
-
 
1113
  printf("    ------------- Endgame -----------\n");
-
 
1114
  for (i = 0; i < 8; i++) {
-
 
1115
    printf("    ");
-
 
1116
    for (j = 0; j < 8; j++)
-
 
1117
      printf("%3d ", array[(7 - i) * 8 + j]);
-
 
1118
    printf("  |  %d  |", 8 - i);
-
 
1119
    printf("  ");
-
 
1120
    for (j = 0; j < 8; j++)
-
 
1121
      printf("%3d ", array2[(7 - i) * 8 + j]);
-
 
1122
    printf("\n");
-
 
1123
  }
-
 
1124
  printf
-
 
1125
      ("    ----------------------------------       ---------------------------------\n");
-
 
1126
  printf("      a   b   c   d   e   f   g   h        ");
-
 
1127
  printf("      a   b   c   d   e   f   g   h\n");
-
 
1128
}
-
 
1129
 
-
 
1130
/*
-
 
1131
 *******************************************************************************
-
 
1132
 *                                                                             *
-
 
1133
 *   DisplayType5() prints personality parameters that use an array[size].     *
-
 
1134
 *                                                                             *
-
 
1135
 *******************************************************************************
-
 
1136
 */
-
 
1137
void DisplayType5(int *array, int size) {
-
 
1138
  int i;
-
 
1139
 
-
 
1140
  printf("   ");
-
 
1141
  for (i = 0; i < size; i++)
-
 
1142
    printf("%4d ", array[i]);
-
 
1143
  printf("\n");
-
 
1144
}
-
 
1145
 
-
 
1146
/*
-
 
1147
 *******************************************************************************
-
 
1148
 *                                                                             *
-
 
1149
 *   DisplayType6() prints personality parameters that use an array[mg][8]     *
-
 
1150
 *   format.                                                                   *
-
 
1151
 *                                                                             *
-
 
1152
 *******************************************************************************
-
 
1153
 */
-
 
1154
void DisplayType6(int *array) {
-
 
1155
  int i;
-
 
1156
 
-
 
1157
  printf("    ----------- Middlegame ------------ ");
-
 
1158
  printf("    ------------- Endgame ------------\n");
-
 
1159
  printf("    ");
-
 
1160
  for (i = 0; i < 8; i++)
-
 
1161
    printf("%3d ", array[i]);
-
 
1162
  printf("  |     |");
-
 
1163
  printf("  ");
-
 
1164
  for (i = 8; i < 16; i++)
-
 
1165
    printf("%3d ", array[i]);
-
 
1166
  printf("\n");
-
 
1167
}
1177
}
1168
 
1178
 
1169
/*
1179
/*
1170
 *******************************************************************************
1180
 *******************************************************************************
1171
 *                                                                             *
1181
 *                                                                             *
Line 1177... Line 1187...
1177
 *                                                                             *
1187
 *                                                                             *
1178
 *******************************************************************************
1188
 *******************************************************************************
1179
 */
1189
 */
1180
#if !defined(NOEGTB)
1190
#if !defined(NOEGTB)
1181
void EGTBPV(TREE * RESTRICT tree, int wtm) {
1191
void EGTBPV(TREE * RESTRICT tree, int wtm) {
-
 
1192
  uint64_t hk[1024], phk[1024], pos[1024];
1182
  int moves[1024], current[256];
1193
  unsigned moves[1024], current[256], *last;
1183
  uint64_t hk[1024], phk[1024];
1194
  int value, ply, i, j, nmoves;
-
 
1195
  int t_move_number, best = 0, bestmv = 0, optimal_mv = 0, legal;
1184
  char buffer[16384], *next;
1196
  char buffer[16384], *next;
1185
  uint64_t pos[1024];
-
 
1186
  int value;
-
 
1187
  int ply, i, j, nmoves, *last, t_move_number;
-
 
1188
  int best = 0, bestmv = 0, optimal_mv = 0;
-
 
1189
  int legal;
-
 
1190
 
1197
 
1191
/*
1198
/*
1192
 ************************************************************
1199
 ************************************************************
1193
 *                                                          *
1200
 *                                                          *
1194
 *  First, see if this is a known EGTB position.  If not,   *
1201
 *  First, see if this is a known EGTB position.  If not,   *
Line 1202... Line 1209...
1202
  if (Castle(1, white) + Castle(1, white))
1209
  if (Castle(1, white) + Castle(1, white))
1203
    return;
1210
    return;
1204
  if (!EGTBProbe(tree, 1, wtm, &value))
1211
  if (!EGTBProbe(tree, 1, wtm, &value))
1205
    return;
1212
    return;
1206
  t_move_number = move_number;
1213
  t_move_number = move_number;
1207
  if (display_options & 64)
-
 
1208
    sprintf_s(buffer, sizeof (buffer), "%d.", move_number); // Pierre-Marie Baty -- use safe version
1214
  sprintf(buffer, "%d.", move_number);
1209
  else
1215
  if (!wtm)
1210
    buffer[0] = 0;
-
 
1211
  if ((display_options & 64) && !wtm)
-
 
1212
    strcat_s(buffer, sizeof (buffer), " ..."); // Pierre-Marie Baty -- use safe version
1216
    sprintf(buffer + strlen(buffer), " ...");
1213
/*
1217
/*
1214
 ************************************************************
1218
 ************************************************************
1215
 *                                                          *
1219
 *                                                          *
1216
 *  The rest is simple, but messy.  Generate all moves,     *
1220
 *  The rest is simple, but messy.  Generate all moves,     *
1217
 *  then find the move with the best egtb score and make it *
1221
 *  then find the move with the best egtb score and make it *
Line 1228... Line 1232...
1228
    last = GenerateNoncaptures(tree, 1, wtm, last);
1232
    last = GenerateNoncaptures(tree, 1, wtm, last);
1229
    nmoves = last - current;
1233
    nmoves = last - current;
1230
    best = -MATE - 1;
1234
    best = -MATE - 1;
1231
    legal = 0;
1235
    legal = 0;
1232
    for (i = 0; i < nmoves; i++) {
1236
    for (i = 0; i < nmoves; i++) {
1233
      MakeMove(tree, 1, current[i], wtm);
1237
      MakeMove(tree, 1, wtm, current[i]);
1234
      if (!Check(wtm)) {
1238
      if (!Check(wtm)) {
1235
        legal++;
1239
        legal++;
1236
        if (TotalAllPieces == 2 || EGTBProbe(tree, 2, Flip(wtm), &value)) {
1240
        if (TotalAllPieces == 2 || EGTBProbe(tree, 2, Flip(wtm), &value)) {
1237
          if (TotalAllPieces > 2)
1241
          if (TotalAllPieces > 2)
1238
            value = -value;
1242
            value = -value;
Line 1244... Line 1248...
1244
            optimal_mv = 1;
1248
            optimal_mv = 1;
1245
          } else if (value == best)
1249
          } else if (value == best)
1246
            optimal_mv = 0;
1250
            optimal_mv = 0;
1247
        }
1251
        }
1248
      }
1252
      }
1249
      UnmakeMove(tree, 1, current[i], wtm);
1253
      UnmakeMove(tree, 1, wtm, current[i]);
1250
    }
1254
    }
1251
    if (best > -MATE - 1) {
1255
    if (best > -MATE - 1) {
1252
      moves[ply] = bestmv;
1256
      moves[ply] = bestmv;
1253
      if ((display_options & 64) && ply > 1 && wtm)
1257
      if (ply > 1 && wtm)
1254
        sprintf(buffer + strlen(buffer), " %d.", t_move_number);
1258
        sprintf(buffer + strlen(buffer), " %d.", t_move_number);
1255
      sprintf(buffer + strlen(buffer), " %s", OutputMove(tree, bestmv, 1,
1259
      sprintf(buffer + strlen(buffer), " %s", OutputMove(tree, 1, wtm,
1256
              wtm));
1260
              bestmv));
1257
      if (!strchr(buffer, '#') && legal > 1 && optimal_mv)
1261
      if (!strchr(buffer, '#') && legal > 1 && optimal_mv)
1258
        strcat_s(buffer, sizeof (buffer), "!"); // Pierre-Marie Baty -- use safe version
1262
        sprintf(buffer + strlen(buffer), "!");
1259
      hk[ply] = HashKey;
1263
      hk[ply] = HashKey;
1260
      phk[ply] = PawnHashKey;
1264
      phk[ply] = PawnHashKey;
1261
      MakeMove(tree, 1, bestmv, wtm);
1265
      MakeMove(tree, 1, wtm, bestmv);
1262
      tree->status[1] = tree->status[2];
1266
      tree->status[1] = tree->status[2];
1263
      wtm = Flip(wtm);
1267
      wtm = Flip(wtm);
1264
      for (j = 2 - (ply & 1); j < ply; j += 2)
1268
      for (j = 2 - (ply & 1); j < ply; j += 2)
1265
        if (pos[ply] == pos[j])
1269
        if (pos[ply] == pos[j])
1266
          break;
1270
          break;
Line 1278... Line 1282...
1278
  nmoves = ply;
1282
  nmoves = ply;
1279
  for (; ply > 0; ply--) {
1283
  for (; ply > 0; ply--) {
1280
    wtm = Flip(wtm);
1284
    wtm = Flip(wtm);
1281
    tree->save_hash_key[1] = hk[ply];
1285
    tree->save_hash_key[1] = hk[ply];
1282
    tree->save_pawn_hash_key[1] = phk[ply];
1286
    tree->save_pawn_hash_key[1] = phk[ply];
1283
    UnmakeMove(tree, 1, moves[ply], wtm);
1287
    UnmakeMove(tree, 1, wtm, moves[ply]);
1284
    tree->status[2] = tree->status[1];
1288
    tree->status[2] = tree->status[1];
1285
  }
1289
  }
1286
  next = buffer;
1290
  next = buffer;
1287
  while (nmoves) {
1291
  while (nmoves) {
1288
    if ((int) strlen(next) > line_length) { // Pierre-Marie Baty -- added type cast
1292
    if ((int) strlen(next) > line_length) { // Pierre-Marie Baty -- added type cast
Line 1299... Line 1303...
1299
      break;
1303
      break;
1300
    }
1304
    }
1301
  }
1305
  }
1302
}
1306
}
1303
#endif
1307
#endif
1304
/*
-
 
1305
 *******************************************************************************
-
 
1306
 *                                                                             *
-
 
1307
 *   DisplayChessMove() is a debugging function that displays a chess move in  *
-
 
1308
 *   a very simple (non-algebraic) form.                                       *
-
 
1309
 *                                                                             *
-
 
1310
 *******************************************************************************
-
 
1311
 */
-
 
1312
void DisplayChessMove(char *title, int move) {
-
 
1313
  Print(4095, "%s  piece=%d, from=%d, to=%d, captured=%d, promote=%d\n",
-
 
1314
      title, Piece(move), From(move), To(move), Captured(move),
-
 
1315
      Promote(move));
-
 
1316
}
-
 
1317
 
1308
 
1318
/*
1309
/*
1319
 *******************************************************************************
1310
 *******************************************************************************
1320
 *                                                                             *
1311
 *                                                                             *
1321
 *   FormatPV() is used to display a PV during the search.  It will also note  *
1312
 *   FormatPV() is used to display a PV during the search.  It will also note  *
1322
 *   when the PV was terminated by a hash table hit.                           *
1313
 *   when the PV was terminated by a hash table hit.                           *
1323
 *                                                                             *
1314
 *                                                                             *
1324
 *******************************************************************************
1315
 *******************************************************************************
1325
 */
1316
 */
1326
char *FormatPV(TREE * RESTRICT tree, int wtm, PATH pv) {
1317
char *FormatPV(TREE * RESTRICT tree, int wtm, PATH pv) {
-
 
1318
  int i, t_move_number;
1327
  static char buffer[4096];
1319
  static char buffer[4096];
1328
  int i, t_move_number;
-
 
1329
 
1320
 
1330
/*
1321
/*
1331
 ************************************************************
1322
 ************************************************************
1332
 *                                                          *
1323
 *                                                          *
1333
 *  Initialize.                                             *
1324
 *  Initialize.                                             *
1334
 *                                                          *
1325
 *                                                          *
1335
 ************************************************************
1326
 ************************************************************
1336
 */
1327
 */
1337
  t_move_number = move_number;
1328
  t_move_number = move_number;
1338
  if (display_options & 64)
-
 
1339
    sprintf_s(buffer, sizeof (buffer), " %d.", move_number); // Pierre-Marie Baty -- use safe version
1329
  sprintf(buffer, " %d.", move_number);
1340
  else
1330
  if (!wtm)
1341
    buffer[0] = 0;
-
 
1342
  if ((display_options & 64) && !wtm)
-
 
1343
    strcat_s(buffer, sizeof (buffer), " ..."); // Pierre-Marie Baty -- use safe version
1331
    sprintf(buffer + strlen(buffer), " ...");
1344
  for (i = 1; i < (int) pv.pathl; i++) {
1332
  for (i = 1; i < (int) pv.pathl; i++) {
1345
    if ((display_options & 64) && i > 1 && wtm)
1333
    if (i > 1 && wtm)
1346
      sprintf(buffer + strlen(buffer), " %d.", t_move_number);
1334
      sprintf(buffer + strlen(buffer), " %d.", t_move_number);
1347
    sprintf(buffer + strlen(buffer), " %s", OutputMove(tree, pv.path[i], i,
1335
    sprintf(buffer + strlen(buffer), " %s", OutputMove(tree, i, wtm,
1348
            wtm));
1336
            pv.path[i]));
1349
    MakeMove(tree, i, pv.path[i], wtm);
1337
    MakeMove(tree, i, wtm, pv.path[i]);
1350
    wtm = Flip(wtm);
1338
    wtm = Flip(wtm);
1351
    if (wtm)
1339
    if (wtm)
1352
      t_move_number++;
1340
      t_move_number++;
1353
  }
1341
  }
1354
  for (i = pv.pathl - 1; i > 0; i--) {
1342
  for (i = pv.pathl - 1; i > 0; i--) {
1355
    wtm = Flip(wtm);
1343
    wtm = Flip(wtm);
1356
    UnmakeMove(tree, i, pv.path[i], wtm);
1344
    UnmakeMove(tree, i, wtm, pv.path[i]);
1357
  }
1345
  }
1358
  return buffer;
1346
  return buffer;
1359
}
1347
}
1360
 
1348
 
1361
/* last modified 02/26/14 */
1349
/* last modified 02/26/14 */
Line 1368... Line 1356...
1368
 *   to terminate the game.                                                    *
1356
 *   to terminate the game.                                                    *
1369
 *                                                                             *
1357
 *                                                                             *
1370
 *******************************************************************************
1358
 *******************************************************************************
1371
 */
1359
 */
1372
int GameOver(int wtm) {
1360
int GameOver(int wtm) {
1373
  int *mvp, *lastm, rmoves[256];
-
 
1374
  TREE *const tree = block[0];
1361
  TREE *const tree = block[0];
1375
  int over = 1;
1362
  unsigned *mvp, *lastm, rmoves[256], over = 1;
1376
 
1363
 
1377
/*
1364
/*
1378
 ************************************************************
1365
 ************************************************************
1379
 *                                                          *
1366
 *                                                          *
1380
 *  First, use GenerateMoves() to generate the set of       *
1367
 *  First, use GenerateMoves() to generate the set of       *
Line 1393... Line 1380...
1393
 *  officially over.                                        *
1380
 *  officially over.                                        *
1394
 *                                                          *
1381
 *                                                          *
1395
 ************************************************************
1382
 ************************************************************
1396
 */
1383
 */
1397
  for (mvp = rmoves; mvp < lastm; mvp++) {
1384
  for (mvp = rmoves; mvp < lastm; mvp++) {
1398
    MakeMove(tree, 1, *mvp, wtm);
1385
    MakeMove(tree, 1, wtm, *mvp);
1399
    if (!Check(wtm))
1386
    if (!Check(wtm))
1400
      over = 0;
1387
      over = 0;
1401
    UnmakeMove(tree, 1, *mvp, wtm);
1388
    UnmakeMove(tree, 1, wtm, *mvp);
1402
  }
1389
  }
1403
/*
1390
/*
1404
 ************************************************************
1391
 ************************************************************
1405
 *                                                          *
1392
 *                                                          *
1406
 *  If we did not make it thru the complete move list, we   *
1393
 *  If we did not make it thru the complete move list, we   *
Line 1431... Line 1418...
1431
unsigned int ReadClock(void) {
1418
unsigned int ReadClock(void) {
1432
#if defined(UNIX)
1419
#if defined(UNIX)
1433
  struct timeval timeval;
1420
  struct timeval timeval;
1434
  struct timezone timezone;
1421
  struct timezone timezone;
1435
#else
1422
#else
1436
//  HANDLE hThread;
1423
  //HANDLE hThread; // Pierre-Marie Baty -- unreferenced variable
1437
//  FILETIME ftCreate, ftExit, ftKernel, ftUser; // Pierre-Marie Baty -- unused variables
1424
  //FILETIME ftCreate, ftExit, ftKernel, ftUser; // Pierre-Marie Baty -- unreferenced variables
1438
//  uint64_t tUser64;
1425
  //uint64_t tUser64; // Pierre-Marie Baty -- unreferenced variable
1439
#endif
1426
#endif
1440
#if defined(UNIX)
1427
#if defined(UNIX)
1441
  gettimeofday(&timeval, &timezone);
1428
  gettimeofday(&timeval, &timezone);
1442
  return timeval.tv_sec * 100 + (timeval.tv_usec / 10000);
1429
  return timeval.tv_sec * 100 + (timeval.tv_usec / 10000);
1443
#else
1430
#else
Line 1446... Line 1433...
1446
}
1433
}
1447
 
1434
 
1448
/*
1435
/*
1449
 *******************************************************************************
1436
 *******************************************************************************
1450
 *                                                                             *
1437
 *                                                                             *
1451
 *   FindBlockID() converts a thread block pointer into an ID that is easier to*
1438
 *   FindBlockID() converts a thread block pointer into an ID that is easier   *
1452
 *   understand when debugging.                                                *
1439
 *   to understand when debugging.                                             *
1453
 *                                                                             *
1440
 *                                                                             *
1454
 *******************************************************************************
1441
 *******************************************************************************
1455
 */
1442
 */
1456
int FindBlockID(TREE * RESTRICT which) {
1443
int FindBlockID(TREE * RESTRICT which) {
1457
  int i;
1444
  int i;
1458
 
1445
 
1459
  for (i = 0; i < MAX_BLOCKS + 1; i++)
1446
  for (i = 0; i <= (int) smp_max_threads * 64; i++) // Pierre-Marie Baty -- added type cast
1460
    if (which == block[i])
1447
    if (which == block[i])
1461
      return i;
1448
      return i;
1462
  return -1;
1449
  return -1;
1463
}
1450
}
1464
 
1451
 
Line 1471... Line 1458...
1471
 *   squares, and the like.                                                    *
1458
 *   squares, and the like.                                                    *
1472
 *                                                                             *
1459
 *                                                                             *
1473
 *******************************************************************************
1460
 *******************************************************************************
1474
 */
1461
 */
1475
int InvalidPosition(TREE * RESTRICT tree) {
1462
int InvalidPosition(TREE * RESTRICT tree) {
1476
  int error = 0;
-
 
1477
  int wp, wn, wb, wr, wq, bp, bn, bb, br, bq;
1463
  int error = 0, wp, wn, wb, wr, wq, wk, bp, bn, bb, br, bq, bk;
1478
 
1464
 
1479
  wp = PopCnt(Pawns(white));
1465
  wp = PopCnt(Pawns(white));
1480
  wn = PopCnt(Knights(white));
1466
  wn = PopCnt(Knights(white));
1481
  wb = PopCnt(Bishops(white));
1467
  wb = PopCnt(Bishops(white));
1482
  wr = PopCnt(Rooks(white));
1468
  wr = PopCnt(Rooks(white));
1483
  wq = PopCnt(Queens(white));
1469
  wq = PopCnt(Queens(white));
-
 
1470
  wk = PopCnt(Kings(white));
1484
  bp = PopCnt(Pawns(black));
1471
  bp = PopCnt(Pawns(black));
1485
  bn = PopCnt(Knights(black));
1472
  bn = PopCnt(Knights(black));
1486
  bb = PopCnt(Bishops(black));
1473
  bb = PopCnt(Bishops(black));
1487
  br = PopCnt(Rooks(black));
1474
  br = PopCnt(Rooks(black));
1488
  bq = PopCnt(Queens(black));
1475
  bq = PopCnt(Queens(black));
-
 
1476
  bk = PopCnt(Kings(black));
1489
  if (wp > 8) {
1477
  if (wp > 8) {
1490
    Print(4095, "illegal position, too many white pawns\n");
1478
    Print(4095, "illegal position, too many white pawns\n");
1491
    error = 1;
1479
    error = 1;
1492
  }
1480
  }
1493
  if (wp + wn > 10) {
1481
  if (wn && wp + wn > 10) {
1494
    Print(4095, "illegal position, too many white knights\n");
1482
    Print(4095, "illegal position, too many white knights\n");
1495
    error = 1;
1483
    error = 1;
1496
  }
1484
  }
1497
  if (wp + wb > 10) {
1485
  if (wb && wp + wb > 10) {
1498
    Print(4095, "illegal position, too many white bishops\n");
1486
    Print(4095, "illegal position, too many white bishops\n");
1499
    error = 1;
1487
    error = 1;
1500
  }
1488
  }
1501
  if (wp + wr > 10) {
1489
  if (wr && wp + wr > 10) {
1502
    Print(4095, "illegal position, too many white rooks\n");
1490
    Print(4095, "illegal position, too many white rooks\n");
1503
    error = 1;
1491
    error = 1;
1504
  }
1492
  }
1505
  if (wp + wq > 10) {
1493
  if (wq && wp + wq > 10) {
1506
    Print(4095, "illegal position, too many white queens\n");
1494
    Print(4095, "illegal position, too many white queens\n");
1507
    error = 1;
1495
    error = 1;
1508
  }
1496
  }
1509
  if (KingSQ(white) > 63) {
1497
  if (wk == 0) {
1510
    Print(4095, "illegal position, no white king\n");
1498
    Print(4095, "illegal position, no white king\n");
1511
    error = 1;
1499
    error = 1;
1512
  }
1500
  }
-
 
1501
  if (wk > 1) {
-
 
1502
    Print(4095, "illegal position, multiple white kings\n");
-
 
1503
    error = 1;
-
 
1504
  }
1513
  if (wp + wn + wb + wr + wq > 15) {
1505
  if ((wn + wb + wr + wq) && wp + wn + wb + wr + wq > 15) {
1514
    Print(4095, "illegal position, too many white pieces\n");
1506
    Print(4095, "illegal position, too many white pieces\n");
1515
    error = 1;
1507
    error = 1;
1516
  }
1508
  }
1517
  if (Pawns(white) & (rank_mask[RANK1] | rank_mask[RANK8])) {
1509
  if (Pawns(white) & (rank_mask[RANK1] | rank_mask[RANK8])) {
1518
    Print(4095, "illegal position, white pawns on first/eighth rank(s)\n");
1510
    Print(4095, "illegal position, white pawns on first/eighth rank(s)\n");
Line 1520... Line 1512...
1520
  }
1512
  }
1521
  if (bp > 8) {
1513
  if (bp > 8) {
1522
    Print(4095, "illegal position, too many black pawns\n");
1514
    Print(4095, "illegal position, too many black pawns\n");
1523
    error = 1;
1515
    error = 1;
1524
  }
1516
  }
1525
  if (bp + bn > 10) {
1517
  if (bn && bp + bn > 10) {
1526
    Print(4095, "illegal position, too many black knights\n");
1518
    Print(4095, "illegal position, too many black knights\n");
1527
    error = 1;
1519
    error = 1;
1528
  }
1520
  }
1529
  if (bp + bb > 10) {
1521
  if (bb && bp + bb > 10) {
1530
    Print(4095, "illegal position, too many black bishops\n");
1522
    Print(4095, "illegal position, too many black bishops\n");
1531
    error = 1;
1523
    error = 1;
1532
  }
1524
  }
1533
  if (bp + br > 10) {
1525
  if (br && bp + br > 10) {
1534
    Print(4095, "illegal position, too many black rooks\n");
1526
    Print(4095, "illegal position, too many black rooks\n");
1535
    error = 1;
1527
    error = 1;
1536
  }
1528
  }
1537
  if (bp + bq > 10) {
1529
  if (bq && bp + bq > 10) {
1538
    Print(4095, "illegal position, too many black queens\n");
1530
    Print(4095, "illegal position, too many black queens\n");
1539
    error = 1;
1531
    error = 1;
1540
  }
1532
  }
1541
  if (KingSQ(black) > 63) {
1533
  if (bk == 0) {
1542
    Print(4095, "illegal position, no black king\n");
1534
    Print(4095, "illegal position, no black king\n");
1543
    error = 1;
1535
    error = 1;
1544
  }
1536
  }
-
 
1537
  if (bk > 1) {
-
 
1538
    Print(4095, "illegal position, multiple black kings\n");
-
 
1539
    error = 1;
-
 
1540
  }
1545
  if (bp + bn + bb + br + bq > 15) {
1541
  if ((bn + bb + br + bq) && bp + bn + bb + br + bq > 15) {
1546
    Print(4095, "illegal position, too many black pieces\n");
1542
    Print(4095, "illegal position, too many black pieces\n");
1547
    error = 1;
1543
    error = 1;
1548
  }
1544
  }
1549
  if (Pawns(black) & (rank_mask[RANK1] | rank_mask[RANK8])) {
1545
  if (Pawns(black) & (rank_mask[RANK1] | rank_mask[RANK8])) {
1550
    Print(4095, "illegal position, black pawns on first/eighth rank(s)\n");
1546
    Print(4095, "illegal position, black pawns on first/eighth rank(s)\n");
Line 1582... Line 1578...
1582
 *   the setup needed to start a new game.                                     *
1578
 *   the setup needed to start a new game.                                     *
1583
 *                                                                             *
1579
 *                                                                             *
1584
 *******************************************************************************
1580
 *******************************************************************************
1585
 */
1581
 */
1586
void NewGame(int save) {
1582
void NewGame(int save) {
1587
  static int save_book_selection_width = 5;
1583
  TREE *const tree = block[0];
1588
  static int save_kibitz = 0;
1584
  static int save_book_selection_width = 5, save_kibitz = 0;
1589
  static int save_resign = 0, save_resign_count = 0, save_draw_count = 0;
1585
  static int save_resign = 0, save_resign_count = 0, save_draw_count = 0;
1590
  static int save_learning = 0;
-
 
1591
  static int save_learn = 0;
-
 
1592
  static int save_accept_draws = 0;
1586
  static int save_learning = 0, save_learn = 0, save_accept_draws = 0;
1593
  int id;
1587
  int id;
1594
  TREE *const tree = block[0];
-
 
1595
 
1588
 
1596
  new_game = 0;
1589
  new_game = 0;
1597
  if (save) {
1590
  if (save) {
1598
    save_book_selection_width = book_selection_width;
1591
    save_book_selection_width = book_selection_width;
1599
    save_kibitz = kibitz;
1592
    save_kibitz = kibitz;
Line 1619... Line 1612...
1619
    learn_value = 0;
1612
    learn_value = 0;
1620
    ponder_move = 0;
1613
    ponder_move = 0;
1621
    last_search_value = 0;
1614
    last_search_value = 0;
1622
    last_pv.pathd = 0;
1615
    last_pv.pathd = 0;
1623
    last_pv.pathl = 0;
1616
    last_pv.pathl = 0;
1624
    initial_position[0] = 0; // Pierre-Marie Baty -- use safe version
1617
    strcpy(initial_position, "");
1625
    InitializeChessBoard(tree);
1618
    InitializeChessBoard(tree);
1626
    InitializeHashTables();
1619
    InitializeHashTables(0);
1627
    force = 0;
1620
    force = 0;
1628
    books_file = normal_bs_file;
1621
    books_file = normal_bs_file;
1629
    draw_score[0] = 0;
1622
    draw_score[0] = 0;
1630
    draw_score[1] = 0;
1623
    draw_score[1] = 0;
1631
    game_wtm = 1;
1624
    game_wtm = 1;
Line 1637... Line 1630...
1637
    if (move_actually_played) {
1630
    if (move_actually_played) {
1638
      if (log_file) {
1631
      if (log_file) {
1639
        fclose(log_file);
1632
        fclose(log_file);
1640
        fclose(history_file);
1633
        fclose(history_file);
1641
        id = InitializeGetLogID();
1634
        id = InitializeGetLogID();
1642
        sprintf_s(log_filename, sizeof (log_filename), "%s/log.%03d", log_path, id); // Pierre-Marie Baty -- use safe version
1635
        sprintf(log_filename, "%s/log.%03d", log_path, id);
1643
        sprintf_s(history_filename, sizeof (history_filename), "%s/game.%03d", log_path, id); // Pierre-Marie Baty -- use safe version
1636
        sprintf(history_filename, "%s/game.%03d", log_path, id);
1644
        fopen_s (&log_file, log_filename, "w"); // Pierre-Marie Baty -- use safe version
1637
        log_file = fopen(log_filename, "w");
1645
        fopen_s (&history_file, history_filename, "w+"); // Pierre-Marie Baty -- use safe version
1638
        history_file = fopen(history_filename, "w+");
1646
        if (!history_file) {
1639
        if (!history_file) {
1647
          printf("ERROR, unable to open game history file, exiting\n");
1640
          printf("ERROR, unable to open game history file, exiting\n");
1648
          CraftyExit(1);
1641
          CraftyExit(1);
1649
        }
1642
        }
1650
      }
1643
      }
Line 1676... Line 1669...
1676
 *   time resolution.                                                          *
1669
 *   time resolution.                                                          *
1677
 *                                                                             *
1670
 *                                                                             *
1678
 *******************************************************************************
1671
 *******************************************************************************
1679
 */
1672
 */
1680
int ParseTime(char *string) {
1673
int ParseTime(char *string) {
1681
  int time = 0;
-
 
1682
  int minutes = 0;
1674
  int time = 0, minutes = 0;
1683
 
1675
 
1684
  while (*string) {
1676
  while (*string) {
1685
    switch (*string) {
1677
    switch (*string) {
1686
      case '0':
1678
      case '0':
1687
      case '1':
1679
      case '1':
Line 1717... Line 1709...
1717
 *   the side whose turn it is to move.                                        *
1709
 *   the side whose turn it is to move.                                        *
1718
 *                                                                             *
1710
 *                                                                             *
1719
 *******************************************************************************
1711
 *******************************************************************************
1720
 */
1712
 */
1721
void Pass(void) {
1713
void Pass(void) {
1722
  char buffer[128];
-
 
1723
  const int halfmoves_done = 2 * (move_number - 1) + (1 - game_wtm);
1714
  const int halfmoves_done = 2 * (move_number - 1) + (1 - game_wtm);
1724
  int prev_pass = 0;
1715
  int prev_pass = 0;
-
 
1716
  char buffer[128];
1725
 
1717
 
1726
/* Was previous move a pass? */
1718
/* Was previous move a pass? */
1727
  if (halfmoves_done > 0) {
1719
  if (halfmoves_done > 0) {
1728
    if (history_file) {
1720
    if (history_file) {
1729
      fseek(history_file, (halfmoves_done - 1) * 10, SEEK_SET);
1721
      fseek(history_file, (halfmoves_done - 1) * 10, SEEK_SET);
1730
      if (fscanf_s(history_file, "%s", buffer, sizeof (buffer)) == 0 ||
1722
      if (fscanf(history_file, "%s", buffer) == 0 ||
1731
          strcmp(buffer, "pass") == 0)
1723
          strcmp(buffer, "pass") == 0)
1732
        prev_pass = 1;
1724
        prev_pass = 1;
1733
    }
1725
    }
1734
  }
1726
  }
1735
  if (prev_pass) {
1727
  if (prev_pass) {
Line 1765... Line 1757...
1765
 */
1757
 */
1766
void Print(int vb, char *fmt, ...) {
1758
void Print(int vb, char *fmt, ...) {
1767
  va_list ap;
1759
  va_list ap;
1768
 
1760
 
1769
  va_start(ap, fmt);
1761
  va_start(ap, fmt);
1770
  if (vb & display_options)
1762
  if (vb == 4095 || vb & display_options) {
1771
    vprintf(fmt, ap);
1763
    vprintf(fmt, ap);
1772
  fflush(stdout);
1764
    fflush(stdout);
-
 
1765
  }
1773
  if (time_limit > -99 || tc_time_remaining[root_wtm] > 6000 || vb == 4095) {
1766
  if (time_limit > 5 || tc_time_remaining[root_wtm] > 1000 || vb == 4095) {
1774
    va_start(ap, fmt);
1767
    va_start(ap, fmt);
1775
    if (log_file)
1768
    if (log_file) {
1776
      vfprintf(log_file, fmt, ap);
1769
      vfprintf(log_file, fmt, ap);
1777
    if (log_file)
-
 
1778
      fflush(log_file);
1770
      fflush(log_file);
-
 
1771
    }
1779
  }
1772
  }
1780
  va_end(ap);
1773
  va_end(ap);
1781
}
-
 
1782
 
-
 
1783
/*
-
 
1784
 *******************************************************************************
-
 
1785
 *                                                                             *
-
 
1786
 *   PrintKM() converts a binary value to a real K/M type value, rather than   *
-
 
1787
 *   the more common K=1000, M=1000000 type output.  This is used for info     *
-
 
1788
 *   about the hash table sizes for one thing.                                 *
-
 
1789
 *                                                                             *
-
 
1790
 *******************************************************************************
-
 
1791
 */
-
 
1792
char *PrintKM(size_t val, int realK) {
-
 
1793
  static char buf[32];
-
 
1794
 
-
 
1795
  if (realK) {
-
 
1796
    if (val >= 1 << 20 && !(val & ((1 << 20) - 1)))
-
 
1797
      sprintf_s(buf, sizeof (buf), "%dM", (int) (val / (1 << 20))); // Pierre-Marie Baty -- use safe version
-
 
1798
    else if (val >= 1 << 10)
-
 
1799
      sprintf_s(buf, sizeof (buf), "%dK", (int) (val / (1 << 10))); // Pierre-Marie Baty -- use safe version
-
 
1800
    else
-
 
1801
      sprintf_s(buf, sizeof (buf), "%d", (int) val); // Pierre-Marie Baty -- use safe version
-
 
1802
    return buf;
-
 
1803
  } else {
-
 
1804
    if (val >= 1000000 && !(val % 1000000))
-
 
1805
      sprintf_s(buf, sizeof (buf), "%dM", (int) (val / 1000000)); // Pierre-Marie Baty -- use safe version
-
 
1806
    else if (val >= 1000)
-
 
1807
      sprintf_s(buf, sizeof (buf), "%dK", (int) (val / 1000)); // Pierre-Marie Baty -- use safe version
-
 
1808
    else
-
 
1809
      sprintf_s(buf, sizeof (buf), "%d", (int) val); // Pierre-Marie Baty -- use safe version
-
 
1810
    return buf;
-
 
1811
  }
-
 
1812
}
1774
}
1813
 
1775
 
1814
/*
1776
/*
1815
 *******************************************************************************
1777
 *******************************************************************************
1816
 *                                                                             *
1778
 *                                                                             *
Line 1887... Line 1849...
1887
 *   Read() copies data from the command_buffer into a local buffer, and then  *
1849
 *   Read() copies data from the command_buffer into a local buffer, and then  *
1888
 *   uses ReadParse to break this command up into tokens for processing.       *
1850
 *   uses ReadParse to break this command up into tokens for processing.       *
1889
 *                                                                             *
1851
 *                                                                             *
1890
 *******************************************************************************
1852
 *******************************************************************************
1891
 */
1853
 */
1892
int Read(int wait, char *buffer, size_t buffer_size) {
1854
int Read(int wait, char *buffer) {
1893
  char *eol, *ret, readdata;
1855
  char *eol, *ret, readdata;
1894
 
1856
 
1895
  *buffer = 0;
1857
  *buffer = 0;
1896
/*
1858
/*
1897
 case 1:  We have a complete command line, with terminating
1859
 case 1:  We have a complete command line, with terminating
Line 1931... Line 1893...
1931
  eol = strchr(cmd_buffer, '\n');
1893
  eol = strchr(cmd_buffer, '\n');
1932
  *eol = 0;
1894
  *eol = 0;
1933
  ret = strchr(cmd_buffer, '\r');
1895
  ret = strchr(cmd_buffer, '\r');
1934
  if (ret)
1896
  if (ret)
1935
    *ret = ' ';
1897
    *ret = ' ';
1936
  strcpy_s(buffer, buffer_size, cmd_buffer); // Pierre-Marie Baty -- use safe version
1898
  strcpy(buffer, cmd_buffer);
1937
  memmove(cmd_buffer, eol + 1, strlen(eol + 1) + 1);
1899
  memmove(cmd_buffer, eol + 1, strlen(eol + 1) + 1);
1938
  return 1;
1900
  return 1;
1939
}
1901
}
1940
 
1902
 
1941
/*
1903
/*
1942
 *******************************************************************************
1904
 *******************************************************************************
1943
 *                                                                             *
1905
 *                                                                             *
1944
 *   ReadClear() clears the input buffer when input_stream is being switched to*
1906
 *   ReadClear() clears the input buffer when input_stream is being switched   *
1945
 *   a file, since we have info buffered up from a different input stream.     *
1907
 *   to a file, since we have info buffered up from a different input stream.  *
1946
 *                                                                             *
1908
 *                                                                             *
1947
 *******************************************************************************
1909
 *******************************************************************************
1948
 */
1910
 */
1949
void ReadClear() {
1911
void ReadClear() {
1950
  cmd_buffer[0] = 0;
1912
  cmd_buffer[0] = 0;
Line 1958... Line 1920...
1958
 *   delimit fields.                                                           *
1920
 *   delimit fields.                                                           *
1959
 *                                                                             *
1921
 *                                                                             *
1960
 *******************************************************************************
1922
 *******************************************************************************
1961
 */
1923
 */
1962
int ReadParse(char *buffer, char *args[], char *delims) {
1924
int ReadParse(char *buffer, char *args[], char *delims) {
1963
  char *next, tbuffer[4096];
-
 
1964
  int nargs;
1925
  int nargs;
-
 
1926
  char *next, tbuffer[4096];
1965
 
1927
 
1966
  strcpy_s(tbuffer, sizeof (tbuffer), buffer); // Pierre-Marie Baty -- use safe version
1928
  strcpy(tbuffer, buffer);
1967
  for (nargs = 0; nargs < 512; nargs++)
1929
  for (nargs = 0; nargs < 512; nargs++)
1968
    *(args[nargs]) = 0;
1930
    *(args[nargs]) = 0;
1969
  next = strtok(tbuffer, delims);
1931
  next = strtok(tbuffer, delims);
1970
  if (!next)
1932
  if (!next)
1971
    return 0;
1933
    return 0;
Line 1993... Line 1955...
1993
 *   command_buffer for later processing.                                      *
1955
 *   command_buffer for later processing.                                      *
1994
 *                                                                             *
1956
 *                                                                             *
1995
 *******************************************************************************
1957
 *******************************************************************************
1996
 */
1958
 */
1997
int ReadInput(void) {
1959
int ReadInput(void) {
1998
  char buffer[4096], *end;
-
 
1999
  int bytes;
1960
  int bytes;
-
 
1961
  char buffer[4096], *end;
2000
 
1962
 
2001
  do
1963
  do
2002
    bytes = _read(_fileno(input_stream), buffer, 2048); // Pierre-Marie Baty -- use ISO C++ conformant names
1964
    bytes = _read(_fileno(input_stream), buffer, 2048); // Pierre-Marie Baty -- POSIX/ISO C++ names fixes
2003
  while (bytes < 0 && errno == EINTR);
1965
  while (bytes < 0 && errno == EINTR);
2004
  if (bytes == 0) {
1966
  if (bytes == 0) {
2005
    if (input_stream != stdin)
1967
    if (input_stream != stdin)
2006
      fclose(input_stream);
1968
      fclose(input_stream);
2007
    input_stream = stdin;
1969
    input_stream = stdin;
Line 2017... Line 1979...
2017
}
1979
}
2018
 
1980
 
2019
/*
1981
/*
2020
 *******************************************************************************
1982
 *******************************************************************************
2021
 *                                                                             *
1983
 *                                                                             *
2022
 *   ReadChessMove() is used to read a move from an input file.  The main issue*
1984
 *   ReadChessMove() is used to read a move from an input file.  The main      *
2023
 *   is to skip over "trash" like move numbers, times, comments, and so forth, *
1985
 *   issue is to skip over "trash" like move numbers, times, comments, and so  *
2024
 *   and find the next actual move.                                            *
1986
 *   forth, and find the next actual move.                                     *
2025
 *                                                                             *
1987
 *                                                                             *
2026
 *******************************************************************************
1988
 *******************************************************************************
2027
 */
1989
 */
2028
int ReadChessMove(TREE * RESTRICT tree, FILE * input, int wtm, int one_move) {
1990
int ReadChessMove(TREE * RESTRICT tree, FILE * input, int wtm, int one_move) {
-
 
1991
  int move = 0, status;
2029
  static char text[128];
1992
  static char text[128];
2030
  char *tmove;
1993
  char *tmove;
2031
  int move = 0, status;
-
 
2032
 
1994
 
2033
  while (move == 0) {
1995
  while (move == 0) {
2034
    status = fscanf(input, "%s", text);
1996
    status = fscanf(input, "%s", text);
2035
    if (status <= 0)
1997
    if (status <= 0)
2036
      return -1;
1998
      return -1;
Line 2041... Line 2003...
2041
    if (((tmove[0] >= 'a' && tmove[0] <= 'z') || (tmove[0] >= 'A' &&
2003
    if (((tmove[0] >= 'a' && tmove[0] <= 'z') || (tmove[0] >= 'A' &&
2042
                tmove[0] <= 'Z')) || !strcmp(tmove, "0-0")
2004
                tmove[0] <= 'Z')) || !strcmp(tmove, "0-0")
2043
        || !strcmp(tmove, "0-0-0")) {
2005
        || !strcmp(tmove, "0-0-0")) {
2044
      if (!strcmp(tmove, "exit"))
2006
      if (!strcmp(tmove, "exit"))
2045
        return -1;
2007
        return -1;
2046
      move = InputMove(tree, tmove, 0, wtm, 1, 0);
2008
      move = InputMove(tree, 0, wtm, 1, 0, tmove);
2047
    }
2009
    }
2048
    if (one_move)
2010
    if (one_move)
2049
      break;
2011
      break;
2050
  }
2012
  }
2051
  return move;
2013
  return move;
Line 2071... Line 2033...
2071
  if (((tmove[0] >= 'a' && tmove[0] <= 'z') || (tmove[0] >= 'A' &&
2033
  if (((tmove[0] >= 'a' && tmove[0] <= 'z') || (tmove[0] >= 'A' &&
2072
              tmove[0] <= 'Z')) || !strcmp(tmove, "0-0")
2034
              tmove[0] <= 'Z')) || !strcmp(tmove, "0-0")
2073
      || !strcmp(tmove, "0-0-0")) {
2035
      || !strcmp(tmove, "0-0-0")) {
2074
    if (!strcmp(tmove, "exit"))
2036
    if (!strcmp(tmove, "exit"))
2075
      return -1;
2037
      return -1;
2076
    move = InputMove(tree, tmove, ply, wtm, 1, 0);
2038
    move = InputMove(tree, ply, wtm, 1, 0, tmove);
2077
  }
2039
  }
2078
  return move;
2040
  return move;
2079
}
2041
}
2080
 
2042
 
2081
/*
2043
/*
Line 2089... Line 2051...
2089
 *                                                                             *
2051
 *                                                                             *
2090
 *******************************************************************************
2052
 *******************************************************************************
2091
 */
2053
 */
2092
int ReadPGN(FILE * input, int option) {
2054
int ReadPGN(FILE * input, int option) {
2093
  static int data = 0, lines_read = 0;
2055
  static int data = 0, lines_read = 0;
-
 
2056
  int braces = 0, parens = 0, brackets = 0, analysis = 0, last_good_line;
2094
  static char input_buffer[4096];
2057
  static char input_buffer[4096];
2095
  char *eof, analysis_move[64];
2058
  char *eof, analysis_move[64];
2096
  int braces = 0, parens = 0, brackets = 0, analysis = 0, last_good_line;
-
 
2097
 
2059
 
2098
/*
2060
/*
2099
 ************************************************************
2061
 ************************************************************
2100
 *                                                          *
2062
 *                                                          *
2101
 *  If the line counter is being requested, return it with  *
2063
 *  If the line counter is being requested, return it with  *
Line 2165... Line 2127...
2165
          else if (strstr(input_buffer, "Black"))
2127
          else if (strstr(input_buffer, "Black"))
2166
            strcpy(pgn_black, value);
2128
            strcpy(pgn_black, value);
2167
          else if (strstr(input_buffer, "Result"))
2129
          else if (strstr(input_buffer, "Result"))
2168
            strcpy(pgn_result, value);
2130
            strcpy(pgn_result, value);
2169
          else if (strstr(input_buffer, "FEN")) {
2131
          else if (strstr(input_buffer, "FEN")) {
2170
            sprintf_s(buffer, sizeof (buffer), "setboard %s", value); // Pierre-Marie Baty -- use safe version
2132
            sprintf(buffer, "setboard %s", value);
2171
            (void) Option(block[0]);
2133
            Option(block[0]);
2172
            continue;
2134
            continue;
2173
          }
2135
          }
2174
          return 1;
2136
          return 1;
2175
        } while (0);
2137
        } while (0);
2176
      data = 1;
2138
      data = 1;
Line 2199... Line 2161...
2199
          memmove(input_buffer, skip, strlen(skip) + 1);
2161
          memmove(input_buffer, skip, strlen(skip) + 1);
2200
      }
2162
      }
2201
/*
2163
/*
2202
 ************************************************************
2164
 ************************************************************
2203
 *                                                          *
2165
 *                                                          *
2204
 *  This skips over nested {} or () characters and finds the*
2166
 *  This skips over nested {} or () characters and finds    *
2205
 *  'mate', before returning any more moves.  It also stops *
2167
 *  the 'mate', before returning any more moves.  It also   *
2206
 *  if a PGN header is encountered, probably due to an      *
2168
 *  stops if a PGN header is encountered, probably due to   *
2207
 *  incorrectly bracketed analysis variation.               *
2169
 *  an incorrectly bracketed analysis variation.            *
2208
 *                                                          *
2170
 *                                                          *
2209
 ************************************************************
2171
 ************************************************************
2210
 */
2172
 */
2211
      last_good_line = lines_read;
2173
      last_good_line = lines_read;
2212
      analysis_move[0] = 0;
2174
      analysis_move[0] = 0;
Line 2293... Line 2255...
2293
          skip = strstr(input_buffer, buffer) + strlen(buffer);
2255
          skip = strstr(input_buffer, buffer) + strlen(buffer);
2294
          memmove(input_buffer, skip, strlen(skip) + 1);
2256
          memmove(input_buffer, skip, strlen(skip) + 1);
2295
      } else {
2257
      } else {
2296
        int skip;
2258
        int skip;
2297
 
2259
 
2298
        if ((skip = strspn(buffer, "0123456789."))) {
2260
        if ((skip = strspn(buffer, "0123456789./-"))) {
2299
          if (skip > 1)
2261
          if (skip > 1)
2300
            memmove(buffer, buffer + skip, strlen(buffer + skip) + 1);
2262
            memmove(buffer, buffer + skip, strlen(buffer + skip) + 1);
2301
        }
2263
        }
2302
        if (isalpha(buffer[0]) || strchr(buffer, '-')) {
2264
        if (isalpha(buffer[0]) || strchr(buffer, '-')) {
2303
          char *first, *last, *percent;
2265
          char *first, *last, *percent;
Line 2326... Line 2288...
2326
 
2288
 
2327
/*
2289
/*
2328
 *******************************************************************************
2290
 *******************************************************************************
2329
 *                                                                             *
2291
 *                                                                             *
2330
 *   RestoreGame() resets the position to the beginning of the game, and then  *
2292
 *   RestoreGame() resets the position to the beginning of the game, and then  *
2331
 *   reads in the game.nnn history file to set the position up so that the game*
2293
 *   reads in the game.nnn history file to set the position up so that the     *
2332
 *   position matches the position at the end of the history file.             *
2294
 *   game position matches the position at the end of the history file.        *
2333
 *                                                                             *
2295
 *                                                                             *
2334
 *******************************************************************************
2296
 *******************************************************************************
2335
 */
2297
 */
2336
void RestoreGame(void) {
2298
void RestoreGame(void) {
2337
  int i, move;
2299
  int i, v, move;
2338
  char cmd[16];
2300
  char cmd[16];
2339
 
2301
 
2340
  if (!history_file)
2302
  if (!history_file)
2341
    return;
2303
    return;
2342
  game_wtm = 1;
2304
  game_wtm = 1;
2343
  InitializeChessBoard(block[0]);
2305
  InitializeChessBoard(block[0]);
2344
  for (i = 0; i < 500; i++) {
2306
  for (i = 0; i < 500; i++) {
2345
    fseek(history_file, i * 10, SEEK_SET);
2307
    fseek(history_file, i * 10, SEEK_SET);
2346
    strcpy(cmd, "");
2308
    strcpy(cmd, "");
2347
    fscanf(history_file, "%s", cmd);
2309
    v = fscanf(history_file, "%s", cmd);
-
 
2310
    if (v < 0)
-
 
2311
      perror("RestoreGame fscanf error: ");
2348
    if (strcmp(cmd, "pass")) {
2312
    if (strcmp(cmd, "pass")) {
2349
      move = InputMove(block[0], cmd, 0, game_wtm, 1, 0);
2313
      move = InputMove(block[0], 0, game_wtm, 1, 0, cmd);
2350
      if (move)
2314
      if (move)
2351
        MakeMoveRoot(block[0], move, game_wtm);
2315
        MakeMoveRoot(block[0], game_wtm, move);
2352
      else
2316
      else
2353
        break;
2317
        break;
2354
    }
2318
    }
2355
    game_wtm = Flip(game_wtm);
2319
    game_wtm = Flip(game_wtm);
2356
  }
2320
  }
Line 2371... Line 2335...
2371
  nps = (int) ((time) ? 100 * nodes / (uint64_t) time : nodes);
2335
  nps = (int) ((time) ? 100 * nodes / (uint64_t) time : nodes);
2372
  if (!puzzling) {
2336
  if (!puzzling) {
2373
    char prefix[128];
2337
    char prefix[128];
2374
 
2338
 
2375
    if (!(kibitz & 16))
2339
    if (!(kibitz & 16))
2376
      sprintf_s(prefix, sizeof (prefix), "kibitz"); // Pierre-Marie Baty -- use safe version
2340
      sprintf(prefix, "kibitz");
2377
    else
2341
    else
2378
      sprintf_s(prefix, sizeof (prefix), "whisper"); // Pierre-Marie Baty -- use safe version
2342
      sprintf(prefix, "whisper");
2379
    switch (level) {
2343
    switch (level) {
2380
      case 1:
2344
      case 1:
2381
        if ((kibitz & 15) >= 1) {
2345
        if ((kibitz & 15) >= 1) {
2382
          if (value > 0) {
2346
          if (value > 0) {
2383
            printf("%s mate in %d moves.\n\n", prefix, value);
2347
            printf("%s mate in %d moves.\n\n", prefix, value);
Line 2386... Line 2350...
2386
            printf("%s mated in %d moves.\n\n", prefix, -value);
2350
            printf("%s mated in %d moves.\n\n", prefix, -value);
2387
          }
2351
          }
2388
        }
2352
        }
2389
        break;
2353
        break;
2390
      case 2:
2354
      case 2:
2391
        if ((kibitz & 15) >= 2) {
2355
        if ((kibitz & 15) >= 2)
2392
          printf("%s ply=%d; eval=%s; nps=%s; time=%s(%d%%); egtb=%d\n",
2356
          printf("%s ply=%d; eval=%s; nps=%s; time=%s(%d%%); egtb=%d\n",
2393
              prefix, depth, DisplayEvaluationKibitz(value, wtm),
2357
              prefix, depth, DisplayEvaluationKibitz(value, wtm),
2394
              DisplayKMB(nps), DisplayTimeKibitz(time), ip, tb_hits);
2358
              DisplayKMB(nps, 0), DisplayTimeKibitz(time), ip, tb_hits);
2395
        }
-
 
2396
      case 3:
2359
      case 3:
2397
        if ((kibitz & 15) >= 3 && (nodes > 5000 || level == 2)) {
2360
        if ((kibitz & 15) >= 3 && (nodes > 5000 || level == 2))
2398
          printf("%s %s\n", prefix, pv);
2361
          printf("%s %s\n", prefix, pv);
2399
        }
-
 
2400
        break;
2362
        break;
2401
      case 4:
2363
      case 4:
2402
        if ((kibitz & 15) >= 4) {
2364
        if ((kibitz & 15) >= 4)
2403
          printf("%s %s\n", prefix, pv);
2365
          printf("%s %s\n", prefix, pv);
2404
        }
-
 
2405
        break;
2366
        break;
2406
      case 5:
2367
      case 5:
2407
        if ((kibitz & 15) >= 5 && nodes > 5000) {
2368
        if ((kibitz & 15) >= 5 && nodes > 5000) {
2408
          printf("%s d%d-> %s/s %s(%d%%) %s %s ", prefix, depth,
2369
          printf("%s d%d-> %s/s %s(%d%%) %s %s ", prefix, depth,
2409
              DisplayKMB(nps), DisplayTimeKibitz(time), ip,
2370
              DisplayKMB(nps, 0), DisplayTimeKibitz(time), ip,
2410
              DisplayEvaluationKibitz(value, wtm), pv);
2371
              DisplayEvaluationKibitz(value, wtm), pv);
2411
          if (tb_hits)
2372
          if (tb_hits)
2412
            printf("egtb=%d", tb_hits);
2373
            printf("egtb=%d", tb_hits);
2413
          printf("\n");
2374
          printf("\n");
2414
        }
-
 
2415
        break;
-
 
2416
      case 6:
-
 
2417
        if ((kibitz & 15) >= 6 && nodes > 5000) {
-
 
2418
          if (wtm)
-
 
2419
            printf("%s d%d+ %s/s %s(%d%%) >(%s) %s <re-searching>\n", prefix,
-
 
2420
                depth, DisplayKMB(nps), DisplayTimeKibitz(time), ip,
-
 
2421
                DisplayEvaluationKibitz(value, wtm), pv);
-
 
2422
          else
-
 
2423
            printf("%s d%d+ %s/s %s(%d%%) <(%s) %s <re-searching>\n", prefix,
-
 
2424
                depth, DisplayKMB(nps), DisplayTimeKibitz(time), ip,
-
 
2425
                DisplayEvaluationKibitz(value, wtm), pv);
-
 
2426
        }
2375
        }
2427
        break;
2376
        break;
2428
    }
2377
    }
2429
    value = (wtm) ? value : -value;
2378
    value = (wtm) ? value : -value;
2430
    if (post && level > 1) {
2379
    if (post && level > 1) {
2431
      if (strstr(pv, "book"))
2380
      if (strstr(pv, "book"))
2432
        printf("        %2d  %5d %7d %" PRIu64 " %s\n", depth, value, time,
2381
        printf("      %2d  %5d %7d %" PRIu64 " %s\n", depth, value, time,
2433
            nodes, pv + 10);
2382
            nodes, pv + 10);
2434
      else
2383
      else
2435
        printf("        %2d  %5d %7d %" PRIu64 " %s\n", depth, value, time,
2384
        printf("      %2d  %5d %7d %" PRIu64 " %s\n", depth, value, time,
2436
            nodes, pv);
2385
            nodes, pv);
2437
    }
2386
    }
2438
    fflush(stdout);
2387
    fflush(stdout);
2439
  }
2388
  }
2440
}
2389
}
2441
 
2390
 
2442
/*
2391
/*
2443
 *******************************************************************************
2392
 *******************************************************************************
2444
 *                                                                             *
2393
 *                                                                             *
2445
 *   Output() is used to print the principal variation whenever it changes.    *
2394
 *   Output() is used to print the principal variation whenever it changes.    *
2446
 *   One additional feature is that Output() will try to do something about    *
-
 
2447
 *   variations truncated by the transposition table.  If the variation was    *
-
 
2448
 *   cut short by a transposition table hit, then we can make the last move,   *
-
 
2449
 *   add it to the end of the variation and extend the depth of the variation  *
-
 
2450
 *   to cover it.                                                              *
-
 
2451
 *                                                                             *
2395
 *                                                                             *
2452
 *******************************************************************************
2396
 *******************************************************************************
2453
 */
2397
 */
2454
void Output(TREE * RESTRICT tree, int bound) {
2398
void Output(TREE * RESTRICT tree) {
2455
  int wtm;
2399
  int wtm, i;
2456
  int i;
-
 
2457
  ROOT_MOVE temp_rm;
-
 
2458
 
2400
 
2459
/*
2401
/*
2460
 ************************************************************
2402
 ************************************************************
2461
 *                                                          *
2403
 *                                                          *
-
 
2404
 *  Output the PV by walking down the path being backed up. *
2462
 *  First, move the best move to the top of the ply-1 move  *
2405
 *  We do set the "age" for this move to "4" which will     *
2463
 *  list if it's not already there, so that it will be the  *
2406
 *  keep it in the group of "search with all threads" moves *
2464
 *  first move tried in the next iteration.                 *
2407
 *  so that it will be searched faster.                     *
2465
 *                                                          *
2408
 *                                                          *
2466
 ************************************************************
2409
 ************************************************************
2467
 */
2410
 */
2468
  wtm = root_wtm;
2411
  wtm = root_wtm;
2469
  if (!abort_search) {
2412
  if (!abort_search) {
2470
    kibitz_depth = iteration_depth;
2413
    kibitz_depth = iteration;
-
 
2414
    end_time = ReadClock();
-
 
2415
    DisplayPV(tree, 6, wtm, end_time - start_time, &tree->pv[1], 0);
2471
    for (i = 0; i < n_root_moves; i++)
2416
    for (i = 0; i < n_root_moves; i++)
2472
      if (tree->curmv[1] == root_moves[i].move)
2417
      if (tree->pv[1].path[1] == root_moves[i].move)
2473
        break;
2418
        break;
2474
    if (i && i < n_root_moves) {
-
 
2475
      temp_rm = root_moves[i];
-
 
2476
      for (; i > 0; i--)
-
 
2477
        root_moves[i] = root_moves[i - 1];
2419
    root_moves[i].path = tree->pv[1];
2478
      root_moves[0] = temp_rm;
2420
    root_moves[i].bm_age = 4;
2479
    }
2421
  }
2480
    root_moves[0].bm_age = 4;
-
 
2481
    end_time = ReadClock();
-
 
-
 
2422
}
-
 
2423
 
2482
/*
2424
/*
2483
 ************************************************************
2425
 *******************************************************************************
2484
 *                                                          *
2426
 *                                                                             *
-
 
2427
 *   SortRootMoves() is used to sort the root move list based on the value     *
-
 
2428
 *   saved for each move.  After a fail high or fail low, we always re-sort    *
-
 
2429
 *   the root move list so that the best move found so far is first in the     *
-
 
2430
 *   list.  This is primarily intended as a defense against getting a score    *
-
 
2431
 *   for the first root move, and then getting a fail-high on the second move, *
2485
 *  If this is not a fail-high move, then output the PV by  *
2432
 *   which should move this move to the front of the moves.  But if the move   *
-
 
2433
 *   then fails low, we want to move it back down since a deeper/less-reduced  *
2486
 *  walking down the path being backed up.                  *
2434
 *   search did not verify the fail-high.                                      *
2487
 *                                                          *
2435
 *                                                                             *
2488
 ************************************************************
2436
 *******************************************************************************
2489
 */
2437
 */
2490
    if (tree->pv[1].pathv < bound) {
2438
void SortRootMoves() {
2491
      UnmakeMove(tree, 1, tree->pv[1].path[1], root_wtm);
2439
  ROOT_MOVE rtemp;
2492
      DisplayPV(tree, 6, wtm, end_time - start_time, &tree->pv[1]);
-
 
2493
      MakeMove(tree, 1, tree->pv[1].path[1], root_wtm);
2440
  int mvp, done;
-
 
2441
 
-
 
2442
  do {
2494
    } else {
2443
    done = 1;
2495
      if (tree->curmv[1] != tree->pv[1].path[1]) {
2444
    for (mvp = 0; mvp < n_root_moves - 1; mvp++) {
2496
        tree->pv[1].path[1] = tree->curmv[1];
2445
      if (root_moves[mvp].path.pathv < root_moves[mvp + 1].path.pathv) {
2497
        tree->pv[1].pathl = 2;
2446
        rtemp = root_moves[mvp];
2498
        tree->pv[1].pathh = 0;
2447
        root_moves[mvp] = root_moves[mvp + 1];
2499
        tree->pv[1].pathd = iteration_depth;
2448
        root_moves[mvp + 1] = rtemp;
-
 
2449
        done = 0;
2500
      }
2450
      }
2501
    }
2451
    }
2502
  }
2452
  } while (!done);
2503
}
2453
}
2504
 
2454
 
2505
/*
2455
/*
2506
 *******************************************************************************
2456
 *******************************************************************************
2507
 *                                                                             *
2457
 *                                                                             *
2508
 *   Trace() is used to print the search trace output each time a node is*
2458
 *   Trace() is used to print the search trace output each time a node is      *
2509
 *   traversed in the tree.                                                    *
2459
 *   traversed in the tree.                                                    *
2510
 *                                                                             *
2460
 *                                                                             *
2511
 *******************************************************************************
2461
 *******************************************************************************
2512
 */
2462
 */
2513
void Trace(TREE * RESTRICT tree, int ply, int depth, int wtm, int alpha,
2463
void Trace(TREE * RESTRICT tree, int ply, int depth, int wtm, int alpha,
2514
    int beta, const char *name, int phase) {
2464
    int beta, const char *name, int mode, int phase, int order) {
2515
  int i;
2465
  int i;
2516
 
2466
 
2517
  Lock(lock_io);
2467
  Lock(lock_io);
2518
  for (i = 1; i < ply; i++)
2468
  for (i = 1; i < ply; i++)
2519
    printf("  ");
2469
    Print(-1, "  ");
2520
  if (phase != EVALUATION) {
2470
  if (phase != EVALUATION) {
2521
    printf("%d  %s d:%2d [%s,", ply, OutputMove(tree, tree->curmv[ply], ply,
2471
    Print(-1, "%d  %s(%d) d:%2d [%s,", ply, OutputMove(tree, ply, wtm,
2522
            wtm), depth, DisplayEvaluation(alpha, 1));
2472
            tree->curmv[ply]), order, depth, DisplayEvaluation(alpha, 1));
2523
    printf("%s] n:%" PRIu64 " %s(%d)", DisplayEvaluation(beta, 1),
2473
    Print(-1, "%s] n:%" PRIu64 " %s(%c:%d)", DisplayEvaluation(beta, 1),
2524
        (tree->nodes_searched), name, phase);
2474
        tree->nodes_searched, name, (mode) ? 'P' : 'S', phase);
2525
    if (smp_max_threads > 1)
-
 
2526
      printf(" (t=%d) ", tree->thread_id);
2475
    Print(-1, " (t=%d)\n", tree->thread_id);
2527
    printf("\n");
-
 
2528
  } else {
2476
  } else {
2529
    printf("%d window/eval(%s) = {", ply, name);
2477
    Print(-1, "%d window/eval(%s) = {", ply, name);
2530
    printf("%s, ", DisplayEvaluation(alpha, 1));
2478
    Print(-1, "%s, ", DisplayEvaluation(alpha, 1));
2531
    printf("%s, ", DisplayEvaluation(depth, 1));
2479
    Print(-1, "%s, ", DisplayEvaluation(depth, 1));
2532
    printf("%s}\n", DisplayEvaluation(beta, 1));
2480
    Print(-1, "%s}\n", DisplayEvaluation(beta, 1));
2533
  }
2481
  }
2534
  fflush(0);
2482
  fflush(0);
2535
  Unlock(lock_io);
2483
  Unlock(lock_io);
2536
}
2484
}
2537
 
2485
 
Line 2541... Line 2489...
2541
 *   StrCnt() counts the number of times a character occurs in a string.       *
2489
 *   StrCnt() counts the number of times a character occurs in a string.       *
2542
 *                                                                             *
2490
 *                                                                             *
2543
 *******************************************************************************
2491
 *******************************************************************************
2544
 */
2492
 */
2545
int StrCnt(char *string, char testchar) {
2493
int StrCnt(char *string, char testchar) {
2546
  int count = 0;
2494
  int count = 0, i;
2547
  size_t i; // Pierre-Marie Baty -- fixed type
-
 
2548
 
2495
 
2549
  for (i = 0; i < strlen(string); i++)
2496
  for (i = 0; i < (int) strlen(string); i++) // Pierre-Marie Baty -- added type cast
2550
    if (string[i] == testchar)
2497
    if (string[i] == testchar)
2551
      count++;
2498
      count++;
2552
  return count;
2499
  return count;
2553
}
2500
}
2554
 
2501
 
Line 2561... Line 2508...
2561
 *   against the current chess board, castling status, en passant status, etc. *
2508
 *   against the current chess board, castling status, en passant status, etc. *
2562
 *                                                                             *
2509
 *                                                                             *
2563
 *******************************************************************************
2510
 *******************************************************************************
2564
 */
2511
 */
2565
int ValidMove(TREE * RESTRICT tree, int ply, int wtm, int move) {
2512
int ValidMove(TREE * RESTRICT tree, int ply, int wtm, int move) {
2566
  static int epdir[2] = { 8, -8 };
-
 
2567
  static int csq[2] = { C8, C1 };
-
 
2568
  static int dsq[2] = { D8, D1 };
-
 
2569
  static int esq[2] = { E8, E1 };
-
 
2570
  static int fsq[2] = { F8, F1 };
-
 
2571
  static int gsq[2] = { G8, G1 };
-
 
2572
  int btm = Flip(wtm);
2513
  int btm = Flip(wtm);
2573
 
2514
 
2574
/*
2515
/*
2575
 ************************************************************
2516
 ************************************************************
2576
 *                                                          *
2517
 *                                                          *
Line 2632... Line 2573...
2632
 ************************************************************
2573
 ************************************************************
2633
 */
2574
 */
2634
    case pawn:
2575
    case pawn:
2635
      if (((wtm) ? To(move) - From(move) : From(move) - To(move)) < 0)
2576
      if (((wtm) ? To(move) - From(move) : From(move) - To(move)) < 0)
2636
        return 0;
2577
        return 0;
2637
      if (Abs(From(move) - To(move)) == 8) {
2578
      if (Abs(From(move) - To(move)) == 8)
2638
        if (!PcOnSq(To(move)))
2579
        return (PcOnSq(To(move))) ? 0 : 1;
2639
          return 1;
-
 
2640
        return 0;
-
 
2641
      }
-
 
2642
      if (Abs(From(move) - To(move)) == 16) {
2580
      if (Abs(From(move) - To(move)) == 16)
2643
        if (!PcOnSq(To(move)) && !PcOnSq(To(move) + epdir[wtm]))
2581
        return (PcOnSq(To(move)) || PcOnSq(To(move) + epdir[wtm])) ? 0 : 1;
2644
          return 1;
-
 
2645
        return 0;
-
 
2646
      }
-
 
2647
      if (!Captured(move))
2582
      if (!Captured(move))
2648
        return 0;
2583
        return 0;
2649
/*
2584
/*
2650
 ************************************************************
2585
 ************************************************************
2651
 *                                                          *
2586
 *                                                          *
Line 2684... Line 2619...
2684
 *  checking the from and to squares and also the attack    *
2619
 *  checking the from and to squares and also the attack    *
2685
 *  status for completeness.                                *
2620
 *  status for completeness.                                *
2686
 *                                                          *
2621
 *                                                          *
2687
 ************************************************************
2622
 ************************************************************
2688
 */
2623
 */
2689
  if ((Captured(move) == ((wtm) ? -PcOnSq(To(move)) : PcOnSq(To(move))))
2624
  return ((Captured(move) == ((wtm) ? -PcOnSq(To(move)) : PcOnSq(To(move))))
2690
      && Captured(move) != king)
2625
      && Captured(move) != king) ? 1 : 0;
2691
    return 1;
-
 
2692
  return 0;
-
 
2693
}
2626
}
2694
 
2627
 
2695
/* last modified 02/26/14 */
2628
/* last modified 02/26/14 */
2696
/*
2629
/*
2697
 *******************************************************************************
2630
 *******************************************************************************
Line 2701... Line 2634...
2701
 *   move to be sure it is safe to make it on the permanent game board.        *
2634
 *   move to be sure it is safe to make it on the permanent game board.        *
2702
 *                                                                             *
2635
 *                                                                             *
2703
 *******************************************************************************
2636
 *******************************************************************************
2704
 */
2637
 */
2705
int VerifyMove(TREE * RESTRICT tree, int ply, int wtm, int move) {
2638
int VerifyMove(TREE * RESTRICT tree, int ply, int wtm, int move) {
2706
  int moves[220], *mv, *mvp;
2639
  unsigned moves[256], *mv, *mvp;
2707
 
2640
 
2708
/*
2641
/*
2709
 Generate moves, then eliminate any that are illegal.
2642
 Generate moves, then eliminate any that are illegal.
2710
 */
2643
 */
2711
  if (move == 0)
2644
  if (move == 0)
2712
    return 0;
2645
    return 0;
2713
  tree->status[MAXPLY] = tree->status[ply];
2646
  tree->status[MAXPLY] = tree->status[ply];
2714
  mvp = GenerateCaptures(tree, MAXPLY, wtm, moves);
2647
  mvp = GenerateCaptures(tree, MAXPLY, wtm, moves);
2715
  mvp = GenerateNoncaptures(tree, MAXPLY, wtm, mvp);
2648
  mvp = GenerateNoncaptures(tree, MAXPLY, wtm, mvp);
2716
  for (mv = &moves[0]; mv < mvp; mv++) {
2649
  for (mv = &moves[0]; mv < mvp; mv++) {
2717
    MakeMove(tree, MAXPLY, *mv, wtm);
2650
    MakeMove(tree, MAXPLY, wtm, *mv);
2718
    if (!Check(wtm) && move == *mv) {
2651
    if (!Check(wtm) && move == *mv) {
2719
      UnmakeMove(tree, MAXPLY, *mv, wtm);
2652
      UnmakeMove(tree, MAXPLY, wtm, *mv);
2720
      return 1;
2653
      return 1;
2721
    }
2654
    }
2722
    UnmakeMove(tree, MAXPLY, *mv, wtm);
2655
    UnmakeMove(tree, MAXPLY, wtm, *mv);
2723
  }
2656
  }
2724
  return 0;
2657
  return 0;
2725
}
2658
}
2726
 
2659
 
2727
/*
2660
/*
Line 2730... Line 2663...
2730
 *   Windows NUMA support                                                      *
2663
 *   Windows NUMA support                                                      *
2731
 *                                                                             *
2664
 *                                                                             *
2732
 *******************************************************************************
2665
 *******************************************************************************
2733
 */
2666
 */
2734
#if !defined(UNIX)
2667
#if !defined(UNIX)
2735
lock_t ThreadsLock;
-
 
2736
static BOOL(WINAPI * pGetNumaHighestNodeNumber) (PULONG);
2668
static BOOL(WINAPI * pGetNumaHighestNodeNumber) (PULONG);
2737
static BOOL(WINAPI * pGetNumaNodeProcessorMask) (UCHAR, PULONGLONG);
2669
static BOOL(WINAPI * pGetNumaNodeProcessorMask) (UCHAR, PULONGLONG);
2738
static DWORD(WINAPI * pSetThreadIdealProcessor) (HANDLE, DWORD);
2670
static DWORD(WINAPI * pSetThreadIdealProcessor) (HANDLE, DWORD);
2739
static volatile BOOL fThreadsInitialized = FALSE;
2671
static volatile BOOL fThreadsInitialized = FALSE;
2740
static BOOL fSystemIsNUMA = FALSE;
2672
static BOOL fSystemIsNUMA = FALSE;
Line 2742... Line 2674...
2742
static ULONG ulNumaNodes;
2674
static ULONG ulNumaNodes;
2743
static ULONG ulNumaNode = 0;
2675
static ULONG ulNumaNode = 0;
2744
 
2676
 
2745
// Get NUMA-related information from Windows
2677
// Get NUMA-related information from Windows
2746
static void WinNumaInit(void) {
2678
static void WinNumaInit(void) {
2747
  //DWORD_PTR dwMask; // Pierre-Marie Baty -- unused variable
2679
  //DWORD_PTR dwMask; // Pierre-Marie Baty -- unreferenced variable
2748
  HMODULE hModule;
2680
  HMODULE hModule;
2749
  ULONG ulCPU, ulNode;
2681
  ULONG ulCPU, ulNode;
2750
  ULONGLONG ullMask;
2682
  ULONGLONG ullMask;
2751
  DWORD dwCPU;
2683
  DWORD dwCPU;
2752
 
2684
 
2753
  if (!fThreadsInitialized) {
2685
  if (!fThreadsInitialized) {
2754
    Lock(ThreadsLock);
2686
    Lock(lock_smp);
2755
    if (!fThreadsInitialized) {
2687
    if (!fThreadsInitialized) {
2756
      printf("\nInitializing multiple threads.\n");
2688
      printf("\nInitializing multiple threads.\n");
2757
      fThreadsInitialized = TRUE;
2689
      fThreadsInitialized = TRUE;
2758
      hModule = GetModuleHandle("kernel32");
2690
      hModule = GetModuleHandle("kernel32");
2759
      pGetNumaHighestNodeNumber =
2691
      pGetNumaHighestNodeNumber =
Line 2793... Line 2725...
2793
        dwCPU =
2725
        dwCPU =
2794
            pSetThreadIdealProcessor(GetCurrentThread(), MAXIMUM_PROCESSORS);
2726
            pSetThreadIdealProcessor(GetCurrentThread(), MAXIMUM_PROCESSORS);
2795
        printf("Current ideal CPU is %u\n", dwCPU);
2727
        printf("Current ideal CPU is %u\n", dwCPU);
2796
        pSetThreadIdealProcessor(GetCurrentThread(), dwCPU);
2728
        pSetThreadIdealProcessor(GetCurrentThread(), dwCPU);
2797
        if ((((DWORD) - 1) != dwCPU) && (MAXIMUM_PROCESSORS != dwCPU)
2729
        if ((((DWORD) - 1) != dwCPU) && (MAXIMUM_PROCESSORS != dwCPU)
2798
            && !(ullProcessorMask[0] & (1ull << dwCPU))) { // Pierre-Marie Baty -- added "ll" prefix
2730
            && !(ullProcessorMask[0] & (1uLL << dwCPU))) { // Pierre-Marie Baty -- added type cast
2799
          for (ulNode = 1; ulNode <= ulNumaNodes; ulNode++) {
2731
          for (ulNode = 1; ulNode <= ulNumaNodes; ulNode++) {
2800
            if (ullProcessorMask[ulNode] & (1ull << dwCPU)) { // Pierre-Marie Baty -- added "ll" prefix
2732
            if (ullProcessorMask[ulNode] & (1uLL << dwCPU)) { // Pierre-Marie Baty -- added type cast
2801
              printf("Exchanging nodes 0 and %d\n", ulNode);
2733
              printf("Exchanging nodes 0 and %d\n", ulNode);
2802
              ullMask = ullProcessorMask[ulNode];
2734
              ullMask = ullProcessorMask[ulNode];
2803
              ullProcessorMask[ulNode] = ullProcessorMask[0];
2735
              ullProcessorMask[ulNode] = ullProcessorMask[0];
2804
              ullProcessorMask[0] = ullMask;
2736
              ullProcessorMask[0] = ullMask;
2805
              break;
2737
              break;
Line 2807... Line 2739...
2807
          }
2739
          }
2808
        }
2740
        }
2809
      } else
2741
      } else
2810
        printf("System is SMP, not NUMA.\n");
2742
        printf("System is SMP, not NUMA.\n");
2811
    }
2743
    }
2812
    Unlock(ThreadsLock);
2744
    Unlock(lock_smp);
2813
  }
2745
  }
2814
}
2746
}
2815
 
2747
 
2816
// Start thread. For NUMA system set its affinity.
2748
// Start thread. For NUMA system set its affinity.
2817
#  if (CPUS > 1)
2749
#  if (CPUS > 1)
Line 2878... Line 2810...
2878
  DWORD dwPageSize;             // the page size on this computer
2810
  DWORD dwPageSize;             // the page size on this computer
2879
  LPVOID lpvResult;
2811
  LPVOID lpvResult;
2880
 
2812
 
2881
  WinNumaInit();
2813
  WinNumaInit();
2882
  if (fSystemIsNUMA && (cThreads > 1)) {
2814
  if (fSystemIsNUMA && (cThreads > 1)) {
2883
    GetSystemInfo(&sSysInfo);   // populate the system information structure
2815
    GetSystemInfo(&sSysInfo); // populate the system information structure
2884
    dwPageSize = sSysInfo.dwPageSize;
2816
    dwPageSize = sSysInfo.dwPageSize;
2885
// Reserve pages in the process's virtual address space.
2817
// Reserve pages in the process's virtual address space.
2886
    pBase = (char *) VirtualAlloc(NULL, cbBytes, MEM_RESERVE, PAGE_NOACCESS);
2818
    pBase = (char *) VirtualAlloc(NULL, cbBytes, MEM_RESERVE, PAGE_NOACCESS);
2887
    if (pBase == NULL) {
2819
    if (pBase == NULL) {
2888
      printf("VirtualAlloc() reserve failed\n");
2820
      printf("VirtualAlloc() reserve failed\n");
Line 2895... Line 2827...
2895
    for (iThread = 0; iThread < cThreads; iThread++) {
2827
    for (iThread = 0; iThread < cThreads; iThread++) {
2896
      ulNode = iThread % (ulNumaNodes + 1);
2828
      ulNode = iThread % (ulNumaNodes + 1);
2897
      dwAffinityMask =
2829
      dwAffinityMask =
2898
          SetThreadAffinityMask(hThread, (DWORD_PTR) ullProcessorMask[ulNode]); // Pierre-Marie Baty -- added type cast
2830
          SetThreadAffinityMask(hThread, (DWORD_PTR) ullProcessorMask[ulNode]); // Pierre-Marie Baty -- added type cast
2899
      for (pch = pBase + iThread * dwPageSize; pch < pEnd; pch += dwStep) {
2831
      for (pch = pBase + iThread * dwPageSize; pch < pEnd; pch += dwStep) {
2900
        lpvResult = VirtualAlloc(pch,   // next page to commit
2832
        lpvResult = VirtualAlloc(pch, // next page to commit
2901
            dwPageSize, // page size, in bytes
2833
            dwPageSize, // page size, in bytes
2902
            MEM_COMMIT, // allocate a committed page
2834
            MEM_COMMIT, // allocate a committed page
2903
            PAGE_READWRITE);    // read/write access
2835
            PAGE_READWRITE); // read/write access
2904
        if (lpvResult == NULL)
2836
        if (lpvResult == NULL)
2905
          ExitProcess(GetLastError());
2837
          ExitProcess(GetLastError());
2906
        memset(lpvResult, 0, dwPageSize);
2838
        memset(lpvResult, 0, dwPageSize);
2907
      }
2839
      }
2908
      SetThreadAffinityMask(hThread, dwAffinityMask);
2840
      SetThreadAffinityMask(hThread, dwAffinityMask);