From 37e3a43738c2fe80d04fc099d4e942d63b5f1603 Mon Sep 17 00:00:00 2001 From: Paolo Capriotti Date: Tue, 31 Jul 2007 15:19:23 +0200 Subject: [PATCH] Fixed instantiation of Serializer and MoveGenerator for chess. --- tests/hlvariants/prototype/chess/movegenerator.h | 50 ++++---- tests/hlvariants/prototype/chess/serializer.h | 141 ++++++++++++++--------- tests/hlvariants/prototype/tagua_wrapped.h | 25 ++-- tests/hlvariants/prototype/variantdata.h | 17 +++ 4 files changed, 143 insertions(+), 90 deletions(-) create mode 100644 tests/hlvariants/prototype/variantdata.h diff --git a/tests/hlvariants/prototype/chess/movegenerator.h b/tests/hlvariants/prototype/chess/movegenerator.h index 0b6b305..5ae645d 100644 --- a/tests/hlvariants/prototype/chess/movegenerator.h +++ b/tests/hlvariants/prototype/chess/movegenerator.h @@ -56,7 +56,7 @@ MoveGenerator::~MoveGenerator() { } template bool MoveGenerator::check(typename Piece::Color turn) const { - Point kingPosition = m_state.board().find(turn, Piece::KING); + Point kingPosition = m_state.board().find(Piece(turn, Piece::KING)); if (!kingPosition.valid()) { // a missing king is considered in check return true; @@ -87,8 +87,7 @@ template void MoveGenerator::generate(MoveCallback& callback) const { for (int i = 0; i < m_state.board().size().x; i++) { for (int j = 0; j < m_state.board().size().y; j++) { - if (!generateFrom(Point(i, j), callback)) - return false; + generateFrom(Point(i, j), callback); } } } @@ -108,20 +107,20 @@ bool MoveGenerator::generateFrom(const Point& p, MoveCallback& ca } else { return addMove(Move(p, p + dir), callback) && - addMove(p, p + dir * 2) && - addMove(p, p + dir + Point(1, 0)) && - addMove(p, p + dir - Point(1, 0)); + addMove(Move(p, p + dir * 2), callback) && + addMove(Move(p, p + dir + Point(1, 0)), callback) && + addMove(Move(p, p + dir - Point(1, 0)), callback); } } case Piece::KNIGHT: - return addMove(p, p + Point(1, 2), callback) && - addMove(p, p + Point(1, -2), callback) && - addMove(p, p + Point(-1, 2), callback) && - addMove(p, p + Point(-1, -2), callback) && - addMove(p, p + Point(2, 1), callback) && - addMove(p, p + Point(2, -1), callback) && - addMove(p, p + Point(-2, 1), callback) && - addMove(p, p + Point(-2, -1), callback); + return addMove(Move(p, p + Point(1, 2)), callback) && + addMove(Move(p, p + Point(1, -2)), callback) && + addMove(Move(p, p + Point(-1, 2)), callback) && + addMove(Move(p, p + Point(-1, -2)), callback) && + addMove(Move(p, p + Point(2, 1)), callback) && + addMove(Move(p, p + Point(2, -1)), callback) && + addMove(Move(p, p + Point(-2, 1)), callback) && + addMove(Move(p, p + Point(-2, -1)), callback); case Piece::BISHOP: return generateSlide(p, Point(1, 1), callback) && generateSlide(p, Point(1, -1), callback) && @@ -142,14 +141,14 @@ bool MoveGenerator::generateFrom(const Point& p, MoveCallback& ca generateSlide(p, Point(-1, -1), callback) && generateSlide(p, Point(-1, 1), callback); case Piece::KING: - return addMove(p, p + Point(1,0), callback) && - addMove(p, p + Point(1,1), callback) && - addMove(p, p + Point(0,1), callback) && - addMove(p, p + Point(-1,1), callback) && - addMove(p, p + Point(-1,0), callback) && - addMove(p, p + Point(-1,-1), callback) && - addMove(p, p + Point(0,-1), callback) && - addMove(p, p + Point(1,-1), callback); + return addMove(Move(p, p + Point(1,0)), callback) && + addMove(Move(p, p + Point(1,1)), callback) && + addMove(Move(p, p + Point(0,1)), callback) && + addMove(Move(p, p + Point(-1,1)), callback) && + addMove(Move(p, p + Point(-1,0)), callback) && + addMove(Move(p, p + Point(-1,-1)), callback) && + addMove(Move(p, p + Point(0,-1)), callback) && + addMove(Move(p, p + Point(1,-1)), callback); default: return true; } @@ -163,7 +162,7 @@ bool MoveGenerator:: generateSlide(const Point& p, const Point& dir, MoveCallback& callback) const { Point q = p + dir; while (m_state.board().valid(q)) { - if (!addMove(Move(p, q))) + if (!addMove(Move(p, q), callback)) return false; q += dir; } @@ -175,8 +174,9 @@ generateSlide(const Point& p, const Point& dir, MoveCallback& callback) const { template bool MoveGenerator::addMove(const Move& m, MoveCallback& callback) const { LegalityCheck check(m_state); - if (check.legal(m)) { - return callback(m); + Move move(m); + if (check.legal(move)) { + return callback(move); } return true; diff --git a/tests/hlvariants/prototype/chess/serializer.h b/tests/hlvariants/prototype/chess/serializer.h index 8323d71..9a84295 100644 --- a/tests/hlvariants/prototype/chess/serializer.h +++ b/tests/hlvariants/prototype/chess/serializer.h @@ -40,6 +40,10 @@ protected: virtual QString suffix(const Move& move, const GameState& ref); virtual QString san(const Move& move, const GameState& ref); + + virtual void minimal_notation(SAN& san, const GameState& ref); + + virtual Move get_san(const SAN& san, const GameState& ref); public: /** * Create a serializer to a given string representation for moves. @@ -92,8 +96,6 @@ QString Serializer::san(const Move& move, const GameState& ref) { if (piece == Piece()) return ""; // no piece in the initial square - Q_ASSERT(piece); - if (move.kingSideCastling()) { res = "O-O"; } @@ -108,18 +110,20 @@ QString Serializer::san(const Move& move, const GameState& ref) { tmp.to = move.to(); tmp.type = piece.type(); tmp.castling = SAN::NoCastling; - minimalNotation(tmp, ref); + minimal_notation(tmp, ref); res += tmp.from.toString(ref.board().size().y); - if (captured) + if (captured != Piece()) res += "x"; res += tmp.to.toString(ref.board().size().y); } if (move.promoteTo() != -1) - res += "=" + Piece::typeName(move.promoteTo())[0].toUpper(); + res += "=" + QString(Piece::typeName( + static_cast(move.promoteTo()) + )[0].toUpper()); - res += suffix(); + res += suffix(move, ref); return res; } @@ -152,7 +156,7 @@ QString Serializer::suffix(const Move& move, const GameState& ref tmp.move(move); MoveGenerator generator(tmp); - if (generator.check()) { + if (generator.check(ref.turn())) { if (generator.stalled()) return "#"; else @@ -165,6 +169,57 @@ QString Serializer::suffix(const Move& move, const GameState& ref template typename Serializer::Move +Serializer::get_san(const SAN& san, const GameState& ref) { + Move candidate; + + if (san.invalid()) + return candidate; + + if (san.castling != SAN::NoCastling) { + Point from = ref.kingStartingPosition(ref.turn()); + Point to = from + (san.castling == SAN::KingSide? Point(2,0) : Point(-2,0)); + Piece king = ref.board().get(from); + if (king.type() != Piece::KING) + return candidate; + else + return Move(from, to); + } + + if (san.from.valid()) { + candidate = Move(san.from, san.to, static_cast(san.promotion)); + } + else { + for (int i = 0; i < ref.board().size().x; i++) { + for (int j = 0; j < ref.board().size().y; j++) { + Point p(i, j); + Piece piece = ref.board().get(p); + + Move mv(p, san.to, static_cast(san.promotion)); + if (p.resembles(san.from) && + piece.type() == san.type && + piece.color() == ref.turn()) { + + LegalityCheck check(ref); + if (check.legal(mv)) { + if (candidate.valid()) { + // ambiguous! + return Move(); + } + else { + // ok, we have found a candidate move + candidate = mv; + } + } + } + } + } + } + + return candidate; +} + +template +typename Serializer::Move Serializer::deserialize(const QString& str, const GameState& ref) { switch (m_rep) { case SIMPLE: @@ -173,59 +228,39 @@ Serializer::deserialize(const QString& str, const GameState& ref) { SAN tmp; tmp.load(str, ref.board().size().y); - Move candidate; - - if (san.invalid()) - return candidate; - - if (san.castling != SAN::NoCastling) { - Point from = ref.kingStartingPosition(ref.turn()); - Point to = from + (san.castling == SAN::KingSide? Point(2,0) : Point(-2,0)); - Piece king = ref.board().get(from); - if (king.type() != Piece::KING) - return candidate; - else - return Move(from, to); - } - - if (san.from.valid()) { - candidate = Move(san.from, san.to, static_cast(san.promotion)); - } - else { - for (int i = 0; i < ref.board().size().x; i++) { - for (int j = 0; j < ref.board().size().y; j++) { - Point p(i, j); - Piece piece = ref.board().get(p); - - Move mv(p, san.to, static_cast(san.promotion)); - if (p.resembles(san.from) && - piece.type() == san.type && - piece.color() == ref.turn()) { - - LegalityCheck check(ref); - if (check.legal(mv)) { - if (candidate.valid()) { - // ambiguous! - return Move(); - } - else { - // ok, we have found a candidate move - candidate = mv; - } - } - } - } - } - } - - return candidate; + return get_san(tmp, ref); } case DECORATED: + default: // no need to parse decorated moves return Move(); } } + +#define TRY(x) if(get_san(x, ref).valid()) return; +template +void Serializer::minimal_notation(SAN& san, const GameState& ref) { + Point from = san.from; + san.castling = SAN::NoCastling; + + // try notation without starting point + san.from = Point::invalid(); + TRY(san); + + // add column indication + san.from = Point(from.x, -1); + TRY(san); + + // add row indication + san.from = Point(-1, from.y); + TRY(san); + + // add complete starting point + san.from = from; +} +#undef TRY + } // namespace Chess } // namespace HLVariant diff --git a/tests/hlvariants/prototype/tagua_wrapped.h b/tests/hlvariants/prototype/tagua_wrapped.h index 84f9171..57625a6 100644 --- a/tests/hlvariants/prototype/tagua_wrapped.h +++ b/tests/hlvariants/prototype/tagua_wrapped.h @@ -4,6 +4,7 @@ #include "tagua.h" #include "fwd.h" #include "nopool.h" +#include "variantdata.h" #ifdef Q_CC_GNU #define __FUNC__ __PRETTY_FUNCTION__ @@ -25,7 +26,7 @@ namespace HLVariant { template class WrappedPiece : public AbstractPiece { - typedef typename Variant::LegalityCheck::GameState::Board::Piece Piece; + typedef typename VariantData::Piece Piece; Piece m_piece; public: @@ -57,10 +58,10 @@ namespace HLVariant { template class WrappedMove : public AbstractMove { - typedef typename Variant::LegalityCheck LegalityCheck; - typedef typename Variant::Serializer Serializer; - typedef typename LegalityCheck::Move Move; - typedef typename LegalityCheck::GameState GameState; + typedef typename VariantData::LegalityCheck LegalityCheck; + typedef typename VariantData::Serializer Serializer; + typedef typename VariantData::Move Move; + typedef typename VariantData::GameState GameState; Move m_move; public: @@ -74,8 +75,8 @@ namespace HLVariant { WrappedPosition* ref = dynamic_cast*>(_ref.get()); if (ref) { - - return ""; //BROKEN + Serializer serializer(Serializer::COMPACT); + return serializer.serialize(m_move, ref->inner()); } else { MISMATCH(*_ref.get(), WrappedPosition); @@ -134,11 +135,11 @@ namespace HLVariant { template class WrappedPosition : public AbstractPosition { - typedef typename Variant::LegalityCheck LegalityCheck; - typedef typename LegalityCheck::GameState GameState; - typedef typename GameState::Board Board; - typedef typename Board::Piece Piece; - typedef typename GameState::Move Move; + typedef typename VariantData::LegalityCheck LegalityCheck; + typedef typename VariantData::GameState GameState; + typedef typename VariantData::Board Board; + typedef typename VariantData::Piece Piece; + typedef typename VariantData::Move Move; GameState m_state; public: diff --git a/tests/hlvariants/prototype/variantdata.h b/tests/hlvariants/prototype/variantdata.h new file mode 100644 index 0000000..98af753 --- /dev/null +++ b/tests/hlvariants/prototype/variantdata.h @@ -0,0 +1,17 @@ +#ifndef HLVARIANTS__VARIANTDATA_H +#define HLVARIANTS__VARIANTDATA_H + +template +struct VariantData { + typedef typename Variant::MoveGenerator MoveGenerator; + typedef typename MoveGenerator::LegalityCheck LegalityCheck; + typedef typename LegalityCheck::GameState GameState; + typedef typename GameState::Board Board; + typedef typename GameState::Move Move; + typedef typename Board::Piece Piece; + + typedef typename Variant::Serializer Serializer; +}; + +#endif // HLVARIANTS__VARIANTDATA_H + -- 2.11.4.GIT