Go to the documentation of this file.00001
00002
00003 #include "osl/game_playing/gameState.h"
00004 #include "osl/game_playing/openingBookTracer.h"
00005 #include "osl/checkmate/immediateCheckmate.h"
00006 #include "osl/move_classifier/pawnDropCheckmate.h"
00007 #include "osl/move_classifier/moveAdaptor.h"
00008 #include "osl/move_generator/legalMoves.h"
00009 #include "osl/effect_util/effectUtil.h"
00010 #include "osl/state/historyState.h"
00011 #include "osl/hash/hashKeyStack.h"
00012 #include "osl/container/moveStack.h"
00013 #include "osl/misc/align16New.h"
00014 #include "osl/repetitionCounter.h"
00015 #include "osl/sennichite.h"
00016 #include "osl/enter_king/enterKing.h"
00017 #include <boost/foreach.hpp>
00018
00019 struct osl::game_playing::GameState::State
00020 #if OSL_WORDSIZE == 32
00021 : public osl::misc::Align16New
00022 #endif
00023 {
00024 HistoryState state;
00025 RepetitionCounter counter;
00026 MoveStack move_history;
00027 vector<int> eval_stack;
00028
00029 State(const SimpleState& initial_state)
00030 : state(initial_state), counter(state.state())
00031 {
00032 move_history.reserve(1024);
00033 }
00034 };
00035
00036 osl::game_playing::
00037 GameState::GameState(const SimpleState& initial_state)
00038 : stack(new State(initial_state))
00039 {
00040 }
00041
00042 osl::game_playing::
00043 GameState::GameState(const State& src)
00044 : stack(new State(src))
00045 {
00046 }
00047
00048 osl::game_playing::
00049 GameState::~GameState()
00050 {
00051 }
00052
00053 const osl::Sennichite osl::game_playing::
00054 GameState::pushMove(Move m, int eval)
00055 {
00056 stack->move_history.push(m);
00057 const Sennichite result
00058 = stack->counter.isSennichite(state(), m);
00059 stack->counter.push(state(), m);
00060 stack->state.makeMove(m);
00061 stack->eval_stack.push_back(eval);
00062 return result;
00063 }
00064
00065 osl::game_playing::GameState::MoveType osl::game_playing::
00066 GameState::isIllegal(Move m) const
00067 {
00068 if (! state().isValidMove(m, false))
00069 return OTHER_INVALID;
00070 typedef move_classifier::PlayerMoveAdaptor<move_classifier::PawnDropCheckmate>
00071 PawnDropCheckmate_t;
00072 if (PawnDropCheckmate_t::isMember(state(), m))
00073 return PAWN_DROP_FOUL;
00074
00075 stack->state.makeMove(m);
00076 const bool unsafe_king = state().inCheck(alt(state().turn()));
00077 stack->state.unmakeMove();
00078
00079 if (unsafe_king)
00080 return UNSAFE_KING;
00081
00082 return VALID;
00083 }
00084
00085 const osl::Move osl::game_playing::
00086 GameState::popMove()
00087 {
00088 const Move result = stack->move_history.lastMove();
00089 assert(canPopMove());
00090 stack->move_history.pop();
00091 stack->counter.pop();
00092 stack->state.unmakeMove();
00093 stack->eval_stack.pop_back();
00094 return result;
00095 }
00096
00097 const osl::NumEffectState& osl::game_playing::
00098 GameState::state() const
00099 {
00100 return stack->state.state();
00101 }
00102
00103 int osl::game_playing::
00104 GameState::moves() const
00105 {
00106 return stack->move_history.size();
00107 }
00108
00109 const osl::MoveStack& osl::game_playing::
00110 GameState::moveHistory() const
00111 {
00112 return stack->move_history;
00113 }
00114
00115 const osl::hash::HashKeyStack& osl::game_playing::
00116 GameState::hashHistory() const
00117 {
00118 return stack->counter.history();
00119 }
00120
00121 const osl::RepetitionCounter& osl::game_playing::
00122 GameState::counter() const
00123 {
00124 return stack->counter;
00125 }
00126
00127 bool osl::game_playing::
00128 GameState::canPopMove() const
00129 {
00130 return ! stack->state.empty();
00131 }
00132
00133 const boost::shared_ptr<osl::game_playing::GameState> osl::game_playing::
00134 GameState::clone() const
00135 {
00136 boost::shared_ptr<GameState> result(new GameState(*stack));
00137 return result;
00138 }
00139
00140 const osl::state::SimpleState& osl::game_playing::
00141 GameState::getInitialState() const
00142 {
00143 return stack->state.initialState();
00144 }
00145
00146 const osl::vector<int>& osl::game_playing::
00147 GameState::evalStack() const
00148 {
00149 return stack->eval_stack;
00150 }
00151
00152 void osl::game_playing::
00153 GameState::generateMoves(container::MoveVector& normal,
00154 container::MoveVector& win,
00155 container::MoveVector& draw,
00156 container::MoveVector& loss) const
00157 {
00158 MoveVector all;
00159 LegalMoves::generate(state(), all);
00160 NumEffectState copy;
00161 BOOST_FOREACH(Move m, all) {
00162 if (isIllegal(m) != VALID) {
00163 loss.push_back(m);
00164 continue;
00165 }
00166 const Sennichite result
00167 = counter().isSennichite(state(), m);
00168 if (! result.isNormal()) {
00169 if (! result.hasWinner())
00170 draw.push_back(m);
00171 else {
00172 if (result.winner() == alt(state().turn()))
00173 loss.push_back(m);
00174 else
00175 win.push_back(m);
00176 }
00177 continue;
00178 }
00179 copy.copyFrom(state());
00180 copy.makeMove(m);
00181 if (! copy.inCheck()) {
00182 if (checkmate::ImmediateCheckmate::hasCheckmateMove(copy.turn(), copy)
00183 || EnterKing::canDeclareWin(copy)) {
00184 loss.push_back(m);
00185 continue;
00186 }
00187 }
00188 normal.push_back(m);
00189 }
00190 }
00191
00192 void osl::game_playing::
00193 GameState::generateNotLosingMoves(MoveVector& normal_or_win_or_draw,
00194 MoveVector& loss) const
00195 {
00196 MoveVector win, draw;
00197 generateMoves(normal_or_win_or_draw, win, draw, loss);
00198 normal_or_win_or_draw.push_back(win.begin(), win.end());
00199 normal_or_win_or_draw.push_back(draw.begin(), draw.end());
00200 }
00201
00202
00203
00204
00205
00206