gameState.cc
Go to the documentation of this file.
00001 /* gameState.cc
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))       // clone
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 // ;;; Local Variables:
00204 // ;;; mode:c++
00205 // ;;; c-basic-offset:2
00206 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines