Class: Sc2::Player::Bot

Inherits:
Sc2::Player show all
Includes:
Actions, Debug, Units
Defined in:
lib/sc2ai/player.rb

Overview

An object which interacts with an SC2 client and is game-aware.

Constant Summary

Constants inherited from Sc2::Player

IDENTIFIED_RACES

Instance Attribute Summary collapse

Attributes included from Debug

#debug_command_queue, #debug_commands_queue

Attributes included from Actions

#action_queue

Attributes included from Units

#all_seen_unit_tags, #all_units, #blips, #effects, #event_units_damaged, #event_units_destroyed, #neutral, #placeholders, #power_sources, #radar_rings, #structures, #units, #upgrades_completed

Attributes inherited from Sc2::Player

#IDENTIFIED_RACES, #ai_build, #api, #callbacks_defined, #difficulty, #enable_feature_layer, #interface_options, #name, #opponent_id, #race, #realtime, #step_count, #type

Attributes included from GameState

#chats_received, #data, #game_info, #game_loop, #observation, #result, #spent_minerals, #spent_supply, #spent_vespene, #status

Instance Method Summary collapse

Methods included from Debug

#debug_create_unit, #debug_draw_box, #debug_draw_line, #debug_draw_sphere, #debug_end_game, #debug_game_state, #debug_kill_unit, #debug_print, #debug_set_score, #debug_set_unit_value, #debug_test_process, #debug_text_screen, #debug_text_world, #debug_tile, #queue_debug_command

Methods included from Actions

#action, #action_chat, #action_raw_camera_move, #action_raw_toggle_autocast, #action_raw_unit_command, #action_spatial_camera_move, #action_spatial_unit_command, #action_spatial_unit_selection_point, #action_spatial_unit_selection_rect, #action_ui_cargo_panel_unload, #action_ui_control_group, #action_ui_multi_panel, #action_ui_production_panel_remove_from_queue, #action_ui_select_army, #action_ui_select_idle_worker, #action_ui_select_larva, #action_ui_select_warp_gates, #action_ui_toggle_autocast, #build, #queue_action, #research, #warp

Methods included from Units

#ability_data, #can_afford?, #can_afford_upgrade?, #subtract_cost, #tech_requirement_met?, #unit_ability_available?, #unit_data, #unit_group_from_tags, #unit_has_attribute?, #units_in_progress, #upgrade_completed?, #upgrade_data, #upgrade_in_progress?, #upgrades_in_progress

Methods inherited from Sc2::Player

#callback_defined?, #connect, #create_game, #disconnect, #join_game, #leave_game, #prepare_start, #quit, #race_unknown?, #refresh_game_info, #refresh_state, #requires_client?, #set_enemy, #set_race_for_random, #started, #step_forward

Methods included from GameState

#available_abilities, #common, #on_status_change

Methods included from Connection::StatusListener

#on_status_change

Constructor Details

#initialize(race:, name:) ⇒ Bot



199
200
201
202
203
204
205
# File 'lib/sc2ai/player.rb', line 199

def initialize(race:, name:)
  super(race:, name:, type: Api::PlayerType::PARTICIPANT, difficulty: nil, ai_build: nil)
  @previous = Sc2::Player::PreviousState.new
  @geo = Sc2::Player::Geo.new(self)

  configure
end

Instance Attribute Details

#enemySc2::Player::Enemy



189
190
191
# File 'lib/sc2ai/player.rb', line 189

def enemy
  @enemy
end

#geoSc2::Player::Geo



197
198
199
# File 'lib/sc2ai/player.rb', line 197

def geo
  @geo
end

#previousSc2::Player::PreviousState



193
194
195
# File 'lib/sc2ai/player.rb', line 193

def previous
  @previous
end

Instance Method Details

#configurevoid Also known as: before_join

This method returns an undefined value.

Override to customize initialization Alias of before_join You can enable_feature_layer=true, set step_count, define

Examples:

def configure
  step_count = 4 # Update less frequently
  enable_feature_layer = true

end


217
218
# File 'lib/sc2ai/player.rb', line 217

def configure
end

#on_action_errors(errors) ⇒ void

This method returns an undefined value.

Called on step if errors are present. Equivalent of UI red text errors. Override to read action errors.



327
328
329
# File 'lib/sc2ai/player.rb', line 327

def on_action_errors(errors)
  # Sc2.logger.debug errors
end

#on_actions_performed(actions) ⇒ void

This method returns an undefined value.

Actions this player performed since the last Observation. Override to read actions successfully performed



335
336
337
# File 'lib/sc2ai/player.rb', line 335

def on_actions_performed(actions)
  # Sc2.logger.debug actions
end

#on_alerts(alerts) ⇒ void

This method returns an undefined value.

Callback when observation.alerts is populated Override to use alerts or read Player.observation.alerts

Examples:

alerts.each do |alert|
  case alert
  when :NUCLEAR_LAUNCH_DETECTED
    pp "TAKE COVER!"
  when :NYDUS_WORM_DETECTED
    pp "FIND THE WORM!"
  end
end

See Also:

  • Alert in sc2api.proto for options


353
354
# File 'lib/sc2ai/player.rb', line 353

def on_alerts(alerts)
end

#on_finish(result) ⇒ void

This method returns an undefined value.

Override to handle game result (:Victory/:Loss/:Tie) Called when game has ended with a result, i.e. result = :Victory

Examples:

def on_finish(result)
  if result == :VICTORY
    puts "Yay!"
  else
    puts "Lets try again!"
  end
end


312
313
314
# File 'lib/sc2ai/player.rb', line 312

def on_finish(result)
  # Sc2.logger.debug { "#{self.class} on_finish" }
end

#on_parse_observation_unit(unit) ⇒ void

This method returns an undefined value.

Callback, on observation parse when iterating over every unit Can be useful for decorating additional properties on a unit before on_step A Sc2::Player should override this to decorate additional properties



372
373
# File 'lib/sc2ai/player.rb', line 372

def on_parse_observation_unit(unit)
end

#on_random_race_detected(race) ⇒ void

This method returns an undefined value.

Called when Random race is first detected. Override to handle race identification of random enemy.



320
321
# File 'lib/sc2ai/player.rb', line 320

def on_random_race_detected(race)
end

#on_startvoid

This method returns an undefined value.

Override to perform steps before first on_step gets called. Current game_loop is 0 and @api is available



281
282
283
# File 'lib/sc2ai/player.rb', line 281

def on_start
  # Sc2.logger.debug { "#{self.class} on_start" }
end

#on_stepvoid

This method returns an undefined value.

Override to implement your own game logic. Gets called whenever the game moves forward.

Raises:

  • (NotImplementedError)


288
289
290
291
292
293
294
295
296
# File 'lib/sc2ai/player.rb', line 288

def on_step
  return unless is_a? Bot

  raise NotImplementedError,
    "You are required to override #{__method__} in your Bot with: def #{__method__}"

  # Sc2.logger.debug { "#{self.class}.#{__method__}" }
  # Sc2.logger.debug "on_step"
end

#on_structure_completed(unit) ⇒ void

This method returns an undefined value.

Callback for structure building is completed Override to use in your bot class or use Player.



411
412
# File 'lib/sc2ai/player.rb', line 411

def on_structure_completed(unit)
end

#on_structure_started(unit) ⇒ void

This method returns an undefined value.

Callback for structure building began Override to use in your bot class.



404
405
# File 'lib/sc2ai/player.rb', line 404

def on_structure_started(unit)
end

#on_unit_created(unit) ⇒ void

This method returns an undefined value.

Callback for unit created. Override to use in your bot class.



388
389
# File 'lib/sc2ai/player.rb', line 388

def on_unit_created(unit)
end

#on_unit_damaged(unit, amount) ⇒ void

This method returns an undefined value.

Callback for unit (Unit/Structure) taking damage Override to use in your bot class or use Player.



419
420
# File 'lib/sc2ai/player.rb', line 419

def on_unit_damaged(unit, amount)
end

#on_unit_destroyed(unit) ⇒ void

This method returns an undefined value.

Callback for unit destroyed. Tags might be found in ‘previous.all_units` This excludes unknown objects, like projectiles and only shows things the API has “seen” as a unit Override to use in your bot class or use Player.

See Also:

  • Units#units_destroyed


381
382
# File 'lib/sc2ai/player.rb', line 381

def on_unit_destroyed(unit)
end

#on_unit_type_changed(unit, previous_unit_type_id) ⇒ void

This method returns an undefined value.

Callback for unit type changing. To detect certain unit creations, you should use this method to watch morphs. Override to use in your bot class or use Player.



397
398
# File 'lib/sc2ai/player.rb', line 397

def on_unit_type_changed(unit, previous_unit_type_id)
end

#on_upgrades_completed(upgrade_ids) ⇒ void

This method returns an undefined value.

Callback when upgrades are completed, multiple might finish on the same observation.



359
360
# File 'lib/sc2ai/player.rb', line 359

def on_upgrades_completed(upgrade_ids)
end

#playInteger

TODO: If this suffices for Bot and Observer, they should share this code. Initializes and refreshes game data and runs the game loop



225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
# File 'lib/sc2ai/player.rb', line 225

def play
  # Step 0
  prepare_start
  refresh_state
  started

  # Callback before first step is taken
  on_start
  # Callback for step 0
  on_step

  # Local play prints out avg times
  unless Sc2.ladder?
    running_avg_step_times = []
    average_runtime = 0.0
  end

  puts ""

  # Step 1 to n
  i = 0
  loop do
    if i >= 5
      i = 0
    end
    r = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
    perform_actions
    perform_debug_commands unless Sc2.ladder?
    step_forward

    unless Sc2.ladder?
      time_delta = (::Process.clock_gettime(::Process::CLOCK_MONOTONIC) - r) * 1000
      step_delta = game_loop - @previous.game_loop
      # running_avg_step_times.shift if running_avg_step_times.size == 5
      running_avg_step_times << [time_delta, step_delta]

      if i == 0
        sum_t, sum_s = running_avg_step_times.each_with_object([0, 0]) do |n, total|
          total[0] += n[0]
          total[1] += n[1]
        end
        average_runtime = sum_t / sum_s
        running_avg_step_times.clear
      end
      print "\e[2K#{step_delta} Step(s) Took (ms): #{"%.2f" % time_delta} | Avg (ms/frame): #{"%.2f" % average_runtime}\n\e[1A\r"
    end

    i += 1
    return @result unless @result.nil?
    break if @status != :IN_GAME
  end
end