The Pedigree Project  0.1
Minimax.cc
1 /*
2  *
3  * Copyright (c) 2008-2014, Pedigree Developers
4  *
5  * Please see the CONTRIB file in the root of the source tree for a full
6  * list of contributors.
7  *
8  * Permission to use, copy, modify, and distribute this software for any
9  * purpose with or without fee is hereby granted, provided that the above
10  * copyright notice and this permission notice appear in all copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19  */
20 
21 #include "Minimax.h"
22 #include <stdio.h>
23 
24 #ifdef DO_ALG
25 #undef DO_ALG
26 #endif
27 #define DO_ALG \
28  for (Square sq2 = b.getAndClearFirstSetBit(); \
29  !sq2.invalid(); \
30  sq2 = b.getAndClearFirstSetBit()) \
31  { \
32  MoveList tmpList; \
33  BoardState newState = state; \
34  newState.move( Move(sq.col, sq.row, sq2.col, sq2.row), toPlay, Queen /* Default promotion piece */ ); \
35  long tmpHeuristic = doSearch(side, curDepth+1, !isMaximising, maxDepth, newState, tmpList); \
36  \
37  if ( (isMaximising && tmpHeuristic > accumulator) || \
38  (!isMaximising && tmpHeuristic < accumulator) ) \
39  { \
40  accumulator = tmpHeuristic; \
41  moveList = tmpList; \
42  moveList.push_front(Move(sq.col, sq.row, sq2.col, sq2.row)); \
43  } \
44  }
45 
46 Minimax::Minimax(volatile bool *keepGoing) :
47  SearchAlgorithm(keepGoing)
48 {
49 }
50 
51 Minimax::~Minimax()
52 {
53 }
54 
55 long Minimax::search(Side side, int maxDepth, BoardState state, MoveList &moveList)
56 {
57  nodesSearched = 0;
58  return doSearch(side, 0, true, maxDepth, state, moveList);
59 }
60 
61 long Minimax::doSearch(Side side, int curDepth, bool isMaximising, int maxDepth, BoardState state, MoveList &moveList)
62 {
63  if (*m_KeepGoing == false)
64  return 0;
65 
66  nodesSearched ++;
67 
68  // What side is to move?
69  Side toPlay;
70  if ( (side == White && isMaximising) || (side == Black && !isMaximising) )
71  toPlay = White;
72  else
73  toPlay = Black;
74 
75  long h;
76  if (state.load(maxDepth-curDepth, toPlay, moveList, h))
77  {
78  // Loading succeeded - we have a record of this BoardState evaluated to at least maxDepth-curDepth depth.
79  return h;
80  }
81 
82  // Check goal states.
83  if (curDepth == maxDepth)
84  return state.heuristic(side);
85 // else if (state.inCheck(White) && // So that we don't do an inCheckmate check for every position!
86 // state.inCheckmate(White))
87 // {
88 // return state.heuristic(side);
89 // }
90 // else if (state.inCheck(Black) && // So that we don't do an inCheckmate check for every position!
91 // state.inCheckmate(Black))
92 // {
93 // return state.heuristic(side);
94 // }
95 // else if (state.inStalemate())
96 // {
97 // return state.heuristic();
98 // }
99 
100  // For each piece type...
101  Square sq;
102  Bitboard b;
103  long accumulator = (isMaximising) ? -10000000 : 10000000;
104 
105  for (sq = state.firstPawn(toPlay, &b);
106  !sq.invalid();
107  sq = state.nextPawn(toPlay, &b))
108  {
109  DO_ALG
110  }
111  for (sq = state.firstKnight(toPlay, &b);
112  !sq.invalid();
113  sq = state.nextKnight(toPlay, &b))
114  {
115  DO_ALG
116  }
117  for (sq = state.firstRook(toPlay, &b);
118  !sq.invalid();
119  sq = state.nextRook(toPlay, &b))
120  {
121  DO_ALG
122  }
123  for (sq = state.firstBishop(toPlay, &b);
124  !sq.invalid();
125  sq = state.nextBishop(toPlay, &b))
126  {
127  DO_ALG
128  }
129  for (sq = state.firstQueen(toPlay, &b);
130  !sq.invalid();
131  sq = state.nextQueen(toPlay, &b))
132  {
133  DO_ALG
134  }
135  sq = state.firstKing(toPlay, &b);
136  DO_ALG
137 
138  // Return best move.
139  state.save(maxDepth-curDepth, toPlay, accumulator, moveList); \
140  return accumulator;
141 
142 }
bool load(int minPly, Side toPlay, MoveList &ml, long &h)
Definition: BoardState.cc:704
Square firstPawn(Side s, Bitboard *b=NULL)
Definition: BoardState.cc:260
long heuristic(Side side)
Definition: BoardState.cc:649
void save(int ply, Side toPlay, long h, MoveList &ml)
Definition: BoardState.cc:709
Definition: Square.h:24