Browse Source

Merge branch 'eesast:dev' into new

tags/0.1.0
shangfengh GitHub 2 years ago
parent
commit
06ecc7d1a9
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 128 additions and 116 deletions
  1. +2
    -4
      CAPI/cpp/API/src/logic.cpp
  2. +1
    -1
      CAPI/python/PyAPI/AI.py
  3. +1
    -7
      CAPI/python/PyAPI/Communication.py
  4. +21
    -9
      CAPI/python/PyAPI/State.py
  5. +71
    -61
      CAPI/python/PyAPI/structures.py
  6. +0
    -6
      CAPI/python/PyAPI/utils.py
  7. +5
    -5
      CAPI/python/run.sh
  8. +1
    -1
      dependency/Dockerfile/Dockerfile_base
  9. +10
    -6
      dependency/shell/compile.sh
  10. +6
    -6
      docs/CAPI接口(cpp).md
  11. +10
    -10
      docs/CAPI接口(python).md

+ 2
- 4
CAPI/cpp/API/src/logic.cpp View File

@@ -564,7 +564,7 @@ void Logic::LoadBufferCase(const protobuf::MessageOfObj& item)
}
case THUAI6::MessageOfObj::GateMessage:
{
if (!AssistFunction::HaveView(viewRange, x, y, item.gate_message().x(), item.gate_message().y(), bufferState->gameMap))
if (AssistFunction::HaveView(viewRange, x, y, item.gate_message().x(), item.gate_message().y(), bufferState->gameMap))
{
auto pos = std::make_pair(AssistFunction::GridToCell(item.gate_message().x()), AssistFunction::GridToCell(item.gate_message().y()));
if (bufferState->mapInfo->gateState.count(pos) == 0)
@@ -695,9 +695,7 @@ void Logic::Main(CreateAIFunc createAI, std::string IP, std::string port, bool f
fileLogger->set_pattern(pattern);
printLogger->set_pattern(pattern);
if (file)
{
fileLogger->set_level(spdlog::level::trace);
}
fileLogger->set_level(spdlog::level::debug);
else
fileLogger->set_level(spdlog::level::off);
if (print)


+ 1
- 1
CAPI/python/PyAPI/AI.py View File

@@ -11,7 +11,7 @@ class Setting:
# 为假则play()期间确保游戏状态不更新,为真则只保证游戏状态在调用相关方法时不更新
@staticmethod
def asynchronous() -> bool:
return True
return False

# 选手需要依次将player0到player4的职业都定义
@staticmethod


+ 1
- 7
CAPI/python/PyAPI/Communication.py View File

@@ -16,19 +16,13 @@ class BoolErrorHandler(IErrorHandler):


class Communication:

__THUAI6Stub: Services.AvailableServiceStub
__haveNewMessage: bool
__message2Client: Message2Clients.MessageToClient
__mtxMessage: threading.Lock
__cvMessage: threading.Condition

def __init__(self, sIP: str, sPort: str):
aim = sIP + ':' + sPort
channel = grpc.insecure_channel(aim)
self.__THUAI6Stub = Services.AvailableServiceStub(channel)
self.__haveNewMessage = False
self.__cvMessage = threading.Condition()
self.__message2Client: Message2Clients.MessageToClient

def Move(self, time: int, angle: float, playerID: int) -> bool:
try:


+ 21
- 9
CAPI/python/PyAPI/State.py View File

@@ -3,21 +3,33 @@ import PyAPI.structures as THUAI6


class State:
def __init__(self, **kwargs) -> None:
self.teamScore = 0
self.self = THUAI6.Student()
self.students = []
self.trickers = []
self.props = []
self.gameMap = []
self.bullets = []
self.bombedBullets = []
self.mapInfo = THUAI6.GameMap()
self.gameInfo = THUAI6.GameInfo()
self.guids = []
teamScore: int
self: Union[THUAI6.Student, THUAI6.Tricker]

students: List[THUAI6.Student] = []
trickers: List[THUAI6.Tricker] = []
students: List[THUAI6.Student]
trickers: List[THUAI6.Tricker]

props: List[THUAI6.Prop] = []
props: List[THUAI6.Prop]

gameMap: List[List[THUAI6.PlaceType]] = []
gameMap: List[List[THUAI6.PlaceType]]

bullets: List[THUAI6.Bullet] = []
bombedBullets: List[THUAI6.BombedBullet] = []
bullets: List[THUAI6.Bullet]
bombedBullets: List[THUAI6.BombedBullet]

mapInfo: THUAI6.GameMap = THUAI6.GameMap()
mapInfo: THUAI6.GameMap

gameInfo: THUAI6.GameInfo = THUAI6.GameInfo()
gameInfo: THUAI6.GameInfo

guids: List[int] = []
guids: List[int]

+ 71
- 61
CAPI/python/PyAPI/structures.py View File

@@ -143,85 +143,95 @@ class HiddenGateState(Enum):


class Player:
x: int
y: int
speed: int
viewRange: int
playerID: int
guid: int
radius: int
score: int
facingDirection: float
timeUntilSkillAvailable: List[float] = []
playerType: PlayerType
prop: List[PropType] = []
place: PlaceType
bulletType: BulletType
playerState: PlayerState
def __init__(self, **kwargs) -> None:
self.x: int = 0
self.y: int = 0
self.speed: int = 0
self.viewRange: int = 0
self.playerID: int = 0
self.guid: int = 0
self.radius: int = 0
self.score: int = 0
self.facingDirection: float = 0.0
self.timeUntilSkillAvailable: List[float] = []
self.playerType: PlayerType = PlayerType.NullPlayerType
self.prop: List[PropType] = []
self.place: PlaceType = PlaceType.NullPlaceType
self.bulletType: BulletType = BulletType.NullBulletType
self.playerState: PlayerState = PlayerState.NullState


class Student(Player):
studentType: StudentType
determination: int
addiction: int
encourageProgress: int
rouseProgress: int
learningSpeed: int
encourageSpeed: int
dangerAlert: float
buff: List[StudentBuffType] = []
def __init__(self, **kwargs) -> None:
super().__init__()
self.studentType: StudentType = StudentType.NullStudentType
self.determination: int = 0
self.addiction: int = 0
self.encourageProgress: int = 0
self.rouseProgress: int = 0
self.learningSpeed: int = 0
self.encourageSpeed: int = 0
self.dangerAlert: float = 0.0
self.buff: List[StudentBuffType] = []


class Tricker(Player):
trickerType: TrickerType
trickDesire: float
classVolume: float
buff: List[TrickerBuffType] = []
def __init__(self, **kwargs) -> None:
super().__init__()
self.trickerType: TrickerType = TrickerType.NullTrickerType
self.trickDesire: float = 0.0
self.classVolume: float = 0.0
self.buff: List[TrickerBuffType] = []


class Prop:
x: int
y: int
guid: int
type: PropType
place: PlaceType
facingDirection: float
def __init__(self, **kwargs) -> None:
self.x: int = 0
self.y: int = 0
self.guid: int = 0
self.type: PropType = PropType.NullPropType
self.place: PlaceType = PlaceType.NullPlaceType
self.facingDirection: float = 0.0


class Bullet:
bulletType: BulletType
x: int
y: int
facingDirection: float
guid: int
team: PlayerType
place: PlaceType
bombRange: float
speed: int
def __init__(self, **kwargs) -> None:
self.bulletType: BulletType = BulletType.NullBulletType
self.x: int = 0
self.y: int = 0
self.facingDirection: float = 0.0
self.guid: int = 0
self.team: PlayerType = PlayerType.NullPlayerType
self.place: PlaceType = PlaceType.NullPlaceType
self.bombRange: float = 0.0
self.speed: int = 0


class BombedBullet:
bulletType: BulletType
x: int
y: int
facingDirection: float
mappingID: int
bombRange: float
def __init__(self, **kwargs) -> None:
self.bulletType: BulletType = BulletType.NullBulletType
self.x: int = 0
self.y: int = 0
self.facingDirection: float = 0.0
self.mappingID: int = 0
self.bombRange: float = 0.0


class GameMap:
classroomState: Dict[Tuple[int, int], int] = {}
gateState: Dict[Tuple[int, int], int] = {}
chestState: Dict[Tuple[int, int], int] = {}
doorState: Dict[Tuple[int, int], bool] = {}
doorProgress: Dict[Tuple[int, int], int] = {}
hiddenGateState: Dict[Tuple[int, int], HiddenGateState] = {}
def __init__(self, **kwargs) -> None:
self.classroomState: Dict[Tuple[int, int], int] = {}
self.gateState: Dict[Tuple[int, int], int] = {}
self.chestState: Dict[Tuple[int, int], int] = {}
self.doorState: Dict[Tuple[int, int], bool] = {}
self.doorProgress: Dict[Tuple[int, int], int] = {}
self.hiddenGateState: Dict[Tuple[int, int], HiddenGateState] = {}


class GameInfo:
gameTime: int
subjectFinished: int
studentGraduated: int
studentQuited: int
studentScore: int
trickerScore: int
def __init__(self, **kwargs) -> None:
self.gameTime: int = 0
self.subjectFinished: int = 0
self.studentGraduated: int = 0
self.studentQuited: int = 0
self.studentScore: int = 0
self.trickerScore: int = 0

+ 0
- 6
CAPI/python/PyAPI/utils.py View File

@@ -177,12 +177,10 @@ class Proto2THUAI6(NoInstance):
tricker.trickDesire = trickerMsg.trick_desire
tricker.classVolume = trickerMsg.class_volume
tricker.bulletType = Proto2THUAI6.bulletTypeDict[trickerMsg.bullet_type]
tricker.timeUntilSkillAvailable.clear()
for time in trickerMsg.time_until_skill_available:
tricker.timeUntilSkillAvailable.append(time)
tricker.place = Proto2THUAI6.placeTypeDict[trickerMsg.place]
tricker.playerState = Proto2THUAI6.playerStateDict[trickerMsg.player_state]
tricker.prop.clear()
for item in trickerMsg.prop:
tricker.prop.append(Proto2THUAI6.propTypeDict[item])
tricker.trickerType = Proto2THUAI6.trickerTypeDict[trickerMsg.tricker_type]
@@ -190,7 +188,6 @@ class Proto2THUAI6(NoInstance):
tricker.playerID = trickerMsg.player_id
tricker.viewRange = trickerMsg.view_range
tricker.radius = trickerMsg.radius
tricker.buff.clear()
for buff in trickerMsg.buff:
tricker.buff.append(Proto2THUAI6.trickerBuffTypeDict[buff])
tricker.playerType = THUAI6.PlayerType.TrickerPlayer
@@ -212,11 +209,9 @@ class Proto2THUAI6(NoInstance):
student.encourageProgress = studentMsg.treat_progress
student.rouseProgress = studentMsg.rescue_progress
student.dangerAlert = studentMsg.danger_alert
student.timeUntilSkillAvailable.clear()
for time in studentMsg.time_until_skill_available:
student.timeUntilSkillAvailable.append(time)
student.place = Proto2THUAI6.placeTypeDict[studentMsg.place]
student.prop.clear()
for item in studentMsg.prop:
student.prop.append(Proto2THUAI6.propTypeDict[item])
student.studentType = Proto2THUAI6.studentTypeDict[studentMsg.student_type]
@@ -225,7 +220,6 @@ class Proto2THUAI6(NoInstance):
student.playerID = studentMsg.player_id
student.viewRange = studentMsg.view_range
student.radius = studentMsg.radius
student.buff.clear()
for buff in studentMsg.buff:
student.buff.append(Proto2THUAI6.studentBuffTypeDict[buff])
student.playerType = THUAI6.PlayerType.StudentPlayer


+ 5
- 5
CAPI/python/run.sh View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash

python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 0 -d -o &
python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 1 -d &
python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 2 -d &
python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 3 -d &
# python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 4 -d &
python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 0 -d -o&
python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 1&
# python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 2&
# python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 3&
# python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 4&

+ 1
- 1
dependency/Dockerfile/Dockerfile_base View File

@@ -1,5 +1,5 @@
FROM python:3.9.16-bullseye
MAINTAINER eesast.com
MAINTAINER eesast
WORKDIR /usr/local
RUN apt-get update && apt-get install --no-install-recommends -y gcc g++ make wget ca-certificates cmake autoconf automake libtool curl unzip git
RUN git clone -b v1.46.3 --depth 1 --shallow-submodules https://gitee.com/mirrors/grpc.git && wget -P . https://cloud.tsinghua.edu.cn/f/1f2713efd9e44255abd6/?dl=1 && mv 'index.html?dl=1' third_party.tar.gz


+ 10
- 6
dependency/shell/compile.sh View File

@@ -3,15 +3,19 @@
i=1
flag=1
bind=/usr/local/mnt
while (( $i <= 4 ))
while (( $i <= 5 ))
do
mv -f $bind/player$i.cpp ./API/src/AI.cpp
cmake ./CMakeLists.txt && make >compile_log$i.txt 2>&1
mv ./capi $bind/capi$i # executable file
if [ $? -ne 0 ]; then
if [ -f "${bind}/player${i}.cpp" ]; then
cp -f $bind/player$i.cpp ./API/src/AI.cpp
cmake ./CMakeLists.txt && make >compile_log$i.txt 2>&1
mv ./capi $bind/capi$i # executable file
if [ $? -ne 0 ]; then
flag=0
fi
mv ./compile_log$i.txt $bind/compile_log$i.txt
elif [ ! -f "${bind}/player${i}.py" ]; then
flag=0
fi
mv ./compile_log$i.txt $bind/compile_log$i.txt
let "i++"
done
# HTML request to update status.


+ 6
- 6
docs/CAPI接口(cpp).md View File

@@ -13,9 +13,9 @@

#### 人物
- `std::future<bool> EndAllAction()`:可以使不处在不可行动状态中的玩家终止当前行动
- 在指令仍在进行时,重复发出同一类型的交互指令和移动指令是无效的,你需要先发出Stop指令终止进行的指令
- 在指令仍在进行时,重复发出同一类型的交互指令和移动指令是无效的,你需要先发出 Stop 指令终止进行的指令
- 实际上唤醒或勉励不同的人是有效的
- EndAllAction()及Move指令调用数总和一帧内不超过10次
- EndAllAction() Move 指令调用数总和一帧内不超过 10

#### 攻击
- `std::future<bool> Attack(double angleInRadian)`:`angleInRadian`为攻击方向
@@ -59,7 +59,7 @@

- `THUAI6::PlaceType GetPlaceType(int32_t cellX, int32_t cellY)` :返回某一位置场地种类信息。场地种类详见 structure.h 。
- `bool IsDoorOpen(int32_t cellX, int32_t cellY) const`:查询特定位置门是否开启,没有门也返回false
- 以下指令特定位置没有对应物品返回-1
- 以下指令,若查询物品当前在视野内,则返回最新进度;若物品当前不在视野内、但曾经出现在视野内,则返回最后一次看到时的进度;若物品从未出现在视野内,或查询位置没有对应的物品,则返回 -1。
- `int32_t GetChestProgress(int32_t cellX, int32_t cellY) const`:查询特定位置箱子开启进度
- `int32_t GetGateProgress(int32_t cellX, int32_t cellY) const`:查询特定位置校门开启进度
- `int32_t GetClassroomProgress(int32_t cellX, int32_t cellY) const`:查询特定位置教室作业完成进度
@@ -74,9 +74,9 @@
- `std::vector<std::vector<THUAI6::PlaceType>> GetFullMap() const`:返回整张地图的地形信息。可以写成类似`api.GetFullMap()[x][y]`,其中x为地图自上到下第几行,y为自左向右第几列,注意从0开始

### 辅助函数
`static inline int CellToGrid(int cell) noexcept`:将地图格数 cell 转换为绝对坐标grid。
`static inline int CellToGrid(int cell) noexcept`:将地图格数 cell 转换为绝对坐标 grid。

`static inline int GridToCell(int grid) noexcept`:将绝对坐标 grid 转换为地图格数cell。
`static inline int GridToCell(int grid) noexcept`:将绝对坐标 grid 转换为地图格数 cell。

下面为用于DEBUG的输出函数,选手仅在开启Debug模式的情况下可以使用
~~~c++
@@ -126,7 +126,7 @@
// 获取视野内可见的道具信息
[[nodiscard]] virtual std::vector<std::shared_ptr<const THUAI6::Prop>> GetProps() const = 0;

// 获取地图信息,视野外的地图统一为Land
// 获取地图信息
[[nodiscard]] virtual std::vector<std::vector<THUAI6::PlaceType>> GetFullMap() const = 0;
[[nodiscard]] virtual THUAI6::PlaceType GetPlaceType(int32_t cellX, int32_t cellY) const = 0;



+ 10
- 10
docs/CAPI接口(python).md View File

@@ -8,7 +8,7 @@

#### 移动

- `def Move(self, timeInMilliseconds: int, angle: float) -> Future[bool]`:移动,`timeInMilliseconds` 为移动时间,单位毫秒;`angleInRadian` 表示移动方向,单位弧度,使用极坐标,**竖直向下方向为x轴,水平向右方向为y轴**因为移动过程中你会受到多种干扰使得移动结果不符合你的预期;因此建议小步移动,边移动边考虑之后的行为。
- `def Move(self, timeInMilliseconds: int, angle: float) -> Future[bool]`:移动,`timeInMilliseconds` 为移动时间,单位毫秒;`angleInRadian` 表示移动方向,单位弧度,使用极坐标,**竖直向下方向为 x 轴,水平向右方向为 y 轴**因为移动过程中你会受到多种干扰使得移动结果不符合你的预期;因此建议小步移动,边移动边考虑之后的行为。
- `def MoveRight(self, timeInMilliseconds: int) -> Future[bool]`即向右移动,`MoveLeft`、`MoveDown`、`MoveUp`同理

#### 使用技能
@@ -18,9 +18,9 @@
#### 人物

- `def EndAllAction(self) -> Future[bool]`:可以使不处在不可行动状态中的玩家终止当前行动
- 在指令仍在进行时,重复发出同一类型的交互指令和移动指令是无效的,你需要先发出Stop指令终止进行的指令
- 在指令仍在进行时,重复发出同一类型的交互指令和移动指令是无效的,你需要先发出 Stop 指令终止进行的指令
- 实际上唤醒或勉励不同的人是有效的
- EndAllAction()及Move指令调用数总和一帧内不超过10次
- EndAllAction() Move 指令调用数总和一帧内不超过 10

#### 攻击

@@ -34,8 +34,8 @@

#### 勉励与唤醒

- `def StartEncourageMate(self, mateID: int) -> Future[bool]`:勉励对应玩家ID的学生。
- `def StartRouseMate(self, mateID: int) -> Future[bool]`:唤醒对应玩家ID的沉迷的学生。
- `def StartEncourageMate(self, mateID: int) -> Future[bool]`:勉励对应玩家 ID 的学生。
- `def StartRouseMate(self, mateID: int) -> Future[bool]`:唤醒对应玩家 ID 的沉迷的学生。

#### 地图互动

@@ -71,13 +71,13 @@

- `def GetPlaceType(self, cellX: int, cellY: int) -> THUAI6.PlaceType` :返回某一位置场地种类信息。场地种类详见 structure.h 。
- `def IsDoorOpen(self, cellX: int, cellY: int) -> bool`:查询特定位置门是否开启,没有门也返回false
- 以下指令特定位置没有对应物品返回-1
- 以下指令,若查询物品当前在视野内,则返回最新进度;若物品当前不在视野内、但曾经出现在视野内,则返回最后一次看到时的进度;若物品从未出现在视野内,或查询位置没有对应的物品,则返回 -1。
- `def GetChestProgress(self, cellX: int, cellY: int) -> int`:查询特定位置箱子开启进度
- `def GetGateProgress(self, cellX: int, cellY: int) -> int`:查询特定位置校门开启进度
- `def GetClassroomProgress(self, cellX: int, cellY: int) -> int`:查询特定位置教室作业完成进度
- `def GetDoorProgress(self, cellX: int, cellY: int) -> int`:查询特定位置门开启状态
- `def GetHiddenGateState(self, cellX: int, cellY: int) -> THUAI6.HiddenGateState`::查询特定位置隐藏校门状态,没有隐藏校门返回THUAI6::HiddenGateState::Null

#### 其他

@@ -89,11 +89,11 @@

### 辅助函数

`def CellToGrid(cell: int) -> int`:将地图格数 cell 转换为绝对坐标grid。
`def CellToGrid(cell: int) -> int`:将地图格数 cell 转换为绝对坐标 grid。

`def GridToCell(grid: int) -> int`:将绝对坐标 grid 转换为地图格数cell。
`def GridToCell(grid: int) -> int`:将绝对坐标 grid 转换为地图格数 cell。

下面为用于DEBUG的输出函数,选手仅在开启Debug模式的情况下可以使用
下面为用于DEBUG的输出函数,选手仅在开启 Debug 模式的情况下可以使用

~~~python
def Print(self, cont: str) -> None:


Loading…
Cancel
Save