sc2ai 0.0.5 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/data/stableid.json +424 -2562
- data/data/versions.json +8 -0
- data/lib/docker_build/Dockerfile.ruby +1 -1
- data/lib/sc2ai/api/ability_id.rb +12 -314
- data/lib/sc2ai/api/buff_id.rb +9 -16
- data/lib/sc2ai/api/data.rb +1 -4
- data/lib/sc2ai/api/tech_tree.rb +35 -0
- data/lib/sc2ai/api/tech_tree_data.rb +14 -9
- data/lib/sc2ai/api/unit_type_id.rb +6 -58
- data/lib/sc2ai/api/upgrade_id.rb +9 -9
- data/lib/sc2ai/connection/requests.rb +34 -16
- data/lib/sc2ai/data.rb +101 -0
- data/lib/sc2ai/local_play/match.rb +1 -3
- data/lib/sc2ai/player/actions.rb +8 -4
- data/lib/sc2ai/player/debug.rb +2 -3
- data/lib/sc2ai/player/game_state.rb +36 -5
- data/lib/sc2ai/player/geometry.rb +138 -55
- data/lib/sc2ai/player/previous_state.rb +2 -1
- data/lib/sc2ai/player/units.rb +66 -3
- data/lib/sc2ai/player.rb +5 -3
- data/lib/sc2ai/protocol/_meta_documentation.rb +18 -0
- data/lib/sc2ai/protocol/extensions/ability_remapable.rb +22 -0
- data/lib/sc2ai/protocol/extensions/point.rb +3 -1
- data/lib/sc2ai/protocol/extensions/point_2_d.rb +1 -1
- data/lib/sc2ai/protocol/extensions/point_distance.rb +11 -0
- data/lib/sc2ai/protocol/extensions/position.rb +48 -13
- data/lib/sc2ai/protocol/extensions/unit.rb +54 -3
- data/lib/sc2ai/protocol/extensions/unit_type.rb +9 -0
- data/lib/sc2ai/unit_group/action_ext.rb +3 -3
- data/lib/sc2ai/unit_group/filter_ext.rb +33 -7
- data/lib/sc2ai/unit_group/geo_ext.rb +28 -0
- data/lib/sc2ai/unit_group.rb +3 -0
- data/lib/sc2ai/version.rb +1 -1
- data/lib/templates/new/run_example_match.rb.tt +1 -1
- data/sig/sc2ai.rbs +653 -567
- metadata +22 -31
@@ -1,12 +1,23 @@
|
|
1
1
|
module Sc2
|
2
2
|
# A unified construct that tames Api::* messages which contain location data
|
3
|
-
# Items which are of type Sc2::
|
3
|
+
# Items which are of type Sc2::Position will have #x and #y property at the least.
|
4
4
|
module Position
|
5
5
|
# Tolerance for floating-point comparisons.
|
6
6
|
TOLERANCE = 1e-9
|
7
7
|
|
8
8
|
# Basic operations
|
9
9
|
|
10
|
+
# Loose equality matches on floats x and y.
|
11
|
+
# We never check z-axis, because the map is single-level.
|
12
|
+
# TODO: We should almost certainly introduce TOLERANCE here, but verify it's cost first.
|
13
|
+
def ==(other)
|
14
|
+
if other.is_a? Position
|
15
|
+
x == other.x && y == other.y
|
16
|
+
else
|
17
|
+
false
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
10
21
|
# A new point representing the sum of this point and the other point.
|
11
22
|
# @param other [Api::Point2D, Numeric] The other point/number to add.
|
12
23
|
# @return [Api::Point2D]
|
@@ -50,19 +61,44 @@ module Sc2
|
|
50
61
|
# @see #divide
|
51
62
|
alias_method :/, :divide
|
52
63
|
|
53
|
-
#
|
54
|
-
#
|
64
|
+
# Returns x coordinate
|
65
|
+
# @return [Float]
|
66
|
+
def x
|
67
|
+
# Perf: Memoizing attributes which are hit hard, show gain
|
68
|
+
@x ||= send(:method_missing, :x)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Sets x coordinate
|
72
|
+
# @return [Float]
|
73
|
+
def x=(x)
|
74
|
+
send(:method_missing, :x=, x)
|
75
|
+
@x = x
|
76
|
+
end
|
77
|
+
|
78
|
+
# Returns y coordinate
|
79
|
+
# @return [Float]
|
55
80
|
def y
|
81
|
+
# Bug: Psych implements method 'y' on Kernel, but protobuf uses method_missing to read AbstractMethod
|
82
|
+
# We send method missing ourselves when y to fix this chain.
|
56
83
|
# This is correct, but an unnecessary conditional:
|
57
84
|
# raise NoMethodError unless location == self
|
58
|
-
|
85
|
+
|
86
|
+
# Perf: Memoizing attributes which are hit hard, show gain
|
87
|
+
@y ||= send(:method_missing, :y)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Sets y coordinate
|
91
|
+
# @return [Float]
|
92
|
+
def y=(y)
|
93
|
+
send(:method_missing, :y=, y)
|
94
|
+
@y = y
|
59
95
|
end
|
60
96
|
|
61
97
|
# Randomly adjusts both x and y by a range of: -offset..offset
|
62
98
|
# @param offset [Float]
|
63
|
-
# @return [
|
99
|
+
# @return [Sc2::Position] new Position
|
64
100
|
def random_offset(offset)
|
65
|
-
|
101
|
+
dup.random_offset!(offset)
|
66
102
|
end
|
67
103
|
|
68
104
|
# Changes this point's x and y by the supplied offset
|
@@ -75,17 +111,16 @@ module Sc2
|
|
75
111
|
end
|
76
112
|
|
77
113
|
# Creates a new point with x and y which is offset
|
78
|
-
# @return [
|
79
|
-
def offset(x, y)
|
80
|
-
|
81
|
-
self
|
114
|
+
# @return [Sc2::Position] new Position
|
115
|
+
def offset(x = 0, y = 0)
|
116
|
+
dup.offset!(x, y)
|
82
117
|
end
|
83
118
|
|
84
119
|
# Changes this point's x and y by the supplied offset
|
85
120
|
# @return [Sc2::Position] self
|
86
|
-
def offset!(x, y)
|
87
|
-
self.x
|
88
|
-
self.y
|
121
|
+
def offset!(x = 0, y = 0)
|
122
|
+
self.x += x
|
123
|
+
self.y += y
|
89
124
|
self
|
90
125
|
end
|
91
126
|
|
@@ -9,6 +9,22 @@ module Api
|
|
9
9
|
tag || super
|
10
10
|
end
|
11
11
|
|
12
|
+
# Returns an integer unique identifier
|
13
|
+
# If the unit goes out of vision and is snapshot-able, they get a random id
|
14
|
+
# - Such a unit gets the same unit tag when it re-enters vision
|
15
|
+
# @return [Integer]
|
16
|
+
def tag
|
17
|
+
# Perf: This speeds up hash and therefore common UnitGroup operations. Sometimes 3x!
|
18
|
+
@tag ||= send(:method_missing, :tag)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Sets unit tag
|
22
|
+
# @return [Integer]
|
23
|
+
def tag=(tag)
|
24
|
+
send(:method_missing, :tag=, tag)
|
25
|
+
@tag = tag
|
26
|
+
end
|
27
|
+
|
12
28
|
# Every unit gets access back to the bot to allow api access.
|
13
29
|
# For your own units, this allows API access.
|
14
30
|
# @return [Sc2::Player] player with active connection
|
@@ -161,6 +177,15 @@ module Api
|
|
161
177
|
|
162
178
|
# @!endgroup Virtual properties
|
163
179
|
|
180
|
+
# Whether unit is effected by buff_id
|
181
|
+
# @example
|
182
|
+
# unit.has_buff??(Api::BuffId::QUEENSPAWNLARVATIMER)
|
183
|
+
# @param [Integer] buff_id
|
184
|
+
# @return [Boolean]
|
185
|
+
def has_buff?(buff_id)
|
186
|
+
buff_ids.include?(buff_id)
|
187
|
+
end
|
188
|
+
|
164
189
|
# @!group Actions
|
165
190
|
|
166
191
|
# Performs action on this unit
|
@@ -202,6 +227,7 @@ module Api
|
|
202
227
|
# @param target [Api::Unit, Integer, Api::Point2D] is a unit, unit tag or a Api::Point2D
|
203
228
|
# @param queue_command [Boolean] shift+command
|
204
229
|
def attack(target:, queue_command: false)
|
230
|
+
return false if target.nil?
|
205
231
|
action(ability_id: Api::AbilityId::ATTACK, target:, queue_command:)
|
206
232
|
end
|
207
233
|
|
@@ -216,7 +242,7 @@ module Api
|
|
216
242
|
end
|
217
243
|
|
218
244
|
# Builds target unit type, i.e. issuing a build command to worker.build(...Api::UnitTypeId::BARRACKS)
|
219
|
-
# @param unit_type_id [Integer] Api::UnitTypeId the unit type
|
245
|
+
# @param unit_type_id [Integer] Api::UnitTypeId the unit type you wish to build
|
220
246
|
# @param target [Api::Point2D, Integer, nil] is a unit tag or a Api::Point2D. Nil for addons/orbital
|
221
247
|
# @param queue_command [Boolean] shift+command
|
222
248
|
def build(unit_type_id:, target: nil, queue_command: false)
|
@@ -238,7 +264,7 @@ module Api
|
|
238
264
|
end
|
239
265
|
|
240
266
|
# Research a specific upgrade
|
241
|
-
# @param upgrade_id [Integer] Api::UnitTypeId the unit type
|
267
|
+
# @param upgrade_id [Integer] Api::UnitTypeId the unit type you wish to research
|
242
268
|
# @param queue_command [Boolean] shift+command
|
243
269
|
def research(upgrade_id:, queue_command: false)
|
244
270
|
@bot.research(units: self, upgrade_id:, queue_command:)
|
@@ -334,7 +360,7 @@ module Api
|
|
334
360
|
# @param target [Api::Unit, Integer] optionally check if unit is engaged with specific target
|
335
361
|
def is_attacking?(target: nil)
|
336
362
|
is_performing_ability_on_target?(
|
337
|
-
[Api::AbilityId::ATTACK_ATTACK],
|
363
|
+
[Api::AbilityId::ATTACK_ATTACK, Api::AbilityId::ATTACK],
|
338
364
|
target:
|
339
365
|
)
|
340
366
|
end
|
@@ -396,6 +422,14 @@ module Api
|
|
396
422
|
end
|
397
423
|
end
|
398
424
|
|
425
|
+
# Returns whether this unit has an ability available
|
426
|
+
# Queries API if necessary
|
427
|
+
# @param [Integer] ability_id
|
428
|
+
# @return [Boolean]
|
429
|
+
def ability_available?(ability_id)
|
430
|
+
@bot.unit_ability_available?(unit_tag: tag, ability_id:)
|
431
|
+
end
|
432
|
+
|
399
433
|
# Checks whether a weapon can target a unit
|
400
434
|
# @param unit [Api::unit]
|
401
435
|
# @param weapon [Api::Weapon]
|
@@ -521,8 +555,25 @@ module Api
|
|
521
555
|
build(unit_type_id: unit_type_id, queue_command:)
|
522
556
|
end
|
523
557
|
|
558
|
+
# PROTOSS Convenience functions ---
|
559
|
+
|
560
|
+
# Warps in unit type at target (location or pylon)
|
561
|
+
# Only works if the source is a Warp Gate
|
562
|
+
# @param unit_type_id [Integer] Api::UnitTypeId the unit type you wish to build
|
563
|
+
# @param target [Api::Point2D] a point, which should be inside an energy source
|
564
|
+
# @param queue_command [Boolean] shift+command
|
565
|
+
def warp(unit_type_id:, target:, queue_command: false)
|
566
|
+
@bot.warp(units: self, unit_type_id:, target:, queue_command:)
|
567
|
+
end
|
568
|
+
|
524
569
|
# GENERAL Convenience functions ---
|
525
570
|
|
571
|
+
# Returns true if unit does not have orders
|
572
|
+
# @return [Boolean] whether unit is idle
|
573
|
+
def is_idle?
|
574
|
+
orders.empty?
|
575
|
+
end
|
576
|
+
|
526
577
|
# ...
|
527
578
|
|
528
579
|
private
|
@@ -26,7 +26,7 @@ module Sc2
|
|
26
26
|
end
|
27
27
|
|
28
28
|
# Builds target unit type, i.e. issuing a build command to worker.build(...Api::UnitTypeId::BARRACKS)
|
29
|
-
# @param unit_type_id [Integer] Api::UnitTypeId the unit type
|
29
|
+
# @param unit_type_id [Integer] Api::UnitTypeId the unit type you wish to build
|
30
30
|
# @param target [Api::Point2D, 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)
|
@@ -41,10 +41,10 @@ module Sc2
|
|
41
41
|
|
42
42
|
# Warps in unit type at target (location or pylon)
|
43
43
|
# Will only have affect is this group consists of warp gates, i.e. bot.structures.warpgates
|
44
|
-
# @param unit_type_id [Integer] Api::UnitTypeId the unit type
|
44
|
+
# @param unit_type_id [Integer] Api::UnitTypeId the unit type you wish to build
|
45
45
|
# @param target [Api::Point2D] a point, which should be inside an energy source
|
46
46
|
# @param queue_command [Boolean] shift+command
|
47
|
-
def warp(unit_type_id:, target
|
47
|
+
def warp(unit_type_id:, target:, queue_command: false)
|
48
48
|
return if size.zero?
|
49
49
|
bot&.warp(units: self, unit_type_id:, target:, queue_command:)
|
50
50
|
end
|
@@ -121,13 +121,14 @@ module Sc2
|
|
121
121
|
|
122
122
|
# @private
|
123
123
|
# Does the opposite of selector and returns those values for parent
|
124
|
-
def
|
125
|
-
@parent.
|
124
|
+
def select(...)
|
125
|
+
@parent.reject(...)
|
126
126
|
end
|
127
127
|
|
128
|
+
# @private
|
128
129
|
# Does the opposite of selector and returns those values for parent
|
129
|
-
def
|
130
|
-
@parent.
|
130
|
+
def reject(...)
|
131
|
+
@parent.select(...)
|
131
132
|
end
|
132
133
|
end
|
133
134
|
|
@@ -230,11 +231,30 @@ module Sc2
|
|
230
231
|
alias_method :assimilators, :gas
|
231
232
|
|
232
233
|
# Selects only units which have finished constructing, i.o.w. build_progress == 1.0
|
233
|
-
# @return [UnitGroup]
|
234
|
+
# @return [UnitGroup] complete unit group
|
234
235
|
def completed
|
235
236
|
select(&:is_completed?)
|
236
237
|
end
|
237
238
|
|
239
|
+
# Selects only units which have finished constructing, i.o.w. build_progress != 1.0
|
240
|
+
# @return [UnitGroup] incomplete unit group
|
241
|
+
def incomplete
|
242
|
+
reject(&:is_completed?)
|
243
|
+
end
|
244
|
+
|
245
|
+
# Selects only units which do not have orders
|
246
|
+
def idle
|
247
|
+
select(&:is_idle?)
|
248
|
+
end
|
249
|
+
|
250
|
+
# Selects units which have this ability available\
|
251
|
+
# Queries API if necessary
|
252
|
+
# @param [Integer] ability_id
|
253
|
+
# @return [UnitGroup] units which have the ability available
|
254
|
+
def ability_available?(ability_id)
|
255
|
+
select { |unit| unit.ability_available?(ability_id) }
|
256
|
+
end
|
257
|
+
|
238
258
|
# NEUTRAL ------------------------------------------
|
239
259
|
|
240
260
|
# Selects mineral fields
|
@@ -290,7 +310,13 @@ module Sc2
|
|
290
310
|
# Selects overlords
|
291
311
|
# @return [Sc2::UnitGroup]
|
292
312
|
def overlords
|
293
|
-
select_type([Api::UnitTypeId::OVERLORD, Api::UnitTypeId::
|
313
|
+
select_type([Api::UnitTypeId::OVERLORD, Api::UnitTypeId::OVERLORDTRANSPORT, Api::UnitTypeId::TRANSPORTOVERLORDCOCOON])
|
314
|
+
end
|
315
|
+
|
316
|
+
# Selects overseers
|
317
|
+
# @return [Sc2::UnitGroup]
|
318
|
+
def overseers
|
319
|
+
select_type([Api::UnitTypeId::OVERLORDCOCOON, Api::UnitTypeId::OVERSEER, Api::UnitTypeId::OVERSEERSIEGEMODE])
|
294
320
|
end
|
295
321
|
|
296
322
|
# Selects creep tumors (all)
|
@@ -329,7 +355,7 @@ module Sc2
|
|
329
355
|
# Selects pylons and warp prisms in phasing mode
|
330
356
|
# @return [Sc2::UnitGroup] pylons annd warp prisms phasing
|
331
357
|
def warpables
|
332
|
-
select_type([Api::UnitTypeId::PYLON, Api::UnitTypeId::WARPPRISMPHASING])
|
358
|
+
select_type([Api::UnitTypeId::PYLON, Api::UnitTypeId::WARPPRISMPHASING]).completed
|
333
359
|
end
|
334
360
|
|
335
361
|
# Geometric/Map ---
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "sc2ai/unit_group"
|
4
|
+
|
5
|
+
module Sc2
|
6
|
+
# A set geometric/map/math methods for unit group
|
7
|
+
class UnitGroup
|
8
|
+
# Returns the center (average) position of all units or nil if the group is empty.
|
9
|
+
# Outliers effect this point
|
10
|
+
# @return [Api::Point2D, nil]
|
11
|
+
def pos_centroid
|
12
|
+
return nil if size == 0
|
13
|
+
size = @units.size
|
14
|
+
sum_x = 0.0
|
15
|
+
sum_y = 0.0
|
16
|
+
i = 0
|
17
|
+
|
18
|
+
while i < size
|
19
|
+
unit = at(i)
|
20
|
+
sum_x += unit.pos.x.to_f
|
21
|
+
sum_y += unit.pos.y.to_f
|
22
|
+
i += 1
|
23
|
+
end
|
24
|
+
|
25
|
+
Api::Point2D[sum_x / size.to_f, sum_y / size.to_f]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/sc2ai/unit_group.rb
CHANGED
@@ -182,6 +182,8 @@ module Sc2
|
|
182
182
|
UnitGroup.new(@units.reject { |tag, _unit| other_unit_group.units.has_key?(tag) })
|
183
183
|
end
|
184
184
|
|
185
|
+
alias_method :-, :subtract
|
186
|
+
|
185
187
|
# Merges unit_group with our units and returns a new unit group
|
186
188
|
# @return [Sc2::UnitGroup] a new unit group with items merged
|
187
189
|
def merge(unit_group)
|
@@ -295,3 +297,4 @@ end
|
|
295
297
|
|
296
298
|
require_relative "unit_group/action_ext"
|
297
299
|
require_relative "unit_group/filter_ext"
|
300
|
+
require_relative "unit_group/geo_ext"
|
data/lib/sc2ai/version.rb
CHANGED