From 68b01ee4432027f731a05cc1cc1b07229b306cba Mon Sep 17 00:00:00 2001
From: Paolo Capriotti
Date: Sun, 29 Jul 2007 22:30:02 +0200
Subject: [PATCH] Added ChessGameState, related classes and tests.
---
tests/hlvariants/CMakeLists.txt | 4 +
tests/hlvariants/chessgamestatetest.cpp | 100 ++++++++++++++
tests/hlvariants/chessgamestatetest.h | 52 +++++++
tests/hlvariants/chessmovetest.cpp | 34 +++++
tests/hlvariants/chessmovetest.h | 35 +++++
tests/hlvariants/chesspiecetest.cpp | 12 ++
tests/hlvariants/chesspiecetest.h | 2 +
tests/hlvariants/prototype/board.h | 2 +
tests/hlvariants/prototype/chess/gamestate.cpp | 29 ++++
tests/hlvariants/prototype/chess/gamestate.h | 179 +++++++++++++++++++++++++
tests/hlvariants/prototype/chess/move.cpp | 63 +++++++++
tests/hlvariants/prototype/chess/move.h | 45 +++++++
tests/hlvariants/prototype/chess/piece.cpp | 20 +++
tests/hlvariants/prototype/chess/piece.h | 5 +
14 files changed, 582 insertions(+)
create mode 100644 tests/hlvariants/chessgamestatetest.cpp
create mode 100644 tests/hlvariants/chessgamestatetest.h
create mode 100644 tests/hlvariants/chessmovetest.cpp
create mode 100644 tests/hlvariants/chessmovetest.h
create mode 100644 tests/hlvariants/prototype/chess/gamestate.cpp
create mode 100644 tests/hlvariants/prototype/chess/gamestate.h
create mode 100644 tests/hlvariants/prototype/chess/move.cpp
create mode 100644 tests/hlvariants/prototype/chess/move.h
diff --git a/tests/hlvariants/CMakeLists.txt b/tests/hlvariants/CMakeLists.txt
index 91bd04d..eff954e 100644
--- a/tests/hlvariants/CMakeLists.txt
+++ b/tests/hlvariants/CMakeLists.txt
@@ -2,10 +2,14 @@ set(main_dir "../../src")
SET(hl_SRC
prototype/chess/piece.cpp
+ prototype/chess/move.cpp
+ prototype/chess/gamestate.cpp
../cppunit_main.cpp
boardtest.cpp
chesspiecetest.cpp
+ chessgamestatetest.cpp
+ chessmovetest.cpp
)
include_directories(
diff --git a/tests/hlvariants/chessgamestatetest.cpp b/tests/hlvariants/chessgamestatetest.cpp
new file mode 100644
index 0000000..0802379
--- /dev/null
+++ b/tests/hlvariants/chessgamestatetest.cpp
@@ -0,0 +1,100 @@
+#include "chessgamestatetest.h"
+#include "prototype/chess/gamestate.h"
+
+CPPUNIT_TEST_SUITE_REGISTRATION(ChessGameStateTest);
+
+void ChessGameStateTest::setUp() {
+ m_state = new ChessGameState;
+ m_state->setup();
+}
+
+void ChessGameStateTest::tearDown() {
+ delete m_state;
+}
+
+void ChessGameStateTest::test_setup() {
+ for (int i = 0; i < 8; i++) {
+ CPPUNIT_ASSERT_EQUAL(ChessPiece::BLACK,
+ m_state->board().get(Point(i, 0)).color());
+ CPPUNIT_ASSERT_EQUAL(ChessPiece::BLACK,
+ m_state->board().get(Point(i, 1)).color());
+ CPPUNIT_ASSERT_EQUAL(ChessPiece::WHITE,
+ m_state->board().get(Point(i, 6)).color());
+ CPPUNIT_ASSERT_EQUAL(ChessPiece::WHITE,
+ m_state->board().get(Point(i, 7)).color());
+ CPPUNIT_ASSERT(m_state->board().get(Point(i, 4)) == ChessPiece());
+ }
+
+ CPPUNIT_ASSERT_EQUAL(ChessPiece::ROOK,
+ m_state->board().get(Point(0, 0)).type());
+ CPPUNIT_ASSERT_EQUAL(ChessPiece::KING,
+ m_state->board().get(Point(4, 7)).type());
+ CPPUNIT_ASSERT_EQUAL(ChessPiece::PAWN,
+ m_state->board().get(Point(6, 6)).type());
+}
+
+void ChessGameStateTest::test_simple_move() {
+ m_state->move(ChessMove(Point(4, 6), Point(4, 5))); // e4
+ CPPUNIT_ASSERT(m_state->board().get(Point(4, 6)) == ChessPiece());
+ CPPUNIT_ASSERT(m_state->board().get(Point(4, 5)) ==
+ ChessPiece(ChessPiece::WHITE, ChessPiece::PAWN));
+}
+
+void ChessGameStateTest::test_capture() {
+ m_state->move(ChessMove(Point(4, 6), Point(4, 4))); // e4
+ m_state->move(ChessMove(Point(3, 1), Point(3, 3))); // d5
+ m_state->move(ChessMove(Point(4, 4), Point(3, 3))); // exd5
+
+ CPPUNIT_ASSERT(m_state->board().get(Point(3, 3)) ==
+ ChessPiece(ChessPiece::WHITE, ChessPiece::PAWN));
+}
+
+void ChessGameStateTest::test_en_passant() {
+ m_state->move(ChessMove(Point(4, 6), Point(4, 4))); // e4
+ m_state->move(ChessMove(Point(7, 1), Point(7, 2))); // h6
+ m_state->move(ChessMove(Point(4, 4), Point(4, 3))); // e5
+
+ ChessMove d5(Point(3, 1), Point(3, 3));
+ d5.setType(ChessMove::EN_PASSANT_TRIGGER);
+ m_state->move(d5);
+
+ ChessMove exd6(Point(4, 3), Point(3, 2));
+ exd6.setType(ChessMove::EN_PASSANT_CAPTURE);
+ m_state->move(exd6);
+
+ CPPUNIT_ASSERT(m_state->board().get(Point(3, 3)) == ChessPiece());
+}
+
+void ChessGameStateTest::test_kingside_castling() {
+ ChessMove oo(Point(4, 7), Point(6, 7));
+ oo.setType(ChessMove::KING_SIDE_CASTLING);
+ m_state->move(oo);
+
+ CPPUNIT_ASSERT(m_state->board().get(Point(6, 7)) ==
+ ChessPiece(ChessPiece::WHITE, ChessPiece::KING));
+ CPPUNIT_ASSERT(m_state->board().get(Point(5, 7)) ==
+ ChessPiece(ChessPiece::WHITE, ChessPiece::ROOK));
+ CPPUNIT_ASSERT(m_state->board().get(Point(7, 7)) == ChessPiece());
+}
+
+void ChessGameStateTest::test_queenside_castling() {
+ ChessMove oo(Point(4, 7), Point(2, 7));
+ oo.setType(ChessMove::QUEEN_SIDE_CASTLING);
+ m_state->move(oo);
+
+ CPPUNIT_ASSERT(m_state->board().get(Point(2, 7)) ==
+ ChessPiece(ChessPiece::WHITE, ChessPiece::KING));
+ CPPUNIT_ASSERT(m_state->board().get(Point(3, 7)) ==
+ ChessPiece(ChessPiece::WHITE, ChessPiece::ROOK));
+ CPPUNIT_ASSERT(m_state->board().get(Point(0, 7)) == ChessPiece());
+}
+
+void ChessGameStateTest::test_promotion() {
+ m_state->board().set(Point(7, 1), ChessPiece(ChessPiece::WHITE, ChessPiece::PAWN));
+ ChessMove h8B(Point(7, 1), Point(7, 0), ChessPiece::BISHOP);
+ h8B.setType(ChessMove::PROMOTION);
+ m_state->move(h8B);
+
+ CPPUNIT_ASSERT(m_state->board().get(Point(7, 0)) ==
+ ChessPiece(ChessPiece::WHITE, ChessPiece::BISHOP));
+}
diff --git a/tests/hlvariants/chessgamestatetest.h b/tests/hlvariants/chessgamestatetest.h
new file mode 100644
index 0000000..5a84bc9
--- /dev/null
+++ b/tests/hlvariants/chessgamestatetest.h
@@ -0,0 +1,52 @@
+#ifndef CHESSGAMESTATETEST_H
+#define CHESSGAMESTATETEST_H
+
+#include
+#include
+#include
+#include
+#include
+
+// forward decl
+namespace HLVariant {
+ template class Board;
+
+ namespace Chess {
+ template class GameState;
+ class Move;
+ class Piece;
+ }
+}
+
+typedef HLVariant::Chess::Move ChessMove;
+typedef HLVariant::Chess::Piece ChessPiece;
+typedef HLVariant::Board Chessboard;
+typedef HLVariant::Chess::GameState ChessGameState;
+
+class ChessGameStateTest : public CppUnit::TestFixture {
+ CPPUNIT_TEST_SUITE(ChessGameStateTest);
+ CPPUNIT_TEST(test_setup);
+ CPPUNIT_TEST(test_simple_move);
+ CPPUNIT_TEST(test_capture);
+ CPPUNIT_TEST(test_en_passant);
+ CPPUNIT_TEST(test_kingside_castling);
+ CPPUNIT_TEST(test_queenside_castling);
+ CPPUNIT_TEST(test_promotion);
+ CPPUNIT_TEST_SUITE_END();
+private:
+ ChessGameState* m_state;
+public:
+ void setUp();
+ void tearDown();
+
+ void test_setup();
+ void test_simple_move();
+ void test_capture();
+ void test_en_passant();
+ void test_kingside_castling();
+ void test_queenside_castling();
+ void test_promotion();
+};
+
+#endif // CHESSGAMESTATETEST_H
+
diff --git a/tests/hlvariants/chessmovetest.cpp b/tests/hlvariants/chessmovetest.cpp
new file mode 100644
index 0000000..c05f24a
--- /dev/null
+++ b/tests/hlvariants/chessmovetest.cpp
@@ -0,0 +1,34 @@
+#include "chessmovetest.h"
+#include "prototype/chess/move.h"
+#include "prototype/chess/piece.h"
+
+typedef HLVariant::Chess::Piece ChessPiece;
+
+CPPUNIT_TEST_SUITE_REGISTRATION(ChessMoveTest);
+
+void ChessMoveTest::setUp() { }
+
+void ChessMoveTest::tearDown() { }
+
+void ChessMoveTest::test_capture_square() {
+ ChessMove m(Point(4, 3), Point(3, 2));
+ CPPUNIT_ASSERT(m.captureSquare() == Point(3, 2));
+
+ m.setType(ChessMove::EN_PASSANT_CAPTURE);
+ CPPUNIT_ASSERT(m.captureSquare() == Point(3, 3));
+}
+
+void ChessMoveTest::test_en_passant_trigger() {
+ ChessMove m(Point(4, 6), Point(4, 4));
+ m.setType(ChessMove::EN_PASSANT_TRIGGER);
+ CPPUNIT_ASSERT(m.enPassantTrigger() == Point(4, 5));
+}
+
+void ChessMoveTest::test_promotion() {
+ ChessMove m(Point(5, 1), Point(5, 0), ChessPiece::ROOK);
+
+ CPPUNIT_ASSERT_EQUAL(-1, m.promoteTo());
+ m.setType(ChessMove::PROMOTION);
+ CPPUNIT_ASSERT_EQUAL((int)ChessPiece::ROOK, m.promoteTo());
+}
+
diff --git a/tests/hlvariants/chessmovetest.h b/tests/hlvariants/chessmovetest.h
new file mode 100644
index 0000000..c5ced7f
--- /dev/null
+++ b/tests/hlvariants/chessmovetest.h
@@ -0,0 +1,35 @@
+#ifndef CHESSMOVETEST_H
+#define CHESSMOVETEST_H
+
+#include
+#include
+#include
+#include
+#include
+
+// forward decl
+namespace HLVariant {
+ namespace Chess {
+ class Move;
+ }
+}
+
+typedef HLVariant::Chess::Move ChessMove;
+
+class ChessMoveTest : public CppUnit::TestFixture {
+ CPPUNIT_TEST_SUITE(ChessMoveTest);
+ CPPUNIT_TEST(test_capture_square);
+ CPPUNIT_TEST(test_en_passant_trigger);
+ CPPUNIT_TEST(test_promotion);
+ CPPUNIT_TEST_SUITE_END();
+public:
+ void setUp();
+ void tearDown();
+
+ void test_capture_square();
+ void test_en_passant_trigger();
+ void test_promotion();
+};
+
+#endif // CHESSMOVETEST_H
+
diff --git a/tests/hlvariants/chesspiecetest.cpp b/tests/hlvariants/chesspiecetest.cpp
index abe685f..60a4f4a 100644
--- a/tests/hlvariants/chesspiecetest.cpp
+++ b/tests/hlvariants/chesspiecetest.cpp
@@ -22,3 +22,15 @@ void ChessPieceTest::test_names() {
CPPUNIT_ASSERT(p.name() == "black_bishop");
}
+void ChessPieceTest::test_compare() {
+ ChessPiece a(ChessPiece::BLACK, ChessPiece::KING);
+ ChessPiece b(ChessPiece::WHITE, ChessPiece::QUEEN);
+ ChessPiece c(ChessPiece::BLACK, ChessPiece::KING);
+
+ CPPUNIT_ASSERT(a != b);
+ CPPUNIT_ASSERT(!(a == b));
+ CPPUNIT_ASSERT(a == c);
+ CPPUNIT_ASSERT(c == a);
+ CPPUNIT_ASSERT(a == a);
+}
+
diff --git a/tests/hlvariants/chesspiecetest.h b/tests/hlvariants/chesspiecetest.h
index 8b823c4..d88848c 100644
--- a/tests/hlvariants/chesspiecetest.h
+++ b/tests/hlvariants/chesspiecetest.h
@@ -13,6 +13,7 @@ class ChessPieceTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(ChessPieceTest);
CPPUNIT_TEST(test_basic);
CPPUNIT_TEST(test_names);
+ CPPUNIT_TEST(test_compare);
CPPUNIT_TEST_SUITE_END();
public:
void setUp();
@@ -20,6 +21,7 @@ public:
void test_basic();
void test_names();
+ void test_compare();
};
#endif // CHESSPIECETEST_H
diff --git a/tests/hlvariants/prototype/board.h b/tests/hlvariants/prototype/board.h
index 5cb1711..b07013b 100644
--- a/tests/hlvariants/prototype/board.h
+++ b/tests/hlvariants/prototype/board.h
@@ -1,6 +1,8 @@
#ifndef HLVARIANT__BOARD_H
#define HLVARIANT__BOARD_H
+#include
+
#include "point.h"
#include "pathinfo.h"
diff --git a/tests/hlvariants/prototype/chess/gamestate.cpp b/tests/hlvariants/prototype/chess/gamestate.cpp
new file mode 100644
index 0000000..dd00364
--- /dev/null
+++ b/tests/hlvariants/prototype/chess/gamestate.cpp
@@ -0,0 +1,29 @@
+#include "gamestate.h"
+
+
+namespace HLVariant {
+namespace Chess {
+
+CastlingData::CastlingData()
+: wk(true)
+, wq(true)
+, bk(true)
+, bq(true) { }
+
+CastlingData::CastlingData(bool wk, bool wq, bool bk, bool bq)
+: wk(wk)
+, wq(wq)
+, bk(bk)
+, bq(bq) { }
+
+bool CastlingData::operator==(const CastlingData& other) const {
+ return wk == other.wk &&
+ wq == other.wq &&
+ bk == other.bk &&
+ bq == other.bq;
+}
+
+
+} // namespace Chess
+} // namespace HLVariant
+
diff --git a/tests/hlvariants/prototype/chess/gamestate.h b/tests/hlvariants/prototype/chess/gamestate.h
new file mode 100644
index 0000000..56109dd
--- /dev/null
+++ b/tests/hlvariants/prototype/chess/gamestate.h
@@ -0,0 +1,179 @@
+#ifndef HLVARIANT__CHESS__GAMESTATE_H
+#define HLVARIANT__CHESS__GAMESTATE_H
+
+#include "../board.h"
+#include "piece.h"
+#include "move.h"
+
+namespace HLVariant {
+namespace Chess {
+
+struct CastlingData {
+ bool wk : 1;
+ bool wq : 1;
+ bool bk : 1;
+ bool bq : 1;
+
+ CastlingData();
+ CastlingData(bool, bool, bool, bool);
+ bool operator==(const CastlingData& other) const;
+};
+
+template
+class GameState {
+public:
+ typedef _Board Board;
+ typedef _Move Move;
+ typedef typename Board::Piece Piece;
+private:
+ Board m_board;
+ CastlingData m_castling;
+ Point m_en_passant;
+ typename Piece::Color m_turn;
+public:
+ GameState();
+ virtual ~GameState() { }
+
+ virtual Board& board();
+ virtual const Board& board() const;
+
+ virtual void setup();
+
+ virtual bool operator==(const GameState& other) const;
+
+ virtual void move(const Move& m);
+ virtual void basicMove(const Move& m);
+ virtual void handleCastling(const Piece& piece, const Move& m);
+ virtual void captureOn(const Point& p);
+
+ virtual void switchTurn();
+ virtual typename Piece::Color turn() const;
+};
+
+// IMPLEMENTATION
+
+template
+GameState::GameState()
+: m_board(Point(8, 8))
+, m_en_passant(Point::invalid())
+, m_turn(Piece::WHITE) { }
+
+template
+Board& GameState::board() { return m_board; }
+
+template
+const Board& GameState::board() const { return m_board; }
+
+template
+void GameState::setup() {
+ for (int c = 0; c < 2; c++) {
+ typename Piece::Color color = static_cast(c);
+ int row = color == Piece::WHITE ? m_board.size().y - 1: 0;
+ for (int i = 0; i < m_board.size().x; i++) {
+ m_board.set(Point(i, color == Piece::WHITE ? row - 1 : row + 1),
+ Piece(color, Piece::PAWN));
+ m_board.set(Point(0, row), Piece(color, Piece::ROOK));
+ m_board.set(Point(1, row), Piece(color, Piece::KNIGHT));
+ m_board.set(Point(2, row), Piece(color, Piece::BISHOP));
+ m_board.set(Point(3, row), Piece(color, Piece::QUEEN));
+ m_board.set(Point(4, row), Piece(color, Piece::KING));
+ m_board.set(Point(5, row), Piece(color, Piece::BISHOP));
+ m_board.set(Point(6, row), Piece(color, Piece::KNIGHT));
+ m_board.set(Point(7, row), Piece(color, Piece::ROOK));
+ }
+ }
+}
+
+template
+bool GameState::operator==(const GameState& other) const {
+ return m_board == other.m_board &&
+ m_castling == other.m_castling &&
+ m_en_passant == other.m_en_passant;
+}
+
+template
+void GameState::captureOn(const Point& p) {
+ m_board.set(p, Piece());
+}
+
+template
+void GameState::basicMove(const Move& m) {
+ if (m.from() != m.to()) {
+ m_board.set(m.to(), m_board.get(m.from()));
+ m_board.set(m.from(), Piece());
+ }
+}
+
+template
+void GameState::handleCastling(const Piece& piece, const Move& m) {
+ if (m.kingSideCastling()) {
+ Point rookSquare = m.to() + Point(1,0);
+ Point rookDestination = m.from() + Point(1,0);
+ basicMove(Move(rookSquare, rookDestination));
+ }
+
+ else if (m.queenSideCastling()) {
+ Point rookSquare = m.to() - Point(2,0);
+ Point rookDestination = m.from() - Point(1,0);
+ basicMove(Move(rookSquare, rookDestination));
+ }
+
+ typename Piece::Type type = piece.type();
+ typename Piece::Color color = piece.color();
+
+ if (type == Piece::KING) {
+ if (color == Piece::WHITE) {
+ m_castling.wk = false;
+ m_castling.wq = false;
+ }
+ else {
+ m_castling.bk = false;
+ m_castling.bq = false;
+ }
+ }
+
+ if (m.from() == Point(0,0) || m.to() == Point(0,0))
+ m_castling.bq = false;
+ else if (m.from() == Point(7,0) || m.to() == Point(7,0))
+ m_castling.bk = false;
+ else if (m.from() == Point(0,7) || m.to() == Point(0,7))
+ m_castling.wq = false;
+ else if (m.from() == Point(7,7) || m.to() == Point(7,7))
+ m_castling.wk = false;
+}
+
+template
+void GameState::switchTurn() {
+ m_turn = Piece::oppositeColor(m_turn);
+}
+
+template
+void GameState::move(const Move& m) {
+ Piece piece = m_board.get(m.from());
+ if (piece == Piece()) return;
+
+ captureOn(m.captureSquare());
+ basicMove(m);
+
+ m_en_passant = m.enPassantTrigger();
+
+ typename Piece::Type promotion_type =
+ static_cast(m.promoteTo());
+ if (promotion_type != Piece::INVALID_TYPE) {
+ m_board.set(m.to(), Piece(piece.color(), promotion_type));
+ }
+
+ handleCastling(piece, m);
+ switchTurn();
+}
+
+template
+typename Board::Piece::Color GameState::turn() const {
+ return m_turn;
+}
+
+} // namespace Chess
+} // namespace HLVariant
+
+#endif // HLVARIANT__CHESS__GAMESTATE_H
+
diff --git a/tests/hlvariants/prototype/chess/move.cpp b/tests/hlvariants/prototype/chess/move.cpp
new file mode 100644
index 0000000..8c9f3d4
--- /dev/null
+++ b/tests/hlvariants/prototype/chess/move.cpp
@@ -0,0 +1,63 @@
+#include "move.h"
+
+namespace HLVariant {
+namespace Chess {
+
+Move::Move(const Point& from, const Point& to, int promotionType)
+: m_from(from)
+, m_to(to)
+, m_promotion(promotionType) { }
+
+Move::~Move() { }
+
+Point Move::enPassantTrigger() const {
+ if (m_type == EN_PASSANT_TRIGGER) {
+ return (m_from + m_to) / 2;
+ }
+ else {
+ return Point::invalid();
+ }
+}
+
+Point Move::captureSquare() const {
+ if (m_type == EN_PASSANT_CAPTURE) {
+ return Point(m_to.x, m_from.y);
+ }
+ else {
+ return m_to;
+ }
+}
+
+int Move::promoteTo() const {
+ if (m_type == PROMOTION) {
+ return m_promotion;
+ }
+ else {
+ return -1;
+ }
+}
+
+bool Move::kingSideCastling() const {
+ return m_type == KING_SIDE_CASTLING;
+}
+
+bool Move::queenSideCastling() const {
+ return m_type == QUEEN_SIDE_CASTLING;
+}
+
+Point Move::from() const {
+ return m_from;
+}
+
+Point Move::to() const {
+ return m_to;
+}
+
+void Move::setType(Type type) {
+ m_type = type;
+}
+
+} // namespace Chess
+} // namespace HLVariant
+
+
diff --git a/tests/hlvariants/prototype/chess/move.h b/tests/hlvariants/prototype/chess/move.h
new file mode 100644
index 0000000..cb36476
--- /dev/null
+++ b/tests/hlvariants/prototype/chess/move.h
@@ -0,0 +1,45 @@
+#ifndef HLVARIANT__CHESS__MOVE_H
+#define HLVARIANT__CHESS__MOVE_H
+
+#include "point.h"
+
+namespace HLVariant {
+namespace Chess {
+
+class Move {
+public:
+ enum Type {
+ NORMAL,
+ EN_PASSANT_CAPTURE,
+ EN_PASSANT_TRIGGER,
+ KING_SIDE_CASTLING,
+ QUEEN_SIDE_CASTLING,
+ PROMOTION
+ };
+private:
+ Type m_type;
+
+ Point m_from;
+ Point m_to;
+ int m_promotion;
+public:
+ Move(const Point& from, const Point& to, int promotionType = -1);
+ virtual ~Move();
+
+ virtual Point enPassantTrigger() const;
+ virtual Point captureSquare() const;
+ virtual int promoteTo() const;
+ virtual bool kingSideCastling() const;
+ virtual bool queenSideCastling() const;
+
+ virtual Point from() const;
+ virtual Point to() const;
+
+ virtual void setType(Type type);
+};
+
+} // namespace Chess
+} // namespace HLVariant
+
+#endif // HLVARIANT__CHESS__MOVE_H
+
diff --git a/tests/hlvariants/prototype/chess/piece.cpp b/tests/hlvariants/prototype/chess/piece.cpp
index a0686c1..4375f19 100644
--- a/tests/hlvariants/prototype/chess/piece.cpp
+++ b/tests/hlvariants/prototype/chess/piece.cpp
@@ -49,6 +49,26 @@ QString Piece::name() const {
return colorName() + '_' + typeName();
}
+Piece::Color Piece::oppositeColor(Color color) {
+ switch (color) {
+ case WHITE:
+ return BLACK;
+ case BLACK:
+ return WHITE;
+ default:
+ return INVALID_COLOR;
+ }
+}
+
+bool Piece::operator==(const Piece& other) const {
+ return m_color == other.m_color &&
+ m_type == other.m_type;
+}
+
+bool Piece::operator!=(const Piece& other) const {
+ return !((*this) == other);
+}
+
} // namespace HLVariant
} // namespace Chess
diff --git a/tests/hlvariants/prototype/chess/piece.h b/tests/hlvariants/prototype/chess/piece.h
index 27088d4..c23ea84 100644
--- a/tests/hlvariants/prototype/chess/piece.h
+++ b/tests/hlvariants/prototype/chess/piece.h
@@ -36,6 +36,11 @@ public:
QString typeName() const;
static QString typeName(Type type);
QString name() const;
+
+ static Color oppositeColor(Color color);
+
+ bool operator==(const Piece& other) const;
+ bool operator!=(const Piece& other) const;
};
} // namespace Chess
--
2.11.4.GIT