Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bug in PyAPI and successfully test it with server #159

Merged
merged 12 commits into from
Mar 31, 2024
6 changes: 3 additions & 3 deletions CAPI/cpp/API/include/structures.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ namespace THUAI7

enum class PlayerTeam : unsigned char
{
NullTeam = 0,
Red = 1,
Blue = 2,
Red = 0,
Blue = 1,
NullTeam = 2,
};

enum class PlayerType : unsigned char
Expand Down
2 changes: 2 additions & 0 deletions CAPI/cpp/API/src/logic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ Logic::Logic(int64_t pID, int64_t tID, THUAI7::PlayerType pType, THUAI7::Sweeper
playerTeam = THUAI7::PlayerTeam::Red;
if (teamID == 1)
playerTeam = THUAI7::PlayerTeam::Blue;
else
playerTeam = THUAI7::PlayerTeam::NullTeam;
}

std::vector<std::shared_ptr<const THUAI7::Sweeper>> Logic::GetSweepers() const
Expand Down
2 changes: 1 addition & 1 deletion CAPI/cpp/API/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ int THUAI7Main(int argc, char** argv, CreateAIFunc AIBuilder)
else
{
playerType = THUAI7::PlayerType::Sweeper;
SweeperType = SweeperTypeDict[pID];
SweeperType = SweeperTypeDict[pID - 1];
}
#ifdef _MSC_VER
std::cout
Expand Down
17 changes: 11 additions & 6 deletions CAPI/python/PyAPI/AI.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,23 @@ def __init__(self, pID: int):

def SweeperPlay(self, api: ISweeperAPI) -> None:
# 公共操作

if self.__playerID == 0:
# player0的操作
return
elif self.__playerID == 1:
if self.__playerID == 1:
api.PrintSelfInfo()
time.sleep(1)
# player1的操作
return
elif self.__playerID == 2:
# player2的操作
return
return
elif self.__playerID == 3:
# player3的操作
return
elif self.__playerID == 4:
# player4的操作
return
returnF

def TeamPlay(self, api: ITeamAPI) -> None:
assert self.__playerID == 0, "Team's playerID must be 0"
# 操作
return
7 changes: 5 additions & 2 deletions CAPI/python/PyAPI/API.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,8 @@ def GetConstructionHp(self, cellX: int, cellY: int) -> int:
def GetBridgeHp(self, cellX: int, cellY: int) -> int:
return self.__logic.GetBridgeHp(cellX, cellY)

def GetResouceState(self, cellX: int, cellY: int) -> int:
return self.__logic.GetResouceState(cellX, cellY)
def GetGarbageState(self, cellX: int, cellY: int) -> int:
return self.__logic.GetGarbageState(cellX, cellY)

def GetHomeHp(self) -> int:
return self.__logic.GetHomeHp()
Expand Down Expand Up @@ -226,5 +226,8 @@ def Print(self, string: str) -> None:
def PrintTeam(self) -> None:
pass

def PrintSweeper(self) -> None:
pass

def PrintSelfInfo(self) -> None:
pass
34 changes: 29 additions & 5 deletions CAPI/python/PyAPI/DebugAPI.py
Original file line number Diff line number Diff line change
Expand Up @@ -450,8 +450,8 @@ def GetConstructionHp(self, cellX: int, cellY: int) -> int:
def GetBridgeHp(self, cellX: int, cellY: int) -> int:
return self.__logic.GetBridgeHp(cellX, cellY)

def GetResouceState(self, cellX: int, cellY: int) -> int:
return self.__logic.GetResouceState(cellX, cellY)
def GetGarbageState(self, cellX: int, cellY: int) -> int:
return self.__logic.GetGarbageState(cellX, cellY)

def GetHomeHp(self) -> int:
return self.__logic.GetHomeHp()
Expand All @@ -472,13 +472,37 @@ def GetEnergy(self) -> int:
return self.__logic.GetEnergy()

def Print(self, string: str) -> None:
pass
self.__logger.info(string)

def PrintSweeper(self) -> None:
for sweeper in self.__logic.GetSweepers():
self.__logger.info("******sweeper Info******")
self.__logger.info(
f"teamID={sweeper.teamID} playerID={sweeper.playerID}, GUID={sweeper.guid} sweeperType:{sweeper.sweeperType}"
)
self.__logger.info(
f"x={sweeper.x}, y={sweeper.y} hp={sweeper.hp} armor={sweeper.armor} shield={sweeper.shield} state:{sweeper.sweeperState}"
)
self.__logger.info(
f"speed={sweeper.speed}, view range={sweeper.viewRange}, facingDirection={sweeper.facingDirection}"
)
self.__logger.info(
f"producerType:{sweeper.producerType} constructorType:{sweeper.constructorType}"
)
self.__logger.info(
f"armorType:{sweeper.armorType} shieldType:{sweeper.shieldType} weaponType:{sweeper.weaponType}"
)
self.__logger.info("************************\n")

def PrintTeam(self) -> None:
pass
self.PrintSelfInfo()

def PrintSelfInfo(self) -> None:
pass
selfInfo = self.__logic.GetSelfInfo()
self.__logger.info("******self team info******")
self.__logger.info(f"teamID:{selfInfo.teamID} playerID:{selfInfo.playerID}")
self.__logger.info(f"score:{selfInfo.score} energy:{selfInfo.energy}")
self.__logger.info("************************\n")

def __GetTime(self) -> float:
return (datetime.datetime.now() - self.__startPoint) / datetime.timedelta(
Expand Down
4 changes: 0 additions & 4 deletions CAPI/python/PyAPI/Interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,6 @@ def HaveMessage(self) -> bool:
def GetMessage(self) -> Tuple[int, str]:
pass

@abstractmethod
def Move(self, timeInMilliseconds: int, angle: float) -> Future[bool]:
pass

# 获取游戏目前所进行的帧数
@abstractmethod
def GetFrameCount(self) -> int:
Expand Down
99 changes: 99 additions & 0 deletions CAPI/python/PyAPI/gym.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
from collections import deque, namedtuple
import random
import PyAPI.structures as THUAI7
from PyAPI.State import State

Transition = namedtuple("Transition", ["state", "action", "reward", "next_state"])


class ObservationSpace:
def __init__(self, state: State):
if isinstance(state.self, THUAI7.Sweeper):
self.selfSweeperInfo = self.__ObsSweeper(state.self)
self.otherSweeperInfo = [
self.__ObsSweeper(sweeper)
for sweeper in state.sweepers
if sweeper.playerID != state.self.playerID
]
self.bulletsInfo = [self.__ObsBullet(bullet) for bullet in state.bullets]
self.homeInfo = [
[*key, *value] for key, value in state.mapInfo.homeState.items()
]
elif isinstance(state.self, THUAI7.Team):
self.sweeperInfo = [
self.__ObsSweeper(sweeper) for sweeper in state.sweepers
]
self.enemySweeperInfo = [
self.__ObsSweeper(sweeper) for sweeper in state.enemySweepers
]
self.recycleBankInfo = [
[*key, *value] for key, value in state.mapInfo.recycleBankState.items()
]
self.chargeStationInfo = [
[*key, *value] for key, value in state.mapInfo.chargeStationState.items()
]
self.signalTowerInfo = [
[*key, *value] for key, value in state.mapInfo.chargeStationState.items()
]
self.bridgeInfo = [
[*key, value] for key, value in state.mapInfo.bridgeState.items()
]
self.garbageInfo = [
[*key, value] for key, value in state.mapInfo.garbageState.items()
]
self.gameInfo = self.__ObsGame(state.gameInfo)

def __ObsSweeper(sweeper: THUAI7.Sweeper):
return [
sweeper.x,
sweeper.y,
sweeper.speed,
sweeper.facingDirection,
sweeper.viewRange,
sweeper.hp,
sweeper.armor,
sweeper.shield,
sweeper.sweeperState.value,
sweeper.sweeperType.value,
sweeper.producerType.value,
sweeper.constructorType.value,
sweeper.armorType.value,
sweeper.shieldType.value,
sweeper.weaponType.value,
]

def __ObsBullet(bullet: THUAI7.Bullet):
return [
bullet.x,
bullet.y,
bullet.facingDirection,
bullet.speed,
bullet.damage,
bullet.bombRange,
bullet.explodeRange,
]

def __ObsGame(gameInfo: THUAI7.GameInfo):
return [
[gameInfo.redHomeHp, gameInfo.redEnergy, gameInfo.redScore],
[gameInfo.blueHomeHp, gameInfo.blueEnergy, gameInfo.blueScore],
]


class ActionSpace:
def __init__(self):
pass


class Memory:
def __init__(self, max_len):
self.memory = deque([], maxlen=max_len)

def push(self, *args):
self.memory.append(Transition(*args))

def sample(self, batch_size):
return random.sample(self.memory, batch_size)

def __len__(self):
return len(self.memory)
30 changes: 18 additions & 12 deletions CAPI/python/PyAPI/logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
from PyAPI.Communication import Communication
from PyAPI.State import State
from PyAPI.Interface import ILogic, IGameTimer
from PyAPI.DebugAPI import SweeperDebugAPI, TeamDebugAPI


class Logic(ILogic):
Expand Down Expand Up @@ -183,27 +182,27 @@ def GetHomeHp(self) -> int:
with self.__mtxState:
self.__logger.debug("Called GetHomeHp")
return copy.deepcopy(
self.__currentState.gameInfo.blueHomeHp
self.__currentState.gameInfo.redHomeHp
if self.__teamID == 1
else self.__currentState.gameInfo.redHomeHp
else self.__currentState.gameInfo.blueHomeHp
)

def GetEnergy(self) -> int:
with self.__mtxState:
self.__logger.debug("Called GetEnergy")
return copy.deepcopy(
self.__currentState.gameInfo.blueMoney
self.__currentState.gameInfo.redEnergy
if self.__teamID == 1
else self.__currentState.gameInfo.redMoney
else self.__currentState.gameInfo.blueEnergy
)

def GetScore(self) -> int:
with self.__mtxState:
self.__logger.debug("Called GetScore")
return copy.deepcopy(
self.__currentState.gameInfo.blueScore
self.__currentState.gameInfo.redScore
if self.__teamID == 1
else self.__currentState.gameInfo.redScore
else self.__currentState.gameInfo.blueScore
)

def Attack(self, angle: float) -> int:
Expand Down Expand Up @@ -893,11 +892,19 @@ def Main(

# 构造timer
if not file and not screen:
self.__timer = SweeperAPI(self)
if self.__playerID == 0:
self.__timer = TeamAPI(self)
else:
self.__timer = SweeperAPI(self)
else:
self.__timer = SweeperDebugAPI(
self, file, screen, warnOnly, self.__playerID
)
if self.__playerID == 0:
self.__timer = TeamDebugAPI(
self, file, screen, warnOnly, self.__playerID
)
else:
self.__timer = SweeperDebugAPI(
self, file, screen, warnOnly, self.__playerID
)

# 构建AI线程
def AIThread():
Expand All @@ -923,7 +930,6 @@ def AIThread():
)
self.__threadAI = threading.Thread(target=AIThread)
self.__threadAI.start()
self.__logger.info("Start to Process Message")
self.__ProcessMessage()
self.__logger.info("Join the AI thread.")
self.__threadAI.join()
Expand Down
4 changes: 3 additions & 1 deletion CAPI/python/PyAPI/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,9 @@ def THUAI7Main(argv: List[str], AIBuilder: Callable) -> None:
playerType = THUAI7.PlayerType.Team
else:
playerType = THUAI7.PlayerType.Sweeper
sweeperType = Setting.SweeperTypes()[pID]
sweeperType = Setting.SweeperTypes()[
pID - 1
] # 减去1 是因为字典从0计数,而我们的船是从1计数

if platform.system().lower() == "windows":
PrintWelcomeString()
Expand Down
9 changes: 3 additions & 6 deletions CAPI/python/PyAPI/structures.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,9 @@ class ShapeType(Enum):


class PlayerTeam(Enum):
NullTeam = 0
Red = 1
Blue = 2


playerTeamDict = {PlayerTeam.NullTeam: 0, PlayerTeam.Red: 1, PlayerTeam.Blue: 2}
Red = 0
Blue = 1
NullTeam =2


class PlayerType(Enum):
Expand Down
23 changes: 23 additions & 0 deletions CAPI/python/debug.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import subprocess
import time
commands = [
"python PyAPI\main.py -I 127.0.0.1 -P 8888 -p 0 -t 0 -o",
"python PyAPI\main.py -I 127.0.0.1 -P 8888 -p 1 -t 0 -o",
"python PyAPI\main.py -I 127.0.0.1 -P 8888 -p 2 -t 0 -o",
"python PyAPI\main.py -I 127.0.0.1 -P 8888 -p 3 -t 0 -o",
"python PyAPI\main.py -I 127.0.0.1 -P 8888 -p 4 -t 0 -o",

"python PyAPI\main.py -I 127.0.0.1 -P 8888 -p 0 -t 1 -o",
"python PyAPI\main.py -I 127.0.0.1 -P 8888 -p 1 -t 1 -o",
"python PyAPI\main.py -I 127.0.0.1 -P 8888 -p 2 -t 1 -o",
"python PyAPI\main.py -I 127.0.0.1 -P 8888 -p 3 -t 1 -o",
"python PyAPI\main.py -I 127.0.0.1 -P 8888 -p 4 -t 1 -o",
]

processes = []
for cmd in commands:
processes.append(subprocess.Popen(cmd, shell=True))
time.sleep(0.5)

for process in processes:
process.wait()
13 changes: 13 additions & 0 deletions CAPI/shell/RunCpp.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env bash

./CAPI/cpp/build/capi -I 127.0.0.1 -P 8888 -p 0 -t 0 -o&
./CAPI/cpp/build/capi -I 127.0.0.1 -P 8888 -p 1 -t 0 -o&
./CAPI/cpp/build/capi -I 127.0.0.1 -P 8888 -p 2 -t 0 -o&
./CAPI/cpp/build/capi -I 127.0.0.1 -P 8888 -p 3 -t 0 -o&
./CAPI/cpp/build/capi -I 127.0.0.1 -P 8888 -p 4 -t 0 -o&

./CAPI/cpp/build/capi -I 127.0.0.1 -P 8888 -p 0 -t 1 -o&
./CAPI/cpp/build/capi -I 127.0.0.1 -P 8888 -p 1 -t 1 -o&
./CAPI/cpp/build/capi -I 127.0.0.1 -P 8888 -p 2 -t 1 -o&
./CAPI/cpp/build/capi -I 127.0.0.1 -P 8888 -p 3 -t 1 -o&
./CAPI/cpp/build/capi -I 127.0.0.1 -P 8888 -p 4 -t 1 -o&
13 changes: 13 additions & 0 deletions CAPI/shell/RunPython.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env bash

python ./CAPI/python/PyAPI/main.py -I 127.0.0.1 -P 8888 -p 0 -t 0 -o&
python ./CAPI/python/PyAPI/main.py -I 127.0.0.1 -P 8888 -p 1 -t 0 -o&
python ./CAPI/python/PyAPI/main.py -I 127.0.0.1 -P 8888 -p 2 -t 0 -o&
python ./CAPI/python/PyAPI/main.py -I 127.0.0.1 -P 8888 -p 3 -t 0 -o&
python ./CAPI/python/PyAPI/main.py -I 127.0.0.1 -P 8888 -p 4 -t 0 -o&

python ./CAPI/python/PyAPI/main.py -I 127.0.0.1 -P 8888 -p 0 -t 1 -o&
python ./CAPI/python/PyAPI/main.py -I 127.0.0.1 -P 8888 -p 1 -t 1 -o&
python ./CAPI/python/PyAPI/main.py -I 127.0.0.1 -P 8888 -p 2 -t 1 -o&
python ./CAPI/python/PyAPI/main.py -I 127.0.0.1 -P 8888 -p 3 -t 1 -o&
python ./CAPI/python/PyAPI/main.py -I 127.0.0.1 -P 8888 -p 4 -t 1 -o&
Loading