add GameBoard

Signed-off-by: szdytom <szdytom@qq.com>
This commit is contained in:
方而静 2024-02-04 21:00:53 +08:00
parent 104452c2d3
commit a3d235b10b
Signed by: szTom
GPG Key ID: 072D999D60C6473C
11 changed files with 302 additions and 19 deletions

View File

@ -0,0 +1,83 @@
#include "GameBoard.h"
#include <algorithm>
GameBoard::GameBoard(std::uint8_t n, std::uint8_t t, pos_t w, pos_t h
, const std::vector<Team> &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);
}

View File

@ -0,0 +1,48 @@
#ifndef OGLG_GAMEBOARD_H_
#define OGLG_GAMEBOARD_H_
#include <vector>
#include <cstdint>
#include <deque>
#include <set>
#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<PlayerMove> tasks;
PlayerState();
};
class GameBoard {
public:
GameBoard(std::uint8_t n, std::uint8_t t, pos_t w, pos_t h, const std::vector<Team> &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<PlayerState> players;
pos_t w, h;
std::vector<Tile> board;
std::set<Point> updated_tiles;
std::vector<Player> defeated_players;
};
#endif

View File

@ -0,0 +1,26 @@
#include <cstdint>
#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];
}

View File

@ -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

10
processor/pc/Point.cpp Normal file
View File

@ -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;
}

18
processor/pc/Point.h Normal file
View File

@ -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

View File

@ -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

13
processor/pc/basictypes.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef OGPC_BASICTYPES_H_
#define OGPC_BASICTYPES_H_
#include <cstdint>
#include <tuple>
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

48
processor/pc/commcode.h Normal file
View File

@ -0,0 +1,48 @@
#ifndef OGPC_COMMCODE_H_
#define OGPC_COMMCODE_H_
#include <cstdint>
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

View File

@ -4,10 +4,10 @@
#include <cstdint>
#include <string>
#include <vector>
#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<PlayerMove> 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)

View File

@ -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")