00001
00002
00003 #ifndef _MOVEGENERATOR_H
00004 #define _MOVEGENERATOR_H
00005
00006 #include "osl/search/simpleHashRecord.h"
00007 #include "osl/search/searchState2.h"
00008 #include "osl/rating/ratingEnv.h"
00009 #include "osl/progress/progress32.h"
00010 #include "osl/container/moveLogProbVector.h"
00011 #include "osl/container/moveStack.h"
00012 #include "osl/misc/carray.h"
00013 #include "osl/misc/carray2d.h"
00014 #include "osl/misc/cstdint.h"
00015
00016 namespace osl
00017 {
00018 namespace category
00019 {
00020 namespace analyzer
00021 {
00022 class CategoryMoveVector;
00023 }
00024 }
00025 namespace eval
00026 {
00027 class ProgressEval;
00028 }
00029 namespace search
00030 {
00031 class SearchState2;
00032 class MoveMarker
00033 {
00034 typedef uint8_t value_t;
00035 CArray2d<value_t,Offset::BOARD_HEIGHT*9,Piece::SIZE*2+PTYPE_SIZE> marker;
00036 value_t cur;
00037 public:
00038 MoveMarker();
00039 void clear();
00040 static unsigned int pieceIndex(const NumEffectState& state, Move m)
00041 {
00042 if (m.isPass() || m.isDrop())
00043 return Piece::SIZE*2+m.ptype();
00044 int base = state.getPieceOnBoard(m.from()).number();
00045 if (m.isPromote())
00046 return base+ Piece::SIZE;
00047 return base;
00048 }
00049 static unsigned int toIndex(Move m)
00050 {
00051 return m.to().index()-Position::onBoardMin().index();
00052 }
00053 void registerMove(const NumEffectState& state, Move m)
00054 {
00055 marker(toIndex(m), pieceIndex(state,m)) = cur;
00056 }
00057 bool registerIfNew(const NumEffectState& state, Move m);
00058 bool registered(const NumEffectState& state, Move m) const;
00059 };
00060 class MoveGenerator
00061 {
00062 enum State {
00063 INITIAL, KING_ESCAPE, TAKE_BACK, BREAK_THREATMATE, CAPTURE, TACTICAL_FINISH,
00064 TESUJI, ALL, FINISH
00065 };
00066 typedef void (MoveGenerator::*generator_t)(const SearchState2&);
00067 static const CArray2d<generator_t, 2, FINISH> Generators;
00068 static const CArray<const char *, FINISH> GeneratorNames;
00069 MoveLogProbVector moves;
00070 int cur_state;
00071 size_t cur_index;
00072 SimpleHashRecord *record;
00073 int limit;
00074 int tried;
00075 MoveMarker marker;
00076 RatingEnv env;
00077 Progress32 progress;
00078 bool in_quiesce, in_pv;
00079 public:
00080 MoveGenerator();
00081 void init(int limit, SimpleHashRecord *record, const eval::ProgressEval&,
00082 const NumEffectState&, bool in_pv, Move hash_move, bool quiesce=false);
00084 template <Player P>
00085 const MoveLogProb nextTacticalMove(const SearchState2& state)
00086 {
00087 assert(cur_state < TACTICAL_FINISH);
00088 if (cur_index < moves.size()) {
00089 ++tried;
00090 return moves[cur_index++];
00091 }
00092 return nextTacticalMoveWithGeneration<P>(state);
00093 }
00094 template <Player P>
00095 const MoveLogProb nextMove(const SearchState2& state)
00096 {
00097 if (cur_state < TACTICAL_FINISH) {
00098 state.abort(Move());
00099 }
00100 assert(cur_state >= TACTICAL_FINISH);
00101 if (cur_index < moves.size()) {
00102 ++tried;
00103 return moves[cur_index++];
00104 }
00105 if (cur_state < FINISH)
00106 return nextMoveWithGeneration<P>(state);
00107 return MoveLogProb();
00108 }
00109
00111 void registerMove(const NumEffectState& state, Move m)
00112 {
00113 ++tried;
00114 if (! m.isNormal())
00115 return;
00116 marker.registerMove(state, m);
00117 }
00118
00119 int triedMoves() const { return tried; }
00120 const PieceMask& myPins() const { return env.my_pin; }
00121 void dump() const;
00122
00123
00124 void generateAll(Player P, const SearchState2& state,
00125 category::analyzer::CategoryMoveVector&);
00126 template <Player P>
00127 void generateAll(const SearchState2&, MoveLogProbVector&);
00128 void generateAll(Player P, const SearchState2& state, MoveLogProbVector& out);
00129
00130 const MoveLogProbVector& generated() const { return moves; }
00131 static int captureValue(Ptype);
00132 template <Player P>
00133 void quiesceCapture(const NumEffectState&, Position);
00134 private:
00135 template <Player P>
00136 const MoveLogProb nextMoveWithGeneration(const SearchState2&) ;
00137 template <Player P>
00138 const MoveLogProb nextTacticalMoveWithGeneration(const SearchState2&) ;
00139 template <Player P>
00140 void generateKingEscape(const SearchState2& state);
00141 template <Player P>
00142 void generateTakeBack(const SearchState2& state);
00143 template <Player P>
00144 void generateBreakThreatmate(const SearchState2& state);
00145 template <Player P>
00146 void generateCapture(const SearchState2& state);
00147 template <Player P>
00148 void generateTesuji(const SearchState2& state);
00149 template <Player P>
00150 void generateAllExp(const SearchState2& state);
00151 template <Player P>
00152 void generateAll(const SearchState2& state);
00153 template <Player P>
00154 void addCapture(const NumEffectState&, const RatingEnv&, const MoveVector&);
00155 };
00156 }
00157 }
00158
00159
00160 #endif
00161
00162
00163
00164