Go to the documentation of this file.00001
00002
00003 #include "osl/search/quiescenceSearch2.h"
00004 #include "osl/search/quiescenceSearch2.tcc"
00005 #include "osl/search/quiescenceLog.h"
00006 #include "osl/search/simpleHashTable.h"
00007 #include "osl/state/numEffectState.h"
00008 #include "osl/effect_util/effectUtil.h"
00009 #include "osl/record/csaString.h"
00010 #include "osl/record/csaRecord.h"
00011 #include "osl/eval/pieceEval.h"
00012 #include "osl/eval/progressEval.h"
00013 #include "osl/misc/perfmon.h"
00014
00015 #include <iostream>
00016 #include <fstream>
00017
00018 using namespace osl;
00019 using namespace osl::search;
00020 using namespace osl::misc;
00021
00022 void qsearch(const char *filename);
00023
00024 void usage(const char *program_name)
00025 {
00026 std::cerr << program_name << " [-C] [-P] [-d depth] [-s skip] [-v] csafiles\n";
00027 std::cerr << "-C comparison w,w/o table\n";
00028 exit(1);
00029 }
00030
00031 int depth = -6;
00032 bool verbose = false;
00033 size_t skip_first = 0;
00034 bool comparison = false;
00035 bool use_progress_eval = false;
00036
00037 template <class Eval>
00038 void qsearch(const char *filename);
00039
00040 int main(int argc, char **argv)
00041 {
00042 const char *program_name = argv[0];
00043 bool error_flag = false;
00044
00045 extern char *optarg;
00046 extern int optind;
00047 char c;
00048 while ((c = getopt(argc, argv, "C:Pd:s:vh")) != EOF)
00049 {
00050 switch(c)
00051 {
00052 case 'C': comparison = true;
00053 break;
00054 case 'd': depth = atoi(optarg);
00055 break;
00056 case 'P': use_progress_eval = true;
00057 break;
00058 case 's': skip_first = atoi(optarg);
00059 break;
00060 case 'v': verbose = true;
00061 break;
00062 default: error_flag = true;
00063 }
00064 }
00065 argc -= optind;
00066 argv += optind;
00067
00068 if (error_flag || (argc < 1))
00069 usage(program_name);
00070
00071 std::cerr << "using table record depth " << depth << "\n";
00072 try
00073 {
00074 for (int i=0; i<argc; ++i)
00075 {
00076 if (use_progress_eval)
00077 qsearch<eval::ProgressEval>(argv[i]);
00078 else
00079 qsearch<PieceEval>(argv[i]);
00080 }
00081 }
00082 catch (std::exception& e)
00083 {
00084 std::cerr << e.what() << "\n";
00085 return 1;
00086 }
00087 catch (...)
00088 {
00089 throw;
00090 }
00091 }
00092
00093 template <class Eval>
00094 void qsearch(const char *filename)
00095 {
00096 unsigned long long total_cycles=0;
00097 unsigned long long positions = 0;
00098 Record rec=CsaFile(filename).getRecord();
00099 NumEffectState state(rec.getInitialState());
00100 const vector<osl::Move> moves=rec.getMoves();
00101
00102 typedef QuiescenceSearch2<Eval> qsearch_t;
00103
00104 SimpleHashTable table(1000000,depth,verbose);
00105 SimpleHashTable nulltable(0,0,false);
00106 SearchState2Core::checkmate_t checkmate_searcher;
00107 Eval ev(state);
00108 size_t i=0;
00109 while (true)
00110 {
00111 if (i >= skip_first)
00112 {
00113 SearchState2Core core(state, checkmate_searcher);
00114 qsearch_t qs(core, table);
00115 qsearch_t qsnull(core, nulltable);
00116 const Move last_move = (i > 0) ? moves[i-1] : Move::PASS(alt(moves[0].player()));
00117 if (verbose)
00118 std::cerr << i << " " << last_move << "\n";
00119 if (verbose)
00120 {
00121 const char *logfile = "/tmp/q-w-table.log";
00122 unlink(logfile);
00123 QuiescenceLog::init(logfile);
00124 }
00125 PerfMon clock;
00126 const int val = qs.search(state.turn(), ev, last_move);
00127 total_cycles += clock.stop();
00128 if (comparison)
00129 {
00130 if (verbose)
00131 {
00132 const char *logfile = "/tmp/q-wo-table.log";
00133 unlink(logfile);
00134 QuiescenceLog::init(logfile);
00135 }
00136 const int valnull = qsnull.search(state.turn(), ev, last_move);
00137 if (verbose || (valnull != val))
00138 {
00139 std::cerr << state << "\n";
00140 std::cerr << ev.value() << " " ;
00141 if (! state.inCheck())
00142 std::cerr << ((state.turn() == BLACK)
00143 ? qs.template staticValueWithThreat<BLACK>(ev)
00144 : qs.template staticValueWithThreat<WHITE>(ev)) << " ";
00145 std::cerr << val << " " << valnull << "\n";
00146
00147 }
00148 }
00149 positions += qs.nodeCount();
00150 }
00151 if (i >= moves.size())
00152 break;
00153 const Move move = moves[i++];
00154 state.makeMove(move);
00155 ev.update(state, move);
00156 }
00157 const size_t checkmate_count = checkmate_searcher.totalNodeCount();
00158 std::cerr << total_cycles << " / ( " << positions
00159 << " + " << checkmate_count << " ) = "
00160 << total_cycles/(double)(positions + checkmate_count) << "\n";
00161 }
00162
00163
00164
00165
00166
00167