00001 //---------------------------------------------------------------------------- 00002 /** @file Game.cpp 00003 */ 00004 //---------------------------------------------------------------------------- 00005 00006 #include "Game.hpp" 00007 #include "Groups.hpp" 00008 00009 using namespace benzene; 00010 00011 //---------------------------------------------------------------------------- 00012 00013 Game::Game(StoneBoard& board) 00014 : m_board(&board), 00015 m_allow_swap(false), 00016 m_game_time(1800) 00017 { 00018 NewGame(); 00019 } 00020 00021 void Game::NewGame() 00022 { 00023 LogFine() << "Game::NewGame()" << '\n'; 00024 m_board->StartNewGame(); 00025 m_time_remaining[BLACK] = m_game_time; 00026 m_time_remaining[WHITE] = m_game_time; 00027 m_history.clear(); 00028 } 00029 00030 void Game::SetGameTime(double time) 00031 { 00032 m_game_time = time; 00033 m_time_remaining[BLACK] = m_game_time; 00034 m_time_remaining[WHITE] = m_game_time; 00035 } 00036 00037 Game::ReturnType Game::PlayMove(HexColor color, HexPoint cell) 00038 { 00039 if (cell < 0 || cell >= FIRST_INVALID || !m_board->Const().IsValid(cell)) 00040 return INVALID_MOVE; 00041 if (color == EMPTY) 00042 return INVALID_MOVE; 00043 if (HexPointUtil::isSwap(cell)) 00044 { 00045 if (!m_allow_swap || m_history.size() != 1) 00046 return INVALID_MOVE; 00047 } 00048 if (m_board->IsPlayed(cell)) 00049 return OCCUPIED_CELL; 00050 00051 m_board->PlayMove(color, cell); 00052 m_history.push_back(Move(color, cell)); 00053 00054 return VALID_MOVE; 00055 } 00056 00057 void Game::UndoMove() 00058 { 00059 if (m_history.empty()) 00060 return; 00061 m_board->UndoMove(m_history.back().point()); 00062 m_history.pop_back(); 00063 } 00064 00065 //---------------------------------------------------------------------------- 00066 00067 bool GameUtil::IsGameOver(const Game& game) 00068 { 00069 Groups groups; 00070 GroupBuilder::Build(game.Board(), groups); 00071 return groups.IsGameOver(); 00072 } 00073 00074 bool GameUtil::SequenceFromPosition(const Game& game, const StoneBoard& pos, 00075 MoveSequence& seq) 00076 { 00077 if (game.Board().Const() != pos.Const()) 00078 return false; 00079 StoneBoard cur(pos); 00080 cur.StartNewGame(); 00081 if (cur == pos) 00082 { 00083 seq = game.History(); 00084 return true; 00085 } 00086 const MoveSequence& history = game.History(); 00087 for (MoveSequence::const_iterator it = history.begin(); 00088 it != history.end(); ++it) 00089 { 00090 const Move& move = *it; 00091 cur.PlayMove(move.color(), move.point()); 00092 if (cur == pos) 00093 { 00094 LogInfo() << "Position matched!" << '\n'; 00095 seq.assign(++it, history.end()); 00096 return true; 00097 } 00098 } 00099 return false; 00100 } 00101 00102 void GameUtil::HistoryToSequence(const MoveSequence& history, 00103 PointSequence& sequence) 00104 { 00105 sequence.clear(); 00106 for (MoveSequence::const_iterator it = history.begin(); 00107 it != history.end(); ++it) 00108 { 00109 const Move& move = *it; 00110 sequence.push_back(move.point()); 00111 } 00112 } 00113 00114 //----------------------------------------------------------------------------