Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

PlayAndSolve.cpp

Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 /** @file PlayAndSolve.cpp
00003  */
00004 //----------------------------------------------------------------------------
00005 
00006 #include "PlayAndSolve.hpp"
00007 
00008 using namespace benzene;
00009 
00010 //----------------------------------------------------------------------------
00011 
00012 PlayAndSolve::PlayAndSolve(HexBoard& playerBrd, HexBoard& solverBrd,
00013                            BenzenePlayer& player, DfpnSolver& solver,
00014                            DfpnStates& positions, const Game& game)
00015     : m_playerBrd(playerBrd),
00016       m_solverBrd(solverBrd),
00017       m_player(player),
00018       m_solver(solver),
00019       m_positions(positions),
00020       m_game(game)
00021 {
00022 }
00023 
00024 HexPoint PlayAndSolve::GenMove(const HexState& state, double maxTime)
00025 {
00026     {
00027         // HACK: The player and solver threads could race to call
00028         // VCPattern::GetPatterns(), which constructs the patterns for
00029         // the first time. Force the player to build the vcs first so
00030         // this is not a problem.
00031         LogInfo() << "PlayAndSolve: Building VCs to avoid race condition.\n";
00032         m_playerBrd.GetPosition().SetPosition(state.Position());
00033         m_playerBrd.ComputeAll(state.ToPlay());
00034         LogInfo() << "PlayAndSolve: Continuing on as usual.\n";
00035     }
00036 
00037     boost::mutex mutex;
00038     boost::barrier barrier(3);
00039     m_parallelResult = INVALID_POINT;
00040     boost::thread playerThread(PlayerThread(*this, mutex, barrier, 
00041                                             state, maxTime));
00042     boost::thread solverThread(SolverThread(*this, mutex, barrier, state));
00043     barrier.wait();
00044     playerThread.join();
00045     solverThread.join();
00046     return m_parallelResult;
00047 }
00048 
00049 
00050 void PlayAndSolve::PlayerThread::operator()()
00051 {
00052     LogInfo() << "*** PlayerThread ***\n";
00053     HexBoard& brd = m_ps.m_playerBrd;
00054     brd.GetPosition().SetPosition(m_state.Position());
00055     double score;
00056     HexPoint move = m_ps.m_player.GenMove(m_state, m_ps.m_game, brd,
00057                                           m_maxTime, score);
00058     {
00059         boost::mutex::scoped_lock lock(m_mutex);
00060         if (m_ps.m_parallelResult == INVALID_POINT)
00061         {
00062             LogInfo() << "*** Player move: " << move << '\n';
00063             m_ps.m_parallelResult = move;
00064         }
00065     }
00066     SgSetUserAbort(true);
00067     m_barrier.wait();
00068 }
00069 
00070 
00071 void PlayAndSolve::SolverThread::operator()()
00072 {
00073     LogInfo() << "*** SolverThread ***\n";
00074     HexBoard& brd = m_ps.m_solverBrd;
00075     brd.GetPosition().SetPosition(m_state.Position());
00076     PointSequence pv;
00077     HexColor winner = m_ps.m_solver.StartSearch(m_state, m_ps.m_solverBrd,
00078                                                 m_ps.m_positions, pv);
00079     
00080     if (winner != EMPTY)
00081     {
00082         if (!pv.empty() && pv[0] != INVALID_POINT)
00083         {  
00084             boost::mutex::scoped_lock lock(m_mutex);
00085             m_ps.m_parallelResult = pv[0];
00086             if (winner == m_state.ToPlay())
00087             {
00088                 LogInfo() << "*** FOUND WIN!!! ***\n" 
00089                           << "PV: " << HexPointUtil::ToString(pv) << '\n';
00090             }
00091             else
00092             {
00093                 LogInfo() << "*** FOUND LOSS!! ***\n" 
00094                           << "PV: " << HexPointUtil::ToString(pv) << '\n';
00095             }
00096             SgSetUserAbort(true);
00097         }
00098     }
00099     m_barrier.wait();
00100 }
00101 
00102 //----------------------------------------------------------------------------


6 Jan 2011 Doxygen 1.6.3