Skip to content

Commit

Permalink
feat: geo helpers enemy_start_position start_position
Browse files Browse the repository at this point in the history
Enemy start position was nested deeply and not friendly.
Own start position relies on checking your own main hq, which might be dead. Using camera start position on frame 0 instead.
  • Loading branch information
dysonreturns committed Mar 14, 2024
1 parent 6d4c865 commit 116f29d
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 10 deletions.
2 changes: 1 addition & 1 deletion docs/QUICK_REFERENCE.md
Expand Up @@ -288,7 +288,7 @@ Here's an example using Protoss `warp` for five stalkers. We use the unit group
```ruby

def on_step
enemy_main = game_info.start_raw.start_locations.first
enemy_main = geo.enemy_start_position

if can_afford?(unit_type_id: Api::UnitTypeId::STALKER, quantity: 5)

Expand Down
11 changes: 5 additions & 6 deletions docs/README.md
Expand Up @@ -194,8 +194,7 @@ require "sc2ai"
class MyCleverBot < Sc2::Player::Bot
def on_step
if game_loop == 0
enemy_start_pos = game_info.start_raw.start_locations.first
units.workers.attack(target: enemy_start_pos)
units.workers.attack(target: geo.enemy_start_position)
end

# If your attack fails, "good game" and exit
Expand Down Expand Up @@ -232,9 +231,9 @@ bundle exec ruby --yjit run_example_match.rb

**The replay** is auto-saved as `replays/autosave-#{botname}.SC2Replay` for casual review.

If the code scares you, especially that `game_info.start_raw.start_locations.first` part, fear not.
The syntax is generally quite friendly while also forcibly teaching you the API.
We have some extremely useful tutorials ahead once you're done skimming the next two sections.
While the code might seem foreign right now, fear not!
The syntax is generally quite friendly while also forcibly teaching you the API.
We have some extremely useful tutorials ahead once you're done skimming the next two sections.

## Competing on the ladder

Expand Down Expand Up @@ -333,7 +332,7 @@ Or even how is ANY OF THIS possible?
Let's go through all of the above in byte sized chunks with the tutorials which follows.
The README is over, but check out [Acknowledgements](#label-Acknowledgements) below which answers one of these questions.

Onwards, {file:docs/QUICK_REFERENCE.md to the tutorials!}
Onwards, {file:docs/QUICK_REFERENCE.md to the tutorials! ➡️}

## Development

Expand Down
2 changes: 2 additions & 0 deletions lib/sc2ai/player.rb
Expand Up @@ -490,6 +490,8 @@ def prepare_start
def started
# Calculate expansions
geo.expansions
# Set our start position base on camera
geo.start_position
end

# Moves emulation ahead and calls back #on_step
Expand Down
16 changes: 15 additions & 1 deletion lib/sc2ai/player/geometry.rb
Expand Up @@ -402,6 +402,19 @@ def divide_grid(input_grid, length)
output_grid
end

# Returns own 2d start position as set by initial camera
# This differs from position of first base structure
# @return [Api::Point2D]
def start_position
@start_position ||= bot.observation.raw_data.player.camera
end

# Returns the enemy 2d start position
# @return [Api::Point2D]
def enemy_start_position
bot.game_info.start_raw.start_locations.first
end

# Gets expos and surrounding minerals
# The index is a build location for an expo and the value is a UnitGroup, which has minerals and geysers
# @example
Expand Down Expand Up @@ -506,13 +519,14 @@ def expansion_points
end

# Returns a slice of #expansions where a base hasn't been built yet
# The has index is a build position and the value is a UnitGroup of resources for the base
# @example
# # Lets find the nearest unoccupied expo
# expo_pos = expansions_unoccupied.keys.min { |p2d| p2d.distance_to(structures.hq.first) }
# # What minerals/geysers does it have?
# puts expansions_unoccupied[expo_pos].minerals # or expansions[expo_pos]... => UnitGroup
# puts expansions_unoccupied[expo_pos].geysers # or expansions[expo_pos]... => UnitGroup
# @return [Hash<Api::Point2D], UnitGroup] Location => UnitGroup of resources (minerals+geysers)
# @return [Hash<Api::Point2D, UnitGroup>] Location => UnitGroup of resources (minerals+geysers)
def expansions_unoccupied
taken_bases = bot.structures.hq.map { |hq| hq.pos.to_p2d } + bot.enemy.structures.hq.map { |hq| hq.pos.to_p2d }
remaining_points = expansion_points - taken_bases
Expand Down
3 changes: 1 addition & 2 deletions lib/templates/new/my_bot.rb.tt
Expand Up @@ -10,8 +10,7 @@ class <%= @classname %> < Sc2::Player::Bot

def on_step
if game_loop == 0
enemy_start_pos = game_info.start_raw.start_locations.first
units.workers.attack(target: enemy_start_pos)
units.workers.attack(target: geo.enemy_start_position)
end

# If your attack fails, "good game" and exit
Expand Down

0 comments on commit 116f29d

Please sign in to comment.