lib/sc2ai/player/game_state.rb in sc2ai-0.0.5 vs lib/sc2ai/player/game_state.rb in sc2ai-0.0.7

- old
+ new

@@ -14,14 +14,17 @@ self.status = status end extend Forwardable - # @!attribute game_loop - # @return [Integer] current game loop - def_delegators :observation, :game_loop + attr_writer :game_loop + # @return [Integer] current game loop + def game_loop + @game_loop || 0 + end + # @!attribute game_info [rw] # Access useful game information. Used in parsed pathing grid, terrain height, placement grid. # Holds Api::ResponseGameInfo::#start_locations. # @return [Api::ResponseGameInfo] attr_reader :game_info @@ -36,20 +39,20 @@ # Used to determine staleness. # @return [Integer] attr_accessor :game_info_loop # Determines if your game_info will be refreshed at this moment - # Has a hard-capped refresh of only ever 2 steps + # Has a hard-capped refresh of only ever 4 steps # In general game_info is only refreshed Player::Bot reads from pathing_grid or placement_grid # @return [Boolean] def game_info_stale? return true if game_info_loop.nil? || game_info.nil? return false if game_info_loop == game_loop # Note: No minimum step count set anymore # We can do something like, only updating every 2+ frames: - game_info_loop + 2 <= game_loop + game_info_loop + 4 <= game_loop end # @!attribute data # @return [Api::ResponseData] attr_accessor :data @@ -99,9 +102,37 @@ @observation || Api::Observation.new(game_loop: 0) end def chats_received @chats_received || [] + end + + # @private + # @!attribute available_abilities_loop + # This is the last loop at which available_abilities was queried. + # Used to determine staleness. + # @return [Integer] + attr_accessor :available_abilities_loop + private :available_abilities_loop + + # A Hash by unit tag, holding an array of available ability ids + # Synchronously calls RequestQueryAvailableAbilities and caches for this game loop. + # @return [Hash<Integer, Array<Integer>>] { unit_tag => [ability_id, ...], ... } + def available_abilities + # Save/check when last we refreshed abilities + if @available_abilities_loop != game_loop + + # Query abilities for all our units + structure tags combined + abilities = api.query_abilities_for_unit_tags(units.tags + structures.tags, ignore_resource_requirements: false) + # Build the hash by unit tag + fresh_available_abilities = {} + abilities.each do |row| + fresh_available_abilities[row.unit_tag] = row.abilities.map(&:ability_id) + end + @available_abilities = fresh_available_abilities + @available_abilities_loop = game_loop + end + @available_abilities end # An alias for observation.player_common to allow easier access to i.e. common.minerals # @return [Api::PlayerCommon] common info such as minerals, vespene, supply def common