00001 //---------------------------------------------------------------------------- 00002 /** VulPreCheck.cpp 00003 */ 00004 //---------------------------------------------------------------------------- 00005 00006 #include "VulPreCheck.hpp" 00007 00008 using namespace benzene; 00009 00010 //---------------------------------------------------------------------------- 00011 00012 VulPreCheck::VulPreCheck() 00013 : m_killedOpptStones() 00014 { 00015 } 00016 00017 VulPreCheck::~VulPreCheck() 00018 { 00019 } 00020 00021 HexPoint VulPreCheck::KillLastMove(HexBoard& brd, const Game& game_state, 00022 HexColor color) 00023 { 00024 LogWarning() << "Performing vulnerable pre-check...\n"; 00025 if (!game_state.History().empty()) 00026 { 00027 // Setup the board as it was prior to the opponent's last move. 00028 MoveSequence gh = game_state.History(); 00029 StoneBoard b(brd.Width(), brd.Height()); 00030 PatternState pastate(b); 00031 for (std::size_t i = 0; i + 1 < gh.size(); ++i) 00032 { 00033 HexPoint p = gh[i].point(); 00034 HexColor c = gh[i].color(); 00035 00036 /** If we've killed this opponent stone, give it to ourselves. 00037 This often helps to find more vulnerable opponent moves. 00038 00039 @todo Make this both colors (ie, dead) once 00040 PatternState supports stones of both colors. 00041 */ 00042 if (m_killedOpptStones.test(p)) 00043 { 00044 HexAssert(c == !color); 00045 c = !c; 00046 } 00047 b.PlayMove(c, p); 00048 } 00049 pastate.Update(); 00050 LogWarning() << "Board before last move:" << b << '\n'; 00051 00052 // Check if last move played (by opponent) was vulnerable. 00053 HexPoint lastCell = gh.back().point(); 00054 bitset_t lastMoveOnly; 00055 lastMoveOnly.set(lastCell); 00056 LogWarning() << "Last move on this board:" 00057 << b.Write(lastMoveOnly) << '\n'; 00058 HexAssert(gh.back().color() == !color); 00059 InferiorCells inf; 00060 brd.ICE().FindVulnerable(pastate, !color, lastMoveOnly, inf); 00061 LogWarning() << "Inferior cells:" << inf.GuiOutput() << '\n'; 00062 00063 // If it was, simply return the killer. 00064 if (inf.Vulnerable().test(lastCell)) 00065 { 00066 LogWarning() << "Opponent's last move was vulnerable - killing it!" 00067 << '\n'; 00068 std::set<VulnerableKiller> killers = inf.Killers(lastCell); 00069 HexAssert(!killers.empty()); 00070 00071 /** If opponent's last move can be made unconditionally dead, 00072 this is preferable since we can treat it as such in the 00073 future, thereby finding more opponent vulnerable cells. */ 00074 std::set<VulnerableKiller>::iterator i; 00075 for (i = killers.begin(); i != killers.end(); ++i) 00076 { 00077 if (i->carrier().none()) 00078 { 00079 m_killedOpptStones.set(lastCell); 00080 return i->killer(); 00081 } 00082 } 00083 // Otherwise, just kill it any which way. 00084 return killers.begin()->killer(); 00085 } 00086 } 00087 return INVALID_POINT; 00088 } 00089 00090 //----------------------------------------------------------------------------