Subversion Repositories Games.Chess Giants

Rev

Rev 108 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
33 pmbaty 1
#include "chess.h"
2
#include "data.h"
3
/* last modified 05/08/14 */
4
/*
5
 *******************************************************************************
6
 *                                                                             *
7
 *   Repeat() is used to detect a draw by repetition.  The repetition list is  *
8
 *   a simple 1d array that contains the Zobrist signatures for each position  *
9
 *   reached in the game since the last irreversable moves at the root.  New   *
10
 *   positions are only added to this list here in Repeat().                   *
11
 *                                                                             *
12
 *   Repeat() scans the list to determine if this position has occurred at     *
13
 *   once previously (two-fold repetition.)  If so, this will be treated as a  *
14
 *   draw by Search()/Quiesce().                                               *
15
 *                                                                             *
16
 *   Repeat() also handles 50-move draws.  The position[] structure contains   *
17
 *   the count of moves since the last capture or pawn push.  When this value  *
18
 *   reaches 100 (plies, which is 50 moves) the score is set to DRAW.          *
19
 *                                                                             *
20
 *   Repeat() has one tricky issue.  MakeMoveRoot() has to insert moves into   *
21
 *   the repetition list so that things will work well.  We end up with the    *
22
 *   list having entries from 0 through "rep_index" where the last entry is    *
23
 *   the entry stored after the last actual move in the game.  Search() will   *
24
 *   call Repeat() at ply=1, which stores the SAME position at position        *
25
 *   rep_index + 1.  That gets the list out of sync.  To solve this, Iterate() *
26
 *   decrements rep_index immediately prior to calling Search(), and it then   *
27
 *   increments it immediately after Search() returns.  This causes Search()   *
28
 *   to overwrite the entry with the same value for ply=1, but now the list is *
29
 *   in a sane state for the rest of the search.  Do NOT remove those to lines *
30
 *   in Iterate() or repetition detection will be broken.                      *
31
 *                                                                             *
32
 *******************************************************************************
33
 */
34
int Repeat(TREE * RESTRICT tree, int ply) {
35
  int where;
36
 
37
/*
38
 ************************************************************
39
 *                                                          *
40
 *  If the 50-move rule has been reached, then adjust the   *
41
 *  score to reflect the impending draw.  If we have not    *
42
 *  made 2 moves for each side (or more) since the last     *
43
 *  irreversible move, there is no way to repeat a prior    *
44
 *  position.                                               *
45
 *                                                          *
46
 ************************************************************
47
 */
48
  tree->rep_list[tree->rep_index + ply] = HashKey;
49
  if (Reversible(ply) < 4)
50
    return 0;
51
  if (Reversible(ply) > 99)
52
    return 2;
53
/*
54
 ************************************************************
55
 *                                                          *
56
 *  Now we scan the right part of the repetition list,      *
57
 *  which is to search backward from the entry for 2 plies  *
58
 *  back (no point in checking current position, we KNOW    *
59
 *  that is a match but it is not a repetition, it is just  *
60
 *  the current position's entry which we don't want to     *
61
 *  check).  We can use the reversible move counter as a    *
62
 *  limit since there is no point in scanning the list back *
63
 *  beyond the last capture/pawn move since there can not   *
64
 *  possibly be a repeat beyond that point.                 *
65
 *                                                          *
66
 ************************************************************
67
 */
68
  for (where = tree->rep_index + ply - 2; where >= ply - Reversible(ply) - 2;
69
      where -= 2)
70
    if (HashKey == tree->rep_list[where])
71
      return 1;
72
  return 0;
73
}
74
 
75
/* last modified 05/08/14 */
76
/*
77
 *******************************************************************************
78
 *                                                                             *
79
 *   Repeat3x() is used to detect a real draw by repetition.  This routine is  *
80
 *   only called from Main() and simply scans the complete list searching for  *
81
 *   exactly three repetitions (two additional repetitions of the current      *
82
 *   position.)  This is used to actually claim a draw by repetition or by the *
83
 *   50 move rule.                                                             *
84
 *                                                                             *
85
 *******************************************************************************
86
 */
87
int Repeat3x(TREE * RESTRICT tree, int wtm) {
88
  int reps, where;
89
 
90
/*
91
 ************************************************************
92
 *                                                          *
93
 *  If the 50-move rule has been reached, then return an    *
94
 *  indicator that a draw can be claimed if wanted.         *
95
 *                                                          *
96
 ************************************************************
97
 */
98
  if (Reversible(0) > 99)
99
    return 2;
100
/*
101
 ************************************************************
102
 *                                                          *
103
 *  Scan the repetition list to determine if this position  *
104
 *  has occurred two times previously, making this an       *
105
 *  actual 3-fold repetition.  Note we only check every     *
106
 *  other entry since the position has to be repeated 3x    *
107
 *  with the SAME side on move.                             *
108
 *                                                          *
109
 ************************************************************
110
 */
111
  reps = 0;
112
  for (where = tree->rep_index % 2; where < tree->rep_index; where += 2)
113
    if (HashKey == tree->rep_list[where])
114
      reps++;
115
  return reps == 2;
116
}