sc2ai 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/data/sc2ai/protocol/common.proto +6 -6
  3. data/data/sc2ai/protocol/data.proto +23 -20
  4. data/data/sc2ai/protocol/debug.proto +25 -21
  5. data/data/sc2ai/protocol/error.proto +217 -215
  6. data/data/sc2ai/protocol/query.proto +1 -1
  7. data/data/sc2ai/protocol/raw.proto +16 -14
  8. data/data/sc2ai/protocol/sc2api.proto +108 -94
  9. data/data/sc2ai/protocol/score.proto +4 -3
  10. data/data/sc2ai/protocol/spatial.proto +6 -5
  11. data/data/sc2ai/protocol/ui.proto +17 -14
  12. data/exe/sc2ai +0 -3
  13. data/lib/docker_build/Dockerfile.ruby +4 -2
  14. data/lib/sc2ai/api/ability_id.rb +6 -1
  15. data/lib/sc2ai/api/data.rb +18 -3
  16. data/lib/sc2ai/api/tech_tree.rb +1 -1
  17. data/lib/sc2ai/api/tech_tree_data.rb +54 -3
  18. data/lib/sc2ai/connection/connection_listener.rb +3 -3
  19. data/lib/sc2ai/connection/requests.rb +31 -35
  20. data/lib/sc2ai/connection/status_listener.rb +1 -1
  21. data/lib/sc2ai/connection.rb +1 -2
  22. data/lib/sc2ai/local_play/client.rb +2 -2
  23. data/lib/sc2ai/local_play/match.rb +7 -2
  24. data/lib/sc2ai/overrides/async/process/child.rb +1 -1
  25. data/lib/sc2ai/paths.rb +12 -2
  26. data/lib/sc2ai/player/actions.rb +54 -35
  27. data/lib/sc2ai/player/debug.rb +54 -20
  28. data/lib/sc2ai/player/game_state.rb +11 -18
  29. data/lib/sc2ai/player/geo.rb +56 -66
  30. data/lib/sc2ai/player/units.rb +41 -17
  31. data/lib/sc2ai/player.rb +104 -47
  32. data/lib/sc2ai/ports.rb +1 -2
  33. data/lib/sc2ai/protocol/_meta_documentation.rb +270 -25
  34. data/lib/sc2ai/protocol/common_pb.rb +3862 -33
  35. data/lib/sc2ai/protocol/data_pb.rb +9106 -36
  36. data/lib/sc2ai/protocol/debug_pb.rb +10434 -45
  37. data/lib/sc2ai/protocol/error_pb.rb +1084 -29
  38. data/lib/sc2ai/protocol/extensions/ability_remapable.rb +9 -9
  39. data/lib/sc2ai/protocol/extensions/action.rb +60 -0
  40. data/lib/sc2ai/protocol/extensions/point_2_d.rb +9 -0
  41. data/lib/sc2ai/protocol/extensions/position.rb +11 -36
  42. data/lib/sc2ai/protocol/extensions/power_source.rb +3 -0
  43. data/lib/sc2ai/protocol/extensions/unit.rb +61 -36
  44. data/lib/sc2ai/protocol/extensions/unit_type_data.rb +8 -0
  45. data/lib/sc2ai/protocol/query_pb.rb +5022 -36
  46. data/lib/sc2ai/protocol/raw_pb.rb +18347 -46
  47. data/lib/sc2ai/protocol/sc2api_pb.rb +48424 -126
  48. data/lib/sc2ai/protocol/score_pb.rb +5965 -30
  49. data/lib/sc2ai/protocol/spatial_pb.rb +11941 -37
  50. data/lib/sc2ai/protocol/ui_pb.rb +12924 -46
  51. data/lib/sc2ai/unit_group/action_ext.rb +0 -2
  52. data/lib/sc2ai/unit_group/filter_ext.rb +24 -8
  53. data/lib/sc2ai/unit_group/geo_ext.rb +0 -2
  54. data/lib/sc2ai/unit_group.rb +1 -1
  55. data/lib/sc2ai/version.rb +2 -3
  56. data/lib/sc2ai.rb +10 -11
  57. data/lib/templates/ladderzip/bin/ladder.tt +0 -3
  58. data/lib/templates/new/.ladderignore +15 -5
  59. data/lib/templates/new/api/common.proto +6 -6
  60. data/lib/templates/new/api/data.proto +23 -20
  61. data/lib/templates/new/api/debug.proto +25 -21
  62. data/lib/templates/new/api/error.proto +217 -215
  63. data/lib/templates/new/api/query.proto +1 -1
  64. data/lib/templates/new/api/raw.proto +16 -14
  65. data/lib/templates/new/api/sc2api.proto +108 -94
  66. data/lib/templates/new/api/score.proto +4 -3
  67. data/lib/templates/new/api/spatial.proto +6 -5
  68. data/lib/templates/new/api/ui.proto +17 -14
  69. data/lib/templates/new/boot.rb.tt +1 -1
  70. data/lib/templates/new/my_bot.rb.tt +2 -2
  71. data/lib/templates/new/run_example_match.rb.tt +2 -2
  72. data/sig/sc2ai.rbs +11072 -1651
  73. metadata +31 -26
  74. data/lib/sc2ai/overrides/kernel.rb +0 -33
  75. data/lib/sc2ai/protocol/extensions/unit_type.rb +0 -9
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "sc2ai/unit_group"
4
-
5
3
  module Sc2
6
4
  # A set of action related tasks for unit groups
7
5
  class UnitGroup
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "sc2ai/unit_group"
4
3
  require "kdtree"
5
4
 
6
5
  module Sc2
@@ -118,7 +117,7 @@ module Sc2
118
117
  # structures.not.creep_tumors #=> all structures
119
118
  # structures.not.pylons #=>
120
119
  # units.not.workers # equivalent of units.army, but works too
121
- # @return [Sc2::UnitGroupNotSelector]
120
+ # @return [Sc2::UnitGroup::UnitGroupNotSelector]
122
121
  def not
123
122
  UnitGroupNotSelector.new(self)
124
123
  end
@@ -128,6 +127,8 @@ module Sc2
128
127
  class UnitGroupNotSelector < UnitGroup
129
128
  attr_accessor :parent
130
129
 
130
+ # @param unit_group [Sc2::UnitGroup]
131
+ # @return [UnitGroupNotSelector]
131
132
  def initialize(unit_group)
132
133
  @parent = unit_group
133
134
  super
@@ -150,10 +151,10 @@ module Sc2
150
151
  # Multiple values work as an "AND" filter
151
152
  # @example
152
153
  # # Single
153
- # ug.select_attribute(Api::Attribute::Structure) #=> <UnitGroup: ...>
154
+ # ug.select_attribute(Api::Attribute::STRUCTURE) #=> <UnitGroup: ...>
154
155
  # ug.select_attribute(:Structure) #=> <UnitGroup: ...>
155
156
  # # Multiple - select mechanical flying units
156
- # ug.select_attribute([:Mechanical, :Flying]) #=> <UnitGroup: ...>
157
+ # ug.select_attribute([:MECHANICAL, :FLYING]) #=> <UnitGroup: ...>
157
158
  # @param attributes [Integer, Array<Integer>] one or an array of unit Api::UnitTypeId
158
159
  # @return [UnitGroup]
159
160
  def select_attribute(attributes)
@@ -170,7 +171,7 @@ module Sc2
170
171
  # Multiple values work as an "AND" filter
171
172
  # @example
172
173
  # # Single
173
- # ug.reject_attribute(Api::Attribute::Structure) #=> <UnitGroup: ...>
174
+ # ug.reject_attribute(Api::Attribute::STRUCTURE) #=> <UnitGroup: ...>
174
175
  # ug.reject_attribute(:Structure) #=> <UnitGroup: ...>
175
176
  # # Multiple - reject mechanical flying units
176
177
  # ug.reject_attribute(:Mechanical, :Flying) #=> <UnitGroup: ...>
@@ -188,6 +189,15 @@ module Sc2
188
189
 
189
190
  # GENERICS ---
190
191
 
192
+ # Selects units you own
193
+ # i.e. @bot.all_units.owned # => Units you own
194
+ # @return [Sc2::UnitGroup] workers
195
+ def owned
196
+ cached("#{__method__}:SELF") do
197
+ select { |unit| unit.alliance == :SELF }
198
+ end
199
+ end
200
+
191
201
  # Selects worker units
192
202
  # @return [Sc2::UnitGroup] workers
193
203
  def workers
@@ -207,7 +217,7 @@ module Sc2
207
217
  # Selects units with attribute Structure
208
218
  # @return [Sc2::UnitGroup] structures
209
219
  def structures
210
- select_attribute(Api::Attribute::Structure)
220
+ select_attribute(Api::Attribute::STRUCTURE)
211
221
  end
212
222
 
213
223
  # Contains an array non-army types
@@ -261,7 +271,7 @@ module Sc2
261
271
  select(&:is_idle?)
262
272
  end
263
273
 
264
- # Selects units which have this ability available\
274
+ # Selects units which have this ability available
265
275
  # Queries API if necessary
266
276
  # @param [Integer] ability_id
267
277
  # @return [UnitGroup] units which have the ability available
@@ -269,6 +279,12 @@ module Sc2
269
279
  select { |unit| unit.ability_available?(ability_id) }
270
280
  end
271
281
 
282
+ # Checks whether any unit's first order matches these abilities
283
+ # @param ability_ids [Integer, Array<Integer>] accepts one or an array of Api::AbilityId
284
+ def is_performing_ability?(ability_ids)
285
+ any? { |unit| unit.is_performing_ability?(ability_ids) }
286
+ end
287
+
272
288
  # NEUTRAL ------------------------------------------
273
289
 
274
290
  # Selects mineral fields
@@ -390,7 +406,7 @@ module Sc2
390
406
  attr_accessor :use_kdtree
391
407
 
392
408
  # Builds a kdtree if not already built and returns it
393
- # @return [Kdtree]
409
+ # @return [::Kdtree]
394
410
  def kdtree
395
411
  return @kdtree unless @kdtree.nil?
396
412
  @kdtree = Kdtree.new(@units.values.each_with_index.map { |unit, index| [unit.pos.x, unit.pos.y, index] })
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "sc2ai/unit_group"
4
-
5
3
  module Sc2
6
4
  # A set geometric/map/math methods for unit group
7
5
  class UnitGroup
@@ -18,7 +18,7 @@ module Sc2
18
18
  def initialize(units = nil)
19
19
  @units = {}
20
20
  case units
21
- when Array, Google::Protobuf::RepeatedField
21
+ when Array
22
22
  units.each do |unit|
23
23
  @units[unit.tag] = unit
24
24
  end
data/lib/sc2ai/version.rb CHANGED
@@ -1,6 +1,5 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Sc2
4
2
  # gem version
5
- VERSION = "0.1.0"
3
+ # @return [String]
4
+ VERSION = "0.3.0"
6
5
  end
data/lib/sc2ai.rb CHANGED
@@ -38,20 +38,16 @@ Dir.glob(File.join(__dir__, "sc2ai", "overrides", "**", "*.rb")).each do |file|
38
38
  require(file)
39
39
  end
40
40
 
41
- # Protobuf internals don't allow sharing enums in the same package,
42
- # so Blizzard under_scored some names. This throws errors when defining constants
43
- # during packing/unpacking, because they dont start capitalized, so we silence temporarily.
44
- silence_warnings do
45
- require "rumale"
46
- require_relative "sc2ai/protocol/sc2api_pb"
47
- end
41
+ require "rumale"
42
+
48
43
  # noinspection RubyMismatchedArgumentType
49
- Dir[File.join(__dir__, "sc2ai", "*.rb")].each { |file| require(file) }
50
- # The upper include can probably preload everything it needs
44
+ Dir[File.join(__dir__, "sc2ai", "protocol", "*.rb")].sort.each { |file| require(file) }
51
45
  # noinspection RubyMismatchedArgumentType
52
- Dir[File.join(__dir__, "sc2ai", "protocol", "extensions", "**", "*.rb")].each { |file| require(file) }
46
+ Dir[File.join(__dir__, "sc2ai", "protocol", "extensions", "*.rb")].sort.each { |file| require(file) }
53
47
  # noinspection RubyMismatchedArgumentType
54
- Dir[File.join(__dir__, "sc2ai", "local_play", "**", "*.rb")].each { |file| require(file) }
48
+ Dir[File.join(__dir__, "sc2ai", "*.rb")].sort.each { |file| require(file) }
49
+ # noinspection RubyMismatchedArgumentType
50
+ Dir[File.join(__dir__, "sc2ai", "local_play", "**", "*.rb")].sort.each { |file| require(file) }
55
51
 
56
52
  # Facilitates StarCraft 2 AI
57
53
  module Sc2
@@ -61,6 +57,7 @@ module Sc2
61
57
  class << self
62
58
  # Instantiate the Configuration singleton or return it.
63
59
  # Remember that the instance has attribute readers so that we can access the configured values
60
+ # @return [Sc2::Configuration]
64
61
  def config
65
62
  @config ||= Configuration.new
66
63
  yield @config if block_given?
@@ -81,6 +78,8 @@ module Sc2
81
78
 
82
79
  @logger = Logger.new($stdout)
83
80
  @logger.level = :debug
81
+ @logger.datetime_format = "%H:%M:%S.%6N"
82
+
84
83
  @logger
85
84
  end
86
85
 
@@ -15,9 +15,6 @@ export RUBY_GC_HEAP_INIT_SIZE_160_SLOTS=18000
15
15
  export RUBY_GC_HEAP_INIT_SIZE_320_SLOTS=2000
16
16
  export RUBY_GC_HEAP_INIT_SIZE_640_SLOTS=1000
17
17
 
18
- # Maxime <3
19
- export RUBY_YJIT_ENABLE=true
20
-
21
18
  export AIARENA=true
22
19
  sc2ai ladderconfig
23
20
  exec sc2ai laddermatch "$@" 1>&2
@@ -5,16 +5,26 @@
5
5
  *.proto
6
6
  *.zip
7
7
 
8
-
9
8
  # Gem-specific ignores
10
9
  .build/
11
10
  data/debug_observation.json
11
+ run_example_match.rb
12
12
 
13
- # Other
14
- .idea/
15
- vendor/bundle
13
+ # Generic ruby gitignores
14
+ *.gem
15
+ *.rbc
16
+ .config
17
+ coverage/
18
+ pkg/
16
19
  spec/
17
20
  test/
21
+ tmp/
22
+ .byebug_history
23
+ .bundle/
24
+ vendor/bundle
25
+ lib/bundler/man/
18
26
 
19
- # My ignores
27
+ # Other
28
+ .idea/
29
+ .vscode/
20
30
 
@@ -1,5 +1,5 @@
1
1
 
2
- syntax = "proto2";
2
+ syntax = "proto3";
3
3
 
4
4
  package Api;
5
5
 
@@ -49,11 +49,11 @@ message Size2DI {
49
49
  }
50
50
 
51
51
  enum Race {
52
- NoRace = 0;
53
- Terran = 1;
54
- Zerg = 2;
55
- Protoss = 3;
56
- Random = 4;
52
+ NO_RACE = 0;
53
+ TERRAN = 1;
54
+ ZERG = 2;
55
+ PROTOSS = 3;
56
+ RANDOM = 4;
57
57
  }
58
58
 
59
59
 
@@ -1,5 +1,5 @@
1
1
 
2
- syntax = "proto2";
2
+ syntax = "proto3";
3
3
 
4
4
  package Api;
5
5
 
@@ -19,11 +19,12 @@ message AbilityData {
19
19
  optional uint32 remaps_to_ability_id = 7; // This ability id may be represented by the given more generic id.
20
20
 
21
21
  enum Target {
22
- None = 1; // Does not require a target.
23
- Point = 2; // Requires a target position.
24
- Unit = 3; // Requires a unit to target. Given by position using feature layers.
25
- PointOrUnit = 4; // Requires either a target point or target unit.
26
- PointOrNone = 5; // Requires either a target point or no target. (eg. building add-ons)
22
+ ENUM_TARGET_UNSET = 0; // PROTO3 COMPAT
23
+ NONE = 1; // DOES NOT REQUIRE A TARGET.
24
+ POINT = 2; // REQUIRES A TARGET POSITION.
25
+ UNIT = 3; // REQUIRES A UNIT TO TARGET. GIVEN BY POSITION USING FEATURE LAYERS.
26
+ POINT_OR_UNIT = 4; // REQUIRES EITHER A TARGET POINT OR TARGET UNIT.
27
+ POINT_OR_NONE = 5; // REQUIRES EITHER A TARGET POINT OR NO TARGET. (EG. BUILDING ADD_ONS)
27
28
  }
28
29
 
29
30
  optional bool available = 8; // If true, the ability may be used by this set of mods/map.
@@ -37,17 +38,18 @@ message AbilityData {
37
38
  }
38
39
 
39
40
  enum Attribute {
40
- Light = 1;
41
- Armored = 2;
42
- Biological = 3;
43
- Mechanical = 4;
44
- Robotic = 5;
45
- Psionic = 6;
46
- Massive = 7;
47
- Structure = 8;
48
- Hover = 9;
49
- Heroic = 10;
50
- Summoned = 11;
41
+ ENUM_ATTRIBUTE_UNSET = 0; // PROTO3 COMPAT
42
+ LIGHT = 1;
43
+ ARMORED = 2;
44
+ BIOLOGICAL = 3;
45
+ MECHANICAL = 4;
46
+ ROBOTIC = 5;
47
+ PSIONIC = 6;
48
+ MASSIVE = 7;
49
+ STRUCTURE = 8;
50
+ HOVER = 9;
51
+ HEROIC = 10;
52
+ SUMMONED = 11;
51
53
  }
52
54
 
53
55
  message DamageBonus {
@@ -57,9 +59,10 @@ message DamageBonus {
57
59
 
58
60
  message Weapon {
59
61
  enum TargetType {
60
- Ground = 1;
61
- Air = 2;
62
- Any = 3;
62
+ ENUM_TARGET_TYPE_UNSET = 0; // PROTO3 COMPAT
63
+ GROUND = 1;
64
+ AIR = 2;
65
+ ANY = 3;
63
66
  }
64
67
  optional TargetType type = 1;
65
68
  optional float damage = 2;
@@ -1,5 +1,5 @@
1
1
 
2
- syntax = "proto2";
2
+ syntax = "proto3";
3
3
 
4
4
  package Api;
5
5
 
@@ -67,18 +67,19 @@ message DebugSphere {
67
67
  }
68
68
 
69
69
  enum DebugGameState {
70
- show_map = 1;
71
- control_enemy = 2;
72
- food = 3;
73
- free = 4;
74
- all_resources = 5;
75
- god = 6;
76
- minerals = 7;
77
- gas = 8;
78
- cooldown = 9;
79
- tech_tree = 10;
80
- upgrade = 11;
81
- fast_build = 12;
70
+ ENUM_DEBUG_GAME_STATE_UNSET = 0; // PROTO3 COMPAT
71
+ SHOW_MAP = 1;
72
+ CONTROL_ENEMY = 2;
73
+ FOOD = 3;
74
+ FREE = 4;
75
+ ALL_RESOURCES = 5;
76
+ GOD = 6;
77
+ MINERALS = 7;
78
+ GAS = 8;
79
+ COOLDOWNS = 9;
80
+ TECH_TREE = 10;
81
+ UPGRADE = 11;
82
+ FAST_BUILD = 12;
82
83
  }
83
84
 
84
85
  message DebugCreateUnit {
@@ -94,9 +95,10 @@ message DebugKillUnit {
94
95
 
95
96
  message DebugTestProcess {
96
97
  enum Test {
97
- hang = 1;
98
- crash = 2;
99
- exit = 3;
98
+ ENUM_TEST_UNSET = 0; // PROTO3 COMPAT
99
+ HANG = 1;
100
+ CRASH = 2;
101
+ EXIT = 3;
100
102
  }
101
103
  optional Test test = 1;
102
104
  optional int32 delay_ms = 2;
@@ -108,17 +110,19 @@ message DebugSetScore {
108
110
 
109
111
  message DebugEndGame {
110
112
  enum EndResult {
111
- Surrender = 1; // Default if nothing is set. The current player admits defeat.
112
- DeclareVictory = 2;
113
+ ENUM_END_RESULT_UNSET = 0; // PROTO3 COMPAT
114
+ SURRENDER = 1; // DEFAULT IF NOTHING IS SET. THE CURRENT PLAYER ADMITS DEFEAT.
115
+ DECLARE_VICTORY = 2;
113
116
  }
114
117
  optional EndResult end_result = 1;
115
118
  }
116
119
 
117
120
  message DebugSetUnitValue {
118
121
  enum UnitValue {
119
- Energy = 1;
120
- Life = 2;
121
- Shields = 3;
122
+ ENUM_UNIT_VALUE_UNSET = 0; // PROTO3 COMPAT
123
+ ENERGY = 1;
124
+ LIFE = 2;
125
+ SHIELDS = 3;
122
126
  }
123
127
  optional UnitValue unit_value = 1;
124
128
  optional float value = 2;