00001 #include "osl/ntesuki/ntesukiRecord.h"
00002 #include "osl/ntesuki/ntesukiRecord.tcc"
00003 #include "osl/player.h"
00004 #include <iostream>
00005 #include <algorithm>
00006
00007
00008 unsigned int osl::ntesuki::NtesukiRecord::
00009 fixed_search_depth = 0;
00010
00011 unsigned int osl::ntesuki::NtesukiRecord::
00012 inversion_cost = 0;
00013
00014 bool osl::ntesuki::NtesukiRecord::
00015 use_dominance = false;
00016
00017 osl::ntesuki::NtesukiTable *
00018 osl::ntesuki::NtesukiRecord::table = NULL;
00019
00020 osl::NumEffectState *
00021 osl::ntesuki::NtesukiRecord::state = NULL;
00022
00023 osl::ntesuki::NtesukiMoveGenerator *
00024 osl::ntesuki::NtesukiRecord::mg = NULL;
00025
00026 int osl::ntesuki::NtesukiRecord::
00027 pass_count = 0;
00028
00029 bool osl::ntesuki::NtesukiRecord::
00030 max_for_split = false;
00031
00032 bool osl::ntesuki::NtesukiRecord::
00033 use_rzone_move_generation= false;
00034
00035 bool osl::ntesuki::NtesukiRecord::
00036 delay_lame_long = false;
00037
00038 bool osl::ntesuki::NtesukiRecord::
00039 use_9rzone = false;
00040
00041 unsigned int osl::ntesuki::NtesukiRecord::
00042 split_count = 0;
00043
00044 unsigned int osl::ntesuki::NtesukiRecord::
00045 confluence_count = 0;
00046
00047
00048
00049 osl::ntesuki::NtesukiRecord::
00050 NtesukiRecord(signed short distance,
00051 const HashKey& key,
00052 const PieceStand& white_stand,
00053 RecordList* same_board_list)
00054 : black_stand(key.getPieceStand()), white_stand(white_stand),
00055 distance(distance), key(key), same_board_list(same_board_list),
00056 rev_refcount(0),
00057 child_count(0), read_count(0), written_count(0),
00058 visited(false), by_simulation(false),
00059 by_fixed_black(false), by_fixed_white(false),
00060 already_set_up(false),
00061 final(false), is_split(false),
00062 do_oracle_attack(true),
00063 do_oracle_aunt(true),
00064 rzone_move_generation(use_rzone_move_generation)
00065 {
00066 std::fill(values_black.begin(), values_black.end(), ProofDisproof(1, 1));
00067 std::fill(values_white.begin(), values_white.end(), ProofDisproof(1, 1));
00068
00069 std::fill(read_interpose.begin(), read_interpose.end(), false);
00070 std::fill(read_check_defense.begin(), read_check_defense.end(), false);
00071 std::fill(read_non_attack.begin(), read_non_attack.end(), false);
00072
00073 std::fill(is_ntesuki_black.begin(), is_ntesuki_black.end(), false);
00074 std::fill(is_ntesuki_white.begin(), is_ntesuki_white.end(), false);
00075
00076 std::fill(propagated_oracle_black.begin(), propagated_oracle_black.end(), false);
00077 std::fill(propagated_oracle_white.begin(), propagated_oracle_white.end(), false);
00078
00079 std::fill(use_old_black.begin(), use_old_black.end(), false);
00080 std::fill(use_old_white.begin(), use_old_white.end(), false);
00081
00082 if (use_dominance)
00083 {
00084 lookup_same_board_list();
00085 }
00086 }
00087
00088 void
00089 osl::ntesuki::NtesukiRecord::
00090 updateWithChild(osl::ntesuki::NtesukiRecord* child,
00091 int pass_left)
00092 {
00093 for (unsigned int i = pass_left; i < SIZE; i++)
00094 {
00095 rzone<BLACK>()[i].update(child->rzone<BLACK>()[i]);
00096 rzone<WHITE>()[i].update(child->rzone<WHITE>()[i]);
00097 }
00098 }
00099 void
00100 osl::ntesuki::NtesukiRecord::
00101 lookup_same_board_list()
00102 {
00103 for (RecordList::iterator it = same_board_list->begin();
00104 it != same_board_list->end(); it++)
00105 {
00106 if (&(*it) == this) continue;
00107
00108 for (size_t pass_left = 0; pass_left < SIZE; pass_left++)
00109 {
00110 if (isDominatedByProofPieces<BLACK>(&(*it), pass_left))
00111 {
00112 PieceStand ps = it->getPDPieces<BLACK>(pass_left);
00113 TRY_DFPN;
00114 setResult<BLACK>(pass_left, it->getValue<BLACK>(pass_left),
00115 it->getBestMove<BLACK>(pass_left), false, &ps);
00116 CATCH_DFPN;
00117 return;
00118 }
00119 else if (isDominatedByProofPieces<WHITE>(&(*it), pass_left))
00120 {
00121 PieceStand ps = it->getPDPieces<WHITE>(pass_left);
00122 TRY_DFPN;
00123 setResult<WHITE>(pass_left, it->getValue<WHITE>(pass_left),
00124 it->getBestMove<WHITE>(pass_left), false, &ps);
00125 CATCH_DFPN;
00126 return;
00127 }
00128 }
00129 for (int pass_left = (int)SIZE - 1; pass_left >= 0; pass_left--)
00130 {
00131 if (isDominatedByDisproofPieces<BLACK>(&(*it), pass_left))
00132 {
00133 PieceStand ps = it->getPDPieces<BLACK>(pass_left);
00134 TRY_DFPN;
00135 setResult<BLACK>(pass_left, it->getValue<BLACK>(pass_left),
00136 it->getBestMove<BLACK>(pass_left), false, &ps);
00137 CATCH_DFPN;
00138 return;
00139 }
00140 else if (isDominatedByDisproofPieces<WHITE>(&(*it), pass_left))
00141 {
00142 PieceStand ps = it->getPDPieces<WHITE>(pass_left);
00143 const NtesukiMove& best_move = it->getBestMove<WHITE>(pass_left);
00144 TRY_DFPN;
00145 setResult<WHITE>(pass_left, it->getValue<WHITE>(pass_left),
00146 best_move, false, &ps);
00147 CATCH_DFPN;
00148 return;
00149 }
00150 }
00151 }
00152 }
00153
00154
00155
00156
00157
00158 const osl::ntesuki::NtesukiResult
00159 osl::ntesuki::NtesukiRecord::
00160 getValueSlow(const Player player, int i) const
00161 {
00162 if (BLACK == player)
00163 return values<BLACK>()[i];
00164 else
00165 return values<WHITE>()[i];
00166 }
00167
00168 const osl::ntesuki::NtesukiResult
00169 osl::ntesuki::NtesukiRecord::
00170 getValueOfTurn(int i) const
00171 {
00172 return getValueSlow(turn(), i);
00173 }
00174
00175 const osl::ntesuki::NtesukiResult
00176 osl::ntesuki::NtesukiRecord::
00177 valueBeforeFinal() const
00178 {
00179 return value_before_final;
00180 }
00181
00182 const osl::ntesuki::NtesukiMove&
00183 osl::ntesuki::NtesukiRecord::
00184 getBestMoveSlow(Player P, int i) const
00185 {
00186 if (BLACK == P)
00187 return getBestMove<BLACK>(i);
00188 else
00189 return getBestMove<WHITE>(i);
00190 }
00191
00192 bool
00193 osl::ntesuki::NtesukiRecord::
00194 isByFixedSlow(Player P) const
00195 {
00196 if (P == BLACK)
00197 return isByFixed<BLACK>();
00198 else
00199 return isByFixed<WHITE>();
00200 }
00201
00202 osl::PieceStand
00203 osl::ntesuki::NtesukiRecord::
00204 getPDPiecesSlow(Player p, int pass_left) const
00205 {
00206 if (p == BLACK)
00207 return pdpieces<BLACK>()[pass_left];
00208 else
00209 return pdpieces<WHITE>()[pass_left];
00210 }
00211
00212
00213
00214
00215 namespace osl
00216 {
00217 namespace ntesuki
00218 {
00219 template
00220 void NtesukiRecord::
00221 setResult<BLACK>(int i,
00222 const NtesukiResult& r,
00223 const NtesukiMove& m,
00224 bool bs,
00225 const PieceStand* ps);
00226 template
00227 void NtesukiRecord::
00228 setResult<WHITE>(int i,
00229 const NtesukiResult& r,
00230 const NtesukiMove& m,
00231 bool bs,
00232 const PieceStand* ps);
00233
00234 template
00235 bool NtesukiRecord::
00236 setUpNode<BLACK>();
00237
00238 template
00239 bool NtesukiRecord::
00240 setUpNode<WHITE>();
00241
00242 template
00243 void NtesukiRecord::
00244 generateMoves<BLACK>(NtesukiMoveList& moves,
00245 int pass_left,
00246 bool all_moves);
00247
00248 template
00249 void NtesukiRecord::
00250 generateMoves<WHITE>(NtesukiMoveList& moves,
00251 int pass_left,
00252 bool all_moves);
00253
00254 template
00255 bool NtesukiRecord::
00256 isNtesuki<BLACK>(int pass_left) const;
00257
00258 template
00259 bool NtesukiRecord::
00260 isNtesuki<WHITE>(int pass_left) const;
00261
00262 template
00263 void NtesukiRecord::
00264 setNtesuki<BLACK>(int pass_left);
00265
00266 template
00267 void NtesukiRecord::
00268 setNtesuki<WHITE>(int pass_left);
00269
00270 template
00271 bool NtesukiRecord::
00272 hasTriedPropagatedOracle<BLACK>(int pass_left) const;
00273
00274 template
00275 bool NtesukiRecord::
00276 hasTriedPropagatedOracle<WHITE>(int pass_left) const;
00277
00278 template
00279 void NtesukiRecord::
00280 triedPropagatedOracle<BLACK>(int pass_left);
00281
00282 template
00283 void NtesukiRecord::
00284 triedPropagatedOracle<WHITE>(int pass_left);
00285
00286 template
00287 bool NtesukiRecord::
00288 useOld<BLACK>(int pass_left) const;
00289
00290 template
00291 bool NtesukiRecord::
00292 useOld<WHITE>(int pass_left) const;
00293
00294 template
00295 void NtesukiRecord::
00296 setUseOld<BLACK>(int pass_left, bool b);
00297
00298 template
00299 void NtesukiRecord::
00300 setUseOld<WHITE>(int pass_left, bool b);
00301
00302 template
00303 PieceStand NtesukiRecord::
00304 getPDPieces<BLACK>(int pass_left) const;
00305
00306 template
00307 PieceStand NtesukiRecord::
00308 getPDPieces<WHITE>(int pass_left) const;
00309
00310 template
00311 void NtesukiRecord::
00312 setPDPieces<BLACK>(int pass_left,
00313 const PieceStand p);
00314 template
00315 void NtesukiRecord::
00316 setPDPieces<WHITE>(int pass_left,
00317 const PieceStand p);
00318
00319 template
00320 bool NtesukiRecord::
00321 isLoopWithPath<BLACK>(int pass_left,
00322 const PathEncoding& path) const;
00323 template
00324 bool NtesukiRecord::
00325 isLoopWithPath<WHITE>(int pass_left,
00326 const PathEncoding& path) const;
00327
00328 template
00329 void NtesukiRecord::
00330 setLoopWithPath<BLACK>(int pass_left,
00331 const PathEncoding& path);
00332
00333 template
00334 void NtesukiRecord::
00335 setLoopWithPath<WHITE>(int pass_left,
00336 const PathEncoding& path);
00337
00338 template
00339 const NtesukiResult NtesukiRecord::
00340 getValueWithPath<BLACK>(int max_pass_left, const PathEncoding path) const;
00341
00342 template
00343 const NtesukiResult NtesukiRecord::
00344 getValueWithPath<WHITE>(int max_pass_left, const PathEncoding pat) const;
00345
00346 template
00347 const NtesukiResult NtesukiRecord::
00348 getValueOr<BLACK>(int max_pass_left, const PathEncoding path,
00349 IWScheme iwscheme) const;
00350
00351 template
00352 const NtesukiResult NtesukiRecord::
00353 getValueOr<WHITE>(int max_pass_left, const PathEncoding pat,
00354 IWScheme iwscheme) const;
00355
00356 template
00357 const NtesukiResult NtesukiRecord::
00358 getValueAnd<BLACK>(int max_pass_left, const PathEncoding pat,
00359 IWScheme iwscheme, PSScheme psscheme) const;
00360
00361 template
00362 const NtesukiResult NtesukiRecord::
00363 getValueAnd<WHITE>(int max_pass_left, const PathEncoding pat,
00364 IWScheme iwscheme, PSScheme psscheme) const;
00365
00366
00367 std::ostream&
00368 operator<<(std::ostream& os, const NtesukiRecord& record)
00369 {
00370 os << "player:\t" << record.key.turn() << "\n"
00371 << "visited:\t" << record.isVisited() << "\n"
00372 << "distance:\t" << record.distance << "\n"
00373 << "subtree:\t" << record.getChildCount() << "\n"
00374 << record.key << "\nBS"
00375 << record.black_stand << "\nWS"
00376 << record.white_stand << "\n";
00377
00378
00379 for(size_t i = 0; i < NtesukiRecord::SIZE; ++i)
00380 {
00381 os << i << " B\tmove("
00382 << record.getBestMove<BLACK>(i) << ")\t"
00383 << record.getValue<BLACK>(i) << "\tdom("
00384 << record.getPDPieces<BLACK>(i)
00385 << "\n"
00386 << i << " W\tmove("
00387 << record.getBestMove<WHITE>(i) << ")\t"
00388 << record.getValue<WHITE>(i) << "\tdom("
00389 << record.getPDPieces<WHITE>(i)
00390 << "\n";
00391 }
00392
00393 return os;
00394 }
00395
00396 std::ostream&
00397 operator<<(std::ostream& os,
00398 const NtesukiRecord::IWScheme& s)
00399 {
00400 switch (s)
00401 {
00402 case NtesukiRecord::no_iw: os << "no_widening";
00403 break;
00404 case NtesukiRecord::strict_iw: os << "iterative_widening";
00405 break;
00406 case NtesukiRecord::pn_iw: os << "pnbased_widening";
00407 break;
00408 default:
00409 throw std::runtime_error("cannot parse string");
00410 }
00411 return os;
00412 }
00413
00414 std::istream&
00415 operator>>(std::istream& is,
00416 NtesukiRecord::IWScheme& s)
00417 {
00418 std::string token;
00419 is >> token;
00420
00421 switch (token[0])
00422 {
00423 case 'n':
00424 s = NtesukiRecord::no_iw;
00425 break;
00426 case 'i':
00427 s = NtesukiRecord::strict_iw;
00428 break;
00429 case 'p':
00430 s = NtesukiRecord::pn_iw;
00431 break;
00432 default:
00433 throw std::runtime_error("cannot parse string");
00434 }
00435 return is;
00436 }
00437
00438 std::ostream&
00439 operator<<(std::ostream& os,
00440 const NtesukiRecord::PSScheme& s)
00441 {
00442 switch (s)
00443 {
00444 case NtesukiRecord::no_ps: os << "single_lambda";
00445 break;
00446 case NtesukiRecord::pn_ps: os << "dual_lambda";
00447 break;
00448 default:
00449 throw std::runtime_error("cannot parse string");
00450 }
00451 return os;
00452 }
00453
00454 std::istream&
00455 operator>>(std::istream& is,
00456 NtesukiRecord::PSScheme& s)
00457 {
00458 std::string token;
00459 is >> token;
00460
00461 switch (token[0])
00462 {
00463 case 'n':
00464 case 's':
00465 s = NtesukiRecord::no_ps;
00466 break;
00467 case 'p':
00468 case 'd':
00469 s = NtesukiRecord::pn_ps;
00470 break;
00471 default:
00472 throw std::runtime_error("cannot parse string");
00473 }
00474 return is;
00475 }
00476
00477 std::ostream&
00478 operator<<(std::ostream& os,
00479 const NtesukiRecord::ISScheme& s)
00480 {
00481 switch (s)
00482 {
00483 case NtesukiRecord::no_is: os << "katagyoku";
00484 break;
00485 case NtesukiRecord::tonshi_is: os << "tonshi-only";
00486 break;
00487 case NtesukiRecord::delay_is: os << "delay-inversion";
00488 break;
00489 case NtesukiRecord::normal_is: os << "full-inversion";
00490 break;
00491 default:
00492 throw std::runtime_error("cannot parse string");
00493 }
00494
00495 return os;
00496 }
00497
00498 std::istream&
00499 operator>>(std::istream& is,
00500 NtesukiRecord::ISScheme& s)
00501 {
00502 std::string token;
00503 is >> token;
00504
00505 switch (token[0])
00506 {
00507 case 'n':
00508 s = NtesukiRecord::no_is;
00509 break;
00510 case 't':
00511 s = NtesukiRecord::tonshi_is;
00512 break;
00513 case 'd':
00514 s = NtesukiRecord::delay_is;
00515 break;
00516 case 'f':
00517 s = NtesukiRecord::normal_is;
00518 break;
00519 default:
00520 throw std::runtime_error("cannot parse string");
00521 }
00522 return is;
00523 }
00524
00525 }
00526 }