sc2ai 0.0.7 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/data/sc2ai/protocol/raw.proto +1 -1
- data/data/sc2ai/protocol/ui.proto +1 -1
- data/lib/docker_build/Dockerfile.ruby +1 -1
- data/lib/sc2ai/cli/cli.rb +1 -1
- data/lib/sc2ai/connection.rb +1 -0
- data/lib/sc2ai/local_play/client_manager.rb +2 -0
- data/lib/sc2ai/local_play/match.rb +0 -11
- data/lib/sc2ai/paths.rb +1 -1
- data/lib/sc2ai/player/{geometry.rb → geo.rb} +39 -3
- data/lib/sc2ai/player/units.rb +7 -35
- data/lib/sc2ai/player.rb +10 -45
- data/lib/sc2ai/protocol/extensions/color.rb +1 -1
- data/lib/sc2ai/protocol/extensions/unit.rb +1 -1
- data/lib/sc2ai/protocol/extensions/unit_type.rb +3 -3
- data/lib/sc2ai/unit_group/action_ext.rb +2 -2
- data/lib/sc2ai/unit_group/filter_ext.rb +20 -0
- data/lib/sc2ai/version.rb +1 -1
- data/lib/sc2ai.rb +0 -7
- data/lib/templates/new/api/raw.proto +1 -1
- data/lib/templates/new/api/ui.proto +1 -1
- data/sig/sc2ai.rbs +801 -970
- metadata +65 -23
- data/lib/sc2ai/data.rb +0 -101
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7feb936b57c5b3e4c5cae670ea743f43ccb36a5111bf39abb88ad6e63702ffc5
|
4
|
+
data.tar.gz: 3b25e577bae3d33255f4e648fa69a8005e67af47e207cffdb7d0e2c790b86961
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3c0d3dac4646702e85531561eb94d11ce8c5a5da53a255832a18803f34daad07f42958be0309f2b043a003581cdb5a9ac198b1326f13a93cd7a6f92211f75fa0
|
7
|
+
data.tar.gz: 43baa9be2700f945f0f9aed19c81b9bd77ee21df9fa43a151caa2b7d09646de17f2fe69814d8cfd0384e1644106123d01d96b2e34a413563411da41d5f67b0c1
|
data/lib/sc2ai/cli/cli.rb
CHANGED
@@ -26,7 +26,7 @@ module Sc2
|
|
26
26
|
say "Press any key to continue..."
|
27
27
|
ask ""
|
28
28
|
|
29
|
-
say "You must accept the Blizzard®
|
29
|
+
say "You must accept the Blizzard® StarCraft® II AI and Machine Learning License at"
|
30
30
|
say "https://blzdistsc2-a.akamaihd.net/AI_AND_MACHINE_LEARNING_LICENSE.html"
|
31
31
|
say "It is PERMISSIVE and grants you freedoms over the standard EULA."
|
32
32
|
say "We do not record this action, but depend on software goverend by that license to continue."
|
data/lib/sc2ai/connection.rb
CHANGED
@@ -78,6 +78,7 @@ module Sc2
|
|
78
78
|
# Add a listener of specific callback type
|
79
79
|
# @param listener [Object]
|
80
80
|
# @param klass [Module<Sc2::Connection::ConnectionListener>,Module<Sc2::Connection::StatusListener>]
|
81
|
+
# @return [void]
|
81
82
|
def add_listener(listener, klass:)
|
82
83
|
@listeners[klass.to_s] ||= []
|
83
84
|
@listeners[klass.to_s].push(listener)
|
@@ -10,17 +10,6 @@ module Sc2
|
|
10
10
|
# Callback when game status changes
|
11
11
|
def on_status_change(status)
|
12
12
|
Sc2.logger.debug { "Status from Match: #{status}" }
|
13
|
-
|
14
|
-
# if status == :ended
|
15
|
-
# # Go through each player, looking for result if we don't have one.
|
16
|
-
# api_players.each do |player|
|
17
|
-
# Sc2.logger.debug { "TODO: Get results for players" }
|
18
|
-
# # result = player.result
|
19
|
-
# Sc2.logger.debug { "Leaving Game and Disconnecting players" }
|
20
|
-
# player.leave_game
|
21
|
-
# player.disconnect
|
22
|
-
# end
|
23
|
-
# end
|
24
13
|
end
|
25
14
|
|
26
15
|
# @!attribute players Sets the Player(s) for the match
|
data/lib/sc2ai/paths.rb
CHANGED
@@ -7,7 +7,7 @@ module Sc2
|
|
7
7
|
# Helps determine common paths to sc2 install dir, executable and maps.
|
8
8
|
# It maintains some semblance of compatibility with python-sc2 config
|
9
9
|
#
|
10
|
-
# ENV['SC2PATH'] can be set manually to
|
10
|
+
# ENV['SC2PATH'] can be set manually to StarCraft 2 base directory for Linux
|
11
11
|
# ENV['SC2PF'] can and should be manually set to "WineLinux" when running Wine
|
12
12
|
# Credit to Hannes, Sean and Burny for setting the standard
|
13
13
|
class Paths
|
@@ -6,7 +6,7 @@ require "rumale/pairwise_metric"
|
|
6
6
|
module Sc2
|
7
7
|
class Player
|
8
8
|
# Holds map and geography helper functions
|
9
|
-
class
|
9
|
+
class Geo
|
10
10
|
# @!attribute bot
|
11
11
|
# @return [Sc2::Player] player with active connection
|
12
12
|
attr_accessor :bot
|
@@ -98,7 +98,7 @@ module Sc2
|
|
98
98
|
expo_placement_grid[y.to_i, x.to_i] == 1
|
99
99
|
end
|
100
100
|
|
101
|
-
# Returns a grid where
|
101
|
+
# Returns a grid where only the expo locations are marked
|
102
102
|
# @return [Numo::Bit]
|
103
103
|
def expo_placement_grid
|
104
104
|
if @expo_placement_grid.nil?
|
@@ -121,6 +121,42 @@ module Sc2
|
|
121
121
|
@expo_placement_grid
|
122
122
|
end
|
123
123
|
|
124
|
+
# Returns a grid where only placement obstructions are marked
|
125
|
+
# includes Tumors and lowered Supply Depots
|
126
|
+
# @return [Numo::Bit]
|
127
|
+
private def placement_obstruction_grid
|
128
|
+
# Get obstructing structures
|
129
|
+
obstructure_types = [Api::UnitTypeId::SUPPLYDEPOTLOWERED, Api::UnitTypeId::CREEPTUMORQUEEN, Api::UnitTypeId::CREEPTUMOR, Api::UnitTypeId::CREEPTUMORBURROWED]
|
130
|
+
obstructures = bot.structures.select_type(obstructure_types) + bot.enemy.structures.select_type(obstructure_types)
|
131
|
+
cache_key = obstructures.tags.sort.hash
|
132
|
+
|
133
|
+
# Return cache if obstructing structures haven't changed
|
134
|
+
if !@placement_obstruction_grid.nil? && @placement_obstruction_grid[1] == cache_key
|
135
|
+
return @placement_obstruction_grid[0]
|
136
|
+
end
|
137
|
+
map = Numo::Bit.zeros(map_height, map_width)
|
138
|
+
|
139
|
+
# Cache empty, if no obstructing structures
|
140
|
+
if obstructures.size.zero?
|
141
|
+
@placement_obstruction_grid = [map, cache_key]
|
142
|
+
return map
|
143
|
+
end
|
144
|
+
|
145
|
+
# For each obstructing structure, mark it's tiles with 1's
|
146
|
+
obstructures.each do |structure|
|
147
|
+
x = structure.pos.x.floor
|
148
|
+
y = structure.pos.y.floor
|
149
|
+
|
150
|
+
if structure.unit_type == Api::UnitTypeId::SUPPLYDEPOTLOWERED
|
151
|
+
map[(y - 1)..(y), (x - 1)..(x)] = 1
|
152
|
+
else
|
153
|
+
map[y, x] = 1
|
154
|
+
end
|
155
|
+
end
|
156
|
+
@placement_obstruction_grid = [map, cache_key]
|
157
|
+
map
|
158
|
+
end
|
159
|
+
|
124
160
|
# Returns a grid where powered locations are marked true
|
125
161
|
# @return [Numo::Bit]
|
126
162
|
def parsed_power_grid
|
@@ -680,7 +716,7 @@ module Sc2
|
|
680
716
|
return @_build_coordinates[cache_key] if !@_build_coordinates[cache_key].nil? && !bot.game_info_stale?
|
681
717
|
|
682
718
|
result = []
|
683
|
-
input_grid = parsed_pathing_grid & parsed_placement_grid & ~expo_placement_grid
|
719
|
+
input_grid = parsed_pathing_grid & parsed_placement_grid & ~expo_placement_grid & ~placement_obstruction_grid
|
684
720
|
input_grid = if on_creep
|
685
721
|
parsed_creep & input_grid
|
686
722
|
else
|
data/lib/sc2ai/player/units.rb
CHANGED
@@ -41,6 +41,12 @@ module Sc2
|
|
41
41
|
# @return [Array<Integer>] a group of neutral units
|
42
42
|
def upgrades_completed = observation&.raw_data&.player&.upgrade_ids.to_a || [] # not a unit
|
43
43
|
|
44
|
+
# Returns true if this upgrade has finished researching
|
45
|
+
# @return [Boolean]
|
46
|
+
def upgrade_completed?(upgrade_id)
|
47
|
+
upgrades_completed.include?(upgrade_id)
|
48
|
+
end
|
49
|
+
|
44
50
|
# Returns the upgrade ids which are researching or queued
|
45
51
|
# Not set for enemy.
|
46
52
|
# @return [Array<Integer>]
|
@@ -69,7 +75,7 @@ module Sc2
|
|
69
75
|
result - upgrades_completed
|
70
76
|
end
|
71
77
|
|
72
|
-
# Returns the upgrade
|
78
|
+
# Returns true if the upgrade is busy researching
|
73
79
|
# @return [Boolean]
|
74
80
|
def upgrade_in_progress?(upgrade_id)
|
75
81
|
structure_unit_type_id = Api::TechTree.upgrade_researched_from(upgrade_id: upgrade_id)
|
@@ -141,31 +147,6 @@ module Sc2
|
|
141
147
|
|
142
148
|
# Event-driven unit groups ---
|
143
149
|
|
144
|
-
# @!attribute event_units_created
|
145
|
-
# Units created since last frame (visible only, units not structures)
|
146
|
-
# Read this on_step. Alternative to callback on_unit_created
|
147
|
-
# @note Morphed units should watch #event_units_type_changed
|
148
|
-
# @return [Sc2::UnitGroup] group of created units
|
149
|
-
attr_accessor :event_units_created
|
150
|
-
|
151
|
-
# Units which had their type changed since last frame
|
152
|
-
# Read this on_step. Alternative to callback on_unit_type_changed
|
153
|
-
# @!attribute event_units_type_changed
|
154
|
-
# @return [Sc2::UnitGroup] group effected
|
155
|
-
attr_accessor :event_units_type_changed
|
156
|
-
|
157
|
-
# Structures seen since last frame with building not completed (< 1.0)
|
158
|
-
# Read this on_step. Alternative to callback on_structure_started
|
159
|
-
# @!attribute event_structures_started
|
160
|
-
# @return [Sc2::UnitGroup] a group of structures started
|
161
|
-
attr_accessor :event_structures_started
|
162
|
-
|
163
|
-
# Structures which had their building completed (==1.0) since last frame
|
164
|
-
# Read this on_step. Alternative to callback on_structure_completed
|
165
|
-
# @!attribute event_structures_completed
|
166
|
-
# @return [Sc2::UnitGroup] a group of structures started
|
167
|
-
attr_accessor :event_structures_completed
|
168
|
-
|
169
150
|
# Units and Structures which had their health/shields reduced since last frame
|
170
151
|
# Read this on_step. Alternative to callback on_unit_damaged
|
171
152
|
# @!attribute event_units_damaged
|
@@ -330,10 +311,6 @@ module Sc2
|
|
330
311
|
@_all_seen_unit_tags ||= Set.new(@units.tags)
|
331
312
|
|
332
313
|
# Event-driven unit groups as callback alternatives
|
333
|
-
@event_units_created = UnitGroup.new
|
334
|
-
@event_structures_started = UnitGroup.new
|
335
|
-
@event_structures_completed = UnitGroup.new
|
336
|
-
@event_units_type_changed = UnitGroup.new
|
337
314
|
@event_units_damaged = UnitGroup.new
|
338
315
|
# @event_units_buffed = UnitGroup.new
|
339
316
|
|
@@ -428,14 +405,11 @@ module Sc2
|
|
428
405
|
|
429
406
|
if unit.is_structure?
|
430
407
|
if unit.build_progress < 1
|
431
|
-
@event_structures_started.add(unit)
|
432
408
|
on_structure_started(unit)
|
433
409
|
else
|
434
|
-
@event_structures_completed.add(unit)
|
435
410
|
on_structure_completed(unit)
|
436
411
|
end
|
437
412
|
else
|
438
|
-
@event_units_created.add(unit)
|
439
413
|
on_unit_created(unit)
|
440
414
|
end
|
441
415
|
@_all_seen_unit_tags.add(unit.tag)
|
@@ -446,7 +420,6 @@ module Sc2
|
|
446
420
|
def issue_existing_unit_callbacks(unit, previous_unit)
|
447
421
|
# Check if a unit type has changed
|
448
422
|
if unit.unit_type != previous_unit.unit_type
|
449
|
-
@event_units_type_changed.add(unit)
|
450
423
|
on_unit_type_changed(unit, previous_unit.unit_type)
|
451
424
|
end
|
452
425
|
|
@@ -459,7 +432,6 @@ module Sc2
|
|
459
432
|
|
460
433
|
if unit.is_structure?
|
461
434
|
if previous_unit.build_progress < 1 && unit.build_progress == 1
|
462
|
-
@event_structures_completed.add(unit)
|
463
435
|
on_structure_completed(unit)
|
464
436
|
end
|
465
437
|
end
|
data/lib/sc2ai/player.rb
CHANGED
@@ -1,15 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "forwardable"
|
4
|
+
require "numo/narray"
|
3
5
|
require_relative "api/data"
|
4
6
|
require_relative "connection/connection_listener"
|
5
7
|
require_relative "connection/status_listener"
|
6
8
|
require_relative "player/game_state"
|
7
9
|
require_relative "player/units"
|
8
10
|
require_relative "player/previous_state"
|
9
|
-
require_relative "player/
|
11
|
+
require_relative "player/geo"
|
10
12
|
require_relative "player/actions"
|
11
13
|
require_relative "player/debug"
|
12
|
-
require "numo/narray"
|
13
14
|
|
14
15
|
module Sc2
|
15
16
|
# Allows defining Ai, Bot, BotProcess (external), Human or Observer for a Match
|
@@ -188,13 +189,13 @@ module Sc2
|
|
188
189
|
attr_accessor :previous
|
189
190
|
|
190
191
|
# @!attribute geo
|
191
|
-
# @return [Sc2::Player::
|
192
|
+
# @return [Sc2::Player::Geo] geo and map helper functions
|
192
193
|
attr_accessor :geo
|
193
194
|
|
194
195
|
def initialize(race:, name:)
|
195
196
|
super(race:, name:, type: Api::PlayerType::Participant, difficulty: nil, ai_build: nil)
|
196
197
|
@previous = Sc2::Player::PreviousState.new
|
197
|
-
@geo = Sc2::Player::
|
198
|
+
@geo = Sc2::Player::Geo.new(self)
|
198
199
|
|
199
200
|
configure
|
200
201
|
end
|
@@ -231,7 +232,7 @@ module Sc2
|
|
231
232
|
loop do
|
232
233
|
r = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
|
233
234
|
perform_actions
|
234
|
-
perform_debug_commands
|
235
|
+
perform_debug_commands unless Sc2.ladder?
|
235
236
|
step_forward
|
236
237
|
print "\e[2K#{game_loop - @previous.game_loop} Steps Took (ms): #{(::Process.clock_gettime(::Process::CLOCK_MONOTONIC) - r) * 1000}\n\e[1A\r"
|
237
238
|
return @result unless @result.nil?
|
@@ -329,7 +330,7 @@ module Sc2
|
|
329
330
|
|
330
331
|
# Callback for unit destroyed. Tags might be found in `previous.all_units`
|
331
332
|
# This excludes unknown objects, like projectiles and only shows things the API has "seen" as a unit
|
332
|
-
# Override to use in your bot class or use Player.
|
333
|
+
# Override to use in your bot class or use Player.
|
333
334
|
# @param unit [Api::Unit]
|
334
335
|
# @see Sc2::Player::Units#units_destroyed
|
335
336
|
def on_unit_destroyed(unit)
|
@@ -343,7 +344,7 @@ module Sc2
|
|
343
344
|
|
344
345
|
# Callback for unit type changing.
|
345
346
|
# To detect certain unit creations, you should use this method to watch morphs.
|
346
|
-
# Override to use in your bot class or use Player.
|
347
|
+
# Override to use in your bot class or use Player.
|
347
348
|
# @param unit [Api::Unit]
|
348
349
|
# @param previous_unit_type_id [Integer] Api::UnitTypeId::*
|
349
350
|
def on_unit_type_changed(unit, previous_unit_type_id)
|
@@ -356,13 +357,13 @@ module Sc2
|
|
356
357
|
end
|
357
358
|
|
358
359
|
# Callback for structure building is completed
|
359
|
-
# Override to use in your bot class or use Player.
|
360
|
+
# Override to use in your bot class or use Player.
|
360
361
|
# @param unit [Api::Unit]
|
361
362
|
def on_structure_completed(unit)
|
362
363
|
end
|
363
364
|
|
364
365
|
# Callback for unit (Unit/Structure) taking damage
|
365
|
-
# Override to use in your bot class or use Player.
|
366
|
+
# Override to use in your bot class or use Player.
|
366
367
|
# @param unit [Api::Unit]
|
367
368
|
# @param amount [Integer] of damage
|
368
369
|
def on_unit_damaged(unit, amount)
|
@@ -551,7 +552,6 @@ module Sc2
|
|
551
552
|
# This is better than having a bunch of random zero and nil values
|
552
553
|
@previous.reset(self) if @previous.all_units.nil?
|
553
554
|
|
554
|
-
# TODO: remove @events attributes if we don't use them for performance gains
|
555
555
|
# Actions performed and errors (only if implemented)
|
556
556
|
on_actions_performed(response_observation.actions) unless response_observation.actions.empty?
|
557
557
|
on_action_errors(response_observation.action_errors) unless response_observation.action_errors.empty?
|
@@ -608,41 +608,6 @@ module Sc2
|
|
608
608
|
end
|
609
609
|
end
|
610
610
|
|
611
|
-
# Misc -------------------------------
|
612
|
-
# ##TODO: perfect loop implementation
|
613
|
-
# observation has an optional param game_loop and will only return once that step is reached (blocking).
|
614
|
-
# without it, it returns things as they are.
|
615
|
-
# broadly, i think this is what it should be doing, with step_count being minimum of 1, so no zero-steps occur.
|
616
|
-
# @example
|
617
|
-
# desired_game_loop = current_game_loop + step_count
|
618
|
-
# response = client.observation(game_loop: desired_game_loop)
|
619
|
-
#
|
620
|
-
# if response.game_loop > desired_game_loop {
|
621
|
-
#
|
622
|
-
# # our requested point-in-time has passed. bot too slow or unlucky timing.
|
623
|
-
# # so, just re-query things as they stand right now:
|
624
|
-
# missed_response = response
|
625
|
-
# # note no game_loop argument supplied this time
|
626
|
-
# response = client.observation()
|
627
|
-
#
|
628
|
-
# # Combine observations so you didn't miss anything
|
629
|
-
# # Merges
|
630
|
-
# response.actions.merge(missed_response.actions)
|
631
|
-
# response.action_errors.merge(missed_response.action_errors)
|
632
|
-
# response.chat.merge(missed_response.chat)
|
633
|
-
#
|
634
|
-
# # Overrides
|
635
|
-
# if missed_response.player_result && response.player_result.empty?
|
636
|
-
# response.player_result = player_result
|
637
|
-
# end
|
638
|
-
#
|
639
|
-
# # Note we don't touch reponse.observation and keep the latest
|
640
|
-
# end
|
641
|
-
# current_game_loop = response.game_loop
|
642
|
-
# return response # or dispatch events with it
|
643
|
-
# def perfect_loop
|
644
|
-
# end
|
645
|
-
|
646
611
|
private
|
647
612
|
|
648
613
|
# @private
|
@@ -2,7 +2,7 @@ module Api
|
|
2
2
|
# Adds additional functionality and fixes quirks with color specifically pertaining to debug commands
|
3
3
|
module ColorExtension
|
4
4
|
# For lines: r & b are swapped.
|
5
|
-
def initialize(r
|
5
|
+
def initialize(r: 0, g: 0, b: 0)
|
6
6
|
super(r: b, g: g, b: r)
|
7
7
|
end
|
8
8
|
|
@@ -243,7 +243,7 @@ module Api
|
|
243
243
|
|
244
244
|
# Builds target unit type, i.e. issuing a build command to worker.build(...Api::UnitTypeId::BARRACKS)
|
245
245
|
# @param unit_type_id [Integer] Api::UnitTypeId the unit type you wish to build
|
246
|
-
# @param target [Api::Point2D, Integer, nil] is a unit tag or a Api::Point2D. Nil for addons/orbital
|
246
|
+
# @param target [Api::Point2D, Api::Unit, Integer, nil] is a unit tag or a Api::Point2D. Nil for addons/orbital
|
247
247
|
# @param queue_command [Boolean] shift+command
|
248
248
|
def build(unit_type_id:, target: nil, queue_command: false)
|
249
249
|
@bot.build(units: self, unit_type_id:, target:, queue_command:)
|
@@ -6,7 +6,7 @@ module Sc2
|
|
6
6
|
# A set of action related tasks for unit groups
|
7
7
|
class UnitGroup
|
8
8
|
# Our first unit's bot object.
|
9
|
-
# Returns nil if units are empty, so use
|
9
|
+
# Returns nil if units are empty, so use safety operator bot&.method(...)
|
10
10
|
# @return [Sc2::Player, nil] player with active connection
|
11
11
|
def bot
|
12
12
|
first&.bot
|
@@ -27,7 +27,7 @@ module Sc2
|
|
27
27
|
|
28
28
|
# Builds target unit type, i.e. issuing a build command to worker.build(...Api::UnitTypeId::BARRACKS)
|
29
29
|
# @param unit_type_id [Integer] Api::UnitTypeId the unit type you wish to build
|
30
|
-
# @param target [Api::Point2D, Integer, nil] is a unit tag or a Api::Point2D. Nil for addons/orbital
|
30
|
+
# @param target [Api::Point2D, Api::Unit, Integer, nil] is a unit tag or a Api::Point2D. Nil for addons/orbital
|
31
31
|
# @param queue_command [Boolean] shift+command
|
32
32
|
def build(unit_type_id:, target: nil, queue_command: false)
|
33
33
|
return if size.zero?
|
@@ -6,7 +6,11 @@ require "kdtree"
|
|
6
6
|
module Sc2
|
7
7
|
# Manage virtual control groups of units, similar to Hash or Array.
|
8
8
|
class UnitGroup
|
9
|
+
# An array of all worker unit type ids
|
10
|
+
# @return [Array<Integer>]
|
9
11
|
TYPE_WORKER = [Api::UnitTypeId::SCV, Api::UnitTypeId::MULE, Api::UnitTypeId::DRONE, Api::UnitTypeId::DRONEBURROWED, Api::UnitTypeId::PROBE].freeze
|
12
|
+
# An array of all gas structure unit type ids
|
13
|
+
# @return [Array<Integer>]
|
10
14
|
TYPE_GAS_STRUCTURE = [
|
11
15
|
Api::UnitTypeId::REFINERY,
|
12
16
|
Api::UnitTypeId::REFINERYRICH,
|
@@ -15,6 +19,8 @@ module Sc2
|
|
15
19
|
Api::UnitTypeId::EXTRACTOR,
|
16
20
|
Api::UnitTypeId::EXTRACTORRICH
|
17
21
|
].freeze
|
22
|
+
# An array of all mineral unit type ids
|
23
|
+
# @return [Array<Integer>]
|
18
24
|
TYPE_MINERAL = [
|
19
25
|
Api::UnitTypeId::MINERALCRYSTAL,
|
20
26
|
Api::UnitTypeId::RICHMINERALFIELD,
|
@@ -33,6 +39,8 @@ module Sc2
|
|
33
39
|
Api::UnitTypeId::MINERALFIELDOPAQUE,
|
34
40
|
Api::UnitTypeId::MINERALFIELDOPAQUE900
|
35
41
|
].freeze
|
42
|
+
# An array of all open geyser unit type ids
|
43
|
+
# @return [Array<Integer>]
|
36
44
|
TYPE_GEYSER = [
|
37
45
|
Api::UnitTypeId::VESPENEGEYSER,
|
38
46
|
Api::UnitTypeId::SPACEPLATFORMGEYSER,
|
@@ -41,6 +49,8 @@ module Sc2
|
|
41
49
|
Api::UnitTypeId::PURIFIERVESPENEGEYSER,
|
42
50
|
Api::UnitTypeId::SHAKURASVESPENEGEYSER
|
43
51
|
].freeze
|
52
|
+
# An array of all debris unit type ids
|
53
|
+
# @return [Array<Integer>]
|
44
54
|
TYPE_REJECT_DEBRIS = ((TYPE_MINERAL + TYPE_GEYSER) << Api::UnitTypeId::XELNAGATOWER).freeze
|
45
55
|
TYPE_TECHLAB = [
|
46
56
|
Api::UnitTypeId::TECHLAB,
|
@@ -48,12 +58,16 @@ module Sc2
|
|
48
58
|
Api::UnitTypeId::FACTORYTECHLAB,
|
49
59
|
Api::UnitTypeId::STARPORTTECHLAB
|
50
60
|
].freeze
|
61
|
+
# An array of all reactor structure unit type ids
|
62
|
+
# @return [Array<Integer>]
|
51
63
|
TYPE_REACTOR = [
|
52
64
|
Api::UnitTypeId::REACTOR,
|
53
65
|
Api::UnitTypeId::BARRACKSREACTOR,
|
54
66
|
Api::UnitTypeId::FACTORYREACTOR,
|
55
67
|
Api::UnitTypeId::STARPORTREACTOR
|
56
68
|
].freeze
|
69
|
+
# An array of all base structures unit type ids
|
70
|
+
# @return [Array<Integer>]
|
57
71
|
TYPE_BASES = [
|
58
72
|
Api::UnitTypeId::COMMANDCENTER, Api::UnitTypeId::COMMANDCENTERFLYING,
|
59
73
|
Api::UnitTypeId::ORBITALCOMMAND, Api::UnitTypeId::ORBITALCOMMANDFLYING,
|
@@ -301,6 +315,12 @@ module Sc2
|
|
301
315
|
end
|
302
316
|
alias_method :larvae, :larva
|
303
317
|
|
318
|
+
# Selects eggs. Eggs come from Larva and turn into Units.
|
319
|
+
# @return [Sc2::UnitGroup] eggs
|
320
|
+
def eggs
|
321
|
+
select_type(Api::UnitTypeId::EGG)
|
322
|
+
end
|
323
|
+
|
304
324
|
# Selects queens
|
305
325
|
# @return [Sc2::UnitGroup] queens
|
306
326
|
def queens
|
data/lib/sc2ai/version.rb
CHANGED
data/lib/sc2ai.rb
CHANGED
@@ -1,12 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# TODO: MOVE RUBY_GC_* to load into shell ENV, because they apparently can't be set at runtime.
|
4
|
-
# Arbitrary very large numbers which should not be reached
|
5
|
-
# RUBY_GC_MALLOC_LIMIT=128000000000;
|
6
|
-
# RUBY_GC_OLDMALLOC_LIMIT=128000000000;
|
7
|
-
# RUBY_GC_OLDMALLOC_LIMIT_MAX=128000000000;
|
8
|
-
# RUBY_GC_HEAP_INIT_SLOTS=329375
|
9
|
-
|
10
3
|
# In the event major runs, let it compact
|
11
4
|
GC.auto_compact = true
|
12
5
|
|