|
15 | 15 | from .network import setup_controller, ZMQPublisher |
16 | 16 | from .base_utils import default_rng |
17 | 17 | from .team import make_team |
18 | | -from .spec import GameState |
| 18 | +from .spec import GameState, Layout, Pos |
19 | 19 | from .viewer import ProgressViewer, AsciiViewer, ReplyToViewer, ReplayWriter, ResultPrinter |
20 | 20 |
|
21 | 21 | _logger = logging.getLogger(__name__) |
@@ -268,7 +268,7 @@ def setup_viewers(viewers, print_result=True): |
268 | 268 | return viewer_state |
269 | 269 |
|
270 | 270 |
|
271 | | -def setup_game(team_specs, *, layout_dict, max_rounds=300, layout_name="", rng=None, |
| 271 | +def setup_game(team_specs, *, layout_dict: Layout, max_rounds=300, layout_name="", rng=None, |
272 | 272 | allow_camping=False, error_limit=5, timeout_length=3, |
273 | 273 | viewers=None, store_output=False, |
274 | 274 | team_names=(None, None), team_infos=(None, None), |
@@ -316,120 +316,120 @@ def setup_game(team_specs, *, layout_dict, max_rounds=300, layout_name="", rng=N |
316 | 316 |
|
317 | 317 | # Initialize the game state. |
318 | 318 |
|
319 | | - game_state: GameState = dict( |
| 319 | + game_state: GameState = { |
320 | 320 | ### The layout attributes |
321 | 321 | #: Walls. Set of (int, int) |
322 | | - walls=set(layout_dict['walls']), |
| 322 | + 'walls': set(layout_dict['walls']), |
323 | 323 |
|
324 | 324 | #: Shape of the maze. (int, int) |
325 | | - shape=layout_dict['shape'], |
| 325 | + 'shape': layout_dict['shape'], |
326 | 326 |
|
327 | 327 | #: Food per team. List of sets of (int, int) |
328 | | - food=food, |
| 328 | + 'food': food, |
329 | 329 |
|
330 | 330 | #: Food ages per team. Dict of (int, int) to int |
331 | | - food_age=[{}, {}], |
| 331 | + 'food_age': ({}, {}), |
332 | 332 |
|
333 | 333 | ### Round/turn information |
334 | 334 | #: Current bot, int, None |
335 | | - turn=None, |
| 335 | + 'turn': None, |
336 | 336 |
|
337 | 337 | #: Current round, int, None |
338 | | - round=None, |
| 338 | + 'round': None, |
339 | 339 |
|
340 | 340 | #: Is the game finished? bool |
341 | | - gameover=False, |
| 341 | + 'gameover': False, |
342 | 342 |
|
343 | 343 | #: Who won? int, None |
344 | | - whowins=None, |
| 344 | + 'whowins': None, |
345 | 345 |
|
346 | 346 | ### Bot/team status |
347 | 347 | #: Positions of all bots. List of (int, int) |
348 | | - bots=layout_dict['bots'][:], |
| 348 | + 'bots': layout_dict['bots'][:], |
349 | 349 |
|
350 | 350 | #: Score of the teams. List of int |
351 | | - score=[0] * 2, |
| 351 | + 'score': (0, 0), |
352 | 352 |
|
353 | 353 | #: Fatal errors |
354 | | - fatal_errors=[[], []], |
| 354 | + 'fatal_errors': ([], []), |
355 | 355 |
|
356 | 356 | #: Errors |
357 | | - errors=[{}, {}], |
| 357 | + 'errors': ({}, {}), |
358 | 358 |
|
359 | 359 | ### Configuration |
360 | 360 | #: Maximum number of rounds, int |
361 | | - max_rounds=max_rounds, |
| 361 | + 'max_rounds': max_rounds, |
362 | 362 |
|
363 | 363 | #: Time till timeout, int |
364 | | - timeout=3, |
| 364 | + 'timeout': 3, |
365 | 365 |
|
366 | 366 | #: Noise radius, int |
367 | | - noise_radius=NOISE_RADIUS, |
| 367 | + 'noise_radius': NOISE_RADIUS, |
368 | 368 |
|
369 | 369 | #: Sight distance, int |
370 | | - sight_distance=SIGHT_DISTANCE, |
| 370 | + 'sight_distance': SIGHT_DISTANCE, |
371 | 371 |
|
372 | 372 | #: Max food age |
373 | | - max_food_age=max_food_age, |
| 373 | + 'max_food_age': max_food_age, |
374 | 374 |
|
375 | 375 | #: Shadow distance, int |
376 | | - shadow_distance=SHADOW_DISTANCE, |
| 376 | + 'shadow_distance': SHADOW_DISTANCE, |
377 | 377 |
|
378 | 378 | ### Informative |
379 | 379 | #: Name of the layout, str |
380 | | - layout_name=layout_name, |
| 380 | + 'layout_name': layout_name, |
381 | 381 |
|
382 | 382 | #: Name of the teams. Tuple of str |
383 | | - team_names=team_names, |
| 383 | + 'team_names': team_names, |
384 | 384 |
|
385 | 385 | #: Additional team info. Tuple of str|None |
386 | | - team_infos=team_infos, |
| 386 | + 'team_infos': team_infos, |
387 | 387 |
|
388 | 388 | #: Time each team needed, list of float |
389 | | - team_time=[0, 0], |
| 389 | + 'team_time': (0.0, 0.0), |
390 | 390 |
|
391 | 391 | # List of bot deaths, which counts the number of deaths per bot |
392 | 392 | # In other words, deaths[bot_idx] is the number of times the bot |
393 | 393 | # bot_idx has been killed until now. |
394 | | - deaths = [0]*4, |
| 394 | + 'deaths': [0] * 4, |
395 | 395 |
|
396 | 396 | # List of bot kills, which counts the number of kills per bot |
397 | 397 | # In other words, kills[bot_idx] is the number of times the bot |
398 | 398 | # bot_idx has killed another bot until now. |
399 | | - kills = [0]*4, |
| 399 | + 'kills': [0] * 4, |
400 | 400 |
|
401 | 401 | # List of boolean flags weather bot has been eaten since its last move |
402 | | - bot_was_killed = [False]*4, |
| 402 | + 'bot_was_killed': [False]*4, |
403 | 403 |
|
404 | 404 | # The noisy positions that the bot in `turn` has currently been shown. |
405 | 405 | # None, if not noisy |
406 | | - noisy_positions = [None] * 4, |
| 406 | + 'noisy_positions': [None] * 4, |
407 | 407 |
|
408 | 408 | #: The moves that the bots returned. Keeps only the recent one at the respective bot’s index. |
409 | | - requested_moves=[None] * 4, |
| 409 | + 'requested_moves': [None] * 4, |
410 | 410 |
|
411 | 411 | #: Messages the bots say. Keeps only the recent one at the respective bot’s index. |
412 | | - say=[""] * 4, |
| 412 | + 'say': [""] * 4, |
413 | 413 |
|
414 | 414 | ### Internal |
415 | 415 | #: Internal team representation |
416 | | - teams=[None] * 2, |
| 416 | + 'teams': [None] * 2, |
417 | 417 |
|
418 | 418 | #: Random number generator |
419 | | - rng=rng, |
| 419 | + 'rng': rng, |
420 | 420 |
|
421 | 421 | #: Timeout length, int, None |
422 | | - timeout_length=timeout_length, |
| 422 | + 'timeout_length': timeout_length, |
423 | 423 |
|
424 | 424 | #: Error limit. A team loses when the limit is reached, int |
425 | | - error_limit=error_limit, |
| 425 | + 'error_limit': error_limit, |
426 | 426 |
|
427 | 427 | #: Viewers, list |
428 | | - viewers=viewer_state['viewers'], |
| 428 | + 'viewers': viewer_state['viewers'], |
429 | 429 |
|
430 | 430 | #: Controller |
431 | | - controller=viewer_state['controller'] |
432 | | - ) |
| 431 | + 'controller': viewer_state['controller'] |
| 432 | + } |
433 | 433 |
|
434 | 434 | # Wait until the controller tells us that it is ready |
435 | 435 | # We then can send the initial maze |
@@ -590,20 +590,20 @@ def prepare_bot_state(game_state, idx=None): |
590 | 590 | 'error_count': [len(e) for e in game_state['errors'][:]], |
591 | 591 | 'food': [list(team_food) for team_food in game_state['food']], |
592 | 592 | 'shaded_food': shaded_food, |
593 | | - 'team_names': game_state['team_names'][:], |
594 | 593 | 'team_time': game_state['team_time'][:], |
595 | 594 | 'is_noisy': is_noisy, |
596 | 595 | 'round': game_state['round'], |
597 | 596 | 'turn': turn, |
598 | 597 | 'timeout_length': game_state['timeout_length'], |
599 | | - 'max_rounds': game_state['max_rounds'], |
600 | 598 | } |
601 | 599 |
|
602 | 600 | if bot_initialization: |
603 | 601 | bot_state.update({ |
604 | 602 | 'walls': game_state['walls'], # only in initial round |
605 | 603 | 'shape': game_state['shape'], # only in initial round |
606 | | - 'seed': seed # only used in set_initial phase |
| 604 | + 'seed': seed, # only used in set_initial phase |
| 605 | + 'max_rounds': game_state['max_rounds'], |
| 606 | + 'team_names': game_state['team_names'][:], |
607 | 607 | }) |
608 | 608 |
|
609 | 609 | return bot_state |
@@ -1027,8 +1027,8 @@ def check_exit_remote_teams(game_state): |
1027 | 1027 | pass |
1028 | 1028 |
|
1029 | 1029 |
|
1030 | | -def split_food(width, food): |
1031 | | - team_food = [set(), set()] |
| 1030 | +def split_food(width, food: list[Pos]): |
| 1031 | + team_food: tuple[set[Pos], set[Pos]] = (set(), set()) |
1032 | 1032 | for pos in food: |
1033 | 1033 | idx = pos[0] // (width // 2) |
1034 | 1034 | team_food[idx].add(pos) |
|
0 commit comments