00001
00002
00003 #include "osl/search/quiescenceSearch2.h"
00004 #include "osl/search/simpleHashTable.h"
00005 #include "osl/search/searchState2.h"
00006 #include "osl/effect_util/effectUtil.h"
00007 #include "osl/record/csaString.h"
00008 #include "osl/record/csaRecord.h"
00009 #include "osl/eval/ml/openMidEndingEval.h"
00010 #include "osl/misc/perfmon.h"
00011
00012 #include <iostream>
00013 #include <fstream>
00014 #include <cstdio>
00015
00016 using namespace osl;
00017 using namespace osl::search;
00018 using namespace osl::misc;
00019
00020 void qsearch(const char *filename);
00021
00022 void usage(const char *program_name)
00023 {
00024 std::cerr << program_name << " [-d depth] [-s skip] [-v] [-p] csafiles\n";
00025 exit(1);
00026 }
00027
00028 int depth = -2;
00029 bool verbose = false, problem_solving = false;
00030 size_t skip_first = 0;
00031
00032 void qsearch(const char *filename);
00033
00034 int main(int argc, char **argv)
00035 {
00036 const char *program_name = argv[0];
00037 bool error_flag = false;
00038
00039 extern char *optarg;
00040 extern int optind;
00041 char c;
00042 while ((c = getopt(argc, argv, "d:s:pvh")) != EOF)
00043 {
00044 switch(c)
00045 {
00046 case 'd': depth = atoi(optarg);
00047 break;
00048 case 's': skip_first = atoi(optarg);
00049 break;
00050 case 'p': problem_solving = true;
00051 break;
00052 case 'v': verbose = true;
00053 break;
00054 default: error_flag = true;
00055 }
00056 }
00057 argc -= optind;
00058 argv += optind;
00059
00060 if (error_flag || (argc < 1))
00061 usage(program_name);
00062
00063 std::cerr << "using table record depth " << depth << "\n";
00064 eval::ml::OpenMidEndingEval::setUp();
00065 progress::ml::NewProgress::setUp();
00066 try
00067 {
00068 for (int i=0; i<argc; ++i)
00069 {
00070 qsearch(argv[i]);
00071 }
00072 }
00073 catch (std::exception& e)
00074 {
00075 std::cerr << e.what() << "\n";
00076 return 1;
00077 }
00078 catch (...)
00079 {
00080 throw;
00081 }
00082 }
00083
00084 void qsearch(const char *filename)
00085 {
00086 if (verbose)
00087 std::cerr << filename;
00088 unsigned long long total_cycles=0;
00089 unsigned long long positions = 0;
00090 Record rec=CsaFile(filename).getRecord();
00091 NumEffectState state(rec.getInitialState());
00092 const vector<osl::Move> moves=rec.getMoves();
00093
00094 typedef QuiescenceSearch2<eval::ml::OpenMidEndingEval> qsearch_t;
00095
00096 SimpleHashTable table(1000000,depth,verbose);
00097 SearchState2Core::checkmate_t checkmate_searcher;
00098 eval::ml::OpenMidEndingEval ev(state);
00099 size_t i=0;
00100 Player initial_turn = state.getTurn();
00101 while (true)
00102 {
00103 if (i >= skip_first)
00104 {
00105 SearchState2Core core(state, checkmate_searcher);
00106 qsearch_t qs(core, table);
00107 const Move last_move = (i > 0) ? moves[i-1] : Move::PASS(alt(initial_turn));
00108 if (verbose)
00109 std::cerr << i << " " << last_move << "\n";
00110 if (problem_solving)
00111 {
00112 std::cout << state;
00113 table.allocate(HashKey(state), 1000);
00114 }
00115 PerfMon clock;
00116 const int val = qs.search(state.getTurn(), ev, last_move, 4);
00117 total_cycles += clock.stop();
00118 positions += qs.nodeCount();
00119
00120 if (verbose || problem_solving)
00121 {
00122 const SimpleHashRecord *record = table.find(HashKey(state));
00123 std::cout << "result ";
00124 if (record)
00125 std::cout << record::csa::show(record->qrecord.bestMove()) << " ";
00126 std::cout << val << "\n";
00127 if (i < moves.size())
00128 std::cout << "recorded " << record::csa::show(moves[i]) << "\n";
00129 }
00130 }
00131 if (i >= moves.size() || problem_solving)
00132 break;
00133 const Move move = moves[i++];
00134 ApplyMoveOfTurn::doMove(state, move);
00135 ev.update(state, move);
00136 }
00137 const size_t checkmate_count = checkmate_searcher.totalNodeCount();
00138 std::cerr << total_cycles << " / ( " << positions
00139 << " + " << checkmate_count << " ) = "
00140 << total_cycles/(double)(positions + checkmate_count) << "\n";
00141 }
00142
00143
00144
00145
00146
00147