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));
}