diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c0d6489..f68fb4b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,3 +1,4 @@ +add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/libData/) # Library: Core data layer add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/libCore/) # Library: Core game logic add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/libNetwork/) # Library: Network layer networking add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/libGameNet/) # Library: Application layer networking diff --git a/src/gui/GameWidget.cpp b/src/gui/GameWidget.cpp index de55773..9e803cf 100644 --- a/src/gui/GameWidget.cpp +++ b/src/gui/GameWidget.cpp @@ -108,10 +108,10 @@ void GameWidget::setCurrentPlayerText() { } void GameWidget::setGameStateText() { - static const std::map message{{app::GameStatus::Idle, "Idle"}, - {app::GameStatus::Waiting, "Waiting for Player"}, - {app::GameStatus::Active, "Active"}, - {app::GameStatus::Done, "Game Finished"}}; + static const std::map message{{GameStatus::Idle, "Idle"}, + {GameStatus::Ready, "Waiting for Player"}, + {GameStatus::Active, "Active"}, + {GameStatus::Done, "Game Finished"}}; assert(message.contains(m_game.status())); m_statusLabel->setText(QString::fromStdString(message.at(m_game.status()))); } diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index e42349a..0f03b5a 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -11,6 +11,7 @@ namespace go::gui { MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) { // Setup Window setWindowTitle("Go Game"); + setWindowFlags(windowFlags() | Qt::Tool | Qt::WindowStaysOnTopHint); buildLayout(); } diff --git a/src/gui/boardRenderer.cpp b/src/gui/boardRenderer.cpp index 7b1e901..ed322e7 100644 --- a/src/gui/boardRenderer.cpp +++ b/src/gui/boardRenderer.cpp @@ -104,7 +104,7 @@ void BoardRenderer::drawBackground(QPainter& painter) const { painter.restore(); } -void BoardRenderer::drawStone(QPainter& painter, Id x, Id y, const Board::Value player) const { +void BoardRenderer::drawStone(QPainter& painter, unsigned x, unsigned y, const Board::Stone player) const { if (!isReady()) { return; } @@ -113,22 +113,22 @@ void BoardRenderer::drawStone(QPainter& painter, Id x, Id y, const Board::Value const int drawY = static_cast((m_coordStart - m_drawStepPx) + y * m_stoneSize); const QRect dest{drawX, drawY, static_cast(m_stoneSize), static_cast(m_stoneSize)}; - const auto& texture = (player == Board::Value::Black) ? m_scaledBlack : m_scaledWhite; + const auto& texture = (player == Board::Stone::Black) ? m_scaledBlack : m_scaledWhite; painter.drawImage(dest, texture); } void BoardRenderer::drawStones(QPainter& painter, const Board& board) const { - for (Id i = 0; i != board.size(); ++i) { - for (Id j = 0; j != board.size(); ++j) { - if (board.getAt({i, j}) != Board::Value::Empty) { - drawStone(painter, i, j, board.getAt({i, j})); + for (unsigned i = 0; i != board.size(); ++i) { + for (unsigned j = 0; j != board.size(); ++j) { + if (board.get({i, j}) != Board::Stone::Empty) { + drawStone(painter, i, j, board.get({i, j})); } } } } bool BoardRenderer::pixelToCoord(int pX, int pY, Coord& coord) const { - Id x, y; + unsigned x, y; if (pixelToCoord(pX, x) && pixelToCoord(pY, y)) { coord = {x, y}; return true; diff --git a/src/gui/boardRenderer.hpp b/src/gui/boardRenderer.hpp index a0d2e75..aabc997 100644 --- a/src/gui/boardRenderer.hpp +++ b/src/gui/boardRenderer.hpp @@ -1,7 +1,7 @@ #pragma once -#include "core/board.hpp" -#include "core/types.hpp" +#include "data/board.hpp" +#include "data/player.hpp" #include #include @@ -28,7 +28,7 @@ class BoardRenderer { //! Draw all stones given a board. void drawStones(QPainter& painter, const Board& board) const; //! Draw a single stone at a given index. - void drawStone(QPainter& painter, Id x, Id y, Board::Value player) const; + void drawStone(QPainter& painter, unsigned x, unsigned y, Board::Stone player) const; //! Transforms pixel value to board coordinate. bool pixelToCoord(int px, unsigned& coord) const; diff --git a/src/libApp/gameServer.cpp b/src/libApp/gameServer.cpp index 0ae2b21..94cfdf2 100644 --- a/src/libApp/gameServer.cpp +++ b/src/libApp/gameServer.cpp @@ -95,16 +95,6 @@ void GameServer::onNetworkEvent(gameNet::SessionId sessionId, const gameNet::Cli } void GameServer::onGameDelta(const GameDelta& delta) { - const auto toGameNetCoord = [](Coord c) -> gameNet::Coord { return gameNet::Coord{c.x, c.y}; }; - const auto toGameNetCoords = [](const std::vector& coords) -> std::vector { - std::vector res; - res.reserve(coords.size()); - for (const auto& c: coords) { - res.emplace_back(gameNet::Coord{c.x, c.y}); - } - return res; - }; - gameNet::ServerAction action = gameNet::ServerAction::Pass; switch (delta.action) { case GameAction::Place: @@ -123,8 +113,8 @@ void GameServer::onGameDelta(const GameDelta& delta) { .turn = delta.moveId, .seat = delta.player == Player::Black ? gameNet::Seat::Black : gameNet::Seat::White, .action = action, - .coord = delta.coord.has_value() ? std::optional(toGameNetCoord(*delta.coord)) : std::nullopt, - .captures = toGameNetCoords(delta.captures), + .coord = delta.coord, + .captures = delta.captures, .next = delta.nextPlayer == Player::Black ? gameNet::Seat::Black : gameNet::Seat::White, .status = delta.gameActive ? gameNet::GameStatus::Active : gameNet::GameStatus::Draw, }; diff --git a/src/libApp/include/app/position.hpp b/src/libApp/include/app/position.hpp index c98b8ac..14dc1a9 100644 --- a/src/libApp/include/app/position.hpp +++ b/src/libApp/include/app/position.hpp @@ -1,19 +1,13 @@ #pragma once #include "app/eventHub.hpp" -#include "core/board.hpp" -#include "core/types.hpp" +#include "data/board.hpp" +#include "data/gameStatus.hpp" +#include "data/player.hpp" #include "gameNet/nwEvents.hpp" namespace go::app { -enum class GameStatus { - Idle, //!< Nothing happening - Waiting, //!< Waiting for players to connect. - Active, //!< Game being played. - Done //!< Game over. -}; - class Position { public: Position(EventHub& hub); //!< Hub allows to signal listeners on interesting updates. diff --git a/src/libApp/position.cpp b/src/libApp/position.cpp index cd5b6c6..0f0963e 100644 --- a/src/libApp/position.cpp +++ b/src/libApp/position.cpp @@ -92,9 +92,9 @@ void Position::updatePosition(const gameNet::ServerDelta& delta) { if (delta.action == gameNet::ServerAction::Place) { if (delta.coord) { - m_board.setAt(Coord{delta.coord->x, delta.coord->y}, delta.seat == gameNet::Seat::Black ? Board::Value::Black : Board::Value::White); + m_board.place(Coord{delta.coord->x, delta.coord->y}, delta.seat == gameNet::Seat::Black ? Board::Stone::Black : Board::Stone::White); for (const auto c: delta.captures) { - m_board.setAt({c.x, c.y}, Board::Value::Empty); + m_board.place({c.x, c.y}, Board::Stone::Empty); } } else { Logger().Log(Logging::LogLevel::Warning, "Game delta missing place coordinate; skipping board update."); diff --git a/src/libApp/sessionManager.cpp b/src/libApp/sessionManager.cpp index cec2f64..dc07c8c 100644 --- a/src/libApp/sessionManager.cpp +++ b/src/libApp/sessionManager.cpp @@ -27,7 +27,7 @@ void SessionManager::connect(const std::string& hostIp) { { std::lock_guard lock(m_stateMutex); m_position.reset(9u); - m_position.setStatus(GameStatus::Waiting); + m_position.setStatus(GameStatus::Ready); m_chatHistory.clear(); } m_localServer.reset(); @@ -40,7 +40,7 @@ void SessionManager::host(unsigned boardSize) { { std::lock_guard lock(m_stateMutex); m_position.reset(boardSize); - m_position.setStatus(GameStatus::Waiting); + m_position.setStatus(GameStatus::Ready); m_chatHistory.clear(); } diff --git a/src/libCamera/CMakeLists.txt b/src/libCamera/CMakeLists.txt index 27926fe..8e0633e 100644 --- a/src/libCamera/CMakeLists.txt +++ b/src/libCamera/CMakeLists.txt @@ -29,4 +29,3 @@ set_output_directory(${targetName}) # Set the output directory of the library target_compile_definitions(${targetName} PUBLIC VERSION_MAJOR=0) target_compile_definitions(${targetName} PUBLIC VERSION_MINOR=0) target_compile_definitions(${targetName} PUBLIC VERSION_PATCH=1) - diff --git a/src/libCore/CMakeLists.txt b/src/libCore/CMakeLists.txt index 6a40a81..54dba8f 100644 --- a/src/libCore/CMakeLists.txt +++ b/src/libCore/CMakeLists.txt @@ -3,8 +3,6 @@ set(targetName libCore) # Get files to build set(headers - ${CMAKE_CURRENT_LIST_DIR}/include/core/types.hpp - ${CMAKE_CURRENT_LIST_DIR}/include/core/board.hpp ${CMAKE_CURRENT_LIST_DIR}/include/core/game.hpp ${CMAKE_CURRENT_LIST_DIR}/include/core/position.hpp ${CMAKE_CURRENT_LIST_DIR}/include/core/gameEvent.hpp @@ -17,7 +15,6 @@ set(headers ${CMAKE_CURRENT_LIST_DIR}/zobristHash.hpp ) set(sources - ${CMAKE_CURRENT_LIST_DIR}/board.cpp ${CMAKE_CURRENT_LIST_DIR}/position.cpp ${CMAKE_CURRENT_LIST_DIR}/game.cpp ${CMAKE_CURRENT_LIST_DIR}/sgfHandler.cpp @@ -36,6 +33,10 @@ target_include_directories(${targetName} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include ) +target_link_libraries(${targetName} + PUBLIC + go::data +) # Setup project settings set_project_warnings(${targetName}) # Which warnings to enable diff --git a/src/libCore/board.cpp b/src/libCore/board.cpp deleted file mode 100644 index 11c0bb5..0000000 --- a/src/libCore/board.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "core/board.hpp" - -#include - -namespace go { - -Board::Board(const std::size_t size) : m_size(size), m_board(size * size, Value::Empty) { - assert(size == 9 || size == 13 || size == 19); // Core only supports standard board sizes; invalid sizes are a programmer error. -}; - -std::size_t Board::size() const { - return m_size; -} - -void Board::setAt(const Coord c, Value value) { - assert(c.x < m_size && c.y < m_size); // Game should heck isValidMove trying to set - - m_board[c.y * m_size + c.x] = value; -} - -Board::Value Board::getAt(const Coord c) const { - assert(c.x < m_size && c.y < m_size); - - return m_board[c.y * m_size + c.x]; -} - -bool Board::isFree(const Coord c) const { - return getAt(c) == Value::Empty; -} - -} // namespace go diff --git a/src/libCore/game.cpp b/src/libCore/game.cpp index 26a7a14..5f945d2 100644 --- a/src/libCore/game.cpp +++ b/src/libCore/game.cpp @@ -52,7 +52,7 @@ void Game::handleEvent(const PutStoneEvent& event) { return; } - Position next{m_position.board.size()}; + GamePosition next{m_position.board.size()}; std::vector captures{}; if (isNextPositionLegal(m_position, m_position.currentPlayer, event.c, *m_hasher, m_seenHashes, next, captures)) { m_consecutivePasses = 0; @@ -97,7 +97,7 @@ void Game::handleEvent(const PassEvent& event) { return; } - Position next = m_position; + GamePosition next = m_position; next.pass(*m_hasher); if (m_seenHashes.contains(next.hash)) { diff --git a/src/libCore/include/core/IZobristHash.hpp b/src/libCore/include/core/IZobristHash.hpp index 62b8ea4..8da8192 100644 --- a/src/libCore/include/core/IZobristHash.hpp +++ b/src/libCore/include/core/IZobristHash.hpp @@ -1,6 +1,8 @@ #pragma once -#include "core/types.hpp" +#include "data/board.hpp" +#include "data/player.hpp" + #include namespace go { diff --git a/src/libCore/include/core/board.hpp b/src/libCore/include/core/board.hpp deleted file mode 100644 index 5f2739b..0000000 --- a/src/libCore/include/core/board.hpp +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include "core/types.hpp" -#include - -namespace go { - -// TODO: This should be optimized to use 2Bits per site on the field. (B, W, None, ...) -//! \note Game coordinates origin is at bottom left of board and start at 0. Column: A->0, B->1, etc -class Board { -public: - //! Possible ownership values of fields on the board. - enum class Value { Empty = 0, Black = static_cast(Player::Black), White = static_cast(Player::White) }; - -public: - Board(std::size_t size); - - std::size_t size() const; - - void setAt(Coord c, Value value); //!< Set at given coordinate (x,y) \in [0, size-1] - Value getAt(Coord c) const; //!< Get value at given coordinate (x,y) \in [0, size-1] - bool isFree(Coord c) const; //!< Returns whether a certain board coordinate is free or occupied. - -private: - std::size_t m_size; //!< Board size - std::vector m_board{}; //!< Board values. -}; - -//! Returns the Board::Value enum value of input player. -inline constexpr Board::Value toBoardValue(Player player) { - return player == Player::White ? Board::Value::White : Board::Value::Black; -} - -} // namespace go diff --git a/src/libCore/include/core/eventHub.hpp b/src/libCore/include/core/eventHub.hpp index 38ca881..f427047 100644 --- a/src/libCore/include/core/eventHub.hpp +++ b/src/libCore/include/core/eventHub.hpp @@ -2,7 +2,6 @@ #include "core/IGameSignalListener.hpp" #include "core/IGameStateListener.hpp" -#include "core/types.hpp" #include #include diff --git a/src/libCore/include/core/game.hpp b/src/libCore/include/core/game.hpp index 2fd4d27..3bce167 100644 --- a/src/libCore/include/core/game.hpp +++ b/src/libCore/include/core/game.hpp @@ -5,7 +5,7 @@ #include "core/eventHub.hpp" #include "core/gameEvent.hpp" #include "core/position.hpp" -#include "core/types.hpp" +#include "data/player.hpp" #include @@ -42,7 +42,7 @@ class Game { bool m_gameActive; unsigned m_consecutivePasses{0}; //!< Two consequtive passes ends game. - Position m_position; + GamePosition m_position; EventQueue m_eventQueue; //!< Queue of internal game events we have to handle. EventHub m_eventHub; //!< Hub to signal updates of the game state to external components. diff --git a/src/libCore/include/core/gameEvent.hpp b/src/libCore/include/core/gameEvent.hpp index 106d7ee..1bb98c1 100644 --- a/src/libCore/include/core/gameEvent.hpp +++ b/src/libCore/include/core/gameEvent.hpp @@ -1,7 +1,9 @@ #pragma once -#include "core/types.hpp" +#include "data/board.hpp" +#include "data/player.hpp" +#include #include #include #include @@ -21,7 +23,7 @@ using GameEvent = std::variant #include @@ -23,7 +23,7 @@ bool isSuicide(const Board& board, Player player, Coord c); bool isValidMove(const Board& board, Player player, Coord c); //! Compute resulting position if the move is legal (including superko via history). Returns false when illegal. -bool isNextPositionLegal(const Position& current, Player player, Coord c, IZobristHash& hasher, const std::unordered_set& history, Position& out, - std::vector& outCaptures); +bool isNextPositionLegal(const GamePosition& current, Player player, Coord c, IZobristHash& hasher, const std::unordered_set& history, + GamePosition& out, std::vector& outCaptures); } // namespace go diff --git a/src/libCore/include/core/position.hpp b/src/libCore/include/core/position.hpp index 1abeabc..f7ac1f7 100644 --- a/src/libCore/include/core/position.hpp +++ b/src/libCore/include/core/position.hpp @@ -1,20 +1,20 @@ #pragma once #include "core/IZobristHash.hpp" -#include "core/board.hpp" -#include "core/types.hpp" +#include "data/board.hpp" +#include "data/player.hpp" namespace go { //! The current game position. -struct Position { +struct GamePosition { Board board; //!< Current board. Player currentPlayer{Player::Black}; //!< Current Player. uint64_t hash{0}; //!< Game state hash. unsigned moveId{0}; //!< Move number of game. public: - Position(std::size_t boardSize); + GamePosition(std::size_t boardSize); void putStone(Coord c, IZobristHash& hasher); //!< Current player puts a stone (assumes legal move). void pass(IZobristHash& hasher); //!< Current player passes his turn. diff --git a/src/libCore/include/core/sgfHandler.hpp b/src/libCore/include/core/sgfHandler.hpp index 0484d6a..4f05973 100644 --- a/src/libCore/include/core/sgfHandler.hpp +++ b/src/libCore/include/core/sgfHandler.hpp @@ -1,6 +1,6 @@ #pragma once -#include "core/types.hpp" +#include "data/board.hpp" #include diff --git a/src/libCore/moveChecker.cpp b/src/libCore/moveChecker.cpp index 44a5aeb..6860a2a 100644 --- a/src/libCore/moveChecker.cpp +++ b/src/libCore/moveChecker.cpp @@ -22,7 +22,7 @@ static std::size_t groupAnalysis(const Board& board, const Coord startCoord, con auto isPlayerStone = [&](Coord c) { if (pretendStone && pretendStone->x == c.x && pretendStone->y == c.y) return true; - return board.getAt(c) == toBoardValue(player); + return board.get(c) == toStone(player); }; std::vector> visited(boardSize, std::vector(boardSize, false)); @@ -50,7 +50,7 @@ static std::size_t groupAnalysis(const Board& board, const Coord startCoord, con if (nx < 0 || ny < 0 || nx >= static_cast(boardSize) || ny >= static_cast(boardSize)) continue; - const Coord neighbor{static_cast(nx), static_cast(ny)}; + const Coord neighbor{static_cast(nx), static_cast(ny)}; if (isPlayerStone(neighbor)) { if (!visited[neighbor.x][neighbor.y]) { stack.push_back(neighbor); @@ -59,7 +59,7 @@ static std::size_t groupAnalysis(const Board& board, const Coord startCoord, con continue; } - if (board.getAt(neighbor) == Board::Value::Empty && (!blockedLiberty || (blockedLiberty->x != neighbor.x || blockedLiberty->y != neighbor.y)) && + if (board.get(neighbor) == Board::Stone::Empty && (!blockedLiberty || (blockedLiberty->x != neighbor.x || blockedLiberty->y != neighbor.y)) && !libertyVisited[neighbor.x][neighbor.y]) { libertyVisited[neighbor.x][neighbor.y] = true; ++liberties; @@ -90,8 +90,8 @@ static bool wouldCapture(const Board& board, Coord c, Player player) { if (nx < 0 || ny < 0 || nx >= static_cast(boardSize) || ny >= static_cast(boardSize)) continue; - const Coord neighbor{static_cast(nx), static_cast(ny)}; - if (board.getAt(neighbor) != toBoardValue(enemy) || visited[neighbor.x][neighbor.y]) + const Coord neighbor{static_cast(nx), static_cast(ny)}; + if (board.get(neighbor) != toStone(enemy) || visited[neighbor.x][neighbor.y]) continue; group.clear(); @@ -119,8 +119,8 @@ bool isSuicide(const Board& board, Player player, Coord c) { //! Simulate the position after a move //! \param [out] outCaptures List of stones captured by a move. -static Position simulatePosition(const Position& start, Coord move, Player player, IZobristHash& hasher, std::vector& outCaptures) { - assert(start.board.isFree(move)); +static GamePosition simulatePosition(const GamePosition& start, Coord move, Player player, IZobristHash& hasher, std::vector& outCaptures) { + assert(start.board.isEmpty(move)); const auto boardSize = start.board.size(); const auto enemy = opponent(player); @@ -135,8 +135,8 @@ static Position simulatePosition(const Position& start, Coord move, Player playe if (nx < 0 || ny < 0 || nx >= static_cast(boardSize) || ny >= static_cast(boardSize)) continue; - const Coord neighbor{static_cast(nx), static_cast(ny)}; - if (start.board.getAt(neighbor) != toBoardValue(enemy) || visited[neighbor.x][neighbor.y]) + const Coord neighbor{static_cast(nx), static_cast(ny)}; + if (start.board.get(neighbor) != toStone(enemy) || visited[neighbor.x][neighbor.y]) continue; group.clear(); @@ -152,23 +152,23 @@ static Position simulatePosition(const Position& start, Coord move, Player playe } Board nextBoard{boardSize}; - for (Id x = 0; x < boardSize; ++x) { - for (Id y = 0; y < boardSize; ++y) { + for (unsigned x = 0; x < boardSize; ++x) { + for (unsigned y = 0; y < boardSize; ++y) { const Coord pos{x, y}; if (captured[x][y] || (pos.x == move.x && pos.y == move.y)) continue; - const auto value = start.board.getAt(pos); - if (value != Board::Value::Empty) { - nextBoard.setAt(pos, value); + const auto value = start.board.get(pos); + if (value != Board::Stone::Empty) { + nextBoard.place(pos, value); } } } - nextBoard.setAt(move, toBoardValue(player)); + nextBoard.place(move, toStone(player)); outCaptures.clear(); - for (Id x = 0; x < boardSize; ++x) { - for (Id y = 0; y < boardSize; ++y) { + for (unsigned x = 0; x < boardSize; ++x) { + for (unsigned y = 0; y < boardSize; ++y) { if (captured[x][y]) { outCaptures.push_back(Coord{x, y}); } @@ -182,7 +182,7 @@ static Position simulatePosition(const Position& start, Coord move, Player playe } nextHash ^= hasher.togglePlayer(); - Position next = start; + GamePosition next = start; next.board = std::move(nextBoard); next.currentPlayer = opponent(player); next.hash = nextHash; @@ -191,18 +191,18 @@ static Position simulatePosition(const Position& start, Coord move, Player playe } bool isValidMove(const Board& board, Player player, Coord c) { - if (!inBounds(board, c) || board.getAt(c) != Board::Value::Empty) + if (!inBounds(board, c) || board.get(c) != Board::Stone::Empty) return false; return !isSuicide(board, player, c); } -bool isNextPositionLegal(const Position& current, Player player, Coord c, IZobristHash& hasher, const std::unordered_set& history, Position& out, - std::vector& outCaptures) { +bool isNextPositionLegal(const GamePosition& current, Player player, Coord c, IZobristHash& hasher, const std::unordered_set& history, + GamePosition& out, std::vector& outCaptures) { if (!isValidMove(current.board, player, c)) return false; - Position simulated = simulatePosition(current, c, player, hasher, outCaptures); + GamePosition simulated = simulatePosition(current, c, player, hasher, outCaptures); if (history.contains(simulated.hash)) return false; diff --git a/src/libCore/position.cpp b/src/libCore/position.cpp index 0cb8ce9..bbf6315 100644 --- a/src/libCore/position.cpp +++ b/src/libCore/position.cpp @@ -2,11 +2,11 @@ namespace go { -Position::Position(std::size_t boardSize) : board{boardSize} { +GamePosition::GamePosition(std::size_t boardSize) : board{boardSize} { } -void Position::putStone(Coord c, IZobristHash& hasher) { - board.setAt(c, toBoardValue(currentPlayer)); +void GamePosition::putStone(Coord c, IZobristHash& hasher) { + board.place(c, toStone(currentPlayer)); hash ^= hasher.stone(c, currentPlayer); currentPlayer = opponent(currentPlayer); @@ -15,7 +15,7 @@ void Position::putStone(Coord c, IZobristHash& hasher) { ++moveId; } -void Position::pass(IZobristHash& hasher) { +void GamePosition::pass(IZobristHash& hasher) { currentPlayer = opponent(currentPlayer); hash ^= hasher.togglePlayer(); diff --git a/src/libCore/sgfHandler.cpp b/src/libCore/sgfHandler.cpp index b77abca..e333f22 100644 --- a/src/libCore/sgfHandler.cpp +++ b/src/libCore/sgfHandler.cpp @@ -3,7 +3,7 @@ namespace go { Coord fromSGF(const std::string& s) { - return {static_cast(s[0u] - 'a'), static_cast(s[1u] - 'a')}; + return {static_cast(s[0u] - 'a'), static_cast(s[1u] - 'a')}; } std::string toSGF(const Coord c) { diff --git a/src/libCore/zobristHash.hpp b/src/libCore/zobristHash.hpp index c45f670..36c1f8f 100644 --- a/src/libCore/zobristHash.hpp +++ b/src/libCore/zobristHash.hpp @@ -1,7 +1,7 @@ #pragma once #include "core/IZobristHash.hpp" -#include "core/types.hpp" +#include "data/player.hpp" #include #include diff --git a/src/libData/CMakeLists.txt b/src/libData/CMakeLists.txt new file mode 100644 index 0000000..561a001 --- /dev/null +++ b/src/libData/CMakeLists.txt @@ -0,0 +1,27 @@ +# Settings +set(targetName libData) + +# Get files to build +set(headers + ${CMAKE_CURRENT_LIST_DIR}/include/data/player.hpp + ${CMAKE_CURRENT_LIST_DIR}/include/data/coordinate.hpp + ${CMAKE_CURRENT_LIST_DIR}/include/data/board.hpp + ${CMAKE_CURRENT_LIST_DIR}/include/data/gameStatus.hpp +) +set(sources + ${CMAKE_CURRENT_LIST_DIR}/board.cpp +) + +# Create target +add_library(${targetName} STATIC ${headers} ${sources}) +add_library(go::data ALIAS ${targetName}) + +target_include_directories(${targetName} + PUBLIC + ${CMAKE_CURRENT_LIST_DIR}/include +) + +# Setup project settings +set_project_warnings(${targetName}) # Which warnings to enable +set_compile_options(${targetName}) # Which extra compiler flags to enable +set_output_directory(${targetName}) # Set the output directory of the library diff --git a/src/libData/board.cpp b/src/libData/board.cpp new file mode 100644 index 0000000..e8f90f8 --- /dev/null +++ b/src/libData/board.cpp @@ -0,0 +1,45 @@ +#include "data/board.hpp" + +#include + +namespace go { + +Board::Board(std::size_t size) : m_size(size), m_board(size * size, Stone::Empty) { +} + +std::size_t Board::size() const { + return m_size; +} + +bool Board::place(Coord c, Stone value) { + assert(c.x < m_size && c.y < m_size); // Game should verify valid coordinate. + assert(value != Stone::Empty); // Use remove + + if (isEmpty(c)) { + m_board[c.y * m_size + c.x] = value; + return true; + } + return false; +} + +bool Board::remove(Coord c) { + assert(c.x < m_size && c.y < m_size); // Game should verify valid coordinate. + + if (!isEmpty(c)) { + m_board[c.y * m_size + c.x] = Stone::Empty; + return true; + } + return false; +} + +Board::Stone Board::get(Coord c) const { + assert(c.x < m_size && c.y < m_size); // Game should verify valid coordinate. + return m_board[c.y * m_size + c.x]; +} + +bool Board::isEmpty(Coord c) const { + assert(c.x < m_size && c.y < m_size); // Game should verify valid coordinate. + return get(c) == Stone::Empty; +} + +} // namespace go \ No newline at end of file diff --git a/src/libData/include/data/board.hpp b/src/libData/include/data/board.hpp new file mode 100644 index 0000000..9cda82f --- /dev/null +++ b/src/libData/include/data/board.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include "data/coordinate.hpp" +#include "data/player.hpp" + +#include +#include + +namespace go { + +//! A physical go board of arbitrary size. +class Board { +public: + enum class Stone { Empty, Black, White }; + + Board(std::size_t size); + + bool place(Coord c, Stone value); //!< Try to place a stone at the given coordinate. False if not free. + bool remove(Coord c); //!< Remove the stone at the given coordinate. False if already free. + + Stone get(Coord c) const; //!< Get the stone at the given position. + bool isEmpty(Coord c) const; //!< True if the given coordinate is empty. + std::size_t size() const; //!< Size of the board. + +private: + std::size_t m_size{0u}; //!< Board size (typically 9, 13, 19) + std::vector m_board{}; //!< Board data. +}; + +//! Maps a player color to a stone color. +inline constexpr Board::Stone toStone(const Player player) { + assert(player == Player::Black || player == Player::White); + return player == Player::White ? Board::Stone::White : Board::Stone::Black; +} + +} // namespace go \ No newline at end of file diff --git a/src/libData/include/data/coordinate.hpp b/src/libData/include/data/coordinate.hpp new file mode 100644 index 0000000..0343f7c --- /dev/null +++ b/src/libData/include/data/coordinate.hpp @@ -0,0 +1,11 @@ +#pragma once + +namespace go { + +//! Coordinate pair for the board. +struct Coord { + unsigned x; + unsigned y; +}; + +} // namespace go \ No newline at end of file diff --git a/src/libData/include/data/gameStatus.hpp b/src/libData/include/data/gameStatus.hpp new file mode 100644 index 0000000..4bf4d90 --- /dev/null +++ b/src/libData/include/data/gameStatus.hpp @@ -0,0 +1,12 @@ +#pragma once + +namespace go { + +enum class GameStatus { + Idle, //!< Nothing happening. + Ready, //!< Players ready to play. + Active, //!< Game being played. + Done //!< Game over. +}; + +} // namespace go diff --git a/src/libCore/include/core/types.hpp b/src/libData/include/data/player.hpp similarity index 60% rename from src/libCore/include/core/types.hpp rename to src/libData/include/data/player.hpp index b144f1e..96aa1cb 100644 --- a/src/libCore/include/core/types.hpp +++ b/src/libData/include/data/player.hpp @@ -1,16 +1,7 @@ #pragma once -#include - namespace go { -using Id = unsigned; //!< Board ID used by the core library. - -//! Coordinate pair for the board. -struct Coord { - Id x, y; -}; - enum class Player { Black = 1, White = 2 }; //! Returns the opponent enum value of input player. @@ -18,4 +9,4 @@ inline constexpr Player opponent(Player player) { return player == Player::White ? Player::Black : Player::White; } -} // namespace go +} // namespace go \ No newline at end of file diff --git a/src/libGameNet/CMakeLists.txt b/src/libGameNet/CMakeLists.txt index a691836..25d1e1f 100644 --- a/src/libGameNet/CMakeLists.txt +++ b/src/libGameNet/CMakeLists.txt @@ -30,6 +30,8 @@ target_include_directories(${targetName} ) target_link_libraries(${targetName} + PUBLIC + go::data PRIVATE go::network nlohmann_json::nlohmann_json diff --git a/src/libGameNet/include/gameNet/nwEvents.hpp b/src/libGameNet/include/gameNet/nwEvents.hpp index 94dc6c0..3766bb1 100644 --- a/src/libGameNet/include/gameNet/nwEvents.hpp +++ b/src/libGameNet/include/gameNet/nwEvents.hpp @@ -1,5 +1,6 @@ #pragma once +#include "data/coordinate.hpp" #include "gameNet/types.hpp" #include diff --git a/src/libGameNet/include/gameNet/types.hpp b/src/libGameNet/include/gameNet/types.hpp index de7832d..3439875 100644 --- a/src/libGameNet/include/gameNet/types.hpp +++ b/src/libGameNet/include/gameNet/types.hpp @@ -21,11 +21,6 @@ enum class GameStatus : std::uint8_t { Count //!< Used in serialisation to check when enum changes. }; -struct Coord { - unsigned x; - unsigned y; -}; - //! The role in the game. enum class Seat : std::uint8_t { None = 0, //!< Just connected. diff --git a/tests/core/CMakeLists.txt b/tests/core/CMakeLists.txt index ef770db..044b4f7 100644 --- a/tests/core/CMakeLists.txt +++ b/tests/core/CMakeLists.txt @@ -8,7 +8,7 @@ add_executable(${targetName} ) # Link to required libraries -target_link_libraries(${targetName} PUBLIC go::core GTest::gtest_main) +target_link_libraries(${targetName} PRIVATE go::core GTest::gtest_main) set_target_properties(${targetName} PROPERTIES FOLDER "${ideFolderSource}") # Setup project settings diff --git a/tests/core/moveChecker.gtest.cpp b/tests/core/moveChecker.gtest.cpp index 54a0864..171ec5e 100644 --- a/tests/core/moveChecker.gtest.cpp +++ b/tests/core/moveChecker.gtest.cpp @@ -1,6 +1,6 @@ #include "core/moveChecker.hpp" -#include "core/board.hpp" #include "core/game.hpp" +#include "data/board.hpp" #//include "core/zobristHash.hpp" #include @@ -17,17 +17,17 @@ TEST(MoveChecker, ComputeConnectedLiberties_Single) { EXPECT_EQ(computeGroupLiberties(board, {0u, 8u}, Player::Black), 2u); EXPECT_EQ(computeGroupLiberties(board, {8u, 0u}, Player::Black), 2u); // At border - for (Id i = 1; i != 8; ++i) { + for (unsigned i = 1; i != 8; ++i) { EXPECT_EQ(computeGroupLiberties(board, {i, 0u}, Player::Black), 3u); EXPECT_EQ(computeGroupLiberties(board, {i, 8u}, Player::Black), 3u); } - for (Id j = 1; j != 8; ++j) { + for (unsigned j = 1; j != 8; ++j) { EXPECT_EQ(computeGroupLiberties(board, {0u, j}, Player::Black), 3u); EXPECT_EQ(computeGroupLiberties(board, {8u, j}, Player::Black), 3u); } // No borders - for (Id i = 1; i != 8; ++i) { - for (Id j = 1; j != 8; ++j) { + for (unsigned i = 1; i != 8; ++i) { + for (unsigned j = 1; j != 8; ++j) { EXPECT_EQ(computeGroupLiberties(board, {i, j}, Player::Black), 4u); } } @@ -38,8 +38,8 @@ TEST(MoveChecker, ComputeConnectedLiberties_Center) { { Board board(9u); - board.setAt({4u, 3u}, Board::Value::Black); - board.setAt({4u, 4u}, Board::Value::Black); + board.place({4u, 3u}, Board::Stone::Black); + board.place({4u, 4u}, Board::Stone::Black); // Check liberties for each stone to check that full chain is found. EXPECT_EQ(computeGroupLiberties(board, {4u, 3u}, Player::Black), 6u); @@ -48,9 +48,9 @@ TEST(MoveChecker, ComputeConnectedLiberties_Center) { { Board board(9u); - board.setAt({4u, 3u}, Board::Value::Black); - board.setAt({4u, 4u}, Board::Value::Black); - board.setAt({4u, 5u}, Board::Value::Black); + board.place({4u, 3u}, Board::Stone::Black); + board.place({4u, 4u}, Board::Stone::Black); + board.place({4u, 5u}, Board::Stone::Black); // Check liberties for each stone to check that full chain is found. EXPECT_EQ(computeGroupLiberties(board, {4u, 3u}, Player::Black), 8u); @@ -60,9 +60,9 @@ TEST(MoveChecker, ComputeConnectedLiberties_Center) { { Board board(9u); - board.setAt({4u, 3u}, Board::Value::Black); - board.setAt({4u, 4u}, Board::Value::Black); - board.setAt({5u, 4u}, Board::Value::Black); + board.place({4u, 3u}, Board::Stone::Black); + board.place({4u, 4u}, Board::Stone::Black); + board.place({5u, 4u}, Board::Stone::Black); // Check liberties for each stone to check that full chain is found. EXPECT_EQ(computeGroupLiberties(board, {4u, 3u}, Player::Black), 7u); @@ -72,10 +72,10 @@ TEST(MoveChecker, ComputeConnectedLiberties_Center) { { Board board(9u); - board.setAt({4u, 3u}, Board::Value::Black); - board.setAt({4u, 4u}, Board::Value::Black); - board.setAt({4u, 5u}, Board::Value::Black); - board.setAt({5u, 5u}, Board::Value::Black); + board.place({4u, 3u}, Board::Stone::Black); + board.place({4u, 4u}, Board::Stone::Black); + board.place({4u, 5u}, Board::Stone::Black); + board.place({5u, 5u}, Board::Stone::Black); // Check liberties for each stone to check that full chain is found. EXPECT_EQ(computeGroupLiberties(board, {4u, 3u}, Player::Black), 9u); @@ -86,17 +86,17 @@ TEST(MoveChecker, ComputeConnectedLiberties_Center) { { Board board(9u); - board.setAt({4u, 3u}, Board::Value::Black); - board.setAt({4u, 4u}, Board::Value::Black); - board.setAt({4u, 5u}, Board::Value::Black); + board.place({4u, 3u}, Board::Stone::Black); + board.place({4u, 4u}, Board::Stone::Black); + board.place({4u, 5u}, Board::Stone::Black); - board.setAt({5u, 3u}, Board::Value::Black); - board.setAt({5u, 5u}, Board::Value::Black); + board.place({5u, 3u}, Board::Stone::Black); + board.place({5u, 5u}, Board::Stone::Black); - board.setAt({6u, 4u}, Board::Value::Black); - board.setAt({6u, 5u}, Board::Value::Black); + board.place({6u, 4u}, Board::Stone::Black); + board.place({6u, 5u}, Board::Stone::Black); - board.setAt({7u, 4u}, Board::Value::Black); + board.place({7u, 4u}, Board::Stone::Black); // Check liberties for each stone to check that full chain is found. EXPECT_EQ(computeGroupLiberties(board, {4u, 3u}, Player::Black), 13u); @@ -118,11 +118,11 @@ TEST(MoveChecker, ComputeConnectedLiberties_Borders) { { Board board(9u); - board.setAt({0u, 0u}, Board::Value::Black); - board.setAt({0u, 1u}, Board::Value::Black); - board.setAt({0u, 2u}, Board::Value::Black); + board.place({0u, 0u}, Board::Stone::Black); + board.place({0u, 1u}, Board::Stone::Black); + board.place({0u, 2u}, Board::Stone::Black); - board.setAt({1u, 1u}, Board::Value::Black); + board.place({1u, 1u}, Board::Stone::Black); // Check liberties for each stone to check that full chain is found. EXPECT_EQ(computeGroupLiberties(board, {0u, 0u}, Player::Black), 4u); @@ -134,15 +134,15 @@ TEST(MoveChecker, ComputeConnectedLiberties_Borders) { { Board board(9u); - board.setAt({0u, 0u}, Board::Value::Black); - board.setAt({0u, 1u}, Board::Value::Black); - board.setAt({0u, 2u}, Board::Value::Black); + board.place({0u, 0u}, Board::Stone::Black); + board.place({0u, 1u}, Board::Stone::Black); + board.place({0u, 2u}, Board::Stone::Black); - board.setAt({1u, 1u}, Board::Value::Black); + board.place({1u, 1u}, Board::Stone::Black); - board.setAt({2u, 0u}, Board::Value::Black); - board.setAt({2u, 1u}, Board::Value::Black); - board.setAt({2u, 2u}, Board::Value::Black); + board.place({2u, 0u}, Board::Stone::Black); + board.place({2u, 1u}, Board::Stone::Black); + board.place({2u, 2u}, Board::Stone::Black); // Check liberties for each stone to check that full chain is found. EXPECT_EQ(computeGroupLiberties(board, {0u, 0u}, Player::Black), 7u); @@ -158,16 +158,16 @@ TEST(MoveChecker, ComputeConnectedLiberties_Borders) { { Board board(9u); - board.setAt({0u, 0u}, Board::Value::Black); - board.setAt({0u, 1u}, Board::Value::Black); - board.setAt({0u, 2u}, Board::Value::Black); + board.place({0u, 0u}, Board::Stone::Black); + board.place({0u, 1u}, Board::Stone::Black); + board.place({0u, 2u}, Board::Stone::Black); - board.setAt({1u, 0u}, Board::Value::Black); - board.setAt({1u, 2u}, Board::Value::Black); + board.place({1u, 0u}, Board::Stone::Black); + board.place({1u, 2u}, Board::Stone::Black); - board.setAt({2u, 0u}, Board::Value::Black); - board.setAt({2u, 1u}, Board::Value::Black); - board.setAt({2u, 2u}, Board::Value::Black); + board.place({2u, 0u}, Board::Stone::Black); + board.place({2u, 1u}, Board::Stone::Black); + board.place({2u, 2u}, Board::Stone::Black); // Check liberties for each stone to check that full chain is found. EXPECT_EQ(computeGroupLiberties(board, {0u, 0u}, Player::Black), 7u); @@ -184,18 +184,18 @@ TEST(MoveChecker, ComputeConnectedLiberties_Borders) { { Board board(9u); - board.setAt({0u, 0u}, Board::Value::Black); - board.setAt({1u, 0u}, Board::Value::Black); - board.setAt({2u, 0u}, Board::Value::Black); - board.setAt({3u, 0u}, Board::Value::Black); + board.place({0u, 0u}, Board::Stone::Black); + board.place({1u, 0u}, Board::Stone::Black); + board.place({2u, 0u}, Board::Stone::Black); + board.place({3u, 0u}, Board::Stone::Black); - board.setAt({0u, 1u}, Board::Value::Black); - board.setAt({3u, 1u}, Board::Value::Black); + board.place({0u, 1u}, Board::Stone::Black); + board.place({3u, 1u}, Board::Stone::Black); - board.setAt({0u, 2u}, Board::Value::Black); - board.setAt({1u, 2u}, Board::Value::Black); - board.setAt({2u, 2u}, Board::Value::Black); - board.setAt({3u, 2u}, Board::Value::Black); + board.place({0u, 2u}, Board::Stone::Black); + board.place({1u, 2u}, Board::Stone::Black); + board.place({2u, 2u}, Board::Stone::Black); + board.place({3u, 2u}, Board::Stone::Black); EXPECT_EQ(computeGroupLiberties(board, {0u, 0u}, Player::Black), 9u); EXPECT_EQ(computeGroupLiberties(board, {1u, 0u}, Player::Black), 9u); @@ -220,9 +220,9 @@ TEST(MoveChecker, Suicide) { { Board board(9u); - board.setAt({0u, 1u}, Board::Value::Black); - board.setAt({1u, 0u}, Board::Value::Black); - board.setAt({1u, 2u}, Board::Value::Black); + board.place({0u, 1u}, Board::Stone::Black); + board.place({1u, 0u}, Board::Stone::Black); + board.place({1u, 2u}, Board::Stone::Black); // Legal move EXPECT_TRUE(isValidMove(board, Player::Black, {1u, 1u})); @@ -232,10 +232,10 @@ TEST(MoveChecker, Suicide) { { Board board(9u); - board.setAt({0u, 1u}, Board::Value::Black); - board.setAt({1u, 0u}, Board::Value::Black); - board.setAt({1u, 2u}, Board::Value::Black); - board.setAt({2u, 1u}, Board::Value::Black); + board.place({0u, 1u}, Board::Stone::Black); + board.place({1u, 0u}, Board::Stone::Black); + board.place({1u, 2u}, Board::Stone::Black); + board.place({2u, 1u}, Board::Stone::Black); // Suicide -> invalid move EXPECT_FALSE(isValidMove(board, Player::White, {1u, 1u})); @@ -244,24 +244,24 @@ TEST(MoveChecker, Suicide) { { Board board(9u); - board.setAt({0u, 1u}, Board::Value::Black); - board.setAt({0u, 2u}, Board::Value::Black); - board.setAt({0u, 3u}, Board::Value::Black); + board.place({0u, 1u}, Board::Stone::Black); + board.place({0u, 2u}, Board::Stone::Black); + board.place({0u, 3u}, Board::Stone::Black); - board.setAt({1u, 0u}, Board::Value::Black); - board.setAt({1u, 1u}, Board::Value::White); - board.setAt({1u, 2u}, Board::Value::White); - board.setAt({1u, 3u}, Board::Value::Black); + board.place({1u, 0u}, Board::Stone::Black); + board.place({1u, 1u}, Board::Stone::White); + board.place({1u, 2u}, Board::Stone::White); + board.place({1u, 3u}, Board::Stone::Black); - board.setAt({2u, 0u}, Board::Value::Black); - board.setAt({2u, 1u}, Board::Value::White); - board.setAt({2u, 2u}, Board::Value::Black); - board.setAt({2u, 3u}, Board::Value::Black); + board.place({2u, 0u}, Board::Stone::Black); + board.place({2u, 1u}, Board::Stone::White); + board.place({2u, 2u}, Board::Stone::Black); + board.place({2u, 3u}, Board::Stone::Black); - board.setAt({3u, 0u}, Board::Value::Black); - board.setAt({3u, 2u}, Board::Value::Black); + board.place({3u, 0u}, Board::Stone::Black); + board.place({3u, 2u}, Board::Stone::Black); - board.setAt({4u, 1u}, Board::Value::Black); + board.place({4u, 1u}, Board::Stone::Black); // Suicide -> invalid move EXPECT_FALSE(isValidMove(board, Player::White, {3u, 1u})); @@ -269,9 +269,9 @@ TEST(MoveChecker, Suicide) { // Now add white stones which would allow the same move to be a capture // Surround the rightmost black stone. - board.setAt({4u, 0u}, Board::Value::White); - board.setAt({4u, 2u}, Board::Value::White); - board.setAt({5u, 1u}, Board::Value::White); + board.place({4u, 0u}, Board::Stone::White); + board.place({4u, 2u}, Board::Stone::White); + board.place({5u, 1u}, Board::Stone::White); // Now we capture -> Move valid EXPECT_TRUE(isValidMove(board, Player::White, {3u, 1u})); @@ -281,16 +281,16 @@ TEST(MoveChecker, Suicide) { { Board board(9u); - board.setAt({0u, 1u}, Board::Value::Black); + board.place({0u, 1u}, Board::Stone::Black); - board.setAt({1u, 0u}, Board::Value::Black); - board.setAt({1u, 2u}, Board::Value::Black); + board.place({1u, 0u}, Board::Stone::Black); + board.place({1u, 2u}, Board::Stone::Black); - board.setAt({2u, 0u}, Board::Value::White); - board.setAt({2u, 1u}, Board::Value::Black); - board.setAt({2u, 2u}, Board::Value::White); + board.place({2u, 0u}, Board::Stone::White); + board.place({2u, 1u}, Board::Stone::Black); + board.place({2u, 2u}, Board::Stone::White); - board.setAt({3u, 1u}, Board::Value::White); + board.place({3u, 1u}, Board::Stone::White); // Captures -> valid move EXPECT_TRUE(isValidMove(board, Player::White, {1u, 1u})); @@ -302,19 +302,19 @@ TEST(MoveChecker, Kill) { { Board board(9u); - board.setAt({0u, 0u}, Board::Value::White); - board.setAt({0u, 1u}, Board::Value::Black); - board.setAt({0u, 2u}, Board::Value::White); + board.place({0u, 0u}, Board::Stone::White); + board.place({0u, 1u}, Board::Stone::Black); + board.place({0u, 2u}, Board::Stone::White); - board.setAt({1u, 0u}, Board::Value::Black); - board.setAt({1u, 2u}, Board::Value::Black); - board.setAt({1u, 3u}, Board::Value::White); + board.place({1u, 0u}, Board::Stone::Black); + board.place({1u, 2u}, Board::Stone::Black); + board.place({1u, 3u}, Board::Stone::White); - board.setAt({2u, 0u}, Board::Value::White); - board.setAt({2u, 1u}, Board::Value::Black); - board.setAt({2u, 2u}, Board::Value::White); + board.place({2u, 0u}, Board::Stone::White); + board.place({2u, 1u}, Board::Stone::Black); + board.place({2u, 2u}, Board::Stone::White); - board.setAt({3u, 1u}, Board::Value::White); + board.place({3u, 1u}, Board::Stone::White); EXPECT_TRUE(isValidMove(board, Player::White, {1u, 1u})); } @@ -336,11 +336,11 @@ TEST(MoveChecker, Kill) { // TEST(MoveChecker, SuperkoAllowsNewHashes) { // Board board(9u); -// board.setAt({0u, 1u}, Board::Value::White); -// board.setAt({1u, 0u}, Board::Value::White); -// board.setAt({1u, 2u}, Board::Value::White); +// board.place({0u, 1u}, Board::Stone::White); +// board.place({1u, 0u}, Board::Stone::White); +// board.place({1u, 2u}, Board::Stone::White); -// board.setAt({2u, 1u}, Board::Value::Black); +// board.place({2u, 1u}, Board::Stone::Black); // Position pos{9u}; // pos.board = board; @@ -352,8 +352,8 @@ TEST(MoveChecker, Kill) { // for (Id y = 0; y < board.size(); ++y) { // const Coord c{x, y}; // const auto v = board.getAt(c); -// if (v != Board::Value::Empty) -// h ^= hasher.stone(c, v == Board::Value::White ? Player::White : Player::Black); +// if (v != Board::Stone::Empty) +// h ^= hasher.stone(c, v == Board::Stone::White ? Player::White : Player::Black); // } // h ^= hasher.togglePlayer(); // White to move // pos.hash = h; diff --git a/tests/gameNet/nwEvents.gtest.cpp b/tests/gameNet/nwEvents.gtest.cpp index f4a322a..b4ddc0d 100644 --- a/tests/gameNet/nwEvents.gtest.cpp +++ b/tests/gameNet/nwEvents.gtest.cpp @@ -58,8 +58,8 @@ TEST(GameNetMessages, ServerToMessage) { .turn = 42u, .seat = gameNet::Seat::Black, .action = gameNet::ServerAction::Place, - .coord = gameNet::Coord{3u, 4u}, - .captures = {gameNet::Coord{1u, 2u}, gameNet::Coord{5u, 6u}}, + .coord = Coord{3u, 4u}, + .captures = {Coord{1u, 2u}, Coord{5u, 6u}}, .next = gameNet::Seat::White, .status = gameNet::GameStatus::Active, })), diff --git a/tests/network/CMakeLists.txt b/tests/network/CMakeLists.txt index 5955b00..b4a58f4 100644 --- a/tests/network/CMakeLists.txt +++ b/tests/network/CMakeLists.txt @@ -7,7 +7,7 @@ add_executable(${targetName} ) # Link to required libraries -target_link_libraries(${targetName} PUBLIC go::network go::gameNet GTest::gtest_main) +target_link_libraries(${targetName} PRIVATE go::network go::gameNet GTest::gtest_main) set_target_properties(${targetName} PROPERTIES FOLDER "${ideFolderSource}") # Setup project settings diff --git a/tests/network/server.gtest.cpp b/tests/network/server.gtest.cpp index 5c833d0..e52498d 100644 --- a/tests/network/server.gtest.cpp +++ b/tests/network/server.gtest.cpp @@ -82,7 +82,7 @@ class TestServerHandler final : public gameNet::IServerHandler { .turn = moveId, .seat = seat, .action = gameNet::ServerAction::Place, - .coord = gameNet::Coord{event.c.x, event.c.y}, + .coord = event.c, .captures = {}, .next = next, .status = gameNet::GameStatus::Active,