コード例 #1
0
ファイル: parse.cpp プロジェクト: gatgui/gcore
// Branch ::= { Piece }*
Instruction* ParseBranch(const char **ppc, ParseInfo &info)
{
  Instruction *first = 0;
  Instruction *last = 0;
  Instruction *i = 0;
  
  while (**ppc!='\0' && **ppc!='|' && **ppc!=')')
  {
    i = ParsePiece(ppc, info);
    if (!i)
    {
      if (first)
      {
        delete first;
      }
      return 0;
    }
    if (!first)
    {
      first = i;
      last = i;
    }
    else
    {
      last->setNext(i);
      last = i;
    }
  }
  
  return first;
}
コード例 #2
0
ribi::Chess::Move::Move(const std::string& s)
  : m_from(ParseFrom(s)),
    m_is_capture(ParseIsCapture(s)),
    m_is_castling(ParseIsCastling(s)),
    m_is_check(ParseIsCheck(s)),
    m_is_checkmate(ParseIsCheckmate(s)),
    m_is_en_passant(ParseIsEnPassant(s)),
    m_is_promotion(ParseIsPromotion(s)),
    m_piece(ParsePiece(s)),
    m_piece_promotion(ParsePiecePromotion(s)),
    m_score(ParseScore(s)),
    m_str(s),
    m_to(ParseTo(s))
{
  #ifndef NDEBUG
  Test();
  #endif

  if (s.empty()) throw std::logic_error("std::string to parse is empty");
  if (!m_to && !m_is_castling && (!m_score))
  {
    const std::string error = "ribi::Chess::Move::Move exception: m_to not initialized for non-castling non-score move " + s;
    throw std::logic_error(error.c_str());
  }

  #ifndef RIBI_CHESS_ALLOW_SHORT_NOTATION
  if (m_to && !m_from)
  {
    const std::string error = "ribi::Chess::Move::Move exception: if there is a 'to', also supply a 'from' in move " + s;
    throw std::logic_error(error.c_str());
  }
  #endif // RIBI_CHESS_ALLOW_SHORT_NOTATION
  if (!m_piece && !m_is_castling && !m_score)
  {
    const std::string error = "ribi::Chess::Move::Move exception: m_piece not initialized for non-castling non-score move " + s;
    throw std::logic_error(error.c_str());
  }

  if (m_is_en_passant && !m_is_capture) throw std::logic_error("ribi::Chess::Move::Move exception: every en passant capture is a capture");

  if (boost::xpressive::regex_search(s,boost::xpressive::sregex::compile("(e\\.p\\.)")) && !m_is_en_passant)
  {
    const std::string error = "ribi::Chess::Move::Move exception: move is an invalid en passant move: " + s;
    throw std::logic_error(error.c_str());
  }

  if (m_piece)
  {
    if (m_is_castling)
    {
      throw std::logic_error("ribi::Chess::Move::Move exception: m_piece cannot be initialized in a castling move");
    }
    if (m_score) throw std::logic_error("ribi::Chess::Move::Move exception: m_piece cannot be initialized in a score move");
    const bool valid = m_piece->CanDoMove(this);
    if (!valid)
    {
      const std::string t = "Move " + s + " invalid for " + m_piece->GetName();
      throw std::logic_error(t.c_str());
    }
  }
}