15 #include <boost/scoped_ptr.hpp>
16 #include <boost/foreach.hpp>
27 using namespace osl::checkmate;
28 using namespace osl::misc;
45 template<
class DfpnSearch>
46 void search(DfpnSearch&,
const char *filename);
47 void usage(
const char *program_name)
49 std::cerr <<
"usage: " << program_name <<
" [-d] [-v] [-f] [-l limit] [-N] csa-files\n";
51 int main(
int argc,
char **argv)
53 const char *program_name = argv[0];
54 bool error_flag =
false;
60 while ((c = getopt(argc, argv,
"dfl:N:F:s:p:t:vh")) != EOF)
68 case 'd':
debug =
true;
74 case 'l':
limit = atoi(optarg);
76 case 'N': parallel = atoi(optarg);
86 default: error_flag =
true;
92 if (error_flag || (argc < 1)) {
101 for (
int i=0; i<argc; ++i)
106 DfpnParallel dfpn(parallel);
109 std::cerr <<
"to use parallel dfpn, try compile with -DOSL_SMP or -DOSL_DFPN_SMP\n";
125 catch (std::exception& e)
127 std::cerr << e.what() <<
"\n";
134 template <
class DfpnSearch>
137 NumEffectState new_state = state;
138 std::cerr << state <<
" " << checkmate_move <<
"\n";
139 new_state.makeMove(checkmate_move);
140 HashKey key(new_state);
141 const DfpnTable& table = searcher.currentTable();
147 for (
size_t i=0; i<moves.size(); ++i) {
148 NumEffectState tmp = new_state;
149 tmp.makeMove(moves[i]);
156 if (state.turn() ==
BLACK)
157 Dfpn::generateEscape<BLACK>(new_state,
false,
Square(),
moves);
159 Dfpn::generateEscape<WHITE>(new_state,
false,
Square(),
moves);
160 std::cerr <<
"Escape " << moves.size()<<
"\n";
162 if (state.turn() ==
BLACK)
163 Dfpn::generateEscape<BLACK>(new_state,
true,
Square(),
moves);
165 Dfpn::generateEscape<BLACK>(new_state,
true,
Square(),
moves);
166 std::cerr <<
"Escape full " << moves.size() <<
"\n";
170 template <
class DfpnSearch>
172 DfpnSearch& searcher,
173 const SimpleState& sstate,
int limit,
175 const vector<Move>&
moves)
177 const Player P = sstate.turn();
178 NumEffectState state(sstate);
180 const Square my_king = state.kingSquare(P);
182 && ! my_king.isPieceStand() && state.inCheck(P))
187 result = searcher.hasEscapeMove(state, HashKey(state), path, limit,
Move::PASS(
alt(P)));
192 std::cerr << result <<
"\n";
193 if (result.isCheckmateSuccess()) {
197 if (result.isCheckmateFail())
200 assert(! result.isFinal());
212 hasCheckmateMove(state, HashKey(state), path, limit, checkmate_move,
Move(), &pv);
216 std::cerr << result <<
"\n";
218 if (result.isCheckmateSuccess()) {
220 best_move = checkmate_move;
222 std::cerr << checkmate_move <<
"\n";
223 for (
size_t i=0; i<pv.size(); ++i) {
224 std::cerr << std::setw(4) << std::setfill(
' ') << i+1
229 if (pv.size() % 6 != 0)
235 searcher.analyze(path, state, moves);
239 if (result.isFinal())
244 searcher.analyze(path, state, moves);
248 template <
class DfpnSearch>
249 void search(DfpnSearch& searcher,
const char *filename)
251 NumEffectState state;
254 CsaFile file(filename);
255 state = file.getInitialState();
256 moves = file.getRecord().getMoves();
258 for (
int i=0; i<forward_here; ++i)
259 state.makeMove(moves[i]);
260 moves.erase(moves.begin(), moves.begin()+forward_here);
262 catch (CsaIOError&) {
263 std::cerr <<
"\nskipping " << filename <<
"\n";
267 std::cerr <<
"\nsolving " << filename <<
"\n";
271 || state.kingSquare(state.turn()).isPieceStand()
272 || ! state.inCheck(state.turn());
273 DfpnTable table(attack ? state.turn() :
alt(state.turn()));
275 searcher.setTable(&table);
279 const size_t table_used = searcher.currentTable().size();
285 searcher.nodeCount());
289 std::cout << filename <<
"\t" << searcher.nodeCount()
294 std::cout <<
"\n" << std::flush;