From 537876627c0d30a8b748e95ae1e880c78af499ca Mon Sep 17 00:00:00 2001 From: Paolo Capriotti Date: Wed, 8 Aug 2007 12:32:48 +0200 Subject: [PATCH] Ported verbose deserialization. --- src/CMakeLists.txt | 1 + src/hlvariant/chess/icsverbose.cpp | 62 ++++++++++++++++++++++++++++++++++++++ src/hlvariant/chess/icsverbose.h | 42 ++++++++++++++++++++++++++ src/hlvariant/chess/serializer.h | 33 ++++++++++++++++++-- src/hlvariant/icsapi_wrapped.h | 19 ++++++++++++ src/hlvariant/tagua_wrapped.h | 2 +- src/icsapi.h | 11 ++++++- 7 files changed, 165 insertions(+), 5 deletions(-) create mode 100644 src/hlvariant/chess/icsverbose.cpp create mode 100644 src/hlvariant/chess/icsverbose.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ba1d413..cf5ad11 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -33,6 +33,7 @@ set(tagua_SRC hlvariant/chess/variant.cpp hlvariant/chess/san.cpp + hlvariant/chess/icsverbose.cpp hlvariant/chess/move.cpp hlvariant/chess/gamestate.cpp hlvariant/chess/piece.cpp diff --git a/src/hlvariant/chess/icsverbose.cpp b/src/hlvariant/chess/icsverbose.cpp new file mode 100644 index 0000000..d77f7f4 --- /dev/null +++ b/src/hlvariant/chess/icsverbose.cpp @@ -0,0 +1,62 @@ +/* + Copyright (c) 2007 Paolo Capriotti + (c) 2007 Maurizio Monge + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +*/ + +#include "icsverbose.h" + +namespace HLVariant { +namespace Chess { + +// 1 2 3 5 +QRegExp ICSVerbose::pattern("([PRNBKQ])/([a-zA-Z]\\d+|@@)-([a-zA-Z]\\d+)(=([PRNBKQ]))?"); +QRegExp ICSVerbose::kingCastlingPattern("[oO0]-[oO0]"); +QRegExp ICSVerbose::queenCastlingPattern("[oO0]-[oO0]-[oO0]"); +QRegExp ICSVerbose::nonePattern("none"); + +ICSVerbose::ICSVerbose() +: from(Point::invalid()) +, to(Point::invalid()) +, promotion(-1) +, castling(SAN::NoCastling) { } + + +void ICSVerbose::load(const QString& str, int ysize) { + if (nonePattern.indexIn(str) == 0) { + from = Point::invalid(); + to = Point::invalid(); + } + else if (pattern.indexIn(str) == 0) { + if (pattern.cap(2) == "@@") + from = Point::invalid(); + else + from = Point(pattern.cap(2), ysize); + + to = Point(pattern.cap(3), ysize); + + type = SAN::getType(pattern.cap(1)); + if (!pattern.cap(5).isEmpty()) + promotion = SAN::getType(pattern.cap(6)); + else + promotion = -1; + castling = SAN::NoCastling; + } + else if (queenCastlingPattern.indexIn(str) == 0) + castling = SAN::QueenSide; + else if (kingCastlingPattern.indexIn(str) == 0) + castling = SAN::KingSide; + else { + from = Point::invalid(); + to = Point::invalid(); + castling = SAN::NoCastling; + } +} + +} // namespace HLVariant +} // namespace Chess + diff --git a/src/hlvariant/chess/icsverbose.h b/src/hlvariant/chess/icsverbose.h new file mode 100644 index 0000000..f25cd5f --- /dev/null +++ b/src/hlvariant/chess/icsverbose.h @@ -0,0 +1,42 @@ +/* + Copyright (c) 2007 Paolo Capriotti + (c) 2007 Maurizio Monge + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +*/ + +#ifndef HLVARIANT__CHESS__ICSVERBOSE_H +#define HLVARIANT__CHESS__ICSVERBOSE_H + +#include "san.h" + +namespace HLVariant { +namespace Chess { + +class ICSVerbose { + static QRegExp pattern; + static QRegExp kingCastlingPattern; + static QRegExp queenCastlingPattern; + static QRegExp nonePattern; + +public: + ICSVerbose(); + void load(const QString&, int ysize); + + Point from, to; + int type, promotion; + SAN::CastlingType castling; + + inline bool invalid() const { return (from == Point::invalid() && to == Point::invalid()); } + inline bool valid() const { return !invalid(); } +}; + + +} // namespace Chess +} // namespace HLVariant + +#endif // HLVARIANT__CHESS__ICSVERBOSE_H + diff --git a/src/hlvariant/chess/serializer.h b/src/hlvariant/chess/serializer.h index be3030c..1c4f46a 100644 --- a/src/hlvariant/chess/serializer.h +++ b/src/hlvariant/chess/serializer.h @@ -13,6 +13,7 @@ #include "legalitycheck.h" #include "san.h" +#include "icsverbose.h" namespace HLVariant { namespace Chess { @@ -26,7 +27,8 @@ public: enum { SIMPLE = 0, /// The most direct way of representing a move. COMPACT = 1, /// Compact notation. This corresponds to SAN notation for games that support it. - DECORATED = 2 /// Symbolic figurine notation. Figurine names are enclosed in braces. + DECORATED = 2, /// Symbolic figurine notation. Figurine names are enclosed in braces. + ICS_VERBOSE = 3 /// Verbose notation as defined by ICS. } MoveRepresentation; protected: typedef typename MoveGenerator::LegalityCheck LegalityCheck; @@ -46,6 +48,8 @@ protected: virtual Move get_san(const SAN& san, const GameState& ref); virtual QChar symbol(typename Piece::Type type) const; + + virtual Move parse_ics_verbose(const QString& str, const GameState& ref); public: /** * Create a serializer to a given string representation for moves. @@ -162,6 +166,7 @@ QString Serializer::serialize(const Move& move, const GameState& res.replace('P', "{pawn}"); return res; } + case ICS_VERBOSE: default: return ""; } @@ -245,14 +250,15 @@ template typename Serializer::Move Serializer::deserialize(const QString& str, const GameState& ref) { switch (m_rep) { - case SIMPLE: - return Move(); // BROKEN case COMPACT: { SAN tmp; tmp.load(str, ref.board().size().y); return get_san(tmp, ref); } + case ICS_VERBOSE: + return parse_ics_verbose(str, ref); + case SIMPLE: case DECORATED: default: // no need to parse decorated moves @@ -292,6 +298,27 @@ QChar Serializer::symbol(typename Piece::Type type) const { return Piece::typeName(type)[0]; } +template +typename Serializer::Move +Serializer::parse_ics_verbose(const QString& str, const GameState& ref) { + ICSVerbose verbose; + verbose.load(str, ref.board().size().y); + + Point from; + Point to; + + if (verbose.castling == SAN::NoCastling) { + from = verbose.from; + to = verbose.to; + } + else { + from = ref.kingStartingPosition(ref.turn()); + to = from + (verbose.castling == SAN::KingSide ? Point(2,0) : Point(-2, 0)); + } + + return Move(from, to, static_cast(verbose.promotion)); +} + } // namespace Chess } // namespace HLVariant diff --git a/src/hlvariant/icsapi_wrapped.h b/src/hlvariant/icsapi_wrapped.h index 5824a1b..7740a66 100644 --- a/src/hlvariant/icsapi_wrapped.h +++ b/src/hlvariant/icsapi_wrapped.h @@ -11,6 +11,7 @@ class WrappedICSAPI : public ICSAPI { public: virtual PositionPtr createChessboard(int, bool, bool, bool, bool, const Point&); virtual PiecePtr createPiece(const QString& description); + virtual MovePtr parseVerbose(const QString& str, const PositionPtr& ref); }; // IMPLEMENTATION @@ -39,6 +40,24 @@ PiecePtr WrappedICSAPI::createPiece(const QString& description) { VariantData::Piece::fromDescription(description))); } +template +MovePtr WrappedICSAPI::parseVerbose(const QString& str, const PositionPtr& _ref) { + if (!_ref) + return MovePtr(); + + WrappedPosition* ref = dynamic_cast*>(_ref.get()); + if (ref) { + typename VariantData::Serializer serializer( + VariantData::Serializer::ICS_VERBOSE); + return MovePtr(new WrappedMove( + serializer.deserialize(str, ref->inner()))); + } + else { + MISMATCH(*_ref.get(), WrappedPosition); + return MovePtr(); + } +} + /** * Helper metafunction to create a null ICSAPI object * if the variant does not support ICS. diff --git a/src/hlvariant/tagua_wrapped.h b/src/hlvariant/tagua_wrapped.h index 42fe736..835e414 100644 --- a/src/hlvariant/tagua_wrapped.h +++ b/src/hlvariant/tagua_wrapped.h @@ -488,7 +488,7 @@ namespace HLVariant { } virtual MovePtr getVerboseMove(int, const VerboseNotation&) const { - return MovePtr(); // BROKEN + return MovePtr(); } virtual bool simpleMoves() { diff --git a/src/icsapi.h b/src/icsapi.h index 0e9eb1a..e78f8cb 100644 --- a/src/icsapi.h +++ b/src/icsapi.h @@ -41,7 +41,15 @@ public: * meaning is defined by the variant. * \return A newly created piece. */ - virtual AbstractPiece::Ptr createPiece(const QString& description) = 0; + virtual PiecePtr createPiece(const QString& description) = 0; + + /** + * Parse ICS verbose notation. + * \param str A string representation of the move to be parsed. + * \param turn The player who is moving. + * \return A move object corresponding to the given verbose representation. + */ + virtual MovePtr parseVerbose(const QString& str, const PositionPtr& ref) = 0; }; // wrapper @@ -51,6 +59,7 @@ class WrappedICSAPI : public ICSAPI { public: virtual PositionPtr createChessboard(int, bool, bool, bool, bool, const Point&); virtual PiecePtr createPiece(const QString& description); + virtual MovePtr parseVerbose(const QString&, const PositionPtr&) { return MovePtr(); } }; #endif // ICSAPI_H -- 2.11.4.GIT