Source code for bot_api.mapper.event_mapper

import json
from typing import Any, Dict, Union

from ..base_bot_abc import BaseBotABC
from ..bot_exception import BotException
from ..events import (
    BotDeathEvent,
    BulletFiredEvent,
    BulletHitBotEvent,
    BulletHitBulletEvent,
    BulletHitWallEvent,
    DeathEvent,
    HitBotEvent,
    HitByBulletEvent,
    HitWallEvent,
    ScannedBotEvent,
    SkippedTurnEvent,
    TeamMessageEvent,
    TickEvent,
    WonRoundEvent, BotEvent
)
from robocode_tank_royale.schema import (
    BotDeathEvent as SchemaBotDeathEvent,
    BotHitBotEvent as SchemaBotHitBotEvent,
    BotHitWallEvent as SchemaBotHitWallEvent,
    BulletFiredEvent as SchemaBulletFiredEvent,
    BulletHitBotEvent as SchemaBulletHitBotEvent,
    BulletHitBulletEvent as SchemaBulletHitBulletEvent,
    BulletHitWallEvent as SchemaBulletHitWallEvent,
    Event as SchemaEvent,
    ScannedBotEvent as SchemaScannedBotEvent,
    SkippedTurnEvent as SchemaSkippedTurnEvent,
    TeamMessageEvent as SchemaTeamMessageEvent,
    TickEventForBot as SchemaTickEvent,
    WonRoundEvent as SchemaWonRoundEvent
)
from .bot_state_mapper import BotStateMapper
from .bullet_state_mapper import BulletStateMapper


[docs] class EventMapper: """Utility class for mapping events."""
[docs] @staticmethod def map_tick_event(event: SchemaTickEvent, base_bot: BaseBotABC) -> TickEvent: """Map a schema TickEventForBot to a bot-api TickEvent.""" mapped_events = None assert event.events is not None non_null_events: list[SchemaEvent] = [] for e in event.events: assert e is not None non_null_events.append(e) mapped_events = EventMapper._map_events(non_null_events, base_bot) assert mapped_events is not None return TickEvent( event.turn_number, event.round_number, BotStateMapper.map(event.bot_state), BulletStateMapper.map(event.bullet_states), mapped_events, )
@staticmethod def _map_events(events: list[SchemaEvent], base_bot: BaseBotABC) -> list[BotEvent] | None: """Map a collection of schema events to bot-api events.""" game_bot_events: list[BotEvent] = list() for event in events: game_bot_events.append(EventMapper.map_event(event, base_bot)) return game_bot_events
[docs] @staticmethod def map_event(event: SchemaEvent, base_bot: BaseBotABC) -> BotEvent: """Map a schema event to a bot-api event.""" event_type = type(event).__name__ if isinstance(event, SchemaBotDeathEvent): return EventMapper._map_bot_death_event(event, base_bot.my_id) if isinstance(event, SchemaBotHitBotEvent): return EventMapper._map_hit_bot_event(event) if isinstance(event, SchemaBotHitWallEvent): return EventMapper._map_hit_wall_event(event) if isinstance(event, SchemaBulletFiredEvent): return EventMapper._map_bullet_fired_event(event) if isinstance(event, SchemaBulletHitBotEvent): return EventMapper._map_bullet_hit_bot_event(event, base_bot.my_id) if isinstance(event, SchemaBulletHitBulletEvent): return EventMapper._map_bullet_hit_bullet_event(event) if isinstance(event, SchemaBulletHitWallEvent): return EventMapper._map_bullet_hit_wall_event(event) if isinstance(event, SchemaScannedBotEvent): return EventMapper._map_scanned_bot_event(event) if isinstance(event, SchemaSkippedTurnEvent): return EventMapper.map_skipped_turn_event(event) if isinstance(event, SchemaWonRoundEvent): return EventMapper._map_won_round_event(event) if isinstance(event, SchemaTeamMessageEvent): return EventMapper._map_team_message_event(event) raise BotException(f"No mapping exists for event type: {event_type}")
@staticmethod def _map_bot_death_event(source: SchemaBotDeathEvent, my_bot_id: int) -> Union[DeathEvent, BotDeathEvent]: """Map a schema BotDeathEvent to a bot-api event.""" if source.victim_id == my_bot_id: return DeathEvent(source.turn_number) return BotDeathEvent(source.turn_number, source.victim_id) @staticmethod def _map_hit_bot_event(source: SchemaBotHitBotEvent) -> HitBotEvent: """Map a schema BotHitBotEvent to a bot-api HitBotEvent.""" return HitBotEvent( source.turn_number, source.victim_id, source.energy, source.x, source.y, source.rammed ) @staticmethod def _map_hit_wall_event(source: SchemaBotHitWallEvent) -> HitWallEvent: """Map a schema BotHitWallEvent to a bot-api HitWallEvent.""" return HitWallEvent(source.turn_number) @staticmethod def _map_bullet_fired_event(source: SchemaBulletFiredEvent) -> BulletFiredEvent: """Map a schema BulletFiredEvent to a bot-api BulletFiredEvent.""" return BulletFiredEvent( source.turn_number, BulletStateMapper.map(source.bullet) ) @staticmethod def _map_bullet_hit_bot_event(source: SchemaBulletHitBotEvent, my_bot_id: int) -> Union[ HitByBulletEvent, BulletHitBotEvent]: """Map a schema BulletHitBotEvent to a bot-api event.""" bullet = BulletStateMapper.map(source.bullet) if source.victim_id == my_bot_id: return HitByBulletEvent( source.turn_number, bullet, source.damage, source.energy ) return BulletHitBotEvent( source.turn_number, source.victim_id, bullet, source.damage, source.energy ) @staticmethod def _map_bullet_hit_bullet_event(source: SchemaBulletHitBulletEvent) -> BulletHitBulletEvent: """Map a schema BulletHitBulletEvent to a bot-api BulletHitBulletEvent.""" return BulletHitBulletEvent( source.turn_number, BulletStateMapper.map(source.bullet), BulletStateMapper.map(source.hit_bullet) ) @staticmethod def _map_bullet_hit_wall_event(source: SchemaBulletHitWallEvent) -> BulletHitWallEvent: """Map a schema BulletHitWallEvent to a bot-api BulletHitWallEvent.""" return BulletHitWallEvent( source.turn_number, BulletStateMapper.map(source.bullet) ) @staticmethod def _map_scanned_bot_event(source: SchemaScannedBotEvent) -> ScannedBotEvent: """Map a schema ScannedBotEvent to a bot-api ScannedBotEvent.""" return ScannedBotEvent( source.turn_number, source.scanned_by_bot_id, source.scanned_bot_id, source.energy, source.x, source.y, source.direction, source.speed )
[docs] @staticmethod def map_skipped_turn_event(source: SchemaSkippedTurnEvent) -> SkippedTurnEvent: """Map a schema SkippedTurnEvent to a bot-api SkippedTurnEvent.""" return SkippedTurnEvent(source.turn_number)
@staticmethod def _map_won_round_event(source: SchemaWonRoundEvent) -> WonRoundEvent: """Map a schema WonRoundEvent to a bot-api WonRoundEvent.""" return WonRoundEvent(source.turn_number) @staticmethod def _map_team_message_event(source: SchemaTeamMessageEvent) -> TeamMessageEvent: """Map a schema TeamMessageEvent to a bot-api TeamMessageEvent. Uses the message_type field to look up registered types and deserialize into typed objects. Handles Color fields by converting hex strings. """ from ..team_message import deserialize_team_message message = source.message if message is None: # type: ignore raise BotException("message in TeamMessageEvent is None") message_type = source.message_type if message_type is None: raise BotException("message_type in TeamMessageEvent is None") try: message_object = deserialize_team_message(message, message_type) return TeamMessageEvent(source.turn_number, message_object, source.sender_id) except json.JSONDecodeError as e: raise BotException(f"Could not parse team message: {str(e)}")