Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: correctly adjusted unit costs with tests
- Loading branch information
1 parent
15bffc0
commit c3bd9b1
Showing
8 changed files
with
334 additions
and
89 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# frozen_string_literal: true | ||
|
||
module Api | ||
# Adds additional functionality to message object Api::UnitTypeData | ||
module UnitTypeDataExtension | ||
# Sum of mineral costs for each morph (550 for Orbital command = 400M CC + 150M Upgrade) | ||
# The original cost of units are the sums | ||
# We fix the values for can_afford?, but back up the originals here | ||
# @return [Integer] sum of mineral costs | ||
def mineral_cost_sum | ||
@mineral_cost_sum ||= mineral_cost | ||
end | ||
|
||
# Sum of vespene cost for each morph (250G Broodlord = 100G Corruptor + 150G Morph) | ||
# @return [Integer] sum of gas costs | ||
def vespene_cost_sum | ||
@vespene_cost_sum ||= vespene_cost | ||
end | ||
end | ||
end | ||
Api::UnitTypeData.include Api::UnitTypeDataExtension |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,93 @@ | ||
class ExampleBot < Sc2::Player::Bot | ||
def on_start | ||
puts "test bot started..." | ||
end | ||
RSpec.describe Api::UnitTypeData, type: :integration do | ||
let(:live_terran_data) do | ||
data = {} | ||
|
||
# patch: 5.0.12 | ||
data[Api::UnitTypeId::AUTOTURRET] = Sc2::RSpec::Data::Cost.new(0, 0, 0) | ||
data[Api::UnitTypeId::BANSHEE] = Sc2::RSpec::Data::Cost.new(150, 100, 3) | ||
data[Api::UnitTypeId::BATTLECRUISER] = Sc2::RSpec::Data::Cost.new(400, 300, 6) | ||
data[Api::UnitTypeId::CYCLONE] = Sc2::RSpec::Data::Cost.new(125, 50, 2) | ||
data[Api::UnitTypeId::GHOST] = Sc2::RSpec::Data::Cost.new(150, 125, 2) | ||
data[Api::UnitTypeId::HELLION] = Sc2::RSpec::Data::Cost.new(100, 0, 2) | ||
data[Api::UnitTypeId::HELLIONTANK] = Sc2::RSpec::Data::Cost.new(100, 0, 2) | ||
data[Api::UnitTypeId::LIBERATOR] = Sc2::RSpec::Data::Cost.new(150, 125, 3) | ||
data[Api::UnitTypeId::MARAUDER] = Sc2::RSpec::Data::Cost.new(100, 25, 2) | ||
data[Api::UnitTypeId::MARINE] = Sc2::RSpec::Data::Cost.new(50, 0, 1) | ||
data[Api::UnitTypeId::MEDIVAC] = Sc2::RSpec::Data::Cost.new(100, 100, 2) | ||
data[Api::UnitTypeId::MULE] = Sc2::RSpec::Data::Cost.new(0, 0, 0) | ||
data[Api::UnitTypeId::RAVEN] = Sc2::RSpec::Data::Cost.new(100, 150, 2) | ||
data[Api::UnitTypeId::REAPER] = Sc2::RSpec::Data::Cost.new(50, 50, 1) | ||
data[Api::UnitTypeId::SCV] = Sc2::RSpec::Data::Cost.new(50, 0, 1) | ||
data[Api::UnitTypeId::SIEGETANK] = Sc2::RSpec::Data::Cost.new(150, 125, 3) | ||
data[Api::UnitTypeId::SIEGETANKSIEGED] = Sc2::RSpec::Data::Cost.new(150, 125, 3) | ||
data[Api::UnitTypeId::THOR] = Sc2::RSpec::Data::Cost.new(300, 200, 6) | ||
data[Api::UnitTypeId::THORAP] = Sc2::RSpec::Data::Cost.new(300, 200, 6) | ||
data[Api::UnitTypeId::VIKINGFIGHTER] = Sc2::RSpec::Data::Cost.new(150, 75, 2) | ||
data[Api::UnitTypeId::VIKINGASSAULT] = Sc2::RSpec::Data::Cost.new(150, 75, 2) | ||
data[Api::UnitTypeId::WIDOWMINE] = Sc2::RSpec::Data::Cost.new(75, 25, 2) | ||
data[Api::UnitTypeId::WIDOWMINEBURROWED] = Sc2::RSpec::Data::Cost.new(75, 25, 2) | ||
data[Api::UnitTypeId::BANELING] = Sc2::RSpec::Data::Cost.new(25, 25, 0) | ||
data[Api::UnitTypeId::BROODLORD] = Sc2::RSpec::Data::Cost.new(150, 150, 0) | ||
data[Api::UnitTypeId::BROODLING] = Sc2::RSpec::Data::Cost.new(0, 0, 0) | ||
data[Api::UnitTypeId::CHANGELING] = Sc2::RSpec::Data::Cost.new(0, 0, 0) | ||
data[Api::UnitTypeId::CORRUPTOR] = Sc2::RSpec::Data::Cost.new(150, 100, 2) | ||
data[Api::UnitTypeId::DRONE] = Sc2::RSpec::Data::Cost.new(50, 0, 1) | ||
data[Api::UnitTypeId::HYDRALISK] = Sc2::RSpec::Data::Cost.new(100, 50, 2) | ||
data[Api::UnitTypeId::INFESTOR] = Sc2::RSpec::Data::Cost.new(100, 150, 2) | ||
data[Api::UnitTypeId::LARVA] = Sc2::RSpec::Data::Cost.new(0, 0, 0) | ||
data[Api::UnitTypeId::LOCUSTMP] = Sc2::RSpec::Data::Cost.new(0, 0, 0) | ||
data[Api::UnitTypeId::LOCUSTMPFLYING] = Sc2::RSpec::Data::Cost.new(0, 0, 0) | ||
data[Api::UnitTypeId::LURKERMP] = Sc2::RSpec::Data::Cost.new(50, 100, 0) | ||
data[Api::UnitTypeId::MUTALISK] = Sc2::RSpec::Data::Cost.new(100, 100, 2) | ||
data[Api::UnitTypeId::NYDUSCANAL] = Sc2::RSpec::Data::Cost.new(75, 75, 0) | ||
data[Api::UnitTypeId::OVERLORD] = Sc2::RSpec::Data::Cost.new(100, 0, 0) | ||
data[Api::UnitTypeId::OVERSEER] = Sc2::RSpec::Data::Cost.new(50, 50, 0) | ||
data[Api::UnitTypeId::QUEENMP] = Sc2::RSpec::Data::Cost.new(150, 0, 2) | ||
data[Api::UnitTypeId::RAVAGER] = Sc2::RSpec::Data::Cost.new(25, 75, 1) | ||
data[Api::UnitTypeId::ROACH] = Sc2::RSpec::Data::Cost.new(75, 25, 2) | ||
data[Api::UnitTypeId::SWARMHOSTMP] = Sc2::RSpec::Data::Cost.new(100, 75, 3) | ||
data[Api::UnitTypeId::ULTRALISK] = Sc2::RSpec::Data::Cost.new(275, 200, 6) | ||
data[Api::UnitTypeId::OVERLORDTRANSPORT] = Sc2::RSpec::Data::Cost.new(25, 25, 0) | ||
data[Api::UnitTypeId::VIPER] = Sc2::RSpec::Data::Cost.new(100, 200, 3) | ||
data[Api::UnitTypeId::ZERGLING] = Sc2::RSpec::Data::Cost.new(25, 0, 1) | ||
data[Api::UnitTypeId::ADEPT] = Sc2::RSpec::Data::Cost.new(100, 25, 2) | ||
data[Api::UnitTypeId::ARCHON] = Sc2::RSpec::Data::Cost.new(0, 0, 0) | ||
data[Api::UnitTypeId::CARRIER] = Sc2::RSpec::Data::Cost.new(350, 250, 6) | ||
data[Api::UnitTypeId::COLOSSUS] = Sc2::RSpec::Data::Cost.new(300, 200, 6) | ||
data[Api::UnitTypeId::DARKTEMPLAR] = Sc2::RSpec::Data::Cost.new(125, 125, 2) | ||
data[Api::UnitTypeId::DISRUPTOR] = Sc2::RSpec::Data::Cost.new(150, 150, 4) | ||
data[Api::UnitTypeId::HIGHTEMPLAR] = Sc2::RSpec::Data::Cost.new(50, 150, 2) | ||
data[Api::UnitTypeId::IMMORTAL] = Sc2::RSpec::Data::Cost.new(275, 100, 4) | ||
data[Api::UnitTypeId::INTERCEPTOR] = Sc2::RSpec::Data::Cost.new(15, 0, 0) | ||
data[Api::UnitTypeId::MOTHERSHIP] = Sc2::RSpec::Data::Cost.new(300, 300, 6) | ||
data[Api::UnitTypeId::OBSERVER] = Sc2::RSpec::Data::Cost.new(25, 75, 1) | ||
data[Api::UnitTypeId::ORACLE] = Sc2::RSpec::Data::Cost.new(150, 150, 3) | ||
data[Api::UnitTypeId::PHOENIX] = Sc2::RSpec::Data::Cost.new(150, 100, 2) | ||
data[Api::UnitTypeId::PROBE] = Sc2::RSpec::Data::Cost.new(50, 0, 1) | ||
data[Api::UnitTypeId::SENTRY] = Sc2::RSpec::Data::Cost.new(50, 100, 2) | ||
data[Api::UnitTypeId::STALKER] = Sc2::RSpec::Data::Cost.new(125, 50, 2) | ||
data[Api::UnitTypeId::TEMPEST] = Sc2::RSpec::Data::Cost.new(250, 175, 5) | ||
data[Api::UnitTypeId::VOIDRAY] = Sc2::RSpec::Data::Cost.new(250, 150, 4) | ||
data[Api::UnitTypeId::WARPPRISM] = Sc2::RSpec::Data::Cost.new(250, 0, 2) | ||
data[Api::UnitTypeId::ZEALOT] = Sc2::RSpec::Data::Cost.new(100, 0, 2) | ||
|
||
def on_step | ||
data | ||
end | ||
end | ||
|
||
RSpec.describe Api::UnitTypeData, type: :integration do | ||
context "when playing as Terran" do | ||
let(:bot) { ExampleBot.new(race: :Terran, name: "testbot") } | ||
let(:bot) { Sc2::Player::Bot.new(race: Api::Race::Terran, name: "") } | ||
|
||
# TODO: WIP for testing units. | ||
xit "can_afford? correctly calculates all units" do | ||
start_game(players: [bot]) | ||
step_to(100) | ||
expect(bot.game_loop).to be >= 100 | ||
end | ||
it "map costs match live patch costs" do | ||
start_game(players: [bot], map: "Goldenaura512V2AIE") | ||
|
||
xit "a second example runs succesfully" do | ||
start_game(players: [bot]) | ||
step_to(100) | ||
expect(bot.game_loop).to be >= 100 | ||
# Ensure map data matches real-world patch | ||
live_terran_data.each do |unit_type_id, cost| | ||
mineral_cost, vespene_cost, food_required = cost.to_a # live data | ||
unit_data = bot.unit_data(unit_type_id) # map data | ||
expect(unit_data.mineral_cost).to eq(mineral_cost), "[#{unit_type_id}] mineral_cost mismatch #{unit_data.mineral_cost} vs #{mineral_cost}: #{unit_data.inspect}" | ||
expect(unit_data.vespene_cost).to eq(vespene_cost), "[#{unit_type_id}] vespene_cost mismatch #{unit_data.vespene_cost} vs #{vespene_cost} #{unit_data.inspect}" | ||
expect(unit_data.food_required).to eq(food_required), "[#{unit_type_id}] food_required mismatch #{unit_data.food_required} vs #{food_required} #{unit_data.inspect}" | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
module Sc2 | ||
module RSpec | ||
module Data | ||
class Cost | ||
attr_accessor :mineral_cost, :vespene_cost, :food_required | ||
|
||
def initialize(m, v, f) | ||
@mineral_cost = m | ||
@vespene_cost = v | ||
@food_required = f | ||
end | ||
|
||
def to_a | ||
[mineral_cost, vespene_cost, food_required] | ||
end | ||
end | ||
end | ||
end | ||
end |
Oops, something went wrong.