|
16 | 16 | from .gamestate_filters import noiser, relocate_expired_food, update_food_age, in_homezone |
17 | 17 | from .layout import get_legal_positions, initial_positions |
18 | 18 | from .network import Controller, RemotePlayerFailure, RemotePlayerRecvTimeout, RemotePlayerSendError, ZMQPublisher |
19 | | -from .spec import GameState, Layout, Pos |
| 19 | +from .spec import GameState, Layout, Pos, TeamInitial, TeamState, TeamStateFinished |
20 | 20 | from .team import RemoteTeam, make_team |
21 | 21 | from .viewer import (AsciiViewer, ProgressViewer, ReplayWriter, ReplyToViewer, |
22 | 22 | ResultPrinter) |
@@ -660,89 +660,98 @@ def request_new_position(game_state): |
660 | 660 | return bot_reply |
661 | 661 |
|
662 | 662 |
|
663 | | -def prepare_bot_state(game_state, team_idx=None): |
| 663 | +def prepare_bot_state(game_state: GameState, team_idx=None) -> TeamState | TeamInitial | TeamStateFinished: |
664 | 664 | """ Prepares the bot’s game state for the current bot. |
665 | 665 |
|
666 | 666 | NB: This will update the game_state to store new noisy positions. |
667 | 667 | """ |
668 | | - if game_state['game_phase'] == 'INIT': |
669 | | - # We assume that we are in get_initial phase |
670 | | - turn = team_idx |
671 | | - bot_turn = None |
672 | | - seed = game_state['rng'].randint(0, sys.maxsize) |
673 | | - elif game_state['game_phase'] == 'FINISHED': |
674 | | - # Called for remote players in _exit |
675 | | - turn = team_idx |
676 | | - bot_turn = None |
677 | | - seed = None |
678 | | - elif game_state['game_phase'] == 'RUNNING': |
679 | | - turn = game_state['turn'] |
680 | | - bot_turn = game_state['turn'] // 2 |
681 | | - seed = None |
682 | | - else: |
683 | | - _logger.warning("Got bad game_state in prepare_bot_state") |
684 | | - return |
685 | | - |
686 | | - bot_position = game_state['bots'][turn] |
687 | | - own_team = turn % 2 |
688 | | - enemy_team = 1 - own_team |
689 | | - enemy_positions = game_state['bots'][enemy_team::2] |
690 | | - noised_positions = noiser(walls=game_state['walls'], |
691 | | - shape=game_state['shape'], |
692 | | - bot_position=bot_position, |
693 | | - enemy_positions=enemy_positions, |
694 | | - noise_radius=game_state['noise_radius'], |
695 | | - sight_distance=game_state['sight_distance'], |
696 | | - rng=game_state['rng']) |
697 | | - |
698 | | - |
699 | | - # Update noisy_positions in the game_state |
700 | | - # reset positions |
701 | | - game_state['noisy_positions'] = [None] * 4 |
702 | | - noisy_or_none = [ |
703 | | - noisy_pos if is_noisy else None |
704 | | - for is_noisy, noisy_pos in |
705 | | - zip(noised_positions['is_noisy'], noised_positions['enemy_positions']) |
706 | | - ] |
707 | | - game_state['noisy_positions'][enemy_team::2] = noisy_or_none |
708 | | - |
709 | | - bots = game_state['bots'][:] |
710 | | - bots[enemy_team::2] = noised_positions['enemy_positions'] |
711 | | - |
712 | | - is_noisy = [False for _ in range(4)] |
713 | | - is_noisy[enemy_team::2] = noised_positions['is_noisy'] |
714 | | - |
715 | | - shaded_food_own = list(pos for pos, age in game_state['food_age'][own_team].items() |
716 | | - if age > 0) |
717 | | - shaded_food = [[], []] |
718 | | - shaded_food[own_team] = shaded_food_own |
719 | | - |
720 | | - bot_state = { |
721 | | - 'bots': bots, |
722 | | - 'score': game_state['score'][:], |
723 | | - 'kills': game_state['kills'][:], |
724 | | - 'deaths': game_state['deaths'][:], |
725 | | - 'bot_was_killed': game_state['bot_was_killed'][:], |
726 | | - 'error_count': [len(e) for e in game_state['timeouts'][:]], |
727 | | - 'food': [list(team_food) for team_food in game_state['food']], |
728 | | - 'shaded_food': shaded_food, |
729 | | - 'team_time': game_state['team_time'][:], |
730 | | - 'is_noisy': is_noisy, |
731 | | - 'round': game_state['round'], |
732 | | - 'turn': turn, |
733 | | - 'timeout_length': game_state['timeout_length'], |
734 | | - } |
| 668 | + match game_state['game_phase']: |
| 669 | + case "INIT": |
| 670 | + turn = team_idx |
| 671 | + seed = game_state['rng'].randint(0, sys.maxsize) |
| 672 | + |
| 673 | + team_state_initial: TeamInitial = { |
| 674 | + 'walls': game_state['walls'], |
| 675 | + 'shape': game_state['shape'], |
| 676 | + 'seed': seed, |
| 677 | + 'max_rounds': game_state['max_rounds'], |
| 678 | + 'team_names': game_state['team_names'][:], |
| 679 | + 'timeout_length': game_state['timeout_length'], |
| 680 | + } |
| 681 | + return team_state_initial |
| 682 | + case "RUNNING": |
| 683 | + |
| 684 | + turn = game_state['turn'] |
| 685 | + |
| 686 | + bot_position = game_state['bots'][turn] |
| 687 | + own_team = turn % 2 |
| 688 | + enemy_team = 1 - own_team |
| 689 | + enemy_positions = game_state['bots'][enemy_team::2] |
| 690 | + noised_positions = noiser(walls=game_state['walls'], |
| 691 | + shape=game_state['shape'], |
| 692 | + bot_position=bot_position, |
| 693 | + enemy_positions=enemy_positions, |
| 694 | + noise_radius=game_state['noise_radius'], |
| 695 | + sight_distance=game_state['sight_distance'], |
| 696 | + rng=game_state['rng']) |
| 697 | + |
| 698 | + # Update noisy_positions in the game_state |
| 699 | + # reset positions |
| 700 | + game_state['noisy_positions'] = [None] * 4 |
| 701 | + noisy_or_none = [ |
| 702 | + noisy_pos if is_noisy else None |
| 703 | + for is_noisy, noisy_pos in |
| 704 | + zip(noised_positions['is_noisy'], noised_positions['enemy_positions']) |
| 705 | + ] |
| 706 | + game_state['noisy_positions'][enemy_team::2] = noisy_or_none |
| 707 | + |
| 708 | + bots = game_state['bots'][:] |
| 709 | + bots[enemy_team::2] = noised_positions['enemy_positions'] |
| 710 | + |
| 711 | + is_noisy = [False for _ in range(4)] |
| 712 | + is_noisy[enemy_team::2] = noised_positions['is_noisy'] |
| 713 | + |
| 714 | + shaded_food_own = list(pos for pos, age in game_state['food_age'][own_team].items() |
| 715 | + if age > 0) |
| 716 | + shaded_food = [[], []] |
| 717 | + shaded_food[own_team] = shaded_food_own |
| 718 | + |
| 719 | + bot_state: TeamState = { |
| 720 | + 'bots': bots, |
| 721 | + 'score': game_state['score'][:], |
| 722 | + 'kills': game_state['kills'][:], |
| 723 | + 'deaths': game_state['deaths'][:], |
| 724 | + 'bot_was_killed': game_state['bot_was_killed'][:], |
| 725 | + 'error_count': [len(e) for e in game_state['timeouts'][:]], |
| 726 | + 'food': [list(team_food) for team_food in game_state['food']], |
| 727 | + 'shaded_food': shaded_food, |
| 728 | + 'team_time': game_state['team_time'][:], |
| 729 | + 'is_noisy': is_noisy, |
| 730 | + 'round': game_state['round'], |
| 731 | + 'turn': turn, |
| 732 | + } |
| 733 | + return bot_state |
| 734 | + |
| 735 | + case "FINISHED": |
| 736 | + # Called for remote players in _exit |
| 737 | + turn = team_idx |
| 738 | + # TODO: is turn needed? |
| 739 | + |
| 740 | + team_state_final: TeamStateFinished = { |
| 741 | + 'bots': game_state['bots'][:], |
| 742 | + 'score': game_state['score'][:], |
| 743 | + 'kills': game_state['kills'][:], |
| 744 | + 'deaths': game_state['deaths'][:], |
| 745 | + 'bot_was_killed': game_state['bot_was_killed'][:], |
| 746 | + 'error_count': [len(e) for e in game_state['timeouts'][:]], |
| 747 | + 'food': [list(team_food) for team_food in game_state['food']], |
| 748 | + 'team_time': game_state['team_time'][:], |
| 749 | + 'round': game_state['round'], |
| 750 | + 'turn': turn, |
| 751 | + } |
| 752 | + return team_state_final |
735 | 753 |
|
736 | | - if game_state['game_phase'] == 'INIT': |
737 | | - bot_state.update({ |
738 | | - 'walls': game_state['walls'], # only in initial round |
739 | | - 'shape': game_state['shape'], # only in initial round |
740 | | - 'seed': seed, # only used in set_initial phase |
741 | | - 'max_rounds': game_state['max_rounds'], |
742 | | - 'team_names': game_state['team_names'][:], |
743 | | - }) |
744 | | - |
745 | | - return bot_state |
| 754 | + raise PelitaIllegalGameState("Got bad game_state in prepare_bot_state") |
746 | 755 |
|
747 | 756 |
|
748 | 757 | def update_viewers(game_state): |
|
0 commit comments