diff --git a/processor/logic/GameBoard.cpp b/processor/logic/GameBoard.cpp new file mode 100644 index 0000000..c242a63 --- /dev/null +++ b/processor/logic/GameBoard.cpp @@ -0,0 +1,83 @@ +#include "GameBoard.h" +#include + +GameBoard::GameBoard(std::uint8_t n, std::uint8_t t, pos_t w, pos_t h + , const std::vector &player_team) + : n(n), t(t), w(w), h(h), players(n + 1) +{ + for (std::uint8_t i = 1; i <= n; ++i) { + players[i].id = i; + players[i].team = player_team[i]; + } +} + +Tile& GameBoard::at(pos_t x, pos_t y) { + return board[x * w + y]; +} + +const Tile& GameBoard::at(pos_t x, pos_t y) const { + return board[x * w + y]; +} + +bool GameBoard::attack(const PlayerMove &o) { + if (!o.isValid(w, h)) + return false; + + auto &sc_tile = at(o.x, o.y); + auto &tt_tile = at(o.tx(), o.ty()); + if (sc_tile.owner != o.player) + return false; + + if (sc_tile.unit <= 1) + return false; + + auto moving_unit = o.half ? sc_tile.unit : sc_tile.unit / 2; + sc_tile.unit -= moving_unit; + auto isfriend = isTeammate(o.player, tt_tile.owner); + auto delta = isfriend ? moving_unit + tt_tile.unit : moving_unit - tt_tile.unit; + + updatedPosition(o.x, o.y); + updatedPosition(o.ty(), o.ty()); + + tt_tile.unit = std::abs(delta); + if (delta > 0 && (!isfriend || tt_tile.type != TileType::Capital)) { + if (!isfriend && tt_tile.type == TileType::Capital) + capitalCaptured(tt_tile.owner, o.player); + tt_tile.owner = o.player; + } + return true; +} + +void GameBoard::capitalCaptured(Player tt, Player sc) { + for (pos_t x = 0; x < h; ++x) { + for (pos_t y = 0; y < w; ++y) { + auto &tile = at(x, y); + if (tile.owner != tt || tile.type == TileType::Capital) + continue; + + tile.owner = sc; + tile.unit = std::max(tile.unit / 2, 1); + } + } +} + +bool GameBoard::isTeammate(Player x, Player y) const { + // TODO +} + +PlayerState::PlayerState() { + is_defeated = false; +} + +void GameBoard::turnUpdate() { + // TODO +} + +void GameBoard::roundUpdate() { + // TODO +} + +void GameBoard::updatedPosition(pos_t x, pos_t y) { + updated_tiles.emplace(x, y); +} + diff --git a/processor/logic/GameBoard.h b/processor/logic/GameBoard.h new file mode 100644 index 0000000..cc8a853 --- /dev/null +++ b/processor/logic/GameBoard.h @@ -0,0 +1,48 @@ +#ifndef OGLG_GAMEBOARD_H_ +#define OGLG_GAMEBOARD_H_ + +#include +#include +#include +#include +#include "PlayerMove.h" +#include "pc/pctypes.h" +#include "pc/commcode.h" +#include "pc/astuple.h" + +struct PlayerState { + Player id; + Team team; + bool is_defeated; + std::deque tasks; + + PlayerState(); +}; + +class GameBoard { +public: + GameBoard(std::uint8_t n, std::uint8_t t, pos_t w, pos_t h, const std::vector &player_team); + + const Tile& at(pos_t x, pos_t y) const; + Tile& at(pos_t x, pos_t y); + + bool attack(const PlayerMove &o); + void turnUpdate(); + void roundUpdate(); + bool isTeammate(Player x, Player y) const; + +private: + void capitalCaptured(Player target, Player source); + void updatedPosition(pos_t x, pos_t y); + + std::uint8_t n, t; + std::vector players; + + pos_t w, h; + std::vector board; + std::set updated_tiles; + std::vector defeated_players; +}; + +#endif + diff --git a/processor/logic/PlayerMove.cpp b/processor/logic/PlayerMove.cpp new file mode 100644 index 0000000..551de55 --- /dev/null +++ b/processor/logic/PlayerMove.cpp @@ -0,0 +1,26 @@ +#include +#include "PlayerMove.h" +#include "pc/commcode.h" + +bool PlayerMove::isValid(pos_t w, pos_t h) const { + if (x < 0 || x >= h || y < 0 || y >= w) + return false; + + if ((int)dir >= 4) + return false; + + auto xx = tx(), yy = ty(); + if (xx < 0 || xx >= h || yy < 0 || yy >= w) + return false; + + return true; +} + +pos_t PlayerMove::tx() const { + return x + direction_dx[(std::size_t)dir]; +} + +pos_t PlayerMove::ty() const { + return y + direction_dy[(std::size_t)dir]; +} + diff --git a/processor/logic/PlayerMove.h b/processor/logic/PlayerMove.h new file mode 100644 index 0000000..f9ca009 --- /dev/null +++ b/processor/logic/PlayerMove.h @@ -0,0 +1,22 @@ +#ifndef OGLG_PLAYERMOVE_H_ +#define OGLG_PLAYERMOVE_H_ + +#include "pc/astuple.h" +#include "pc/commcode.h" +#include "pc/pctypes.h" + +struct PlayerMove { + Player player; + pos_t x, y; + Direction dir; + bool half; + + bool isValid(pos_t w, pos_t h) const; + pos_t tx() const; + pos_t ty() const; + + OGPC_DECLARE_ASTUPLE(player, x, y, dir, half) +}; + +#endif + diff --git a/processor/pc/Point.cpp b/processor/pc/Point.cpp new file mode 100644 index 0000000..cf70739 --- /dev/null +++ b/processor/pc/Point.cpp @@ -0,0 +1,10 @@ +#include "Point.h" + +Point::Point() : x(0), y(0) {} + +Point::Point(pos_t x, pos_t y) : x(x), y(y) {} + +bool Point::operator<(const Point &o) const { + return x == o.x ? y < o.y : x < o.x; +} + diff --git a/processor/pc/Point.h b/processor/pc/Point.h new file mode 100644 index 0000000..5c33d69 --- /dev/null +++ b/processor/pc/Point.h @@ -0,0 +1,18 @@ +#ifndef OGPC_POINT_H_ +#define OGPC_POINT_H_ + +#include "basictypes.h" +#include "astuple.h" + +struct Point { + pos_t x, y; + Point(pos_t x, pos_t y); + Point(); + + bool operator<(const Point &o) const; + + OGPC_DECLARE_ASTUPLE(x, y); +}; + +#endif + diff --git a/processor/pc/ProcedureType.h b/processor/pc/ProcedureType.h new file mode 100644 index 0000000..39dc031 --- /dev/null +++ b/processor/pc/ProcedureType.h @@ -0,0 +1,22 @@ +#ifndef OGPC_PROCEDURETYPE_H_ +#define OGPC_PROCEDURETYPE_H_ + +enum class ProcedureType : std::int32_t { + setSeed = 0, + setLogLevel = 1, + getError = 2, + getErrorInfo = 3, + importTerrain = 10, + randomTerrain = 11, + appendOrderQueue = 20, + clearOrderQueue = 21, + popOrderQueue = 22, + setOffline = 23, + init = 30, + tick = 31, + getKeyFrame = 40, + saveReplay = 50, +}; + +#endif + diff --git a/processor/pc/basictypes.h b/processor/pc/basictypes.h new file mode 100644 index 0000000..d7cbcd9 --- /dev/null +++ b/processor/pc/basictypes.h @@ -0,0 +1,13 @@ +#ifndef OGPC_BASICTYPES_H_ +#define OGPC_BASICTYPES_H_ + +#include +#include + +using Player = std::uint8_t; +using Team = std::uint8_t; +using pos_t = std::uint8_t; +using Void = std::tuple<>; +const Player neutral_player = 0; + +#endif diff --git a/processor/pc/commcode.h b/processor/pc/commcode.h new file mode 100644 index 0000000..1d65173 --- /dev/null +++ b/processor/pc/commcode.h @@ -0,0 +1,48 @@ +#ifndef OGPC_COMMCODE_H_ +#define OGPC_COMMCODE_H_ + +#include + +enum class Direction : std::uint8_t { + N = 0x00, + S = 0x01, + W = 0x02, + E = 0x03, +}; + +constexpr int direction_dx[] = {-1, 1, 0, 0}; +constexpr int direction_dy[] = {0, 0, -1, 1}; + +enum class LogLevel : std::uint8_t { + Debug = 0x00, + Info = 0x01, + Warn = 0x02, + Error = 0x03, + Fatal = 0x04, +}; + +enum class TileType : std::uint8_t { + Misty = 0x00, + Mountain = 0x01, + Stronghold = 0x02, + Blank = 0x03, + Capital = 0x04, + Swamp = 0x05, +}; + +enum class MistyTileType : std::uint8_t { + MountainLike = 0x01, + BlankLike = 0x02, + Swamp = 0x03, +}; + +enum class ModifierType : std::uint8_t { + Leapfrog = 0x01, + CityState = 0x02, + MistyVeil = 0x03, + CrystalClear = 0x04, + SilentWar = 0x05, +}; + +#endif + diff --git a/processor/pc/pctypes.h b/processor/pc/pctypes.h index b1cf3f6..8a961ce 100644 --- a/processor/pc/pctypes.h +++ b/processor/pc/pctypes.h @@ -4,10 +4,10 @@ #include #include #include +#include "basictypes.h" #include "astuple.h" - -using Player = std::uint8_t; -using Team = std::uint8_t; +#include "commcode.h" +#include "Point.h" struct uuid { std::uint64_t low, high; @@ -16,27 +16,19 @@ struct uuid { }; struct ImportTerrainConfig { - std::uint8_t w, h; + pos_t w, h; std::string value; OGPC_DECLARE_ASTUPLE(w, h, value) }; struct RandomTerrainConfig { - std::uint8_t w, h; + pos_t w, h; std::uint8_t city_dense, mountain_dense, swamp_dense, light_dense; OGPC_DECLARE_ASTUPLE(w, h, city_dense, mountain_dense, swamp_dense, light_dense) }; -struct PlayerMove { - Player player; - std::uint8_t x, y, dir; - bool half; - - OGPC_DECLARE_ASTUPLE(player, x, y, dir, half) -}; - struct PlayerRanking { Player player; bool is_defeated; @@ -55,15 +47,14 @@ struct TeamRanking { struct Tile { Player owner; - std::uint8_t type; + TileType type; std::int32_t unit; OGPC_DECLARE_ASTUPLE(owner, type, unit) }; struct TileDiff { - std::uint8_t x; - std::uint8_t y; + pos_t x, y; Tile value; OGPC_DECLARE_ASTUPLE(x, y, value) @@ -88,12 +79,14 @@ struct GameState { }; struct Modifier { - std::uint32_t key; + ModifierType key; std::int32_t value; OGPC_DECLARE_ASTUPLE(key, value) }; +struct PlayerMove; + struct ReplayStep { std::uint32_t halfturn_id; std::vector player_moves; @@ -104,7 +97,7 @@ struct ReplayStep { struct PlayerInfo { uuid uid; - std::uint8_t id; + Player id; std::string name; OGPC_DECLARE_ASTUPLE(uid, id, name) diff --git a/processor/xmake.lua b/processor/xmake.lua index 43918c9..26e3d41 100644 --- a/processor/xmake.lua +++ b/processor/xmake.lua @@ -6,7 +6,7 @@ set_targetdir("build") add_includedirs(".", "pc", "utility") -add_files("pc/*.cpp", "utility/*.cpp") +add_files("pc/*.cpp", "utility/*.cpp", "logic/*.cpp") target("main") set_default(true) set_kind("binary")