| @@ -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) | |||
| @@ -11,7 +11,7 @@ class Setting: | |||
| # 为假则play()期间确保游戏状态不更新,为真则只保证游戏状态在调用相关方法时不更新 | |||
| @staticmethod | |||
| def asynchronous() -> bool: | |||
| return True | |||
| return False | |||
| # 选手需要依次将player0到player4的职业都定义 | |||
| @staticmethod | |||
| @@ -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: | |||
| @@ -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] | |||
| @@ -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 | |||
| @@ -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 | |||
| @@ -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,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 | |||
| @@ -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. | |||
| @@ -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; | |||
| @@ -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: | |||