You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

DebugAPI.py 34 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895
  1. from math import pi
  2. from concurrent.futures import ThreadPoolExecutor, Future
  3. from typing import List, cast, Tuple, Union
  4. import logging
  5. import os
  6. import datetime
  7. import PyAPI.structures as THUAI6
  8. from PyAPI.Interface import ILogic, IStudentAPI, ITrickerAPI, IGameTimer, IAI
  9. class StudentDebugAPI(IStudentAPI, IGameTimer):
  10. def __init__(
  11. self, logic: ILogic, file: bool, screen: bool, warnOnly: bool, playerID: int
  12. ) -> None:
  13. self.__logic = logic
  14. self.__pool = ThreadPoolExecutor(20)
  15. self.__startPoint = datetime.datetime.now()
  16. self.__logger = logging.getLogger("api " + str(playerID))
  17. self.__logger.setLevel(logging.DEBUG)
  18. formatter = logging.Formatter(
  19. "[%(name)s] [%(asctime)s.%(msecs)03d] [%(levelname)s] %(message)s",
  20. "%H:%M:%S",
  21. )
  22. # 确保文件存在
  23. if not os.path.exists(
  24. os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + "/logs"
  25. ):
  26. os.makedirs(
  27. os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + "/logs"
  28. )
  29. fileHandler = logging.FileHandler(
  30. os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
  31. + "/logs/api-"
  32. + str(playerID)
  33. + "-log.txt",
  34. mode="w+",
  35. encoding="utf-8",
  36. )
  37. screenHandler = logging.StreamHandler()
  38. if file:
  39. fileHandler.setLevel(logging.DEBUG)
  40. fileHandler.setFormatter(formatter)
  41. self.__logger.addHandler(fileHandler)
  42. if screen:
  43. if warnOnly:
  44. screenHandler.setLevel(logging.WARNING)
  45. else:
  46. screenHandler.setLevel(logging.INFO)
  47. screenHandler.setFormatter(formatter)
  48. self.__logger.addHandler(screenHandler)
  49. # 指挥本角色进行移动,`timeInMilliseconds` 为移动时间,单位为毫秒;`angleInRadian` 表示移动的方向,单位是弧度,使用极坐标——竖直向下方向为 x 轴,水平向右方向为 y 轴
  50. def Move(self, timeInMilliseconds: int, angle: float) -> Future[bool]:
  51. self.__logger.info(
  52. f"Move: timeInMilliseconds = {timeInMilliseconds}, angle = {angle}, called at {self.__GetTime()}ms"
  53. )
  54. def logMove() -> bool:
  55. result = self.__logic.Move(timeInMilliseconds, angle)
  56. if not result:
  57. self.__logger.warning(f"Move: failed at {self.__GetTime()}ms")
  58. return result
  59. return self.__pool.submit(logMove)
  60. # 向特定方向移动
  61. def MoveRight(self, timeInMilliseconds: int) -> Future[bool]:
  62. return self.Move(timeInMilliseconds, pi * 0.5)
  63. def MoveLeft(self, timeInMilliseconds: int) -> Future[bool]:
  64. return self.Move(timeInMilliseconds, pi * 1.5)
  65. def MoveUp(self, timeInMilliseconds: int) -> Future[bool]:
  66. return self.Move(timeInMilliseconds, pi)
  67. def MoveDown(self, timeInMilliseconds: int) -> Future[bool]:
  68. return self.Move(timeInMilliseconds, 0)
  69. def Attack(self, angle: float) -> Future[bool]:
  70. self.__logger.info(f"Attack: angle = {angle}, called at {self.__GetTime()}ms")
  71. def logAttack() -> bool:
  72. result = self.__logic.Attack(angle)
  73. if not result:
  74. self.__logger.warning(f"Attack: failed at {self.__GetTime()}ms")
  75. return result
  76. return self.__pool.submit(logAttack)
  77. # 道具和技能相关
  78. def PickProp(self, propType: THUAI6.PropType) -> Future[bool]:
  79. self.__logger.info(
  80. f"PickProp: prop = {propType.name}, called at {self.__GetTime()}ms"
  81. )
  82. def logPick() -> bool:
  83. result = self.__logic.PickProp(propType)
  84. if not result:
  85. self.__logger.warning(f"PickProp: failed at {self.__GetTime()}ms")
  86. return result
  87. return self.__pool.submit(logPick)
  88. def UseProp(self, propType: THUAI6.PropType) -> Future[bool]:
  89. self.__logger.info(
  90. f"UseProp: prop = {propType.name}, called at {self.__GetTime()}ms"
  91. )
  92. def logUse() -> bool:
  93. result = self.__logic.UseProp(propType)
  94. if not result:
  95. self.__logger.warning(f"UseProp: failed at {self.__GetTime()}ms")
  96. return result
  97. return self.__pool.submit(logUse)
  98. def ThrowProp(self, propType: THUAI6.PropType) -> Future[bool]:
  99. self.__logger.info(
  100. f"ThrowProp: prop = {propType.name}, called at {self.__GetTime()}ms"
  101. )
  102. def logThrow() -> bool:
  103. result = self.__logic.ThrowProp(propType)
  104. if not result:
  105. self.__logger.warning(f"ThrowProp: failed at {self.__GetTime()}ms")
  106. return result
  107. return self.__pool.submit(logThrow)
  108. def UseSkill(self, skillID: int) -> Future[bool]:
  109. self.__logger.info(
  110. f"UseSkill: skillID = {skillID}, called at {self.__GetTime()}ms"
  111. )
  112. def logUse() -> bool:
  113. result = self.__logic.UseSkill(skillID)
  114. if not result:
  115. self.__logger.warning(f"UseSkill: failed at {self.__GetTime()}ms")
  116. return result
  117. return self.__pool.submit(logUse)
  118. # 与地图交互相关
  119. def OpenDoor(self) -> Future[bool]:
  120. self.__logger.info(f"OpenDoor: called at {self.__GetTime()}ms")
  121. def logOpen() -> bool:
  122. result = self.__logic.OpenDoor()
  123. if not result:
  124. self.__logger.warning(f"OpenDoor: failed at {self.__GetTime()}ms")
  125. return result
  126. return self.__pool.submit(logOpen)
  127. def CloseDoor(self) -> Future[bool]:
  128. self.__logger.info(f"CloseDoor: called at {self.__GetTime()}ms")
  129. def logClose() -> bool:
  130. result = self.__logic.CloseDoor()
  131. if not result:
  132. self.__logger.warning(f"CloseDoor: failed at {self.__GetTime()}ms")
  133. return result
  134. return self.__pool.submit(logClose)
  135. def SkipWindow(self) -> Future[bool]:
  136. self.__logger.info(f"SkipWindow: called at {self.__GetTime()}ms")
  137. def logSkip() -> bool:
  138. result = self.__logic.SkipWindow()
  139. if not result:
  140. self.__logger.warning(f"SkipWindow: failed at {self.__GetTime()}ms")
  141. return result
  142. return self.__pool.submit(logSkip)
  143. def StartOpenGate(self) -> Future[bool]:
  144. self.__logger.info(f"StartOpenGate: called at {self.__GetTime()}ms")
  145. def logStart() -> bool:
  146. result = self.__logic.StartOpenGate()
  147. if not result:
  148. self.__logger.warning(f"StartOpenGate: failed at {self.__GetTime()}ms")
  149. return result
  150. return self.__pool.submit(logStart)
  151. def StartOpenChest(self) -> Future[bool]:
  152. self.__logger.info(f"StartOpenChest: called at {self.__GetTime()}ms")
  153. def logStart() -> bool:
  154. result = self.__logic.StartOpenChest()
  155. if not result:
  156. self.__logger.warning(f"StartOpenChest: failed at {self.__GetTime()}ms")
  157. return result
  158. return self.__pool.submit(logStart)
  159. def EndAllAction(self) -> Future[bool]:
  160. self.__logger.info(f"EndAllAction: called at {self.__GetTime()}ms")
  161. def logEnd() -> bool:
  162. result = self.__logic.EndAllAction()
  163. if not result:
  164. self.__logger.warning(f"EndAllAction: failed at {self.__GetTime()}ms")
  165. return result
  166. return self.__pool.submit(logEnd)
  167. # 消息相关,接收消息时无消息则返回(-1, '')
  168. def SendMessage(self, toID: int, message: Union[str, bytes]) -> Future[bool]:
  169. self.__logger.info(
  170. f"SendMessage: toID = {toID}, message = {message}, called at {self.__GetTime()}ms"
  171. )
  172. def logSend() -> bool:
  173. result = self.__logic.SendMessage(toID, message)
  174. if not result:
  175. self.__logger.warning(f"SendMessage: failed at {self.__GetTime()}ms")
  176. return result
  177. return self.__pool.submit(logSend)
  178. def HaveMessage(self) -> bool:
  179. self.__logger.info(f"HaveMessage: called at {self.__GetTime()}ms")
  180. result = self.__logic.HaveMessage()
  181. if not result:
  182. self.__logger.warning(f"HaveMessage: failed at {self.__GetTime()}ms")
  183. return result
  184. def GetMessage(self) -> Tuple[int, Union[str, bytes]]:
  185. self.__logger.info(f"GetMessage: called at {self.__GetTime()}ms")
  186. result = self.__logic.GetMessage()
  187. if result[0] == -1:
  188. self.__logger.warning(f"GetMessage: failed at {self.__GetTime()}ms")
  189. return result
  190. # 等待下一帧
  191. def Wait(self) -> bool:
  192. self.__logger.info(f"Wait: called at {self.__GetTime()}ms")
  193. if self.__logic.GetCounter() == -1:
  194. return False
  195. else:
  196. return self.__logic.WaitThread()
  197. # 获取各类游戏中的消息
  198. def GetFrameCount(self) -> int:
  199. return self.__logic.GetCounter()
  200. def GetPlayerGUIDs(self) -> List[int]:
  201. return self.__logic.GetPlayerGUIDs()
  202. def GetTrickers(self) -> List[THUAI6.Tricker]:
  203. return self.__logic.GetTrickers()
  204. def GetStudents(self) -> List[THUAI6.Student]:
  205. return self.__logic.GetStudents()
  206. def GetProps(self) -> List[THUAI6.Prop]:
  207. return self.__logic.GetProps()
  208. def GetBullets(self) -> List[THUAI6.Bullet]:
  209. return self.__logic.GetBullets()
  210. def GetFullMap(self) -> List[List[THUAI6.PlaceType]]:
  211. return self.__logic.GetFullMap()
  212. def GetPlaceType(self, cellX: int, cellY: int) -> THUAI6.PlaceType:
  213. return self.__logic.GetPlaceType(cellX, cellY)
  214. def IsDoorOpen(self, cellX: int, cellY: int) -> bool:
  215. return self.__logic.IsDoorOpen(cellX, cellY)
  216. def GetChestProgress(self, cellX: int, cellY: int) -> int:
  217. return self.__logic.GetChestProgress(cellX, cellY)
  218. def GetGateProgress(self, cellX: int, cellY: int) -> int:
  219. return self.__logic.GetGateProgress(cellX, cellY)
  220. def GetClassroomProgress(self, cellX: int, cellY: int) -> int:
  221. return self.__logic.GetClassroomProgress(cellX, cellY)
  222. def GetDoorProgress(self, cellX: int, cellY: int) -> int:
  223. return self.__logic.GetDoorProgress(cellX, cellY)
  224. def GetHiddenGateState(self, cellX: int, cellY: int) -> THUAI6.HiddenGateState:
  225. return self.__logic.GetHiddenGateState(cellX, cellY)
  226. def GetGameInfo(self) -> THUAI6.GameInfo:
  227. return self.__logic.GetGameInfo()
  228. def HaveView(self, gridX: int, gridY: int) -> bool:
  229. return self.__logic.HaveView(
  230. gridX,
  231. gridY,
  232. self.GetSelfInfo().x,
  233. self.GetSelfInfo().y,
  234. self.GetSelfInfo().viewRange,
  235. )
  236. # 用于DEBUG的输出函数,仅在DEBUG模式下有效
  237. def Print(self, cont: str) -> None:
  238. self.__logger.info(cont)
  239. def PrintStudent(self) -> None:
  240. for student in self.__logic.GetStudents():
  241. self.__logger.info("******Student Info******")
  242. self.__logger.info(
  243. f"playerID={student.playerID}, GUID={student.guid}, x={student.x}, y={student.y}"
  244. )
  245. self.__logger.info(
  246. f"speed={student.speed}, view range={student.viewRange}, radius={student.radius}"
  247. )
  248. self.__logger.info(
  249. f"score={student.score}, facing direction={student.facingDirection}, skill time={student.timeUntilSkillAvailable}"
  250. )
  251. studentProp = ""
  252. for prop in student.prop:
  253. studentProp += prop.name + ", "
  254. self.__logger.info(
  255. f"state={student.playerState.name}, bullet={student.bulletType.name}, prop={studentProp}"
  256. )
  257. self.__logger.info(
  258. f"type={student.studentType.name}, determination={student.determination}, addiction={student.addiction}, danger alert={student.dangerAlert}"
  259. )
  260. self.__logger.info(
  261. f"learning speed={student.learningSpeed}, encourage speed={student.encourageSpeed}, encourage progress={student.encourageProgress}, rouse progress={student.rouseProgress}"
  262. )
  263. studentBuff = ""
  264. for buff in student.buff:
  265. studentBuff += buff.name + ", "
  266. self.__logger.info(f"buff={studentBuff}")
  267. self.__logger.info("************************\n")
  268. def PrintTricker(self) -> None:
  269. for tricker in self.__logic.GetTrickers():
  270. self.__logger.info("******Tricker Info******")
  271. self.__logger.info(
  272. f"playerID={tricker.playerID}, GUID={tricker.guid}, x={tricker.x}, y={tricker.y}"
  273. )
  274. self.__logger.info(
  275. f"speed={tricker.speed}, view range={tricker.viewRange}, radius={tricker.radius}"
  276. )
  277. self.__logger.info(
  278. f"score={tricker.score}, facing direction={tricker.facingDirection}, skill time={tricker.timeUntilSkillAvailable}"
  279. )
  280. trickerProp = ""
  281. for prop in tricker.prop:
  282. trickerProp += prop.name + ", "
  283. self.__logger.info(
  284. f"state={tricker.playerState.name}, bullet={tricker.bulletType.name}, prop={trickerProp}"
  285. )
  286. self.__logger.info(
  287. f"type={tricker.trickerType.name}, trick desire={tricker.trickDesire}, class volume={tricker.classVolume}"
  288. )
  289. trickerBuff = ""
  290. for buff in tricker.buff:
  291. trickerBuff += buff.name + ", "
  292. self.__logger.info(f"buff={trickerBuff}")
  293. self.__logger.info("************************\n")
  294. def PrintProp(self) -> None:
  295. for prop in self.__logic.GetProps():
  296. self.__logger.info("******Prop Info******")
  297. self.__logger.info(
  298. f"GUID={prop.guid}, x={prop.x}, y={prop.y}, facing direction={prop.facingDirection}"
  299. )
  300. self.__logger.info("*********************")
  301. def PrintSelfInfo(self) -> None:
  302. student = cast(THUAI6.Student, self.__logic.GetSelfInfo())
  303. self.__logger.info("******Student Info******")
  304. self.__logger.info(
  305. f"playerID={student.playerID}, GUID={student.guid}, x={student.x}, y={student.y}"
  306. )
  307. self.__logger.info(
  308. f"speed={student.speed}, view range={student.viewRange}, radius={student.radius}"
  309. )
  310. self.__logger.info(
  311. f"score={student.score}, facing direction={student.facingDirection}, skill time={student.timeUntilSkillAvailable}"
  312. )
  313. studentProp = ""
  314. for prop in student.prop:
  315. studentProp += prop.name + ", "
  316. self.__logger.info(
  317. f"state={student.playerState.name}, bullet={student.bulletType.name}, prop={studentProp}"
  318. )
  319. self.__logger.info(
  320. f"type={student.studentType.name}, determination={student.determination}, addiction={student.addiction}, danger alert={student.dangerAlert}"
  321. )
  322. self.__logger.info(
  323. f"learning speed={student.learningSpeed}, encourage speed={student.encourageSpeed}, encourage progress={student.encourageProgress}, rouse progress={student.rouseProgress}"
  324. )
  325. studentBuff = ""
  326. for buff in student.buff:
  327. studentBuff += buff.name + ", "
  328. self.__logger.info(f"buff={studentBuff}")
  329. self.__logger.info("************************\n")
  330. # 人类阵营的特殊函数
  331. def Graduate(self) -> Future[bool]:
  332. self.__logger.info(f"Graduate: called at {self.__GetTime()}ms")
  333. def logGraduate() -> bool:
  334. result = self.__logic.Graduate()
  335. if not result:
  336. self.__logger.warning(f"Graduate: failed at {self.__GetTime()}ms")
  337. return result
  338. return self.__pool.submit(logGraduate)
  339. def StartLearning(self) -> Future[bool]:
  340. self.__logger.info(f"StartLearning: called at {self.__GetTime()}ms")
  341. def logStart() -> bool:
  342. result = self.__logic.StartLearning()
  343. if not result:
  344. self.__logger.warning(f"StartLearning: failed at {self.__GetTime()}ms")
  345. return result
  346. return self.__pool.submit(logStart)
  347. def StartEncourageMate(self, mateID: int) -> Future[bool]:
  348. self.__logger.info(f"StartEncourageMate: called at {self.__GetTime()}ms")
  349. def logStartEncourageMate() -> bool:
  350. result = self.__logic.StartEncourageMate(mateID)
  351. if not result:
  352. self.__logger.warning(
  353. f"StartEncourageMate: failed at {self.__GetTime()}ms"
  354. )
  355. return result
  356. return self.__pool.submit(logStartEncourageMate)
  357. def StartRouseMate(self, mateID: int) -> Future[bool]:
  358. self.__logger.info(f"StartRouseMate: called at {self.__GetTime()}ms")
  359. def logStartRouseMate() -> bool:
  360. result = self.__logic.StartRouseMate(mateID)
  361. if not result:
  362. self.__logger.warning(f"StartRouseMate: failed at {self.__GetTime()}ms")
  363. return result
  364. return self.__pool.submit(logStartRouseMate)
  365. def GetSelfInfo(self) -> THUAI6.Student:
  366. return cast(THUAI6.Student, self.__logic.GetSelfInfo())
  367. # Timer用
  368. def __GetTime(self) -> float:
  369. return (datetime.datetime.now() - self.__startPoint) / datetime.timedelta(
  370. milliseconds=1
  371. )
  372. def StartTimer(self) -> None:
  373. self.__startPoint = datetime.datetime.now()
  374. self.__logger.info("=== AI.play() ===")
  375. self.__logger.info(f"StartTimer: {self.__startPoint.time()}")
  376. def EndTimer(self) -> None:
  377. self.__logger.info(f"Time elapsed: {self.__GetTime()}ms")
  378. def Play(self, ai: IAI) -> None:
  379. ai.StudentPlay(self)
  380. class TrickerDebugAPI(ITrickerAPI, IGameTimer):
  381. def __init__(
  382. self, logic: ILogic, file: bool, screen: bool, warnOnly: bool, playerID: int
  383. ) -> None:
  384. self.__logic = logic
  385. self.__pool = ThreadPoolExecutor(20)
  386. self.__logger = logging.getLogger("api " + str(playerID))
  387. self.__logger.setLevel(logging.DEBUG)
  388. formatter = logging.Formatter(
  389. "[%(name)s] [%(asctime)s.%(msecs)03d] [%(levelname)s] %(message)s",
  390. "%H:%M:%S",
  391. )
  392. # 确保文件存在
  393. if not os.path.exists(
  394. os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + "/logs"
  395. ):
  396. os.makedirs(
  397. os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + "/logs"
  398. )
  399. fileHandler = logging.FileHandler(
  400. os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
  401. + "/logs/api-"
  402. + str(playerID)
  403. + "-log.txt",
  404. mode="w+",
  405. encoding="utf-8",
  406. )
  407. screenHandler = logging.StreamHandler()
  408. if file:
  409. fileHandler.setLevel(logging.DEBUG)
  410. fileHandler.setFormatter(formatter)
  411. self.__logger.addHandler(fileHandler)
  412. if screen:
  413. if warnOnly:
  414. screenHandler.setLevel(logging.WARNING)
  415. else:
  416. screenHandler.setLevel(logging.INFO)
  417. screenHandler.setFormatter(formatter)
  418. self.__logger.addHandler(screenHandler)
  419. # 指挥本角色进行移动,`timeInMilliseconds` 为移动时间,单位为毫秒;`angleInRadian` 表示移动的方向,单位是弧度,使用极坐标——竖直向下方向为 x 轴,水平向右方向为 y 轴
  420. def Move(self, timeInMilliseconds: int, angle: float) -> Future[bool]:
  421. self.__logger.info(
  422. f"Move: timeInMilliseconds = {timeInMilliseconds}, angle = {angle}, called at {self.__GetTime()}ms"
  423. )
  424. def logMove() -> bool:
  425. result = self.__logic.Move(timeInMilliseconds, angle)
  426. if not result:
  427. self.__logger.warning(f"Move: failed at {self.__GetTime()}ms")
  428. return result
  429. return self.__pool.submit(logMove)
  430. # 向特定方向移动
  431. def MoveRight(self, timeInMilliseconds: int) -> Future[bool]:
  432. return self.Move(timeInMilliseconds, pi * 0.5)
  433. def MoveLeft(self, timeInMilliseconds: int) -> Future[bool]:
  434. return self.Move(timeInMilliseconds, pi * 1.5)
  435. def MoveUp(self, timeInMilliseconds: int) -> Future[bool]:
  436. return self.Move(timeInMilliseconds, pi)
  437. def MoveDown(self, timeInMilliseconds: int) -> Future[bool]:
  438. return self.Move(timeInMilliseconds, 0)
  439. # 道具和技能相关
  440. def Attack(self, angle: float) -> Future[bool]:
  441. self.__logger.info(f"Attack: angle = {angle}, called at {self.__GetTime()}ms")
  442. def logAttack() -> bool:
  443. result = self.__logic.Attack(angle)
  444. if not result:
  445. self.__logger.warning(f"Attack: failed at {self.__GetTime()}ms")
  446. return result
  447. return self.__pool.submit(logAttack)
  448. # 道具和技能相关
  449. def PickProp(self, propType: THUAI6.PropType) -> Future[bool]:
  450. self.__logger.info(
  451. f"PickProp: prop = {propType.name}, called at {self.__GetTime()}ms"
  452. )
  453. def logPick() -> bool:
  454. result = self.__logic.PickProp(propType)
  455. if not result:
  456. self.__logger.warning(f"PickProp: failed at {self.__GetTime()}ms")
  457. return result
  458. return self.__pool.submit(logPick)
  459. def UseProp(self, propType: THUAI6.PropType) -> Future[bool]:
  460. self.__logger.info(
  461. f"UseProp: prop = {propType.name}, called at {self.__GetTime()}ms"
  462. )
  463. def logUse() -> bool:
  464. result = self.__logic.UseProp(propType)
  465. if not result:
  466. self.__logger.warning(f"UseProp: failed at {self.__GetTime()}ms")
  467. return result
  468. return self.__pool.submit(logUse)
  469. def ThrowProp(self, propType: THUAI6.PropType) -> Future[bool]:
  470. self.__logger.info(
  471. f"ThrowProp: prop = {propType.name}, called at {self.__GetTime()}ms"
  472. )
  473. def logThrow() -> bool:
  474. result = self.__logic.ThrowProp(propType)
  475. if not result:
  476. self.__logger.warning(f"ThrowProp: failed at {self.__GetTime()}ms")
  477. return result
  478. return self.__pool.submit(logThrow)
  479. def UseSkill(self, skillID: int) -> Future[bool]:
  480. self.__logger.info(
  481. f"UseSkill: skillID = {skillID}, called at {self.__GetTime()}ms"
  482. )
  483. def logUse() -> bool:
  484. result = self.__logic.UseSkill(skillID)
  485. if not result:
  486. self.__logger.warning(f"UseSkill: failed at {self.__GetTime()}ms")
  487. return result
  488. return self.__pool.submit(logUse)
  489. # 与地图交互相关
  490. def OpenDoor(self) -> Future[bool]:
  491. self.__logger.info(f"OpenDoor: called at {self.__GetTime()}ms")
  492. def logOpen() -> bool:
  493. result = self.__logic.OpenDoor()
  494. if not result:
  495. self.__logger.warning(f"OpenDoor: failed at {self.__GetTime()}ms")
  496. return result
  497. return self.__pool.submit(logOpen)
  498. def CloseDoor(self) -> Future[bool]:
  499. self.__logger.info(f"CloseDoor: called at {self.__GetTime()}ms")
  500. def logClose() -> bool:
  501. result = self.__logic.CloseDoor()
  502. if not result:
  503. self.__logger.warning(f"CloseDoor: failed at {self.__GetTime()}ms")
  504. return result
  505. return self.__pool.submit(logClose)
  506. def SkipWindow(self) -> Future[bool]:
  507. self.__logger.info(f"SkipWindow: called at {self.__GetTime()}ms")
  508. def logSkip() -> bool:
  509. result = self.__logic.SkipWindow()
  510. if not result:
  511. self.__logger.warning(f"SkipWindow: failed at {self.__GetTime()}ms")
  512. return result
  513. return self.__pool.submit(logSkip)
  514. def StartOpenGate(self) -> Future[bool]:
  515. self.__logger.info(f"StartOpenGate: called at {self.__GetTime()}ms")
  516. def logStart() -> bool:
  517. result = self.__logic.StartOpenGate()
  518. if not result:
  519. self.__logger.warning(f"StartOpenGate: failed at {self.__GetTime()}ms")
  520. return result
  521. return self.__pool.submit(logStart)
  522. def StartOpenChest(self) -> Future[bool]:
  523. self.__logger.info(f"StartOpenChest: called at {self.__GetTime()}ms")
  524. def logStart() -> bool:
  525. result = self.__logic.StartOpenChest()
  526. if not result:
  527. self.__logger.warning(f"StartOpenChest: failed at {self.__GetTime()}ms")
  528. return result
  529. return self.__pool.submit(logStart)
  530. def EndAllAction(self) -> Future[bool]:
  531. self.__logger.info(f"EndAllAction: called at {self.__GetTime()}ms")
  532. def logEnd() -> bool:
  533. result = self.__logic.EndAllAction()
  534. if not result:
  535. self.__logger.warning(f"EndAllAction: failed at {self.__GetTime()}ms")
  536. return result
  537. return self.__pool.submit(logEnd)
  538. # 消息相关,接收消息时无消息则返回(-1, '')
  539. def SendMessage(self, toID: int, message: Union[str, bytes]) -> Future[bool]:
  540. self.__logger.info(
  541. f"SendMessage: toID = {toID}, message = {message}, called at {self.__GetTime()}ms"
  542. )
  543. def logSend() -> bool:
  544. result = self.__logic.SendMessage(toID, message)
  545. if not result:
  546. self.__logger.warning(f"SendMessage: failed at {self.__GetTime()}ms")
  547. return result
  548. return self.__pool.submit(logSend)
  549. def HaveMessage(self) -> bool:
  550. self.__logger.info(f"HaveMessage: called at {self.__GetTime()}ms")
  551. result = self.__logic.HaveMessage()
  552. if not result:
  553. self.__logger.warning(f"HaveMessage: failed at {self.__GetTime()}ms")
  554. return result
  555. def GetMessage(self) -> Tuple[int, Union[str, bytes]]:
  556. self.__logger.info(f"GetMessage: called at {self.__GetTime()}ms")
  557. result = self.__logic.GetMessage()
  558. if result[0] == -1:
  559. self.__logger.warning(f"GetMessage: failed at {self.__GetTime()}ms")
  560. return result
  561. # 等待下一帧
  562. def Wait(self) -> bool:
  563. self.__logger.info(f"Wait: called at {self.__GetTime()}ms")
  564. if self.__logic.GetCounter() == -1:
  565. return False
  566. else:
  567. return self.__logic.WaitThread()
  568. # 获取各类游戏中的消息
  569. def GetFrameCount(self) -> int:
  570. return self.__logic.GetCounter()
  571. def GetPlayerGUIDs(self) -> List[int]:
  572. return self.__logic.GetPlayerGUIDs()
  573. def GetTrickers(self) -> List[THUAI6.Tricker]:
  574. return self.__logic.GetTrickers()
  575. def GetStudents(self) -> List[THUAI6.Student]:
  576. return self.__logic.GetStudents()
  577. def GetProps(self) -> List[THUAI6.Prop]:
  578. return self.__logic.GetProps()
  579. def GetBullets(self) -> List[THUAI6.Bullet]:
  580. return self.__logic.GetBullets()
  581. def GetFullMap(self) -> List[List[THUAI6.PlaceType]]:
  582. return self.__logic.GetFullMap()
  583. def GetPlaceType(self, cellX: int, cellY: int) -> THUAI6.PlaceType:
  584. return self.__logic.GetPlaceType(cellX, cellY)
  585. def IsDoorOpen(self, cellX: int, cellY: int) -> bool:
  586. return self.__logic.IsDoorOpen(cellX, cellY)
  587. def GetChestProgress(self, cellX: int, cellY: int) -> int:
  588. return self.__logic.GetChestProgress(cellX, cellY)
  589. def GetGateProgress(self, cellX: int, cellY: int) -> int:
  590. return self.__logic.GetGateProgress(cellX, cellY)
  591. def GetClassroomProgress(self, cellX: int, cellY: int) -> int:
  592. return self.__logic.GetClassroomProgress(cellX, cellY)
  593. def GetDoorProgress(self, cellX: int, cellY: int) -> int:
  594. return self.__logic.GetDoorProgress(cellX, cellY)
  595. def GetHiddenGateState(self, cellX: int, cellY: int) -> THUAI6.HiddenGateState:
  596. return self.__logic.GetHiddenGateState(cellX, cellY)
  597. def GetGameInfo(self) -> THUAI6.GameInfo:
  598. return self.__logic.GetGameInfo()
  599. def HaveView(self, gridX: int, gridY: int) -> bool:
  600. return self.__logic.HaveView(
  601. gridX,
  602. gridY,
  603. self.GetSelfInfo().x,
  604. self.GetSelfInfo().y,
  605. self.GetSelfInfo().viewRange,
  606. )
  607. # 用于DEBUG的输出函数,仅在DEBUG模式下有效
  608. def Print(self, cont: str) -> None:
  609. self.__logger.info(cont)
  610. def PrintStudent(self) -> None:
  611. for student in self.__logic.GetStudents():
  612. self.__logger.info("******Student Info******")
  613. self.__logger.info(
  614. f"playerID={student.playerID}, GUID={student.guid}, x={student.x}, y={student.y}"
  615. )
  616. self.__logger.info(
  617. f"speed={student.speed}, view range={student.viewRange}, radius={student.radius}"
  618. )
  619. self.__logger.info(
  620. f"score={student.score}, facing direction={student.facingDirection}, skill time={student.timeUntilSkillAvailable}"
  621. )
  622. studentProp = ""
  623. for prop in student.prop:
  624. studentProp += prop.name + ", "
  625. self.__logger.info(
  626. f"state={student.playerState.name}, bullet={student.bulletType.name}, prop={studentProp}"
  627. )
  628. self.__logger.info(
  629. f"type={student.studentType.name}, determination={student.determination}, addiction={student.addiction}, danger alert={student.dangerAlert}"
  630. )
  631. self.__logger.info(
  632. f"learning speed={student.learningSpeed}, encourage speed={student.encourageSpeed}, encourage progress={student.encourageProgress}, rouse progress={student.rouseProgress}"
  633. )
  634. studentBuff = ""
  635. for buff in student.buff:
  636. studentBuff += buff.name + ", "
  637. self.__logger.info(f"buff={studentBuff}")
  638. self.__logger.info("************************\n")
  639. def PrintTricker(self) -> None:
  640. for tricker in self.__logic.GetTrickers():
  641. self.__logger.info("******Tricker Info******")
  642. self.__logger.info(
  643. f"playerID={tricker.playerID}, GUID={tricker.guid}, x={tricker.x}, y={tricker.y}"
  644. )
  645. self.__logger.info(
  646. f"speed={tricker.speed}, view range={tricker.viewRange}, radius={tricker.radius}"
  647. )
  648. self.__logger.info(
  649. f"score={tricker.score}, facing direction={tricker.facingDirection}, skill time={tricker.timeUntilSkillAvailable}"
  650. )
  651. trickerProp = ""
  652. for prop in tricker.prop:
  653. trickerProp += prop.name + ", "
  654. self.__logger.info(
  655. f"state={tricker.playerState.name}, bullet={tricker.bulletType.name}, prop={trickerProp}"
  656. )
  657. self.__logger.info(
  658. f"type={tricker.trickerType.name}, trick desire={tricker.trickDesire}, class volume={tricker.classVolume}"
  659. )
  660. trickerBuff = ""
  661. for buff in tricker.buff:
  662. trickerBuff += buff.name + ", "
  663. self.__logger.info(f"buff={trickerBuff}")
  664. self.__logger.info("************************\n")
  665. def PrintProp(self) -> None:
  666. for prop in self.__logic.GetProps():
  667. self.__logger.info("******Prop Info******")
  668. self.__logger.info(
  669. f"GUID={prop.guid}, x={prop.x}, y={prop.y}, facing direction={prop.facingDirection}"
  670. )
  671. self.__logger.info("*********************")
  672. def PrintSelfInfo(self) -> None:
  673. tricker = cast(THUAI6.Tricker, self.__logic.GetSelfInfo())
  674. self.__logger.info("******Tricker Info******")
  675. self.__logger.info(
  676. f"playerID={tricker.playerID}, GUID={tricker.guid}, x={tricker.x}, y={tricker.y}"
  677. )
  678. self.__logger.info(
  679. f"speed={tricker.speed}, view range={tricker.viewRange}, radius={tricker.radius}"
  680. )
  681. self.__logger.info(
  682. f"score={tricker.score}, facing direction={tricker.facingDirection}, skill time={tricker.timeUntilSkillAvailable}"
  683. )
  684. trickerProp = ""
  685. for prop in tricker.prop:
  686. trickerProp += prop.name + ", "
  687. self.__logger.info(
  688. f"state={tricker.playerState.name}, bullet={tricker.bulletType.name}, prop={trickerProp}"
  689. )
  690. self.__logger.info(
  691. f"type={tricker.trickerType.name}, trick desire={tricker.trickDesire}, class volume={tricker.classVolume}"
  692. )
  693. trickerBuff = ""
  694. for buff in tricker.buff:
  695. trickerBuff += buff.name + ", "
  696. self.__logger.info(f"buff={trickerBuff}")
  697. self.__logger.info("************************\n")
  698. # 屠夫阵营的特殊函数
  699. def GetSelfInfo(self) -> THUAI6.Tricker:
  700. return cast(THUAI6.Tricker, self.__logic.GetSelfInfo())
  701. # Timer用
  702. def __GetTime(self) -> float:
  703. return (datetime.datetime.now() - self.__startPoint) / datetime.timedelta(
  704. milliseconds=1
  705. )
  706. def StartTimer(self) -> None:
  707. self.__startPoint = datetime.datetime.now()
  708. self.__logger.info("=== AI.play() ===")
  709. self.__logger.info(f"StartTimer: {self.__startPoint.time()}")
  710. def EndTimer(self) -> None:
  711. self.__logger.info(f"Time elapsed: {self.__GetTime()}ms")
  712. def Play(self, ai: IAI) -> None:
  713. ai.TrickerPlay(self)