text: from enum import Enum, auto
  
  from pysc2.lib import actions
  from pysc2.lib.actions import FunctionCall
  
  from gym import spaces
  from absl import logging
  
  # TERRAN_FUNCTION_NAMES = ['no_op', 'move_camera', 'select_point', 'select_rect', 'select_control_group', 'select_unit', 'select_idle_worker', 'select_army', 'unload', 'build_queue', 'Attack_screen', 'Attack_minimap', 'Attack_Attack_screen', 'Attack_Attack_minimap', 'Attack_AttackBuilding_screen', 'Attack_AttackBuilding_minimap', 'Attack_Redirect_screen', 'Scan_Move_screen', 'Scan_Move_minimap', 'Behavior_CloakOff_quick', 'Behavior_CloakOff_Banshee_quick', 'Behavior_CloakOff_Ghost_quick', 'Behavior_CloakOn_quick', 'Behavior_CloakOn_Banshee_quick', 'Behavior_CloakOn_Ghost_quick', 'Behavior_HoldFireOff_quick', 'Behavior_HoldFireOn_quick', 'Behavior_HoldFireOff_Ghost_quick', 'Behavior_HoldFireOn_Ghost_quick', 'Build_Armory_screen', 'Build_Barracks_screen', 'Build_Bunker_screen', 'Build_CommandCenter_screen', 'Build_EngineeringBay_screen', 'Build_Factory_screen', 'Build_FusionCore_screen', 'Build_GhostAcademy_screen', 'Build_MissileTurret_screen', 'Build_Nuke_quick', 'Build_Reactor_quick', 'Build_Reactor_screen', 'Build_Reactor_Barracks_quick', 'Build_Reactor_Barracks_screen', 'Build_Reactor_Factory_quick', 'Build_Reactor_Factory_screen', 'Build_Reactor_Starport_quick', 'Build_Reactor_Starport_screen', 'Build_Refinery_screen', 'Build_SensorTower_screen', 'Build_Starport_screen', 'Build_SupplyDepot_screen', 'Build_TechLab_quick', 'Build_TechLab_screen', 'Build_TechLab_Barracks_quick', 'Build_TechLab_Barracks_screen', 'Build_TechLab_Factory_quick', 'Build_TechLab_Factory_screen', 'Build_TechLab_Starport_quick', 'Build_TechLab_Starport_screen', 'BurrowDown_quick', 'BurrowUp_WidowMine_quick', 'Cancel_quick', 'Cancel_BarracksAddOn_quick', 'Cancel_BuildInProgress_quick', 'Cancel_FactoryAddOn_quick', 'Cancel_LockOn_quick', 'Cancel_MorphOrbital_quick', 'Cancel_MorphPlanetaryFortress_quick', 'Cancel_MorphThorExplosiveMode_quick', 'Cancel_Nuke_quick', 'Cancel_StarportAddOn_quick', 'Cancel_Last_quick', 'Cancel_Queue1_quick', 'Cancel_Queue5_quick', 'Cancel_QueueAddOn_quick', 'Cancel_QueueCancelToSelection_quick', 'Cancel_QueuePassive_quick', 'Cancel_QueuePassiveCancelToSelection_quick', 'Effect_AutoTurret_screen', 'Effect_CalldownMULE_screen', 'Effect_EMP_screen', 'Effect_GhostSnipe_screen', 'Effect_Heal_screen', 'Effect_Heal_autocast', 'Effect_HunterSeekerMissile_screen', 'Effect_KD8Charge_screen', 'Effect_LockOn_screen', 'Effect_MedivacIgniteAfterburners_quick', 'Effect_NukeCalldown_screen', 'Effect_PointDefenseDrone_screen', 'Effect_Repair_screen', 'Effect_Repair_autocast', 'Effect_Repair_Mule_screen', 'Effect_Repair_Mule_autocast', 'Effect_Repair_SCV_screen', 'Effect_Repair_SCV_autocast', 'Effect_Salvage_quick', 'Effect_Scan_screen', 'Effect_Stim_quick', 'Effect_Stim_Marauder_quick', 'Effect_Stim_Marauder_Redirect_quick', 'Effect_Stim_Marine_quick', 'Effect_Stim_Marine_Redirect_quick', 'Effect_SupplyDrop_screen', 'Effect_TacticalJump_screen', 'Effect_WidowMineAttack_screen', 'Effect_WidowMineAttack_autocast', 'Effect_YamatoGun_screen', 'Halt_Building_quick', 'Halt_TerranBuild_quick', 'Harvest_Gather_screen', 'Harvest_Gather_Mule_screen', 'Harvest_Gather_SCV_screen', 'Harvest_Return_quick', 'Harvest_Return_Mule_quick', 'Harvest_Return_SCV_quick', 'HoldPosition_quick', 'HoldPosition_Hold_quick', 'Land_screen', 'Land_Barracks_screen', 'Land_CommandCenter_screen', 'Land_Factory_screen', 'Land_OrbitalCommand_screen', 'Land_Starport_screen', 'Lift_quick', 'Lift_Barracks_quick', 'Lift_CommandCenter_quick', 'Lift_Factory_quick', 'Lift_OrbitalCommand_quick', 'Lift_Starport_quick', 'Load_screen', 'Load_Bunker_screen', 'Load_Medivac_screen', 'LoadAll_quick', 'LoadAll_CommandCenter_quick', 'Morph_Hellbat_quick', 'Morph_Hellion_quick', 'Morph_LiberatorAAMode_quick', 'Morph_LiberatorAGMode_screen', 'Morph_OrbitalCommand_quick', 'Morph_PlanetaryFortress_quick', 'Morph_SiegeMode_quick', 'Morph_SupplyDepot_Lower_quick', 'Morph_SupplyDepot_Raise_quick', 'Morph_ThorExplosiveMode_quick', 'Morph_ThorHighImpactMode_quick', 'Morph_Unsiege_quick', 'Morph_VikingAssaultMode_quick', 'Morph_VikingFighterMode_quick', 'Move_screen', 'Move_minimap', 'Patrol_screen', 'Patrol_minimap', 'Rally_Units_screen', 'Rally_Units_minimap', 'Rally_Building_screen', 'Rally_Building_minimap', 'Rally_Morphing_Unit_screen', 'Rally_Morphing_Unit_minimap', 'Rally_Workers_screen', 'Rally_Workers_minimap', 'Rally_CommandCenter_screen', 'Rally_CommandCenter_minimap', 'Research_AdvancedBallistics_quick', 'Research_BansheeCloakingField_quick', 'Research_BansheeHyperflightRotors_quick', 'Research_BattlecruiserWeaponRefit_quick', 'Research_CombatShield_quick', 'Research_ConcussiveShells_quick', 'Research_DrillingClaws_quick', 'Research_HiSecAutoTracking_quick', 'Research_HighCapacityFuelTanks_quick', 'Research_InfernalPreigniter_quick', 'Research_SmartServos_quick', 'Research_NeosteelFrame_quick', 'Research_PersonalCloaking_quick', 'Research_RavenCorvidReactor_quick', 'Research_RavenRecalibratedExplosives_quick', 'Research_Stimpack_quick', 'Research_TerranInfantryArmor_quick', 'Research_TerranInfantryArmorLevel1_quick', 'Research_TerranInfantryArmorLevel2_quick', 'Research_TerranInfantryArmorLevel3_quick', 'Research_TerranInfantryWeapons_quick', 'Research_TerranInfantryWeaponsLevel1_quick', 'Research_TerranInfantryWeaponsLevel2_quick', 'Research_TerranInfantryWeaponsLevel3_quick', 'Research_TerranShipWeapons_quick', 'Research_TerranShipWeaponsLevel1_quick', 'Research_TerranShipWeaponsLevel2_quick', 'Research_TerranShipWeaponsLevel3_quick', 'Research_TerranStructureArmorUpgrade_quick', 'Research_TerranVehicleAndShipPlating_quick', 'Research_TerranVehicleAndShipPlatingLevel1_quick', 'Research_TerranVehicleAndShipPlatingLevel2_quick', 'Research_TerranVehicleAndShipPlatingLevel3_quick', 'Research_TerranVehicleWeapons_quick', 'Research_TerranVehicleWeaponsLevel1_quick', 'Research_TerranVehicleWeaponsLevel2_quick', 'Research_TerranVehicleWeaponsLevel3_quick', 'Smart_screen', 'Smart_minimap', 'Stop_quick', 'Stop_Building_quick', 'Stop_Redirect_quick', 'Stop_Stop_quick', 'Train_Banshee_quick', 'Train_Battlecruiser_quick', 'Train_Cyclone_quick', 'Train_Ghost_quick', 'Train_Hellbat_quick', 'Train_Hellion_quick', 'Train_Liberator_quick', 'Train_Marauder_quick', 'Train_Marine_quick', 'Train_Medivac_quick', 'Train_Raven_quick', 'Train_Reaper_quick', 'Train_SCV_quick', 'Train_SiegeTank_quick', 'Train_Thor_quick', 'Train_VikingFighter_quick', 'Train_WidowMine_quick', 'UnloadAll_quick', 'UnloadAll_Bunker_quick', 'UnloadAll_CommandCenter_quick', 'UnloadAllAt_screen', 'UnloadAllAt_minimap', 'UnloadAllAt_Medivac_screen', 'UnloadAllAt_Medivac_minimap', 'Effect_AntiArmorMissile_screen', 'Effect_InterferenceMatrix_screen', 'Effect_Repair_RepairDrone_screen', 'Effect_Repair_RepairDrone_autocast', 'Effect_RepairDrone_screen', 'Research_CycloneRapidFireLaunchers_quick', 'Effect_Scan_minimap', 'Effect_TacticalJump_minimap', 'Morph_LiberatorAGMode_minimap', 'Attack_Battlecruiser_screen', 'Attack_Battlecruiser_minimap', 'Effect_LockOn_autocast', 'HoldPosition_Battlecruiser_quick', 'Move_Battlecruiser_screen', 'Move_Battlecruiser_minimap', 'Move_Move_screen', 'Move_Move_minimap', 'Patrol_Battlecruiser_screen', 'Patrol_Battlecruiser_minimap', 'Patrol_Patrol_screen', 'Patrol_Patrol_minimap', 'Research_CycloneLockOnDamage_quick', 'Stop_Battlecruiser_quick', 'Research_EnhancedShockwaves_quick']
  # PROTOSS_FUNCTION_NAMES = ['no_op', 'move_camera', 'select_point', 'select_rect', 'select_control_group', 'select_unit', 'select_idle_worker', 'select_army', 'select_warp_gates', 'unload', 'build_queue', 'Attack_screen', 'Attack_minimap', 'Attack_Attack_screen', 'Attack_Attack_minimap', 'Attack_AttackBuilding_screen', 'Attack_AttackBuilding_minimap', 'Attack_Redirect_screen', 'Scan_Move_screen', 'Scan_Move_minimap', 'Behavior_PulsarBeamOff_quick', 'Behavior_PulsarBeamOn_quick', 'Build_Assimilator_screen', 'Build_CyberneticsCore_screen', 'Build_DarkShrine_screen', 'Build_FleetBeacon_screen', 'Build_Forge_screen', 'Build_Gateway_screen', 'Build_Interceptors_quick', 'Build_Interceptors_autocast', 'Build_Nexus_screen', 'Build_PhotonCannon_screen', 'Build_Pylon_screen', 'Build_RoboticsBay_screen', 'Build_RoboticsFacility_screen', 'Build_Stargate_screen', 'Build_StasisTrap_screen', 'Build_TemplarArchive_screen', 'Build_TwilightCouncil_screen', 'Cancel_quick', 'Cancel_AdeptPhaseShift_quick', 'Cancel_AdeptShadePhaseShift_quick', 'Cancel_BuildInProgress_quick', 'Cancel_GravitonBeam_quick', 'Cancel_MorphMothership_quick', 'Cancel_StasisTrap_quick', 'Cancel_Last_quick', 'Cancel_HangarQueue5_quick', 'Cancel_Queue1_quick', 'Cancel_Queue5_quick', 'Cancel_QueueAddOn_quick', 'Cancel_QueueCancelToSelection_quick', 'Cancel_QueuePassive_quick', 'Cancel_QueuePassiveCancelToSelection_quick', 'Effect_AdeptPhaseShift_screen', 'Effect_Blink_screen', 'Effect_Blink_Stalker_screen', 'Effect_ShadowStride_screen', 'Effect_Charge_screen', 'Effect_Charge_autocast', 'Effect_ChronoBoost_screen', 'Effect_Feedback_screen', 'Effect_ForceField_screen', 'Effect_GravitonBeam_screen', 'Effect_GuardianShield_quick', 'Effect_ImmortalBarrier_quick', 'Effect_ImmortalBarrier_autocast', 'Effect_MassRecall_screen', 'Effect_MassRecall_Mothership_screen', 'Effect_MassRecall_MothershipCore_screen', 'Effect_OracleRevelation_screen', 'Effect_PhotonOvercharge_screen', 'Effect_PsiStorm_screen', 'Effect_PurificationNova_screen', 'Effect_TimeWarp_screen', 'Effect_VoidRayPrismaticAlignment_quick', 'Hallucination_Adept_quick', 'Hallucination_Archon_quick', 'Hallucination_Colossus_quick', 'Hallucination_Disruptor_quick', 'Hallucination_HighTemplar_quick', 'Hallucination_Immortal_quick', 'Hallucination_Oracle_quick', 'Hallucination_Phoenix_quick', 'Hallucination_Probe_quick', 'Hallucination_Stalker_quick', 'Hallucination_VoidRay_quick', 'Hallucination_WarpPrism_quick', 'Hallucination_Zealot_quick', 'Halt_quick', 'Halt_Building_quick', 'Harvest_Gather_screen', 'Harvest_Gather_Probe_screen', 'Harvest_Return_quick', 'Harvest_Return_Probe_quick', 'HoldPosition_quick' 'HoldPosition_Hold_quick', 'Load_screen', 'Load_WarpPrism_screen', 'LoadAll_quick', 'Morph_Archon_quick', 'Morph_Gateway_quick', 'Morph_Mothership_quick', 'Morph_WarpGate_quick', 'Morph_WarpPrismPhasingMode_quick', 'Morph_WarpPrismTransportMode_quick', 'Move_screen', 'Move_minimap', 'Patrol_screen', 'Patrol_minimap', 'Rally_Units_screen', 'Rally_Units_minimap', 'Rally_Building_screen', 'Rally_Building_minimap', 'Rally_Morphing_Unit_screen', 'Rally_Morphing_Unit_minimap', 'Rally_Workers_screen', 'Rally_Workers_minimap', 'Rally_Nexus_screen', 'Rally_Nexus_minimap', 'Research_AdeptResonatingGlaives_quick', 'Research_Blink_quick', 'Research_Charge_quick', 'Research_ExtendedThermalLance_quick', 'Research_GraviticBooster_quick', 'Research_GraviticDrive_quick', 'Research_InterceptorGravitonCatapult_quick', 'Research_PhoenixAnionPulseCrystals_quick', 'Research_ProtossAirArmor_quick', 'Research_ProtossAirArmorLevel1_quick', 'Research_ProtossAirArmorLevel2_quick', 'Research_ProtossAirArmorLevel3_quick', 'Research_ProtossAirWeapons_quick', 'Research_ProtossAirWeaponsLevel1_quick', 'Research_ProtossAirWeaponsLevel2_quick', 'Research_ProtossAirWeaponsLevel3_quick', 'Research_ProtossGroundArmor_quick', 'Research_ProtossGroundArmorLevel1_quick', 'Research_ProtossGroundArmorLevel2_quick', 'Research_ProtossGroundArmorLevel3_quick', 'Research_ProtossGroundWeapons_quick', 'Research_ProtossGroundWeaponsLevel1_quick', 'Research_ProtossGroundWeaponsLevel2_quick', 'Research_ProtossGroundWeaponsLevel3_quick', 'Research_ProtossShields_quick', 'Research_ProtossShieldsLevel1_quick', 'Research_ProtossShieldsLevel2_quick', 'Research_ProtossShieldsLevel3_quick', 'Research_PsiStorm_quick', 'Research_ShadowStrike_quick', 'Research_WarpGate_quick', 'Smart_screen', 'Smart_minimap', 'Stop_quick', 'Stop_Building_quick', 'Stop_Redirect_quick', 'Stop_Stop_quick', 'Train_Adept_quick', 'Train_Carrier_quick', 'Train_Colossus_quick', 'Train_DarkTemplar_quick', 'Train_Disruptor_quick', 'Train_HighTemplar_quick', 'Train_Immortal_quick', 'Train_MothershipCore_quick', 'Train_Observer_quick', 'Train_Oracle_quick', 'Train_Phoenix_quick', 'Train_Probe_quick', 'Train_Sentry_quick', 'Train_Stalker_quick', 'Train_Tempest_quick', 'Train_VoidRay_quick', 'Train_WarpPrism_quick', 'Train_Zealot_quick', 'TrainWarp_Adept_screen', 'TrainWarp_DarkTemplar_screen', 'TrainWarp_HighTemplar_screen', 'TrainWarp_Sentry_screen', 'TrainWarp_Stalker_screen', 'TrainWarp_Zealot_screen', 'UnloadAll_quick', 'UnloadAllAt_screen', 'UnloadAllAt_minimap', 'UnloadAllAt_WarpPrism_screen', 'UnloadAllAt_WarpPrism_minimap', 'Build_ShieldBattery_screen', 'Effect_ChronoBoostEnergyCost_screen', 'Effect_MassRecall_Nexus_screen', 'Effect_Restore_screen', 'Effect_Restore_autocast', 'Morph_ObserverMode_quick', 'Morph_SurveillanceMode_quick', 'Train_Mothership_quick', 'Effect_Blink_minimap', 'Effect_Blink_Stalker_minimap', 'Effect_ShadowStride_minimap', 'Cancel_VoidRayPrismaticAlignment_quick', 'Effect_AdeptPhaseShift_minimap', 'Effect_MassRecall_StrategicRecall_screen', 'Morph_WarpGate_autocast', 'Move_Move_screen', 'Move_Move_minimap', 'Patrol_Patrol_screen', 'Patrol_Patrol_minimap']
  # ZERG_FUNCTION_NAMES = ['no_op', 'move_camera', 'select_point', 'select_rect', 'select_control_group', 'select_unit', 'select_idle_worker', 'select_army', 'select_larva', 'unload', 'build_queue', 'Attack_screen', 'Attack_minimap', 'Attack_Attack_screen', 'Attack_Attack_minimap', 'Attack_AttackBuilding_screen', 'Attack_AttackBuilding_minimap', 'Attack_Redirect_screen', 'Scan_Move_screen', 'Scan_Move_minimap', 'Behavior_GenerateCreepOff_quick', 'Behavior_GenerateCreepOn_quick', 'Behavior_BuildingAttackOff_quick', 'Behavior_BuildingAttackOn_quick', 'Behavior_HoldFireOff_Lurker_quick', 'Behavior_HoldFireOn_Lurker_quick', 'Build_BanelingNest_screen', 'Build_CreepTumor_screen', 'Build_CreepTumor_Queen_screen', 'Build_CreepTumor_Tumor_screen', 'Build_EvolutionChamber_screen', 'Build_Extractor_screen', 'Build_Hatchery_screen', 'Build_HydraliskDen_screen', 'Build_InfestationPit_screen', 'Build_NydusNetwork_screen', 'Build_NydusWorm_screen', 'Build_RoachWarren_screen', 'Build_SpawningPool_screen', 'Build_SpineCrawler_screen', 'Build_Spire_screen', 'Build_SporeCrawler_screen', 'Build_UltraliskCavern_screen', 'BurrowDown_quick', 'BurrowDown_Baneling_quick', 'BurrowDown_Drone_quick', 'BurrowDown_Hydralisk_quick', 'BurrowDown_Infestor_quick', 'BurrowDown_InfestorTerran_quick', 'BurrowDown_Lurker_quick', 'BurrowDown_Queen_quick', 'BurrowDown_Ravager_quick', 'BurrowDown_Roach_quick', 'BurrowDown_SwarmHost_quick', 'BurrowDown_Ultralisk_quick', 'BurrowDown_WidowMine_quick', 'BurrowDown_Zergling_quick', 'BurrowUp_quick', 'BurrowUp_autocast', 'BurrowUp_Baneling_quick', 'BurrowUp_Baneling_autocast', 'BurrowUp_Drone_quick', 'BurrowUp_Hydralisk_quick', 'BurrowUp_Hydralisk_autocast', 'BurrowUp_Infestor_quick', 'BurrowUp_InfestorTerran_quick', 'BurrowUp_InfestorTerran_autocast', 'BurrowUp_Lurker_quick', 'BurrowUp_Queen_quick', 'BurrowUp_Queen_autocast', 'BurrowUp_Ravager_quick', 'BurrowUp_Ravager_autocast', 'BurrowUp_Roach_quick', 'BurrowUp_Roach_autocast', 'BurrowUp_SwarmHost_quick', 'BurrowUp_Ultralisk_quick', 'BurrowUp_Ultralisk_autocast', 'BurrowUp_Zergling_quick', 'BurrowUp_Zergling_autocast', 'Cancel_quick', 'Cancel_BuildInProgress_quick', 'Cancel_CreepTumor_quick', 'Cancel_MorphBroodlord_quick', 'Cancel_MorphGreaterSpire_quick', 'Cancel_MorphHive_quick', 'Cancel_MorphLair_quick', 'Cancel_MorphLurker_quick', 'Cancel_MorphLurkerDen_quick', 'Cancel_MorphOverlordTransport_quick', 'Cancel_MorphOverseer_quick', 'Cancel_MorphRavager_quick', 'Cancel_NeuralParasite_quick', 'Cancel_SpineCrawlerRoot_quick', 'Cancel_SporeCrawlerRoot_quick', 'Cancel_Last_quick', 'Cancel_Queue1_quick', 'Cancel_Queue5_quick', 'Cancel_QueueAddOn_quick', 'Cancel_QueueCancelToSelection_quick', 'Cancel_QueuePassive_quick', 'Cancel_QueuePassiveCancelToSelection_quick', 'Effect_Abduct_screen', 'Effect_BlindingCloud_screen', 'Effect_CausticSpray_screen', 'Effect_Contaminate_screen', 'Effect_CorrosiveBile_screen', 'Effect_Explode_quick', 'Effect_FungalGrowth_screen', 'Effect_InfestedTerrans_screen', 'Effect_InjectLarva_screen', 'Effect_LocustSwoop_screen', 'Effect_NeuralParasite_screen', 'Effect_ParasiticBomb_screen', 'Effect_SpawnChangeling_quick', 'Effect_SpawnLocusts_screen', 'Effect_Transfusion_screen', 'Effect_ViperConsume_screen', 'Halt_Building_quick', 'Harvest_Gather_screen', 'Harvest_Gather_Drone_screen', 'Harvest_Return_quick', 'Harvest_Return_Drone_quick', 'HoldPosition_quick', 'HoldPosition_Hold_quick', 'Load_screen', 'Load_NydusNetwork_screen', 'Load_NydusWorm_screen', 'Load_Overlord_screen', 'LoadAll_quick', 'Morph_BroodLord_quick', 'Morph_GreaterSpire_quick', 'Morph_Hive_quick', 'Morph_Lair_quick', 'Morph_Lurker_quick', 'Morph_LurkerDen_quick', 'Morph_OverlordTransport_quick', 'Morph_Overseer_quick', 'Morph_OverseerMode_quick', 'Morph_Ravager_quick', 'Morph_Root_screen', 'Morph_SpineCrawlerRoot_screen', 'Morph_SporeCrawlerRoot_screen', 'Morph_Uproot_quick', 'Morph_SpineCrawlerUproot_quick', 'Morph_SporeCrawlerUproot_quick', 'Move_screen', 'Move_minimap', 'Patrol_screen', 'Patrol_minimap', 'Rally_Units_screen', 'Rally_Units_minimap', 'Rally_Building_screen', 'Rally_Building_minimap', 'Rally_Hatchery_Units_screen', 'Rally_Hatchery_Units_minimap', 'Rally_Morphing_Unit_screen', 'Rally_Morphing_Unit_minimap', 'Rally_Workers_screen', 'Rally_Workers_minimap', 'Rally_Hatchery_Workers_screen', 'Rally_Hatchery_Workers_minimap', 'Research_Burrow_quick', 'Research_CentrifugalHooks_quick', 'Research_ChitinousPlating_quick', 'Research_GlialRegeneration_quick', 'Research_GroovedSpines_quick', 'Research_MuscularAugments_quick', 'Research_NeuralParasite_quick', 'Research_PathogenGlands_quick', 'Research_PneumatizedCarapace_quick', 'Research_TunnelingClaws_quick', 'Research_ZergFlyerArmor_quick', 'Research_ZergFlyerArmorLevel1_quick', 'Research_ZergFlyerArmorLevel2_quick', 'Research_ZergFlyerArmorLevel3_quick', 'Research_ZergFlyerAttack_quick', 'Research_ZergFlyerAttackLevel1_quick', 'Research_ZergFlyerAttackLevel2_quick', 'Research_ZergFlyerAttackLevel3_quick', 'Research_ZergGroundArmor_quick', 'Research_ZergGroundArmorLevel1_quick', 'Research_ZergGroundArmorLevel2_quick', 'Research_ZergGroundArmorLevel3_quick', 'Research_ZergMeleeWeapons_quick', 'Research_ZergMeleeWeaponsLevel1_quick', 'Research_ZergMeleeWeaponsLevel2_quick', 'Research_ZergMeleeWeaponsLevel3_quick', 'Research_ZergMissileWeapons_quick', 'Research_ZergMissileWeaponsLevel1_quick', 'Research_ZergMissileWeaponsLevel2_quick', 'Research_ZergMissileWeaponsLevel3_quick', 'Research_ZerglingAdrenalGlands_quick', 'Research_ZerglingMetabolicBoost_quick', 'Smart_screen', 'Smart_minimap', 'Stop_quick', 'Stop_Building_quick', 'Stop_Redirect_quick', 'Stop_Stop_quick', 'Train_Baneling_quick', 'Train_Corruptor_quick', 'Train_Drone_quick', 'Train_Hydralisk_quick', 'Train_Infestor_quick', 'Train_Mutalisk_quick', 'Train_Overlord_quick', 'Train_Queen_quick', 'Train_Roach_quick', 'Train_SwarmHost_quick', 'Train_Ultralisk_quick', 'Train_Viper_quick', 'Train_Zergling_quick', 'UnloadAll_quick', 'UnloadAll_NydusNetwork_quick', 'UnloadAll_NydusWorm_quick', 'UnloadAllAt_screen', 'UnloadAllAt_minimap', 'UnloadAllAt_Overlord_screen', 'UnloadAllAt_Overlord_minimap', 'Build_LurkerDen_screen', 'Morph_OversightMode_quick', 'Research_AdaptiveTalons_quick', 'Move_Move_screen', 'Move_Move_minimap', 'Patrol_Patrol_screen', 'Patrol_Patrol_minimap', 'Research_AnabolicSynthesis_quick']
  
  
  class ActionSet(Enum):
      No_op = auto()
      Select_Army_Move_2D = auto()
      Select_Army_Attack_2D = auto()
      Attack_2D_Move_Camera = auto()
      Select_Multi_Move_2D = auto()
      Select_Multi_Move_Attack_2D = auto()
      Build_SCVs = auto()
      Build_Marines = auto()
  
  
  _FUNCTION_NAMES = {
      ActionSet.No_op: ['no_op'],
      ActionSet.Select_Army_Move_2D: ['no_op', 'select_army', 'Move_screen'],
      ActionSet.Select_Army_Attack_2D: ['no_op', 'select_army', 'Attack_screen'],
      ActionSet.Attack_2D_Move_Camera: ['no_op', 'Attack_screen', 'move_camera'],
      ActionSet.Select_Multi_Move_2D: ['no_op', 'select_army', 'select_point', 'Move_screen'],
      ActionSet.Select_Multi_Move_Attack_2D: ['no_op', 'select_army', 'select_point', 'Move_screen', 'Attack_screen'],
      ActionSet.Build_SCVs: ['no_op', 'select_point', 'select_idle_worker',
                             'Harvest_Gather_screen', 'Rally_Workers_screen', 'Train_SCV_quick',
                             'Build_SupplyDepot_screen', 'Build_Refinery_screen'],
      ActionSet.Build_Marines: ['no_op', 'select_point', 'Build_SupplyDepot_screen',
                                'Build_Barracks_screen', 'Train_Marine_quick',
                                'select_idle_worker', 'Harvest_Gather_screen',
                                'Rally_Workers_screen', 'Train_SCV_quick'],
  }
  
  
  class ActionConverter:
  
      def __init__(self, action_set, action_spec, screen_dim):
  
          self._action_spec = action_spec
          self._screen_dim = screen_dim
          self._valid_actions = action_spec[0].types
          self._function_names = []
          self._function_ids = []
          self._register_actions(action_set)
  
      def _register_actions(self, action_set):
          if isinstance(action_set, ActionSet):
              self._function_names = _FUNCTION_NAMES[action_set]
              for name in self._function_names:
                  self._function_ids.append(actions.FUNCTIONS[name].id)
          else:
              raise ValueError('need a action_converter.ActionSet enum value')
  
      def make_action_space(self):
          # (id, (x, y))         # x and y are in SCREEN space
          # Note: I would like to use MultiDiscrete([id, x, y]), but the categorical projection network does not
          # support this. There is also nothing useful on github, seems unlikely unless I implement it myself.
          return spaces.Tuple((spaces.Discrete(self.get_number_of_actions()),
                               spaces.Tuple((spaces.Discrete(self._screen_dim), spaces.Discrete(self._screen_dim)))
                               ))
  
      def space_id_to_function_id(self, action_space_id):
          return self._function_ids[action_space_id]
  
      def space_to_function(self, space) -> FunctionCall:
          # space is in the action_space defined in 'make_action_space()'.
  
          # first extract the action id
          action_id = space[0]
          # then determine the required arguments for this action
          chosen_args = []
          f = actions.FUNCTIONS[self._function_names[action_id]]
          for arg in f.args:
              option_space, option_type = self._option_space_and_type(arg.id)
              if option_type == 'point':
                  chosen_args.append(space[1])
              elif option_type == 'enum':
                  chosen_args.append(self._get_fixed_arg_value(arg.id))
              elif option_type == 'scalar':
                  logging.warning('SCALAR NOT YET SUPPORTED!')
                  chosen_args.append(space[1][0])
              else:
                  # Note: screen2 would land here
                  raise ValueError('unsupported argtype passed')
  
          # finally return the FunctionCall that can be executed in PySC2
          return FunctionCall(self._function_ids[action_id], chosen_args)
  
      def get_number_of_actions(self):
          return len(self._function_names)
  
      def _option_space_and_type(self, argument_type_id):
          if argument_type_id in [0, 1, 2]:  # points in 2D space
              return self._valid_actions[argument_type_id].sizes, 'point'
          elif argument_type_id in [3, 4, 6, 7, 8, 10]:  # enums
              return None, 'enum'  # NOTE: I choose theses values, fixed to reduce complexity
          elif argument_type_id in [5, 9, 11, 12]:  # scalars
              return self._valid_actions[argument_type_id].sizes, 'scalar'
          else:
              raise ValueError('invalid argument type id')
  
      def _get_fixed_arg_value(self, argument_type_id):
          if argument_type_id == 3:  # 'queued'
              return [0]  # 'now'
          elif argument_type_id == 4:  # 'control_group_act'
              return [1]  # 'set'
          elif argument_type_id == 6:  # 'select_point_act'
              return [0]  # 'select'
          elif argument_type_id == 7:  # 'select_add'
              return [0]  # 'select'
          elif argument_type_id == 8:  # 'select_unit_act'
              return [0]  # 'select'
          elif argument_type_id == 10:  # 'select_worker'
              return [0]  # 'select'
          else:
              raise ValueError('invalid argument type id')
  