const ConnectThree::Move ConnectThree::CheckTwoOther(const std::bitset<3>& is_player_human) const { const Moves moves(GetAllPossibleMoves()); const int nMoves = moves.size(); if (nMoves==0) return CreateInvalidMove(); { //Get anti-human moves Moves v; BOOST_FOREACH(const Move& m, moves) { assert(CanDoMove(m)); //Player is human if (is_player_human[boost::tuples::get<2>(m)]) v.push_back(m); } //If there are anti-player moves, choose one at random if (!v.empty()) { const Move m = v[std::rand() % v.size()]; assert(CanDoMove(m)); return boost::tuples::make_tuple( boost::tuples::get<0>(m), boost::tuples::get<1>(m), boost::tuples::get<2>(m)); } }
///SuggestMove suggests a good move. If the game is a draw, ///it returns an invalid move. const ConnectThree::Move ConnectThree::SuggestMove(const std::bitset<3>& is_player_human) const { if (CanDoMove(CheckTwoHorizontalOwn())) return CheckTwoHorizontalOwn(); if (CanDoMove(CheckTwoVerticalOwn() )) return CheckTwoVerticalOwn(); if (CanDoMove(CheckTwoOther(is_player_human))) return CheckTwoOther(is_player_human); if (CanDoMove(CheckTwoDiagonally() )) return CheckTwoDiagonally(); if (CanDoMove(CheckOneOther(is_player_human) )) return CheckOneOther(is_player_human); return MakeRandomMove(); }
void ribi::tictactoe::Board::DoMove(const int x, const int y, const Player player) noexcept { assert(CanDoMove(x,y)); //std::clog << "Player " << m_current_player // << ": (" << x << "," << y << ")\n"; m_board[x][y] = Helper().PlayerToSquare(player); m_signal_changed(this); }
const ConnectThree::Move ConnectThree::CheckTwoVerticalOwn() const { const int n_rows = GetRows(); for (int y=0; y!=n_rows-1; ++y) //-1 to prevent out of range { const int n_cols = GetCols(); for (int x=0; x!=n_cols; ++x) { //Two consequtive selfs? if (m_area[x][y] == m_player && m_area[x][y+1] == m_player) { if (y >= 1) { if (m_area[x][y-1] == no_player) { const Move p(x,y-1); assert(CanDoMove(p)); return p; } } if (y < n_rows-2) { if (m_area[x][y+2] == no_player) { const Move p(x,y+2); assert(CanDoMove(p)); return p; } } } //Perhaps a gap? if (y < n_rows-2) { if (m_area[x][y] == m_player && m_area[x][y+1] == no_player && m_area[x][y+2] == m_player) { const Move p(x,y+1); assert(CanDoMove(p)); return p; } } } } return CreateInvalidMove(); }
const ConnectThree::Move ConnectThree::CheckTwoHorizontalOwn() const { const int n_rows = GetRows(); for (int y=0; y!=n_rows; ++y) { const int n_cols = GetCols(); for (int x=0; x!=n_cols-1; ++x) //-1 to prevent out of range { //Two consequtive selfs if (m_area[x][y] == m_player && m_area[x+1][y] == m_player) { if (x >= 1) { if (m_area[x-1][y] == no_player) { const Move p(x-1,y); assert(CanDoMove(p)); return p; } } if (x < n_cols-2 && m_area[x+2][y] == no_player) { const Move p(x+2,y); assert(CanDoMove(p)); return p; } } //Perhaps a gap? if (x < n_cols-2) { if (m_area[x][y] == m_player && m_area[x+1][y] == no_player && m_area[x+2][y] == m_player) { const Move p(x+1,y); assert(CanDoMove(p)); return p; } } } } return CreateInvalidMove(); }
void ribi::reversi::Widget::DoMove(const boost::shared_ptr<const ribi::reversi::Move> move) noexcept { #ifndef NDEBUG assert(move); if(!CanDoMove(move)) { TRACE("ERROR"); TRACE(*this); TRACE(move->ToStr()); TRACE("ERROR"); } #endif assert(CanDoMove(move)); //Undo { const boost::shared_ptr<Widget> prev_widget { new Widget(*this) }; m_undo.push_back(std::make_pair(prev_widget,move)); assert(prev_widget->GetCurrentPlayer() == this->GetCurrentPlayer()); } //Actually do the move assert(move); if (boost::dynamic_pointer_cast<const ribi::reversi::MovePass>(move)) { DoMovePass(); } else { const boost::shared_ptr<const ribi::reversi::MovePlacePiece> place { boost::dynamic_pointer_cast<const ribi::reversi::MovePlacePiece>(move) }; assert(place); assert(CanDoMove(place->GetX(),place->GetY())); DoMove(place->GetX(),place->GetY()); } }
void ConnectThree::DoMove(const int x, const int y) { assert( (CreateInvalidMove().get<0>() == x && CreateInvalidMove().get<1>() == y) || CanDoMove(x,y)); if (CreateInvalidMove().get<0>() == x && CreateInvalidMove().get<1>() == y) { return; } m_area[x][y] = m_player; m_player = GetNextPlayer(); }
bool ribi::reversi::Widget::CanDoMove(const boost::shared_ptr<const ribi::reversi::Move> move) const noexcept { assert(move); if (boost::dynamic_pointer_cast<const ribi::reversi::MovePass>(move)) { //Can always pass for now return true; } const boost::shared_ptr<const ribi::reversi::MovePlacePiece> place { boost::dynamic_pointer_cast<const ribi::reversi::MovePlacePiece>(move) }; assert(place); assert(move); return CanDoMove(place->GetX(),place->GetY()); }
void ribi::Chess::GameWidget::DoMove( const boost::shared_ptr<const Square> from, const boost::shared_ptr<const Square> to) { assert(CanDoMove(from,to)); //Construct all possible Moves const Chess::Board::PiecePtr piece = m_game->GetBoard()->GetPiece(from); assert(piece); boost::shared_ptr<const Move> move; for (int i=0; i!=32; ++i) { std::string s = boost::lexical_cast<std::string>(piece->GetNameChar()) + from->ToStr() + ( (i / 1) % 2 ? " " : "x") + to->ToStr(); switch ( (i / 2) % 4) { case 0: s += "e.p."; break; case 1: s += "+"; break; case 2: s += "#"; break; case 3: break; default: break; } const boost::shared_ptr<const Move> maybe_move { MoveFactory().Create(s) }; if (m_game->CanDoMove(maybe_move)) move = maybe_move; if (move) break; } assert(move); m_game->DoMove(move); m_signal_graphic_changed(); }
void ribi::tictactoe::Game::DoMove(const int x, const int y) noexcept { assert(CanDoMove(x,y)); m_board->DoMove(x,y,m_current_player); m_current_player = (m_current_player == Player::player1 ? Player::player2 : Player::player1); }
void ribi::con3::ConnectThreeWidget::DoMove(const int x,const int y) noexcept { assert(CanDoMove(x,y)); m_game.DoMove(x,y); }
void ribi::con3::ConnectThreeWidget::DoMove() noexcept { assert(CanDoMove()); assert(CanDoMove(m_x,m_y)); m_game.DoMove(m_x,m_y); }
void ribi::con3::ConnectThreeWidget::DoComputerMove() noexcept { const auto move = SuggestMove(); assert(CanDoMove(move.GetX(),move.GetY())); DoMove(move.GetX(),move.GetY()); }
bool ConnectThree::CanDoMove(const Move& p) const { return CanDoMove( boost::tuples::get<0>(p), boost::tuples::get<1>(p)); }