├── META-INF
├── native-image
│ └── native-image.properties
└── MANIFEST.MF
├── configs
├── BWAPI.dll
├── run32.bat
├── run64.bat
├── run_proxy.bat
├── PurpleWaveLocalMetal.config.json
├── PurpleWaveLocalDocker.config.json
├── PurpleWaveAIIDE.config.json
├── PurpleWaveSCHNAIL.config.json
├── launch4jPurpleSimViz.xml
└── PurpleWaveBASIL.config.json
├── install
├── instructions1.png
├── instructions2.png
├── instructions3.png
├── instructions4.png
└── instructions5.png
├── src
├── Macro
│ ├── Facts
│ │ └── MacroFacts.scala
│ ├── Requests
│ │ ├── RequestTech.scala
│ │ ├── RequestUpgrade.scala
│ │ └── RequestAutosupply.scala
│ ├── Scheduling
│ │ ├── ScheduleItem.scala
│ │ ├── MacroProducer.scala
│ │ ├── MacroStep.scala
│ │ └── Scheduler.scala
│ ├── Actions
│ │ ├── BuildOnce.scala
│ │ ├── SneakyCitadel.scala
│ │ └── PumpShuttleAndReavers.scala
│ └── Allocation
│ │ └── Priorities.scala
├── Gameplans
│ ├── Zerg
│ │ ├── ZvZ
│ │ │ └── ZergVsZerg.scala
│ │ ├── ZvP
│ │ │ └── ZergVsProtoss.scala
│ │ ├── ZvT
│ │ │ └── ZergVsTerran.scala
│ │ ├── ZvR
│ │ │ └── ZergVsRandom.scala
│ │ └── ZergStandardGameplan.scala
│ ├── Terran
│ │ ├── TvP
│ │ │ ├── TerranVsProtoss.scala
│ │ │ └── TvPRaxExpand.scala
│ │ ├── TvT
│ │ │ └── TerranVsTerran.scala
│ │ ├── TvZ
│ │ │ └── TerranVsZerg.scala
│ │ ├── TerranStandardGameplan.scala
│ │ └── TvE
│ │ │ └── BunkerRush.scala
│ ├── All
│ │ ├── Modal.scala
│ │ ├── ModalGameplan.scala
│ │ └── StandardGameplan.scala
│ └── Protoss
│ │ ├── FFA
│ │ └── ProtossFFAMoney.scala
│ │ ├── PvR
│ │ └── ProtossVsRandom.scala
│ │ ├── PvZ
│ │ └── ProtossVsZerg.scala
│ │ ├── PvP
│ │ └── ProtossVsProtoss.scala
│ │ ├── PvT
│ │ └── ProtossVsTerran.scala
│ │ └── ProtossStandardGameplan.scala
├── Planning
│ ├── Plans
│ │ ├── NoPlan.scala
│ │ └── Plan.scala
│ ├── ResourceLocks
│ │ ├── LockCurrencyFor.scala
│ │ ├── LockCurrency.scala
│ │ └── LockTiles.scala
│ └── Proxy
│ │ └── ProxyRequest.scala
├── Utilities
│ ├── Time
│ │ ├── Frames.scala
│ │ ├── Seconds.scala
│ │ ├── Hours.scala
│ │ ├── Minutes.scala
│ │ ├── GameTime.scala
│ │ ├── Forever.scala
│ │ └── FrameCount.scala
│ ├── UnitCounters
│ │ ├── CountOne.scala
│ │ ├── CountEverything.scala
│ │ ├── CountUpTo.scala
│ │ ├── CountBetween.scala
│ │ ├── CountExactly.scala
│ │ ├── UnitCounter.scala
│ │ └── CountExcept.scala
│ ├── LightYear.scala
│ ├── UnitFilters
│ │ ├── IsFlyingBuilding.scala
│ │ ├── IsFlyingWarrior.scala
│ │ ├── IsGroundWarrior.scala
│ │ ├── IsMechWarrior.scala
│ │ ├── IsAnything.scala
│ │ ├── IsBioWarrior.scala
│ │ ├── IsEnemy.scala
│ │ ├── IsProxied.scala
│ │ ├── UnitFilter.scala
│ │ ├── IsTank.scala
│ │ ├── IsVisible.scala
│ │ ├── IsBuilding.scala
│ │ ├── IsComplete.scala
│ │ ├── IsTownHall.scala
│ │ ├── IsWorker.scala
│ │ ├── IsDetector.scala
│ │ ├── IsHatchlike.scala
│ │ ├── IsLairlike.scala
│ │ ├── IsAntiAir.scala
│ │ ├── Is.scala
│ │ ├── IsAntiGround.scala
│ │ ├── IsWarrior.scala
│ │ ├── IsAny.scala
│ │ ├── IsMobileDetector.scala
│ │ ├── IsLandedBuilding.scala
│ │ ├── IsAll.scala
│ │ ├── IsBurrowedLurker.scala
│ │ ├── IsSpeedling.scala
│ │ ├── IsSpeedlot.scala
│ │ ├── IsSlowling.scala
│ │ ├── IsSlowlot.scala
│ │ ├── IsCompleteFor.scala
│ │ ├── IsSpeedScout.scala
│ │ ├── IsRangedGoon.scala
│ │ ├── IsSpeedVulture.scala
│ │ ├── IsCombatSpellcaster.scala
│ │ └── IsRecruitableForCombat.scala
│ ├── In.scala
│ ├── SomeIf.scala
│ ├── SomeIfO.scala
│ ├── AsJava.scala
│ ├── AsScala.scala
│ ├── UnitPreferences
│ │ ├── UnitPreference.scala
│ │ ├── PreferAnything.scala
│ │ ├── PreferLowEnergy.scala
│ │ ├── PreferBaseWithMoreWorkers.scala
│ │ ├── PreferBaseWithFewerWorkers.scala
│ │ ├── PreferIf.scala
│ │ ├── PreferIdle.scala
│ │ ├── PreferAll.scala
│ │ ├── PreferTiers.scala
│ │ ├── PreferHatcheryWithThreeLarva.scala
│ │ └── PreferScout.scala
│ ├── Ternary.scala
│ ├── SwapIf.scala
│ ├── DoQueue.scala
│ └── SpinWait.scala
├── ProxyBwapi
│ ├── Techs
│ │ └── None.scala
│ ├── Size.scala
│ ├── Players
│ │ └── Players.scala
│ ├── UnitTracking
│ │ ├── Visibility.scala
│ │ └── IndexedSet.scala
│ ├── Bullets
│ │ └── Bullets.scala
│ ├── Races
│ │ └── Neutral.scala
│ ├── Upgrades
│ │ └── Upgrades.scala
│ ├── UnitClasses
│ │ └── UnitClasses.scala
│ ├── UnitInfo
│ │ └── Targeter.scala
│ ├── Buildable.scala
│ └── Readme.md
├── Debugging
│ ├── SimpleString.scala
│ ├── Asciify.scala
│ ├── Decimal.scala
│ ├── English.scala
│ ├── Visualizations
│ │ ├── Rendering
│ │ │ └── TextWidth.scala
│ │ ├── Views
│ │ │ ├── Micro
│ │ │ │ ├── ShowUnitPaths.scala
│ │ │ │ ├── ShowPathfinding.scala
│ │ │ │ └── ShowFormations.scala
│ │ │ ├── Geography
│ │ │ │ └── ShowBWEB.scala
│ │ │ ├── Planning
│ │ │ │ ├── ShowPlacement.scala
│ │ │ │ ├── ShowWall.scala
│ │ │ │ ├── ShowHistory.scala
│ │ │ │ └── ShowFingerprints.scala
│ │ │ ├── Fun
│ │ │ │ ├── ShowBlackScreen.scala
│ │ │ │ └── ShowHappyVision.scala
│ │ │ ├── ShowStoryteller.scala
│ │ │ ├── DebugView.scala
│ │ │ └── Battles
│ │ │ │ └── ShowTeams.scala
│ │ ├── ForceLabel.scala
│ │ ├── Hues.scala
│ │ └── Animation.scala
│ ├── ToString.scala
│ └── EnumerateUnits.scala
├── Mathematics
│ ├── Physics
│ │ ├── Forces.scala
│ │ ├── Gravity.scala
│ │ └── ForceMap.scala
│ ├── Shapes
│ │ ├── Square.scala
│ │ ├── Rectangle.scala
│ │ ├── Corners.scala
│ │ ├── Circle.scala
│ │ ├── Box.scala
│ │ ├── RoundedBox.scala
│ │ └── Ring.scala
│ ├── Points
│ │ ├── Directions.scala
│ │ ├── Points.scala
│ │ ├── WalkTile.scala
│ │ ├── AbstractPoint.scala
│ │ └── Point.scala
│ └── Maff.scala
├── Information
│ ├── Geography
│ │ ├── Pathfinding
│ │ │ ├── Types
│ │ │ │ ├── TileState.scala
│ │ │ │ ├── NoPath.scala
│ │ │ │ └── ZonePathNode.scala
│ │ │ ├── Paths.scala
│ │ │ └── PathfindRepulsor.scala
│ │ ├── NeoGeo
│ │ │ ├── NeoEdge.scala
│ │ │ ├── NeoMetro.scala
│ │ │ ├── NeoRegion.scala
│ │ │ ├── NeoPixel.scala
│ │ │ ├── NeoTile.scala
│ │ │ ├── NeoWalk.scala
│ │ │ ├── NeoContinent.scala
│ │ │ ├── NeoCountry.scala
│ │ │ ├── Internal
│ │ │ │ └── NeoContinentBackend.scala
│ │ │ ├── NeoBase.scala
│ │ │ └── MapIdentifier.scala
│ │ ├── Calculations
│ │ │ ├── ZonesConnecting.scala
│ │ │ └── GetExits.scala
│ │ └── Types
│ │ │ └── LabelGenerator.scala
│ ├── Grids
│ │ ├── Floody
│ │ │ ├── FloodyUnitDepth.scala
│ │ │ ├── FloodyUnit.scala
│ │ │ ├── GridEnemyVision.scala
│ │ │ ├── GridEnemyRangeAir.scala
│ │ │ ├── GridEnemyRangeAirGround.scala
│ │ │ ├── GridEnemyRangeGround.scala
│ │ │ ├── GridFriendlyDetection.scala
│ │ │ └── GridEnemyDetection.scala
│ │ ├── Grid.scala
│ │ ├── GridUpdateUnit.scala
│ │ ├── Construction
│ │ │ ├── GridPsi2Height.scala
│ │ │ ├── GridPsi3Height.scala
│ │ │ ├── GridBuildable.scala
│ │ │ ├── GridBuildableTerrain.scala
│ │ │ └── GridBuildableTownHall.scala
│ │ ├── ArrayTypes
│ │ │ ├── AbstractGridFramestamp.scala
│ │ │ └── AbstractGridArrayBoolean.scala
│ │ ├── Versioned
│ │ │ ├── GridVersionedInt.scala
│ │ │ ├── GridVersionedDouble.scala
│ │ │ └── GridVersionedBoolean.scala
│ │ ├── Movement
│ │ │ ├── GridWalkable.scala
│ │ │ ├── GridFlowField.scala
│ │ │ ├── GridUnwalkableUnits.scala
│ │ │ └── GridWalkableTerrain.scala
│ │ └── Vision
│ │ │ ├── GridScoutingPathsBases.scala
│ │ │ ├── GridScoutingPathsStartLocations.scala
│ │ │ └── GridLastSeen.scala
│ ├── Battles
│ │ ├── Prediction
│ │ │ ├── Simulation
│ │ │ │ ├── Occupancy.scala
│ │ │ │ ├── BehaviorIdle.scala
│ │ │ │ ├── BehaviorHeal.scala
│ │ │ │ ├── BehaviorStorm.scala
│ │ │ │ ├── SimulacrumBehavior.scala
│ │ │ │ ├── BehaviorAssemble.scala
│ │ │ │ ├── SimulationEventDeath.scala
│ │ │ │ ├── BehaviorDetect.scala
│ │ │ │ ├── BehaviorFlee.scala
│ │ │ │ ├── SimulationEventBehavior.scala
│ │ │ │ ├── BehaviorRepair.scala
│ │ │ │ ├── SimulationEventSleep.scala
│ │ │ │ ├── ReportCard.scala
│ │ │ │ ├── SimulationEventMove.scala
│ │ │ │ └── BehaviorGather.scala
│ │ │ ├── Skimulation
│ │ │ │ ├── SkimulationTeam.scala
│ │ │ │ └── SkimulationUnit.scala
│ │ │ └── CPCount.scala
│ │ ├── Types
│ │ │ ├── DivisionRadius.scala
│ │ │ ├── EnemyTeam.scala
│ │ │ ├── FriendlyTeam.scala
│ │ │ ├── JudgmentModifier.scala
│ │ │ └── GroupCentroid.scala
│ │ └── ProcessingStates
│ │ │ ├── BattleProcessInitial.scala
│ │ │ ├── BattleProcessComplete.scala
│ │ │ ├── BattleProcessCluster.scala
│ │ │ ├── BattleProcessState.scala
│ │ │ ├── BattleProcessJudge.scala
│ │ │ └── BattleProcessMatchupAnalysis.scala
│ ├── GameSense
│ │ ├── Budgets.scala
│ │ ├── GameSense.scala
│ │ └── GameSenses.scala
│ ├── Fingerprinting
│ │ ├── TerranStrategies
│ │ │ ├── TerranTimings.scala
│ │ │ ├── Fingerprint1RaxGas.scala
│ │ │ ├── Fingerprint2Fac.scala
│ │ │ ├── Fingerprint3Fac.scala
│ │ │ ├── FingerprintWallIn.scala
│ │ │ ├── Fingerprint2FacVultures.scala
│ │ │ ├── Fingerprint14CC.scala
│ │ │ ├── FingerprintFD.scala
│ │ │ ├── Fingerprint1BaseBioMech.scala
│ │ │ ├── Fingerprint3FacVultures.scala
│ │ │ ├── Fingerprint1RaxFE.scala
│ │ │ └── Fingerprint2PortWraith.scala
│ │ ├── Generic
│ │ │ ├── FingerprintLambda.scala
│ │ │ ├── FingerprintRace.scala
│ │ │ ├── FingerprintNot.scala
│ │ │ ├── FingerprintOr.scala
│ │ │ ├── FingerprintAnd.scala
│ │ │ ├── FingerprintTechBy.scala
│ │ │ ├── FingerprintUpgradeBy.scala
│ │ │ ├── FingerprintGasSteal.scala
│ │ │ ├── FingerprintExistsBy.scala
│ │ │ ├── FingerprintHasExpanded.scala
│ │ │ └── FingerprintGasEmptyUntil.scala
│ │ ├── ZergStrategies
│ │ │ ├── Fingerprint9PoolGas.scala
│ │ │ ├── Fingerprint10Hatch.scala
│ │ │ ├── Fingerprint12HatchHatch.scala
│ │ │ ├── Fingerprint12Pool11Gas.scala
│ │ │ ├── FingerprintOverpoolGas.scala
│ │ │ ├── Fingerprint3HatchSpeedling.scala
│ │ │ ├── Fingerprint10Hatch9Pool8Gas.scala
│ │ │ ├── Fingerprint1HatchGas.scala
│ │ │ ├── Fingerprint12Hatch11Pool10Gas.scala
│ │ │ ├── Fingerprint2HatchGas.scala
│ │ │ ├── Fingerprint12Hatch11Pool.scala
│ │ │ ├── Fingerprint2HatchMain.scala
│ │ │ ├── Fingerprint3HatchHydra.scala
│ │ │ ├── Fingerprint3HatchMuta.scala
│ │ │ ├── Fingerprint9PoolHatch.scala
│ │ │ ├── Fingerprint12Pool.scala
│ │ │ ├── Fingerprint4Pool.scala
│ │ │ └── Fingerprint3HatchGas.scala
│ │ └── ProtossStrategies
│ │ │ ├── FingerprintBunkerRush.scala
│ │ │ ├── FingerprintCannonRush.scala
│ │ │ ├── FingerprintCoreBeforeZealot.scala
│ │ │ ├── FingerprintEarlyForge.scala
│ │ │ ├── FingerprintNexusFirst.scala
│ │ │ └── FingerprintGatewayFirst.scala
│ ├── Counting
│ │ └── MacroCounts.scala
│ └── Scouting
│ │ └── Scouting.scala
├── Lifecycle
│ └── PurpleBWClient.scala
├── Performance
│ ├── TaskQueue
│ │ └── Task.scala
│ ├── CacheForever.scala
│ ├── GameCache.scala
│ ├── Tasks
│ │ ├── SimpleTask.scala
│ │ ├── DummyTask.scala
│ │ └── StateTasks.scala
│ ├── Cache.scala
│ └── Timer.scala
├── Placement
│ ├── Walls
│ │ ├── WallMetrics.scala
│ │ ├── WallFillers.scala
│ │ ├── WallConstraint.scala
│ │ └── WallSpans.scala
│ ├── Templating
│ │ ├── PointGas.scala
│ │ ├── PointNothing.scala
│ │ ├── PointAnything.scala
│ │ ├── PointWalkable.scala
│ │ ├── RequireAnything.scala
│ │ ├── RequireNothing.scala
│ │ ├── RequireWalkable.scala
│ │ └── RequireGas.scala
│ ├── Generation
│ │ ├── TileGenerator.scala
│ │ ├── TemplatesGeneric.scala
│ │ └── TileGeneratorProximity.scala
│ ├── Access
│ │ └── Foundation.scala
│ ├── Architecture
│ │ ├── BuildingPlacement.scala
│ │ ├── Exclusion.scala
│ │ ├── ArchitecturalAssessment.scala
│ │ └── GridExclusion.scala
│ └── FoundationSources.scala
├── Micro
│ ├── Coordination
│ │ ├── TargetMap.scala
│ │ ├── Pushing
│ │ │ ├── ExplosionNuke.scala
│ │ │ ├── TrafficPriority.scala
│ │ │ ├── ExplosionInfestedTerran.scala
│ │ │ ├── ExplosionEMP.scala
│ │ │ ├── ExplosionPsionicStorm.scala
│ │ │ ├── ExplosionIrradiateSplash.scala
│ │ │ ├── ExplosionLurkerNow.scala
│ │ │ └── UnitLinearGroundPush.scala
│ │ └── Coordinator.scala
│ ├── Agency
│ │ ├── BuildIntent.scala
│ │ ├── LocalSimOverrides.scala
│ │ └── LocalSim.scala
│ ├── Formation
│ │ ├── FormationSimple.scala
│ │ ├── FormationEmpty.scala
│ │ └── FormationZone.scala
│ ├── Actions
│ │ ├── ActionPerformance.scala
│ │ ├── Combat
│ │ │ ├── Tactics
│ │ │ │ ├── FewShot.scala
│ │ │ │ └── Potshot.scala
│ │ │ └── Spells
│ │ │ │ └── WraithUncloak.scala
│ │ ├── Basic
│ │ │ ├── DoNothing.scala
│ │ │ ├── Addon.scala
│ │ │ ├── Unstick.scala
│ │ │ └── Bunk.scala
│ │ ├── Commands
│ │ │ ├── Attack.scala
│ │ │ └── Travel.scala
│ │ ├── Terran
│ │ │ ├── Liftoff.scala
│ │ │ ├── FinishConstruction.scala
│ │ │ ├── Scan.scala
│ │ │ └── GetRepairedBuilding.scala
│ │ ├── Scouting
│ │ │ ├── DroneWarfare.scala
│ │ │ ├── Scout.scala
│ │ │ └── PreserveScout.scala
│ │ └── Protoss
│ │ │ └── Shuttle
│ │ │ └── Shuttling.scala
│ ├── Targeting
│ │ ├── TargetFilter.scala
│ │ ├── FiltersRequired
│ │ │ ├── TargetFilterEnemy.scala
│ │ │ ├── TargetFilterMissing.scala
│ │ │ ├── TargetFilterCanAttack.scala
│ │ │ ├── TargetFilterType.scala
│ │ │ ├── TargetFilterExposed.scala
│ │ │ ├── TargetFilterScourge.scala
│ │ │ └── TargetFilterVulture.scala
│ │ └── FiltersSituational
│ │ │ ├── TargetFilterVisibleInRange.scala
│ │ │ ├── TargetFilterWhitelist.scala
│ │ │ ├── TargetFilterPotshot.scala
│ │ │ └── TargetFilterCombatants.scala
│ └── Heuristics
│ │ └── SpellTargets.scala
├── Strategery
│ ├── History
│ │ └── ContextualHistory.scala
│ ├── Strategies
│ │ ├── AllRaces
│ │ │ └── Sandbox.scala
│ │ ├── AllChoices.scala
│ │ └── Protoss
│ │ │ ├── PvRStrategies.scala
│ │ │ └── ProtossFPM.scala
│ ├── Selection
│ │ ├── StrategySelectionPolicy.scala
│ │ ├── WeightedGame.scala
│ │ ├── StrategySelectionFixed.scala
│ │ ├── StrategySelectionRandom.scala
│ │ └── StrategySelectionDynamic.scala
│ └── Rolling.scala
└── Tactic
│ ├── Squads
│ ├── FriendlyUnitGroup.scala
│ ├── Qualities
│ │ └── Quality.scala
│ ├── GenericUnitGroup.scala
│ └── GenericFriendlyUnitGroup.scala
│ ├── GetDefenseBase.scala
│ └── Tactics
│ ├── TacticFloatBuildings.scala
│ ├── TacticGather.scala
│ ├── Tactic.scala
│ └── TacticMeldDarchons.scala
├── 3rdparty
└── apache
│ ├── jna-5.1.0.jar
│ ├── jna-platform-5.1.0.jar
│ ├── commons-lang3-3.8.1.jar
│ ├── commons-lang3-3.8.1-javadoc.jar
│ └── commons-lang3-3.8.1-sources.jar
├── PurpleWave.bat
├── .idea
├── modules.xml
├── encodings.xml
├── codeStyleSettings.xml
└── vcs.xml
├── .gitignore
├── PurpleWaveWithJMX.bat
├── .gitmodules
└── scripts
└── performance.sh
/META-INF/native-image/native-image.properties:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/META-INF/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Main-Class: Lifecycle.Main
3 |
4 |
--------------------------------------------------------------------------------
/configs/BWAPI.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dgant/PurpleWave/HEAD/configs/BWAPI.dll
--------------------------------------------------------------------------------
/install/instructions1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dgant/PurpleWave/HEAD/install/instructions1.png
--------------------------------------------------------------------------------
/install/instructions2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dgant/PurpleWave/HEAD/install/instructions2.png
--------------------------------------------------------------------------------
/install/instructions3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dgant/PurpleWave/HEAD/install/instructions3.png
--------------------------------------------------------------------------------
/install/instructions4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dgant/PurpleWave/HEAD/install/instructions4.png
--------------------------------------------------------------------------------
/install/instructions5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dgant/PurpleWave/HEAD/install/instructions5.png
--------------------------------------------------------------------------------
/src/Macro/Facts/MacroFacts.scala:
--------------------------------------------------------------------------------
1 | package Macro.Facts
2 |
3 | object MacroFacts extends MacroCounting
4 |
--------------------------------------------------------------------------------
/3rdparty/apache/jna-5.1.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dgant/PurpleWave/HEAD/3rdparty/apache/jna-5.1.0.jar
--------------------------------------------------------------------------------
/PurpleWave.bat:
--------------------------------------------------------------------------------
1 | "C:\Program Files (x86)\Java\jre1.8.0_121\bin\java.exe" -jar ./out/artifacts/PurpleWave.jar
2 |
--------------------------------------------------------------------------------
/src/Gameplans/Zerg/ZvZ/ZergVsZerg.scala:
--------------------------------------------------------------------------------
1 | package Gameplans.Zerg.ZvZ
2 |
3 | class ZergVsZerg extends ZvZ10Hatch
--------------------------------------------------------------------------------
/src/Planning/Plans/NoPlan.scala:
--------------------------------------------------------------------------------
1 | package Planning.Plans
2 |
3 | object NoPlan { def apply(): Plan = new Plan }
4 |
--------------------------------------------------------------------------------
/src/Utilities/Time/Frames.scala:
--------------------------------------------------------------------------------
1 | package Utilities.Time
2 |
3 | case class Frames(f: Int) extends FrameCount(f)
4 |
--------------------------------------------------------------------------------
/src/Gameplans/Terran/TvP/TerranVsProtoss.scala:
--------------------------------------------------------------------------------
1 | package Gameplans.Terran.TvP
2 |
3 | class TerranVsProtoss extends TvP2Fac
--------------------------------------------------------------------------------
/src/Gameplans/Terran/TvT/TerranVsTerran.scala:
--------------------------------------------------------------------------------
1 | package Gameplans.Terran.TvT
2 |
3 | class TerranVsTerran extends TvT1Port
--------------------------------------------------------------------------------
/src/Gameplans/Terran/TvZ/TerranVsZerg.scala:
--------------------------------------------------------------------------------
1 | package Gameplans.Terran.TvZ
2 |
3 | class TerranVsZerg extends TvZ8RaxSK
--------------------------------------------------------------------------------
/src/Gameplans/Zerg/ZvP/ZergVsProtoss.scala:
--------------------------------------------------------------------------------
1 | package Gameplans.Zerg.ZvP
2 |
3 | class ZergVsProtoss extends ZvPHydraLurker
--------------------------------------------------------------------------------
/src/Gameplans/Zerg/ZvT/ZergVsTerran.scala:
--------------------------------------------------------------------------------
1 | package Gameplans.Zerg.ZvT
2 |
3 | class ZergVsTerran extends ZvTEffortBust
--------------------------------------------------------------------------------
/src/Utilities/UnitCounters/CountOne.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitCounters
2 |
3 | object CountOne extends CountUpTo(1)
--------------------------------------------------------------------------------
/3rdparty/apache/jna-platform-5.1.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dgant/PurpleWave/HEAD/3rdparty/apache/jna-platform-5.1.0.jar
--------------------------------------------------------------------------------
/src/Utilities/LightYear.scala:
--------------------------------------------------------------------------------
1 | package Utilities
2 |
3 | object LightYear {
4 | def apply(): Int = 256 * 256
5 | }
6 |
--------------------------------------------------------------------------------
/src/Utilities/Time/Seconds.scala:
--------------------------------------------------------------------------------
1 | package Utilities.Time
2 |
3 | case class Seconds(s: Int) extends FrameCount(s * 24)
4 |
--------------------------------------------------------------------------------
/3rdparty/apache/commons-lang3-3.8.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dgant/PurpleWave/HEAD/3rdparty/apache/commons-lang3-3.8.1.jar
--------------------------------------------------------------------------------
/src/Utilities/Time/Hours.scala:
--------------------------------------------------------------------------------
1 | package Utilities.Time
2 |
3 | case class Hours(h: Int) extends FrameCount(h * 60 * 60 * 24)
4 |
--------------------------------------------------------------------------------
/src/Utilities/Time/Minutes.scala:
--------------------------------------------------------------------------------
1 | package Utilities.Time
2 |
3 | case class Minutes(m: Int) extends FrameCount(m * 60 * 24)
4 |
--------------------------------------------------------------------------------
/src/Utilities/UnitCounters/CountEverything.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitCounters
2 |
3 | object CountEverything extends CountUpTo(10000)
--------------------------------------------------------------------------------
/src/Utilities/UnitCounters/CountUpTo.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitCounters
2 |
3 | case class CountUpTo(maximum: Int) extends UnitCounter
--------------------------------------------------------------------------------
/src/ProxyBwapi/Techs/None.scala:
--------------------------------------------------------------------------------
1 | package ProxyBwapi.Techs
2 |
3 | import bwapi.TechType
4 |
5 | object None extends Tech(TechType.None)
--------------------------------------------------------------------------------
/src/Utilities/Time/GameTime.scala:
--------------------------------------------------------------------------------
1 | package Utilities.Time
2 |
3 | case class GameTime(m: Int, s: Int) extends FrameCount(24 * (60 * m + s))
--------------------------------------------------------------------------------
/3rdparty/apache/commons-lang3-3.8.1-javadoc.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dgant/PurpleWave/HEAD/3rdparty/apache/commons-lang3-3.8.1-javadoc.jar
--------------------------------------------------------------------------------
/3rdparty/apache/commons-lang3-3.8.1-sources.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dgant/PurpleWave/HEAD/3rdparty/apache/commons-lang3-3.8.1-sources.jar
--------------------------------------------------------------------------------
/src/Debugging/SimpleString.scala:
--------------------------------------------------------------------------------
1 | package Debugging
2 |
3 | trait SimpleString {
4 | override def toString: String = ToString(this)
5 | }
6 |
--------------------------------------------------------------------------------
/src/Gameplans/All/Modal.scala:
--------------------------------------------------------------------------------
1 | package Gameplans.All
2 |
3 | trait Modal {
4 | def isComplete: Boolean
5 | def update(): Unit
6 | }
7 |
--------------------------------------------------------------------------------
/src/Mathematics/Physics/Forces.scala:
--------------------------------------------------------------------------------
1 | package Mathematics.Physics
2 |
3 | object Forces {
4 | val None: Force = Force(0.0, 0.0)
5 | }
6 |
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsFlyingBuilding.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 |
3 | object IsFlyingBuilding extends IsAll(IsBuilding, _.flying)
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsFlyingWarrior.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 |
3 | object IsFlyingWarrior extends IsAll(IsWarrior, _.flying)
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsGroundWarrior.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 |
3 | object IsGroundWarrior extends IsAll(IsWarrior, ! _.flying)
4 |
--------------------------------------------------------------------------------
/src/Debugging/Asciify.scala:
--------------------------------------------------------------------------------
1 | package Debugging
2 |
3 | object Asciify {
4 | def apply(v: String): String = v.replaceAll("[^\\x00-\\x7F]", "")
5 | }
6 |
--------------------------------------------------------------------------------
/src/Information/Geography/Pathfinding/Types/TileState.scala:
--------------------------------------------------------------------------------
1 | package Information.Geography.Pathfinding.Types
2 |
3 | class TileState {
4 |
5 | }
6 |
--------------------------------------------------------------------------------
/src/Information/Grids/Floody/FloodyUnitDepth.scala:
--------------------------------------------------------------------------------
1 | package Information.Grids.Floody
2 |
3 | case class FloodyUnitDepth(unit: FloodyUnit, value: Int)
4 |
--------------------------------------------------------------------------------
/src/Gameplans/Zerg/ZvR/ZergVsRandom.scala:
--------------------------------------------------------------------------------
1 | package Gameplans.Zerg.ZvR
2 |
3 | import Gameplans.Zerg.ZvE.ZvE4Pool
4 |
5 | class ZergVsRandom extends ZvE4Pool
--------------------------------------------------------------------------------
/src/Lifecycle/PurpleBWClient.scala:
--------------------------------------------------------------------------------
1 | package Lifecycle
2 |
3 | import bwapi.BWClient
4 |
5 | object PurpleBWClient extends BWClient(PurpleEventListener)
6 |
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsMechWarrior.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 |
3 | object IsMechWarrior extends IsAll(IsWarrior, _.unitClass.isMechanical)
4 |
--------------------------------------------------------------------------------
/src/Utilities/In.scala:
--------------------------------------------------------------------------------
1 | package Utilities
2 |
3 | object In {
4 | @inline final def apply[T](element: T, among: T*): Boolean = among.contains(element)
5 | }
6 |
--------------------------------------------------------------------------------
/configs/run32.bat:
--------------------------------------------------------------------------------
1 | echo "Running with default JRE (Presumably 32-bit Java 8)."
2 | java.exe -jar -XX:MaxGCPauseMillis=15 -Xms768m -Xmx768m ./bwapi-data/AI/PurpleWave.jar
3 |
--------------------------------------------------------------------------------
/src/Performance/TaskQueue/Task.scala:
--------------------------------------------------------------------------------
1 | package Performance.TaskQueue
2 |
3 | trait Task {
4 | def canRun: Boolean
5 | def run(): Unit
6 | def skip(): Unit
7 | }
8 |
--------------------------------------------------------------------------------
/src/Placement/Walls/WallMetrics.scala:
--------------------------------------------------------------------------------
1 | package Placement.Walls
2 |
3 | class WallMetrics {
4 | var permutations = 0
5 | var tilesConsidered = 0
6 | }
7 |
--------------------------------------------------------------------------------
/src/Utilities/Time/Forever.scala:
--------------------------------------------------------------------------------
1 | package Utilities.Time
2 |
3 | object Forever extends Frames(345678) // Almost exactly 4 hours, but also a recognizable sentinel value
4 |
--------------------------------------------------------------------------------
/src/Debugging/Decimal.scala:
--------------------------------------------------------------------------------
1 | package Debugging
2 |
3 | object Decimal {
4 | def apply(value: Double, decimals: Int = 2): String = s"%1.${decimals}f".format(value)
5 | }
6 |
--------------------------------------------------------------------------------
/src/Information/Battles/Prediction/Simulation/Occupancy.scala:
--------------------------------------------------------------------------------
1 | package Information.Battles.Prediction.Simulation
2 |
3 | object Occupancy {
4 | val Resolution = 12
5 | }
6 |
--------------------------------------------------------------------------------
/src/Information/Geography/Pathfinding/Paths.scala:
--------------------------------------------------------------------------------
1 | package Information.Geography.Pathfinding
2 |
3 | final class Paths extends TilePathfinder with ZonePathfinder with GroundDistance
--------------------------------------------------------------------------------
/src/Micro/Coordination/TargetMap.scala:
--------------------------------------------------------------------------------
1 | package Micro.Coordination
2 |
3 | class TargetMap {
4 | val targets: Array[Array[Double]] = Array.ofDim[Double](10000, 10000)
5 | }
6 |
--------------------------------------------------------------------------------
/src/Placement/Templating/PointGas.scala:
--------------------------------------------------------------------------------
1 | package Placement.Templating
2 |
3 | import Mathematics.Points.Point
4 |
5 | class PointGas extends TemplatePoint(Point(0, 0), new RequireGas)
--------------------------------------------------------------------------------
/src/Utilities/UnitCounters/CountBetween.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitCounters
2 |
3 | case class CountBetween(override val minimum: Int, override val maximum: Int) extends UnitCounter
--------------------------------------------------------------------------------
/src/Gameplans/Protoss/FFA/ProtossFFAMoney.scala:
--------------------------------------------------------------------------------
1 | package Gameplans.Protoss.FFA
2 |
3 | class ProtossFFAMoney extends ProtossFFA {
4 | override val expandEver: Boolean = false
5 | }
6 |
--------------------------------------------------------------------------------
/src/Macro/Requests/RequestTech.scala:
--------------------------------------------------------------------------------
1 | package Macro.Requests
2 |
3 | import ProxyBwapi.Techs.Tech
4 |
5 | case class RequestTech(techType: Tech) extends RequestBuildable(techType, 1)
6 |
--------------------------------------------------------------------------------
/src/Information/Geography/NeoGeo/NeoEdge.scala:
--------------------------------------------------------------------------------
1 | package Information.Geography.NeoGeo
2 |
3 | /**
4 | * Describes a boundary between two Regions.
5 | */
6 | class NeoEdge {
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/src/Information/Grids/Grid.scala:
--------------------------------------------------------------------------------
1 | package Information.Grids
2 |
3 | trait Grid {
4 | def update(): Unit = {}
5 | var code: String = "uncoded"
6 | def reprAt(i: Int): String
7 | }
8 |
--------------------------------------------------------------------------------
/src/Performance/CacheForever.scala:
--------------------------------------------------------------------------------
1 | package Performance
2 |
3 | import Utilities.Time.Forever
4 |
5 | class CacheForever[T](recalculator: () => T) extends Cache[T](recalculator, Forever())
6 |
--------------------------------------------------------------------------------
/src/Utilities/SomeIf.scala:
--------------------------------------------------------------------------------
1 | package Utilities
2 |
3 | object SomeIf {
4 | @inline final def apply[T](predicate: Boolean, value: => T): Option[T] = ?(predicate, Some(value), None)
5 | }
6 |
--------------------------------------------------------------------------------
/src/Debugging/English.scala:
--------------------------------------------------------------------------------
1 | package Debugging
2 |
3 | object English {
4 | def pluralize(word: String, count: Int): String = {
5 | if (count == 1) word else word + "s"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/Information/Battles/Types/DivisionRadius.scala:
--------------------------------------------------------------------------------
1 | package Information.Battles.Types
2 |
3 | object DivisionRadius {
4 | val inner: Int = 32 * 32
5 | val outer: Int = 32 * 20 + inner
6 | }
7 |
--------------------------------------------------------------------------------
/src/Performance/GameCache.scala:
--------------------------------------------------------------------------------
1 | package Performance
2 |
3 | import Lifecycle.With
4 |
5 | class GameCache[TValue](getValue: () => TValue) extends KeyedCache[TValue, Long](getValue, () => With.id)
--------------------------------------------------------------------------------
/src/Placement/Templating/PointNothing.scala:
--------------------------------------------------------------------------------
1 | package Placement.Templating
2 |
3 | import Mathematics.Points.Point
4 |
5 | class PointNothing extends TemplatePoint(Point(0, 0), new RequireNothing)
6 |
--------------------------------------------------------------------------------
/src/ProxyBwapi/Size.scala:
--------------------------------------------------------------------------------
1 | package ProxyBwapi
2 |
3 | object Size {
4 | trait Type
5 | object Small extends Type
6 | object Medium extends Type
7 | object Large extends Type
8 | }
9 |
--------------------------------------------------------------------------------
/src/Utilities/SomeIfO.scala:
--------------------------------------------------------------------------------
1 | package Utilities
2 |
3 | object SomeIfO {
4 | @inline final def apply[T](predicate: Boolean, value: => Option[T]): Option[T] = ?(predicate, value, None)
5 | }
6 |
--------------------------------------------------------------------------------
/src/Debugging/Visualizations/Rendering/TextWidth.scala:
--------------------------------------------------------------------------------
1 | package Debugging.Visualizations.Rendering
2 |
3 | object TextWidth {
4 | def apply(s: String): Int = {
5 | 9 * s.length
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/Information/Geography/NeoGeo/NeoMetro.scala:
--------------------------------------------------------------------------------
1 | package Information.Geography.NeoGeo
2 |
3 | /**
4 | * A Metro is a collection of one or more closely-
5 | */
6 | class NeoMetro {
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/src/Information/Grids/GridUpdateUnit.scala:
--------------------------------------------------------------------------------
1 | package Information.Grids
2 |
3 | import ProxyBwapi.UnitInfo.UnitInfo
4 |
5 | trait GridUpdateUnit {
6 | def updateUnit(unit: UnitInfo): Unit
7 | }
8 |
--------------------------------------------------------------------------------
/src/Placement/Templating/PointAnything.scala:
--------------------------------------------------------------------------------
1 | package Placement.Templating
2 |
3 | import Mathematics.Points.Point
4 |
5 | class PointAnything extends TemplatePoint(Point(0, 0), new RequireAnything)
6 |
--------------------------------------------------------------------------------
/src/Placement/Templating/PointWalkable.scala:
--------------------------------------------------------------------------------
1 | package Placement.Templating
2 |
3 | import Mathematics.Points.Point
4 |
5 | class PointWalkable extends TemplatePoint(Point(0, 0), new RequireWalkable)
6 |
--------------------------------------------------------------------------------
/src/Utilities/AsJava.scala:
--------------------------------------------------------------------------------
1 | package Utilities
2 |
3 | import scala.collection.JavaConverters._
4 |
5 | object AsJava {
6 | def apply[T](x: Iterable[T]): java.lang.Iterable[T] = x.asJava
7 | }
8 |
--------------------------------------------------------------------------------
/src/Utilities/AsScala.scala:
--------------------------------------------------------------------------------
1 | package Utilities
2 |
3 | import scala.collection.JavaConverters._
4 |
5 | object AsScala {
6 | def apply[T](x: java.lang.Iterable[T]): Iterable[T] = x.asScala
7 | }
8 |
--------------------------------------------------------------------------------
/src/Gameplans/Protoss/PvR/ProtossVsRandom.scala:
--------------------------------------------------------------------------------
1 | package Gameplans.Protoss.PvR
2 |
3 | import Gameplans.All.ModalGameplan
4 |
5 | class ProtossVsRandom extends ModalGameplan(
6 | new PvR2Gate4Gate
7 | )
--------------------------------------------------------------------------------
/src/Mathematics/Shapes/Square.scala:
--------------------------------------------------------------------------------
1 | package Mathematics.Shapes
2 |
3 | import Mathematics.Points.Point
4 |
5 | object Square {
6 | def apply(width: Int): IndexedSeq[Point] = Rectangle(width, width)
7 | }
8 |
--------------------------------------------------------------------------------
/src/Placement/Generation/TileGenerator.scala:
--------------------------------------------------------------------------------
1 | package Placement.Generation
2 |
3 | import Mathematics.Points.Tile
4 |
5 | trait TileGenerator {
6 | def next(): Tile
7 | def hasNext: Boolean
8 | }
9 |
--------------------------------------------------------------------------------
/src/Utilities/UnitCounters/CountExactly.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitCounters
2 |
3 | case class CountExactly(override val minimum: Int) extends UnitCounter {
4 | override val maximum: Int = minimum
5 | }
--------------------------------------------------------------------------------
/configs/run64.bat:
--------------------------------------------------------------------------------
1 | echo "Running with bundled JRE."
2 | ./bwapi-data/AI/jre/bin/java.exe -jar -XX:MaxGCPauseMillis=15 -Xms1536m -Xmx2048m --add-opens=java.base/java.nio=ALL-UNNAMED ./bwapi-data/AI/PurpleWave.jar
3 |
--------------------------------------------------------------------------------
/src/Debugging/Visualizations/Views/Micro/ShowUnitPaths.scala:
--------------------------------------------------------------------------------
1 | package Debugging.Visualizations.Views.Micro
2 |
3 | import Debugging.Visualizations.Views.DebugView
4 |
5 | object ShowUnitPaths extends DebugView
6 |
--------------------------------------------------------------------------------
/src/Utilities/UnitPreferences/UnitPreference.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitPreferences
2 |
3 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
4 |
5 | trait UnitPreference extends Function[FriendlyUnitInfo, Double]
6 |
--------------------------------------------------------------------------------
/src/Macro/Requests/RequestUpgrade.scala:
--------------------------------------------------------------------------------
1 | package Macro.Requests
2 |
3 | import ProxyBwapi.Upgrades.Upgrade
4 |
5 | case class RequestUpgrade(upgradeType: Upgrade, level: Int = 1) extends RequestBuildable(upgradeType, level)
--------------------------------------------------------------------------------
/src/Placement/Access/Foundation.scala:
--------------------------------------------------------------------------------
1 | package Placement.Access
2 |
3 | import Mathematics.Points.Tile
4 | import Placement.Templating.TemplatePoint
5 |
6 | case class Foundation(tile: Tile, point: TemplatePoint, order: Int = 0)
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsAnything.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 | import ProxyBwapi.UnitInfo.UnitInfo
3 |
4 | object IsAnything extends UnitFilter {
5 | override def apply(unit: UnitInfo): Boolean = true
6 | }
7 |
--------------------------------------------------------------------------------
/src/Information/Geography/NeoGeo/NeoRegion.scala:
--------------------------------------------------------------------------------
1 | package Information.Geography.NeoGeo
2 |
3 | /**
4 | * A Region is an open piece of walkable territory.
5 | */
6 | class NeoRegion {
7 | var isChoke: Boolean = _
8 | }
9 |
--------------------------------------------------------------------------------
/src/Information/Grids/Floody/FloodyUnit.scala:
--------------------------------------------------------------------------------
1 | package Information.Grids.Floody
2 |
3 | import Mathematics.Points.Tile
4 | import ProxyBwapi.UnitInfo.UnitInfo
5 |
6 | case class FloodyUnit(unit: UnitInfo, radius: Int, tile: Tile)
--------------------------------------------------------------------------------
/src/Micro/Agency/BuildIntent.scala:
--------------------------------------------------------------------------------
1 | package Micro.Agency
2 |
3 | import Mathematics.Points.Tile
4 | import ProxyBwapi.UnitClasses.UnitClass
5 |
6 | case class BuildIntent(unitClass: UnitClass, tile: Tile, startNow: Boolean = true)
--------------------------------------------------------------------------------
/src/Micro/Coordination/Pushing/ExplosionNuke.scala:
--------------------------------------------------------------------------------
1 | package Micro.Coordination.Pushing
2 |
3 | import Mathematics.Points.Pixel
4 |
5 | class ExplosionNuke(pixel: Pixel) extends CircularPush(TrafficPriorities.Dive, pixel, 256)
6 |
--------------------------------------------------------------------------------
/src/Placement/Architecture/BuildingPlacement.scala:
--------------------------------------------------------------------------------
1 | package Placement.Architecture
2 |
3 | import Mathematics.Points.Tile
4 | import ProxyBwapi.UnitClasses.UnitClass
5 |
6 | case class BuildingPlacement(tile: Tile, unit: UnitClass)
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsBioWarrior.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 |
3 | import ProxyBwapi.Races.Terran
4 |
5 | object IsBioWarrior extends IsAll(IsAny(Terran.Marine, Terran.Firebat), _.aliveAndComplete, _.canMove)
6 |
--------------------------------------------------------------------------------
/src/Debugging/Visualizations/ForceLabel.scala:
--------------------------------------------------------------------------------
1 | package Debugging.Visualizations
2 |
3 | import bwapi.Color
4 |
5 | case class ForceLabel(name: String, color: Color) {
6 | override def toString: String = "Force: " + name
7 | }
8 |
--------------------------------------------------------------------------------
/src/Macro/Requests/RequestAutosupply.scala:
--------------------------------------------------------------------------------
1 | package Macro.Requests
2 |
3 | import ProxyBwapi.Races.Neutral
4 |
5 | object RequestAutosupply extends RequestBuildable(Neutral.Autosupply) {
6 | override val toString = "Autosupply"
7 | }
--------------------------------------------------------------------------------
/src/Micro/Agency/LocalSimOverrides.scala:
--------------------------------------------------------------------------------
1 | package Micro.Agency
2 |
3 | trait LocalSimOverrides {
4 |
5 |
6 |
7 | private def add(outcome: Boolean, name: String, test: () => Boolean): Unit = {
8 |
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/Strategery/History/ContextualHistory.scala:
--------------------------------------------------------------------------------
1 | package Strategery.History
2 |
3 | import Utilities.CountMap
4 |
5 | case class ContextualHistory(
6 | winsByStrategy : CountMap[String],
7 | lossesByStrategy : CountMap[String])
8 |
--------------------------------------------------------------------------------
/src/Utilities/Ternary.scala:
--------------------------------------------------------------------------------
1 | package Utilities
2 |
3 | //noinspection ScalaFileName
4 | object ? {
5 | @inline final def apply[T](predicate: Boolean, yes: => T, no: => T): T = {
6 | if (predicate) yes else no
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsEnemy.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 |
3 | import ProxyBwapi.UnitInfo.UnitInfo
4 |
5 | object IsEnemy extends UnitFilter {
6 | override def apply(unit: UnitInfo): Boolean = unit.isEnemy
7 | }
8 |
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsProxied.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 |
3 | import ProxyBwapi.UnitInfo.UnitInfo
4 |
5 | object IsProxied extends UnitFilter {
6 | override def apply(unit: UnitInfo): Boolean = unit.proxied
7 | }
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/UnitFilter.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 |
3 | import Debugging.SimpleString
4 | import ProxyBwapi.UnitInfo.UnitInfo
5 |
6 | trait UnitFilter extends Function[UnitInfo, Boolean] with SimpleString
7 |
--------------------------------------------------------------------------------
/src/Gameplans/Protoss/PvZ/ProtossVsZerg.scala:
--------------------------------------------------------------------------------
1 | package Gameplans.Protoss.PvZ
2 |
3 | import Gameplans.All.ModalGameplan
4 |
5 | class ProtossVsZerg extends ModalGameplan(
6 | new PvZFE,
7 | new PvZ1BaseReactive,
8 | new PvZ2022
9 | )
--------------------------------------------------------------------------------
/src/Information/Geography/Pathfinding/PathfindRepulsor.scala:
--------------------------------------------------------------------------------
1 | package Information.Geography.Pathfinding
2 |
3 | import Mathematics.Points.Pixel
4 |
5 | final case class PathfindRepulsor(source: Pixel, magnitude: Double, rangePixels: Double)
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsTank.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 |
3 | import ProxyBwapi.UnitInfo.UnitInfo
4 |
5 | object IsTank extends UnitFilter {
6 | override def apply(unit: UnitInfo): Boolean = unit.unitClass.isTank
7 | }
8 |
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsVisible.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 |
3 | import ProxyBwapi.UnitInfo.UnitInfo
4 |
5 | object IsVisible extends UnitFilter {
6 | override def apply(unit: UnitInfo): Boolean = unit.visible
7 | }
8 |
--------------------------------------------------------------------------------
/src/Information/Geography/Pathfinding/Types/NoPath.scala:
--------------------------------------------------------------------------------
1 | package Information.Geography.Pathfinding.Types
2 |
3 | import Mathematics.Points.Tile
4 |
5 | object NoPath {
6 | val value = TilePath(Tile(0, 0), Tile(0, 0), 0, None)
7 | }
8 |
9 |
--------------------------------------------------------------------------------
/src/Placement/Architecture/Exclusion.scala:
--------------------------------------------------------------------------------
1 | package Placement.Architecture
2 |
3 | import Mathematics.Points.TileRectangle
4 |
5 | case class Exclusion(description: String, areaExcluded: TileRectangle, request: Option[BuildingPlacement] = None)
6 |
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsBuilding.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 | import ProxyBwapi.UnitInfo.UnitInfo
3 |
4 | object IsBuilding extends UnitFilter {
5 | override def apply(unit: UnitInfo): Boolean = unit.unitClass.isBuilding
6 | }
7 |
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsComplete.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 |
3 | import ProxyBwapi.UnitInfo.UnitInfo
4 |
5 | object IsComplete extends UnitFilter {
6 |
7 | override def apply(unit: UnitInfo): Boolean = unit.complete
8 | }
9 |
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsTownHall.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 | import ProxyBwapi.UnitInfo.UnitInfo
3 |
4 | object IsTownHall extends UnitFilter {
5 | override def apply(unit: UnitInfo): Boolean = unit.unitClass.isTownHall
6 | }
7 |
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsWorker.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 |
3 | import ProxyBwapi.UnitInfo.UnitInfo
4 |
5 | object IsWorker extends UnitFilter {
6 | override def apply(unit: UnitInfo): Boolean = unit.unitClass.isWorker
7 | }
8 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/Gameplans/Protoss/PvP/ProtossVsProtoss.scala:
--------------------------------------------------------------------------------
1 | package Gameplans.Protoss.PvP
2 |
3 | import Gameplans.All.ModalGameplan
4 |
5 | class ProtossVsProtoss extends ModalGameplan(
6 | new PvPNexusFirst,
7 | new PvPOpening,
8 | new PvPLateGame,
9 | )
--------------------------------------------------------------------------------
/src/Gameplans/Protoss/PvT/ProtossVsTerran.scala:
--------------------------------------------------------------------------------
1 | package Gameplans.Protoss.PvT
2 |
3 | import Gameplans.All.ModalGameplan
4 |
5 | class ProtossVsTerran extends ModalGameplan(
6 | new PvTFastCarrier,
7 | new PvTArbiter,
8 | new PvTDoubleRobo
9 | )
--------------------------------------------------------------------------------
/src/Tactic/Squads/FriendlyUnitGroup.scala:
--------------------------------------------------------------------------------
1 | package Tactic.Squads
2 |
3 | import ProxyBwapi.UnitInfo.UnitInfo
4 |
5 | trait FriendlyUnitGroup extends UnitGroup with TFriendlyUnitGroup {
6 | def groupUnits: Seq[UnitInfo] = groupFriendlyUnits
7 | }
8 |
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsDetector.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 |
3 | import ProxyBwapi.UnitInfo.UnitInfo
4 |
5 | object IsDetector extends UnitFilter {
6 | override def apply(unit: UnitInfo): Boolean = unit.unitClass.isDetector
7 | }
8 |
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsHatchlike.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 |
3 | import ProxyBwapi.UnitInfo.UnitInfo
4 |
5 | object IsHatchlike extends UnitFilter {
6 | override def apply(unit: UnitInfo): Boolean = unit.unitClass.isHatchlike
7 | }
8 |
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsLairlike.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 |
3 | import ProxyBwapi.UnitInfo.UnitInfo
4 |
5 | object IsLairlike extends UnitFilter {
6 | override def apply(unit: UnitInfo): Boolean = unit.unitClass.isLairlike
7 | }
8 |
--------------------------------------------------------------------------------
/src/Macro/Scheduling/ScheduleItem.scala:
--------------------------------------------------------------------------------
1 | package Macro.Scheduling
2 |
3 | import Macro.Requests.RequestBuildable
4 |
5 | case class ScheduleItem(requester: Any, request: RequestBuildable) {
6 | override def toString = f"$request -- for $requester"
7 | }
8 |
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsAntiAir.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 |
3 | import ProxyBwapi.UnitInfo.UnitInfo
4 |
5 | object IsAntiAir extends UnitFilter {
6 |
7 | override def apply(unit: UnitInfo): Boolean = unit.damageOnHitAir > 0
8 | }
9 |
--------------------------------------------------------------------------------
/src/Utilities/UnitPreferences/PreferAnything.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitPreferences
2 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
3 |
4 | object PreferAnything extends UnitPreference {
5 | override def apply(unit: FriendlyUnitInfo): Double = 0
6 | }
7 |
--------------------------------------------------------------------------------
/src/Tactic/Squads/Qualities/Quality.scala:
--------------------------------------------------------------------------------
1 | package Tactic.Squads.Qualities
2 |
3 | import Utilities.UnitFilters.UnitFilter
4 |
5 | trait Quality extends UnitFilter {
6 | val counteredBy: Array[Quality] = Array.empty
7 | def counterScaling: Double = 1.0
8 | }
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/Is.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 |
3 | import ProxyBwapi.UnitInfo.UnitInfo
4 |
5 | case class Is(predicate: UnitInfo => Boolean) extends UnitFilter {
6 | override def apply(unit: UnitInfo): Boolean = predicate(unit)
7 | }
8 |
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsAntiGround.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 |
3 | import ProxyBwapi.UnitInfo.UnitInfo
4 |
5 | object IsAntiGround extends UnitFilter {
6 |
7 | override def apply(unit: UnitInfo): Boolean = unit.damageOnHitGround > 0
8 | }
9 |
--------------------------------------------------------------------------------
/src/Utilities/SwapIf.scala:
--------------------------------------------------------------------------------
1 | package Utilities
2 |
3 | object SwapIf {
4 | def apply[T](predicate: Boolean, a: => T, b: => T): T = {
5 | if (predicate) {
6 | b
7 | a
8 | } else {
9 | a
10 | b
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/Information/Battles/Prediction/Simulation/BehaviorIdle.scala:
--------------------------------------------------------------------------------
1 | package Information.Battles.Prediction.Simulation
2 |
3 | object BehaviorIdle extends SimulacrumBehavior {
4 | val fighting: Boolean = false
5 | override def act(simulacrum: Simulacrum): Unit = {}
6 | }
7 |
--------------------------------------------------------------------------------
/src/Information/GameSense/Budgets.scala:
--------------------------------------------------------------------------------
1 | package Information.GameSense
2 |
3 | object Budgets extends Enumeration {
4 | val
5 | Worker,
6 | Base,
7 | Supply,
8 | Production,
9 | Science,
10 | Defense,
11 | War = Value
12 | }
13 |
--------------------------------------------------------------------------------
/src/Information/Geography/NeoGeo/NeoPixel.scala:
--------------------------------------------------------------------------------
1 | package Information.Geography.NeoGeo
2 |
3 | import bwapi.Position
4 |
5 | case class NeoPixel(x: Int, y: Int) {
6 | def this(position: Position) {
7 | this(position.getX, position.getY)
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/Micro/Formation/FormationSimple.scala:
--------------------------------------------------------------------------------
1 | package Micro.Formation
2 |
3 | import Mathematics.Points.Pixel
4 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
5 |
6 | case class FormationSimple(style: FormationStyle, placements: Map[FriendlyUnitInfo, Pixel]) extends Formation
7 |
--------------------------------------------------------------------------------
/src/Placement/FoundationSources.scala:
--------------------------------------------------------------------------------
1 | package Placement
2 |
3 | object FoundationSources {
4 | trait FoundationSource
5 | object Default extends FoundationSource
6 | object TownHall extends FoundationSource
7 | object Gas extends FoundationSource
8 | }
9 |
--------------------------------------------------------------------------------
/src/Tactic/Squads/GenericUnitGroup.scala:
--------------------------------------------------------------------------------
1 | package Tactic.Squads
2 |
3 | import ProxyBwapi.UnitInfo.UnitInfo
4 |
5 | case class GenericUnitGroup(override val groupUnits: Seq[UnitInfo]) extends UnitGroup {
6 | def this(unit: UnitInfo) {
7 | this(Seq(unit))
8 | }
9 | }
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsWarrior.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 |
3 | import ProxyBwapi.UnitInfo.UnitInfo
4 |
5 | object IsWarrior extends UnitFilter {
6 | override def apply(unit: UnitInfo): Boolean = unit.aliveAndComplete && unit.unitClass.isWarrior
7 | }
8 |
--------------------------------------------------------------------------------
/src/Utilities/UnitPreferences/PreferLowEnergy.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitPreferences
2 |
3 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
4 |
5 | object PreferLowEnergy extends UnitPreference {
6 | override def apply(unit: FriendlyUnitInfo): Double = unit.energy
7 | }
8 |
--------------------------------------------------------------------------------
/src/Information/Battles/ProcessingStates/BattleProcessInitial.scala:
--------------------------------------------------------------------------------
1 | package Information.Battles.ProcessingStates
2 |
3 | class BattleProcessInitial extends BattleProcessState {
4 | override def step(): Unit = {
5 | transitionTo(new BattleProcessCluster)
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/Information/Geography/Pathfinding/Types/ZonePathNode.scala:
--------------------------------------------------------------------------------
1 | package Information.Geography.Pathfinding.Types
2 |
3 | import Information.Geography.Types.{Edge, Zone}
4 |
5 | case class ZonePathNode(from: Zone, edge: Edge) {
6 | def to: Zone = edge.otherSideof(from)
7 | }
8 |
--------------------------------------------------------------------------------
/src/Micro/Actions/ActionPerformance.scala:
--------------------------------------------------------------------------------
1 | package Micro.Actions
2 |
3 | class ActionPerformance {
4 | var invocations: Int = 0
5 | var durationNanos: Long = 0
6 | def totalMs: Double = durationNanos / 1e6
7 | def meanMs: Double = totalMs / invocations.toDouble
8 | }
9 |
--------------------------------------------------------------------------------
/src/Tactic/GetDefenseBase.scala:
--------------------------------------------------------------------------------
1 | package Tactic
2 |
3 | import Information.Geography.Types.Base
4 |
5 | object GetDefenseBase {
6 | def apply(base: Base): Base = {
7 | base.natural.filter(b => b.isOurs || b.plannedExpoRecently).getOrElse(base)
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsAny.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 |
3 | import ProxyBwapi.UnitInfo.UnitInfo
4 |
5 | case class IsAny(matches: UnitFilter*) extends UnitFilter {
6 | @inline final override def apply(unit: UnitInfo): Boolean = matches.exists(_(unit))
7 | }
8 |
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsMobileDetector.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 |
3 | import ProxyBwapi.UnitInfo.UnitInfo
4 |
5 | object IsMobileDetector extends UnitFilter {
6 | override def apply(unit: UnitInfo): Boolean = unit.unitClass.isDetector && unit.canMove
7 | }
8 |
--------------------------------------------------------------------------------
/src/Information/Battles/Types/EnemyTeam.scala:
--------------------------------------------------------------------------------
1 | package Information.Battles.Types
2 |
3 | import ProxyBwapi.UnitInfo.UnitInfo
4 | import Tactic.Squads.UnitGroup
5 |
6 | class EnemyTeam(battle: Battle, units: Seq[UnitInfo]) extends Team(battle, units) with UnitGroup {
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsLandedBuilding.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 |
3 | import ProxyBwapi.UnitInfo.UnitInfo
4 |
5 | object IsLandedBuilding extends UnitFilter {
6 | override def apply(unit: UnitInfo): Boolean = unit.unitClass.isBuilding && ! unit.flying
7 | }
8 |
--------------------------------------------------------------------------------
/src/Information/Geography/NeoGeo/NeoTile.scala:
--------------------------------------------------------------------------------
1 | package Information.Geography.NeoGeo
2 |
3 | import bwapi.TilePosition
4 |
5 | case class NeoTile(x: Int, y: Int) {
6 | def this(tilePosition: TilePosition) {
7 | this(tilePosition.getX, tilePosition.getY)
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/Information/Geography/NeoGeo/NeoWalk.scala:
--------------------------------------------------------------------------------
1 | package Information.Geography.NeoGeo
2 |
3 | import bwapi.WalkPosition
4 |
5 | case class NeoWalk(x: Int, y: Int) {
6 | def this(walkPosition: WalkPosition) {
7 | this(walkPosition.getX, walkPosition.getY)
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/Information/Grids/Construction/GridPsi2Height.scala:
--------------------------------------------------------------------------------
1 | package Information.Grids.Construction
2 |
3 | import Mathematics.Points.Point
4 | import Mathematics.Shapes.Pylons
5 |
6 | class GridPsi2Height extends AbstractGridPsi {
7 | override val psiPoints: Array[Point] = Pylons.points2
8 | }
9 |
--------------------------------------------------------------------------------
/src/Information/Grids/Construction/GridPsi3Height.scala:
--------------------------------------------------------------------------------
1 | package Information.Grids.Construction
2 |
3 | import Mathematics.Points.Point
4 | import Mathematics.Shapes.Pylons
5 |
6 | class GridPsi3Height extends AbstractGridPsi {
7 | override val psiPoints: Array[Point] = Pylons.points3
8 | }
9 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/Placement/Walls/WallFillers.scala:
--------------------------------------------------------------------------------
1 | package Placement.Walls
2 |
3 | import Debugging.SimpleString
4 |
5 | object WallFillers {
6 | trait WallFiller extends SimpleString
7 | object NoFiller extends WallFiller
8 | object PylonsCannons extends WallFiller
9 | }
10 |
--------------------------------------------------------------------------------
/src/Debugging/Visualizations/Hues.scala:
--------------------------------------------------------------------------------
1 | package Debugging.Visualizations
2 |
3 | object Hues {
4 | val Red = 0
5 | val Orange = 24
6 | val Yellow = 64
7 | val Green = 96
8 | val Teal = 128
9 | val Blue = 160
10 | val Indigo = 192
11 | val Violet = 224
12 | }
13 |
--------------------------------------------------------------------------------
/src/Micro/Targeting/TargetFilter.scala:
--------------------------------------------------------------------------------
1 | package Micro.Targeting
2 |
3 | import ProxyBwapi.UnitInfo.{FriendlyUnitInfo, UnitInfo}
4 |
5 | trait TargetFilter {
6 | def appliesTo(actor: FriendlyUnitInfo): Boolean = true
7 | def legal(actor: FriendlyUnitInfo, target: UnitInfo): Boolean
8 | }
9 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .cache-main
2 | *.log.txt
3 | *.log
4 | *.class
5 | *.zip
6 | .idea/workspace.xml
7 | .idea/codeStyles
8 | .idea/hydra.xml
9 | .idea/libraries/scala_sdk_2_12_6.xml
10 | .idea/scala_settings.xml
11 | .gradle/
12 | /out/
13 | /target/
14 | /images/
15 | dependency-reduced-pom.xml
--------------------------------------------------------------------------------
/src/ProxyBwapi/Players/Players.scala:
--------------------------------------------------------------------------------
1 | package ProxyBwapi.Players
2 |
3 | import Lifecycle.With
4 | import bwapi.Player
5 |
6 | object Players {
7 | def all: Iterable[PlayerInfo] = With.proxy.players
8 | def get(player: Player): PlayerInfo = With.proxy.playersById(player.getID)
9 | }
10 |
--------------------------------------------------------------------------------
/src/Information/Grids/ArrayTypes/AbstractGridFramestamp.scala:
--------------------------------------------------------------------------------
1 | package Information.Grids.ArrayTypes
2 |
3 | import Lifecycle.With
4 |
5 | abstract class AbstractGridFramestamp extends AbstractGridVersioned {
6 | override def updateVersion() { version = With.frame }
7 | def frameUpdated: Int = version
8 | }
--------------------------------------------------------------------------------
/src/ProxyBwapi/UnitTracking/Visibility.scala:
--------------------------------------------------------------------------------
1 | package ProxyBwapi.UnitTracking
2 |
3 | object Visibility extends Enumeration {
4 | val
5 | Visible,
6 | InvisibleBurrowed,
7 | InvisibleNearby,
8 | InvisibleMissing,
9 | Hypothetical,
10 | Dead
11 | = Value
12 | }
13 |
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsAll.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 | import ProxyBwapi.UnitInfo.UnitInfo
3 |
4 | case class IsAll(matchers: UnitFilter*) extends UnitFilter {
5 |
6 | override def apply(unit: UnitInfo): Boolean = {
7 | matchers.forall(_(unit))
8 | }
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsBurrowedLurker.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 |
3 | import ProxyBwapi.Races.Zerg
4 | import ProxyBwapi.UnitInfo.UnitInfo
5 |
6 | object IsBurrowedLurker extends UnitFilter {
7 | override def apply(unit: UnitInfo): Boolean = unit.burrowed && Zerg.Lurker(unit)
8 | }
9 |
--------------------------------------------------------------------------------
/src/Performance/Tasks/SimpleTask.scala:
--------------------------------------------------------------------------------
1 | package Performance.Tasks
2 |
3 | class SimpleTask(lambda: () => Unit) extends TimedTask {
4 | def this(name: String, lambda: () => Unit) {
5 | this(lambda)
6 | withName(name)
7 | }
8 | override def onRun(budgetMs: Long): Unit = lambda()
9 | }
10 |
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsSpeedling.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 | import ProxyBwapi.Races.Zerg
3 | import ProxyBwapi.UnitInfo.UnitInfo
4 |
5 | object IsSpeedling extends UnitFilter {
6 | override def apply(unit: UnitInfo): Boolean = Zerg.Zergling(unit) && Zerg.ZerglingSpeed(unit.player)
7 | }
8 |
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsSpeedlot.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 | import ProxyBwapi.Races.Protoss
3 | import ProxyBwapi.UnitInfo.UnitInfo
4 |
5 | object IsSpeedlot extends UnitFilter {
6 | override def apply(unit: UnitInfo): Boolean = Protoss.Zealot(unit) && Protoss.ZealotSpeed(unit.player)
7 | }
8 |
--------------------------------------------------------------------------------
/src/Debugging/ToString.scala:
--------------------------------------------------------------------------------
1 | package Debugging
2 |
3 | object ToString {
4 | def apply(value: Object): String = {
5 | var name = value.getClass.getSimpleName
6 | if (name.contains("anon")) name = value.getClass.getSuperclass.getSimpleName
7 | name.replaceAllLiterally("$", "")
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/Information/Geography/NeoGeo/NeoContinent.scala:
--------------------------------------------------------------------------------
1 | package Information.Geography.NeoGeo
2 |
3 | /**
4 | * A Continent is a fully-walkable area.
5 | * Every tile adjacent to a Continent is unwalkable or off the map entirely.
6 | */
7 | abstract class NeoContinent {
8 | def walkable: Seq[Int]
9 | }
10 |
--------------------------------------------------------------------------------
/src/Information/Geography/NeoGeo/NeoCountry.scala:
--------------------------------------------------------------------------------
1 | package Information.Geography.NeoGeo
2 |
3 | /**
4 | * A map contains one Country for each start location.
5 | * A Country comprises the Metros and Regions associated most closely with that start location.
6 | */
7 | class NeoCountry {
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsSlowling.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 |
3 | import ProxyBwapi.Races.Zerg
4 | import ProxyBwapi.UnitInfo.UnitInfo
5 |
6 | object IsSlowling extends UnitFilter {
7 | override def apply(unit: UnitInfo): Boolean = Zerg.Zergling(unit) && ! Zerg.ZerglingSpeed(unit.player)
8 | }
9 |
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsSlowlot.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 |
3 | import ProxyBwapi.Races.Protoss
4 | import ProxyBwapi.UnitInfo.UnitInfo
5 |
6 | object IsSlowlot extends UnitFilter {
7 | override def apply(unit: UnitInfo): Boolean = Protoss.Zealot(unit) && ! Protoss.ZealotSpeed(unit.player)
8 | }
9 |
--------------------------------------------------------------------------------
/PurpleWaveWithJMX.bat:
--------------------------------------------------------------------------------
1 | "C:\Program Files (x86)\Java\jre1.8.0_121\bin\java.exe" -cp $SCALA_HOME/lib/scala-library.jar -Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.port=20000 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -jar ./out/artifacts/PurpleWave.jar Startup.Main
--------------------------------------------------------------------------------
/src/Mathematics/Shapes/Rectangle.scala:
--------------------------------------------------------------------------------
1 | package Mathematics.Shapes
2 |
3 | import Mathematics.Points.Point
4 |
5 | object Rectangle {
6 | def apply(width: Int, height: Int): IndexedSeq[Point] =
7 | (0 until height).flatten(dy =>
8 | (0 until width).map(dx =>
9 | Point(dx, dy)))
10 | }
11 |
--------------------------------------------------------------------------------
/src/Placement/Walls/WallConstraint.scala:
--------------------------------------------------------------------------------
1 | package Placement.Walls
2 |
3 | import Placement.Walls.WallSpans.WallSpan
4 | import ProxyBwapi.UnitClasses.UnitClass
5 |
6 | case class WallConstraint(
7 | gapTiles : Int,
8 | blocksUnit : UnitClass,
9 | span : WallSpan,
10 | buildings : UnitClass*)
--------------------------------------------------------------------------------
/src/Strategery/Strategies/AllRaces/Sandbox.scala:
--------------------------------------------------------------------------------
1 | package Strategery.Strategies.AllRaces
2 |
3 | import Gameplans.All.Sandbox
4 | import Planning.Plans.Plan
5 | import Strategery.Strategies.Strategy
6 |
7 | object Sandbox extends Strategy {
8 | override def gameplan: Option[Plan] = Some(new Sandbox)
9 | }
10 |
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsCompleteFor.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 | import Lifecycle.With
3 | import ProxyBwapi.UnitInfo.UnitInfo
4 |
5 | case class IsCompleteFor(ageFrames: Int) extends UnitFilter{
6 | override def apply(unit: UnitInfo): Boolean = With.framesSince(unit.completionFrame) >= ageFrames
7 | }
8 |
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsSpeedScout.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 |
3 | import ProxyBwapi.Races.Protoss
4 | import ProxyBwapi.UnitInfo.UnitInfo
5 |
6 | object IsSpeedScout extends UnitFilter {
7 | override def apply(unit: UnitInfo): Boolean = Protoss.Scout(unit) && Protoss.ScoutSpeed(unit.player)
8 | }
9 |
--------------------------------------------------------------------------------
/src/Tactic/Squads/GenericFriendlyUnitGroup.scala:
--------------------------------------------------------------------------------
1 | package Tactic.Squads
2 |
3 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
4 |
5 | case class GenericFriendlyUnitGroup(override val groupFriendlyUnits: Seq[FriendlyUnitInfo]) extends FriendlyUnitGroup {
6 | def this(unit: FriendlyUnitInfo) {
7 | this(Seq(unit))
8 | }
9 | }
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsRangedGoon.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 |
3 | import ProxyBwapi.Races.Protoss
4 | import ProxyBwapi.UnitInfo.UnitInfo
5 |
6 | object IsRangedGoon extends UnitFilter {
7 | override def apply(unit: UnitInfo): Boolean = Protoss.Dragoon(unit) && Protoss.DragoonRange(unit.player)
8 | }
9 |
--------------------------------------------------------------------------------
/.idea/codeStyleSettings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/src/Gameplans/Terran/TvP/TvPRaxExpand.scala:
--------------------------------------------------------------------------------
1 | package Gameplans.Terran.TvP
2 |
3 | import Gameplans.Terran.TvE.TerranGameplan
4 |
5 | class TvPRaxExpand extends TerranGameplan {
6 |
7 | override def executeBuild(): Unit = {
8 |
9 | }
10 |
11 | override def executeMain(): Unit = {
12 |
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/TerranStrategies/TerranTimings.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.TerranStrategies
2 |
3 | import Utilities.Time.GameTime
4 |
5 | object TerranTimings {
6 | object ElevenRax_BarracksCompleteBy extends GameTime(2, 13)
7 | object ElevenRax_MarineCompleteBy extends GameTime(2, 28)
8 | }
9 |
--------------------------------------------------------------------------------
/src/Placement/Walls/WallSpans.scala:
--------------------------------------------------------------------------------
1 | package Placement.Walls
2 |
3 | import Debugging.SimpleString
4 |
5 | object WallSpans {
6 | trait WallSpan extends SimpleString
7 | object TerrainTerrain extends WallSpan
8 | object TerrainGas extends WallSpan
9 | object TerrainHall extends WallSpan
10 | }
11 |
--------------------------------------------------------------------------------
/src/Utilities/UnitPreferences/PreferBaseWithMoreWorkers.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitPreferences
2 |
3 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
4 |
5 | object PreferBaseWithMoreWorkers extends UnitPreference {
6 |
7 | override def apply(unit: FriendlyUnitInfo): Double = 1000 - PreferBaseWithFewerWorkers(unit)
8 | }
9 |
--------------------------------------------------------------------------------
/src/Micro/Actions/Combat/Tactics/FewShot.scala:
--------------------------------------------------------------------------------
1 | package Micro.Actions.Combat.Tactics
2 |
3 | import ProxyBwapi.UnitClasses.UnitClass
4 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
5 |
6 | object FewShot {
7 |
8 | def apply(unit: FriendlyUnitInfo, targetType: UnitClass, maxShots: Int): Unit = {
9 |
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsSpeedVulture.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 |
3 | import ProxyBwapi.Races.{Protoss, Terran}
4 | import ProxyBwapi.UnitInfo.UnitInfo
5 |
6 | object IsSpeedVulture extends UnitFilter {
7 | override def apply(unit: UnitInfo): Boolean = Terran.Vulture(unit) && Terran.VultureSpeed(unit.player)
8 | }
9 |
--------------------------------------------------------------------------------
/src/Information/Battles/ProcessingStates/BattleProcessComplete.scala:
--------------------------------------------------------------------------------
1 | package Information.Battles.ProcessingStates
2 |
3 | class BattleProcessComplete extends BattleProcessState {
4 | override def step(): Unit = {
5 | transitionTo(new BattleProcessInitial)
6 | }
7 |
8 | override val isFinalStep: Boolean = true
9 | }
10 |
--------------------------------------------------------------------------------
/src/Macro/Scheduling/MacroProducer.scala:
--------------------------------------------------------------------------------
1 | package Macro.Scheduling
2 |
3 | import ProxyBwapi.UnitClasses.UnitClass
4 | import Utilities.?
5 |
6 | case class MacroProducer(producer: UnitClass, product: UnitClass) {
7 | val supplyUsePerFrame: Float = product.supplyRequired.toFloat / ?(producer.isHatchlike, 342, product.buildFrames)
8 | }
9 |
--------------------------------------------------------------------------------
/src/Micro/Formation/FormationEmpty.scala:
--------------------------------------------------------------------------------
1 | package Micro.Formation
2 | import Mathematics.Points.Pixel
3 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
4 |
5 | object FormationEmpty extends Formation {
6 | def style: FormationStyle = FormationStyleEmpty
7 | def placements: Map[FriendlyUnitInfo, Pixel] = Map.empty
8 | }
9 |
10 |
--------------------------------------------------------------------------------
/src/Utilities/UnitPreferences/PreferBaseWithFewerWorkers.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitPreferences
2 |
3 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
4 |
5 | object PreferBaseWithFewerWorkers extends UnitPreference {
6 |
7 | override def apply(unit: FriendlyUnitInfo): Double = unit.base.map(_.workerCount).getOrElse(0).toDouble
8 | }
9 |
--------------------------------------------------------------------------------
/src/Utilities/UnitPreferences/PreferIf.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitPreferences
2 |
3 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
4 | import Utilities.?
5 |
6 | case class PreferIf(predicate: FriendlyUnitInfo => Boolean) extends UnitPreference {
7 | override def apply(unit: FriendlyUnitInfo): Double = ?(predicate(unit), 1, 2)
8 | }
9 |
--------------------------------------------------------------------------------
/src/Micro/Actions/Basic/DoNothing.scala:
--------------------------------------------------------------------------------
1 | package Micro.Actions.Basic
2 |
3 | import Micro.Actions.Action
4 | import Micro.Agency.Commander
5 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
6 |
7 | object DoNothing extends Action {
8 | override protected def perform(unit: FriendlyUnitInfo): Unit = { Commander.sleep(unit, 1) }
9 | }
10 |
--------------------------------------------------------------------------------
/src/Debugging/Visualizations/Views/Geography/ShowBWEB.scala:
--------------------------------------------------------------------------------
1 | package Debugging.Visualizations.Views.Geography
2 |
3 | import Debugging.Visualizations.Views.DebugView
4 | import Placement.JBWEBWrapper
5 |
6 | object ShowBWEB extends DebugView {
7 |
8 | override def renderMap(): Unit = {
9 | JBWEBWrapper.draw()
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/Gameplans/All/ModalGameplan.scala:
--------------------------------------------------------------------------------
1 | package Gameplans.All
2 |
3 | import Planning.Plans.Plan
4 |
5 | class ModalGameplan(modes: Modal*) extends Plan with Modal {
6 | override def isComplete: Boolean = modes.forall(_.isComplete)
7 | override def onUpdate(): Unit = {
8 | modes.find( ! _.isComplete).foreach(_.update())
9 | }
10 | }
--------------------------------------------------------------------------------
/src/Mathematics/Points/Directions.scala:
--------------------------------------------------------------------------------
1 | package Mathematics.Points
2 |
3 | object Directions {
4 | object Up extends Direction(0, -1)
5 | object Down extends Direction(0, 1)
6 | object Left extends Direction(-1, 0)
7 | object Right extends Direction(1, 0)
8 | val All: Seq[Direction] = Seq(Up, Down, Left, Right)
9 | }
10 |
--------------------------------------------------------------------------------
/src/Placement/Generation/TemplatesGeneric.scala:
--------------------------------------------------------------------------------
1 | package Placement.Generation
2 |
3 | import Placement.Templating.Template
4 |
5 | object TemplatesGeneric {
6 |
7 | val walkway: Template = new Template().from("-")
8 |
9 | val townhall: Template = new Template().from(
10 | "Hxxx",
11 | "xxxx",
12 | "xxxx")
13 | }
14 |
--------------------------------------------------------------------------------
/src/Mathematics/Shapes/Corners.scala:
--------------------------------------------------------------------------------
1 | package Mathematics.Shapes
2 |
3 | import Mathematics.Points.Point
4 |
5 | object Corners {
6 | def apply(width: Int, height: Int): IndexedSeq[Point] = Vector(
7 | Point(0, 0),
8 | Point(width - 1, 0),
9 | Point(width - 1, height - 1),
10 | Point(0, height - 1))
11 | }
12 |
--------------------------------------------------------------------------------
/src/Micro/Coordination/Pushing/TrafficPriority.scala:
--------------------------------------------------------------------------------
1 | package Micro.Coordination.Pushing
2 |
3 | import bwapi.Color
4 |
5 | case class TrafficPriority(value: Int, color: Color, name: String) extends Ordered[TrafficPriority] {
6 | def compare(other: TrafficPriority): Int = value.compareTo(other.value)
7 | override val toString: String = name
8 | }
9 |
--------------------------------------------------------------------------------
/src/Information/Battles/Prediction/Simulation/BehaviorHeal.scala:
--------------------------------------------------------------------------------
1 | package Information.Battles.Prediction.Simulation
2 |
3 | object BehaviorHeal extends SimulacrumBehavior {
4 | val fighting: Boolean = true
5 | @inline override def act(simulacrum: Simulacrum): Unit = {
6 | // TODO
7 | simulacrum.doBehavior(BehaviorFlee)
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/Information/Battles/Prediction/Simulation/BehaviorStorm.scala:
--------------------------------------------------------------------------------
1 | package Information.Battles.Prediction.Simulation
2 |
3 | object BehaviorStorm extends SimulacrumBehavior {
4 | override val fighting: Boolean = true
5 | override def act(simulacrum: Simulacrum): Unit = {
6 | // TODO
7 | simulacrum.doBehavior(BehaviorFlee)
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/Information/Battles/Prediction/Simulation/SimulacrumBehavior.scala:
--------------------------------------------------------------------------------
1 | package Information.Battles.Prediction.Simulation
2 |
3 | import Debugging.ToString
4 |
5 | trait SimulacrumBehavior {
6 | val fighting: Boolean
7 | def act(simulacrum: Simulacrum): Unit
8 | override val toString: String = ToString(this).replace("Behavior", "")
9 | }
10 |
--------------------------------------------------------------------------------
/src/Micro/Targeting/FiltersRequired/TargetFilterEnemy.scala:
--------------------------------------------------------------------------------
1 | package Micro.Targeting.FiltersRequired
2 |
3 | import Micro.Targeting.TargetFilter
4 | import ProxyBwapi.UnitInfo.{FriendlyUnitInfo, UnitInfo}
5 |
6 | object TargetFilterEnemy extends TargetFilter {
7 | override def legal(actor: FriendlyUnitInfo, target: UnitInfo): Boolean = target.isEnemy
8 | }
9 |
--------------------------------------------------------------------------------
/src/Utilities/UnitCounters/UnitCounter.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitCounters
2 |
3 | trait UnitCounter {
4 | def minimum: Int = 1
5 | def maximum: Int
6 | final def continue[T](iterable: Iterable[T]): Boolean = iterable.size < maximum
7 | final def accept[T](iterable: Iterable[T]): Boolean = iterable.size >= minimum && iterable.size <= maximum
8 | }
9 |
--------------------------------------------------------------------------------
/src/Debugging/Visualizations/Animation.scala:
--------------------------------------------------------------------------------
1 | package Debugging.Visualizations
2 |
3 | import Lifecycle.With
4 |
5 | class Animation {
6 | def durationFrames: Int = 96
7 | def drawScreen(): Unit = {}
8 | def drawMap(): Unit = {}
9 |
10 | final val frameCreated = With.frame
11 | final def age: Int = With.framesSince(frameCreated)
12 | }
13 |
--------------------------------------------------------------------------------
/src/Debugging/Visualizations/Views/Micro/ShowPathfinding.scala:
--------------------------------------------------------------------------------
1 | package Debugging.Visualizations.Views.Micro
2 |
3 | import Debugging.Visualizations.Views.DebugView
4 | import Lifecycle.With
5 |
6 | object ShowPathfinding extends DebugView {
7 |
8 | override def renderMap(): Unit = {
9 | With.grids.debugPathfinding.drawMap()
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/Information/Battles/ProcessingStates/BattleProcessCluster.scala:
--------------------------------------------------------------------------------
1 | package Information.Battles.ProcessingStates
2 |
3 | import Lifecycle.With
4 |
5 | class BattleProcessCluster extends BattleProcessState {
6 | override def step(): Unit = {
7 | With.battles.clustering.recalculate()
8 | transitionTo(new BattleProcessDivisions)
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/Information/Grids/Versioned/GridVersionedInt.scala:
--------------------------------------------------------------------------------
1 | package Information.Grids.Versioned
2 |
3 | import Information.Grids.ArrayTypes.AbstractGridVersionedValue
4 |
5 | class GridVersionedInt extends AbstractGridVersionedValue[Int] {
6 | override val defaultValue: Int = 0
7 | override protected val values: Array[Int] = Array.fill(length)(defaultValue)
8 | }
9 |
--------------------------------------------------------------------------------
/src/Debugging/Visualizations/Views/Planning/ShowPlacement.scala:
--------------------------------------------------------------------------------
1 | package Debugging.Visualizations.Views.Planning
2 |
3 | import Debugging.Visualizations.Views.DebugView
4 | import Lifecycle.With
5 |
6 | object ShowPlacement extends DebugView {
7 |
8 | override def renderMap(): Unit = {
9 | With.placement.fits.foreach(_.drawMap())
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/Utilities/UnitPreferences/PreferIdle.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitPreferences
2 |
3 | import Mathematics.Maff
4 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
5 |
6 | object PreferIdle extends UnitPreference {
7 |
8 | override def apply(unit: FriendlyUnitInfo): Double = unit.remainingOccupationFrames + 240 * Maff.fromBoolean(unit.carrying)
9 | }
10 |
--------------------------------------------------------------------------------
/src/Information/Geography/Calculations/ZonesConnecting.scala:
--------------------------------------------------------------------------------
1 | package Information.Geography.Calculations
2 |
3 | import Information.Geography.Types.{Geo, Zone}
4 | import Lifecycle.With
5 |
6 | object ZonesConnecting {
7 | def apply(a: Geo, b: Geo): Seq[Zone] = {
8 | With.paths.aStar(a.heart, b.heart).tiles.getOrElse(Seq.empty).map(_.zone)
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/Micro/Targeting/FiltersRequired/TargetFilterMissing.scala:
--------------------------------------------------------------------------------
1 | package Micro.Targeting.FiltersRequired
2 |
3 | import Micro.Targeting.TargetFilter
4 | import ProxyBwapi.UnitInfo.{FriendlyUnitInfo, UnitInfo}
5 |
6 | object TargetFilterMissing extends TargetFilter {
7 | override def legal(actor: FriendlyUnitInfo, target: UnitInfo): Boolean = target.likelyStillThere
8 | }
9 |
--------------------------------------------------------------------------------
/src/ProxyBwapi/Bullets/Bullets.scala:
--------------------------------------------------------------------------------
1 | package ProxyBwapi.Bullets
2 |
3 | import Lifecycle.With
4 | import Performance.Cache
5 |
6 | import scala.collection.JavaConverters._
7 |
8 | class Bullets {
9 | def all: Seq[BulletInfo] = cachedBullets()
10 |
11 | private val cachedBullets = new Cache(() => With.game.getBullets.asScala.map(BulletInfo))
12 | }
13 |
--------------------------------------------------------------------------------
/src/Strategery/Selection/StrategySelectionPolicy.scala:
--------------------------------------------------------------------------------
1 | package Strategery.Selection
2 |
3 | import Debugging.SimpleString
4 | import Strategery.Strategies.StrategyBranch
5 |
6 | trait StrategySelectionPolicy extends SimpleString {
7 | def chooseBranch: StrategyBranch
8 | def respectMap : Boolean = true
9 | def respectHistory : Boolean = true
10 | }
11 |
--------------------------------------------------------------------------------
/src/Micro/Targeting/FiltersRequired/TargetFilterCanAttack.scala:
--------------------------------------------------------------------------------
1 | package Micro.Targeting.FiltersRequired
2 |
3 | import Micro.Targeting.TargetFilter
4 | import ProxyBwapi.UnitInfo.{FriendlyUnitInfo, UnitInfo}
5 |
6 | object TargetFilterCanAttack extends TargetFilter {
7 | override def legal(actor: FriendlyUnitInfo, target: UnitInfo): Boolean = actor.canAttack(target)
8 | }
9 |
--------------------------------------------------------------------------------
/src/Performance/Tasks/DummyTask.scala:
--------------------------------------------------------------------------------
1 | package Performance.Tasks
2 |
3 | class DummyTask(classType: Class[_]) extends TimedTask {
4 | withName(if (classType.getSimpleName.contains("anon")) classType.getSuperclass.getSimpleName else classType.getSimpleName)
5 | var runFunction: () => Unit = () => {}
6 | override protected def onRun(budgetMs: Long): Unit = runFunction()
7 | }
8 |
--------------------------------------------------------------------------------
/src/Debugging/Visualizations/Views/Micro/ShowFormations.scala:
--------------------------------------------------------------------------------
1 | package Debugging.Visualizations.Views.Micro
2 |
3 | import Debugging.Visualizations.Views.DebugView
4 | import Lifecycle.With
5 |
6 | object ShowFormations extends DebugView {
7 |
8 | override def renderMap(): Unit = {
9 | With.squads.all.foreach(_.formations.foreach(_.renderMap()))
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/Information/Battles/Types/FriendlyTeam.scala:
--------------------------------------------------------------------------------
1 | package Information.Battles.Types
2 |
3 | import ProxyBwapi.UnitInfo.{FriendlyUnitInfo, UnitInfo}
4 | import Tactic.Squads.TFriendlyUnitGroup
5 |
6 | class FriendlyTeam(battle: Battle, override val groupFriendlyUnits: Seq[FriendlyUnitInfo]) extends Team(battle, groupFriendlyUnits.map(_.asInstanceOf[UnitInfo])) with TFriendlyUnitGroup
7 |
--------------------------------------------------------------------------------
/src/Information/GameSense/GameSense.scala:
--------------------------------------------------------------------------------
1 | package Information.GameSense
2 |
3 | import Debugging.SimpleString
4 |
5 | trait GameSense extends SimpleString {
6 | private var _opposite: Option[GameSense] = None
7 | def opposite: Option[GameSense] = _opposite
8 | def setOpposite(argOpposite: GameSense): Unit = {
9 | _opposite = Some(argOpposite)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/Information/Grids/Versioned/GridVersionedDouble.scala:
--------------------------------------------------------------------------------
1 | package Information.Grids.Versioned
2 |
3 | import Information.Grids.ArrayTypes.AbstractGridVersionedValue
4 |
5 | class GridVersionedDouble extends AbstractGridVersionedValue[Double] {
6 | override val defaultValue: Double = 0.0
7 | override protected val values: Array[Double] = Array.fill(length)(defaultValue)
8 | }
9 |
--------------------------------------------------------------------------------
/src/Mathematics/Physics/Gravity.scala:
--------------------------------------------------------------------------------
1 | package Mathematics.Physics
2 |
3 | import Mathematics.Points.Pixel
4 |
5 | case class Gravity(pixel: Pixel, magnitude: Double) {
6 | def apply(target: Pixel): Force = {
7 | val scale = magnitude / target.pixelDistanceSquared(pixel)
8 | Force(
9 | scale * (pixel.x - target.x),
10 | scale * (pixel.y - target.y))
11 | }
12 | }
--------------------------------------------------------------------------------
/src/Information/Battles/Prediction/Simulation/BehaviorAssemble.scala:
--------------------------------------------------------------------------------
1 | package Information.Battles.Prediction.Simulation
2 |
3 | object BehaviorAssemble extends SimulacrumBehavior {
4 | override val fighting: Boolean = false
5 |
6 | override def act(simulacrum: Simulacrum): Unit = {
7 | simulacrum.move(simulacrum.simulation.enemyVanguard, Some("Assemble"))
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/Information/Grids/Versioned/GridVersionedBoolean.scala:
--------------------------------------------------------------------------------
1 | package Information.Grids.Versioned
2 |
3 | import Information.Grids.ArrayTypes.AbstractGridVersionedValue
4 |
5 | class GridVersionedBoolean extends AbstractGridVersionedValue[Boolean] {
6 | override val defaultValue: Boolean = false
7 | override protected val values: Array[Boolean] = Array.fill(length)(defaultValue)
8 | }
9 |
--------------------------------------------------------------------------------
/src/Micro/Formation/FormationZone.scala:
--------------------------------------------------------------------------------
1 | package Micro.Formation
2 |
3 | import Information.Geography.Types.{Edge, Zone}
4 | import Tactic.Squads.FriendlyUnitGroup
5 |
6 | object FormationZone {
7 | def apply(group: FriendlyUnitGroup, zone: Zone, edge: Edge): Formation = {
8 | new FormationStandard(group, FormationStyleGuard, edge.pixelCenter, Some(zone))
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/Information/Battles/Prediction/Simulation/SimulationEventDeath.scala:
--------------------------------------------------------------------------------
1 | package Information.Battles.Prediction.Simulation
2 |
3 | import Mathematics.Points.Pixel
4 |
5 | final case class SimulationEventDeath(sim: Simulacrum) extends SimulationEvent(sim) {
6 |
7 | override def toString: String = f"$frame: ${sim.describe} dies"
8 |
9 | override val to: Pixel = from
10 | }
11 |
--------------------------------------------------------------------------------
/configs/run_proxy.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | if "%PROCESSOR_ARCHITECTURE%"=="AMD64" (
3 | echo "64-Bit OS"
4 | if exist "bwapi-data/AI/jre/bin/java.exe" (
5 | echo "Found bundled JRE."
6 | bwapi-data/AI/run64.bat
7 | ) else (
8 | echo "Did not find bundled JRE."
9 | bwapi-data/AI/run32.bat
10 | )
11 | ) else (
12 | echo "32-Bit OS"
13 | bwapi-data/AI/run32.bat
14 | )
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/Generic/FingerprintLambda.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.Generic
2 |
3 | import Information.Fingerprinting.Fingerprint
4 |
5 | class FingerprintLambda(predicate: () => Boolean, isSticky: () => Boolean = () => true) extends Fingerprint {
6 | override protected def investigate: Boolean = predicate()
7 | override def sticky: Boolean = isSticky()
8 | }
9 |
--------------------------------------------------------------------------------
/src/Macro/Scheduling/MacroStep.scala:
--------------------------------------------------------------------------------
1 | package Macro.Scheduling
2 |
3 | import Macro.Requests.RequestBuildable
4 |
5 | class MacroStep {
6 | val state: MacroState = new MacroState
7 | var event: MacroEvent = new MacroEvent(state)
8 | var request: Option[RequestBuildable] = None
9 |
10 | override def toString: String = f"${request.map(r => f"[$r] ").getOrElse("")}$event"
11 | }
12 |
--------------------------------------------------------------------------------
/src/Debugging/Visualizations/Views/Fun/ShowBlackScreen.scala:
--------------------------------------------------------------------------------
1 | package Debugging.Visualizations.Views.Fun
2 |
3 | import Debugging.Visualizations.Views.DebugView
4 | import Lifecycle.With
5 | import bwapi.Color
6 |
7 | object ShowBlackScreen extends DebugView {
8 |
9 | override def renderScreen() {
10 | With.game.drawBoxScreen(0, 0, 1500, 1200, Color.Black, true)
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Information/Grids/ArrayTypes/AbstractGridArrayBoolean.scala:
--------------------------------------------------------------------------------
1 | package Information.Grids.ArrayTypes
2 |
3 | abstract class AbstractGridArrayBoolean extends AbstractGridArray[Boolean] {
4 | override val defaultValue: Boolean = false
5 | override val values: Array[Boolean] = Array.fill(width * height)(defaultValue)
6 | override def repr(value: Boolean): String = if (value) "true" else "false"
7 | }
8 |
--------------------------------------------------------------------------------
/src/ProxyBwapi/Races/Neutral.scala:
--------------------------------------------------------------------------------
1 | package ProxyBwapi.Races
2 |
3 | import ProxyBwapi.UnitClasses.UnitClasses
4 | import bwapi.UnitType
5 |
6 | object Neutral {
7 | lazy val Geyser = UnitClasses.get(UnitType.Resource_Vespene_Geyser)
8 | lazy val PsiDisruptor = UnitClasses.get(UnitType.Special_Psi_Disrupter)
9 | lazy val Autosupply = UnitClasses.get(UnitType.Unused_Cantina)
10 | }
11 |
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/ZergStrategies/Fingerprint9PoolGas.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.ZergStrategies
2 |
3 | import Information.Fingerprinting.Generic._
4 | import Information.Fingerprinting.ZergStrategies.ZergTimings.Overpool8Gas_GasCompleteBy
5 | import Utilities.Time.Seconds
6 |
7 | class Fingerprint9PoolGas extends FingerprintGasCompleteBy(Overpool8Gas_GasCompleteBy - Seconds(5))
8 |
--------------------------------------------------------------------------------
/src/Micro/Targeting/FiltersSituational/TargetFilterVisibleInRange.scala:
--------------------------------------------------------------------------------
1 | package Micro.Targeting.FiltersSituational
2 |
3 | import Micro.Targeting.TargetFilter
4 | import ProxyBwapi.UnitInfo.{FriendlyUnitInfo, UnitInfo}
5 |
6 | object TargetFilterVisibleInRange extends TargetFilter {
7 | def legal(actor: FriendlyUnitInfo, target: UnitInfo): Boolean = target.visible && actor.inRangeToAttack(target)
8 | }
9 |
--------------------------------------------------------------------------------
/src/Mathematics/Points/Points.scala:
--------------------------------------------------------------------------------
1 | package Mathematics.Points
2 |
3 | import Lifecycle.With
4 | import Mathematics.Maff
5 |
6 | object Points {
7 |
8 | def middle: Pixel = Pixel(
9 | Maff.div2(With.mapPixelWidth),
10 | Maff.div2(With.mapPixelHeight))
11 |
12 | def tileMiddle: Tile = Tile(
13 | Maff.div2(With.mapTileWidth),
14 | Maff.div2(With.mapTileHeight))
15 | }
16 |
--------------------------------------------------------------------------------
/src/Utilities/UnitPreferences/PreferAll.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitPreferences
2 |
3 | import Mathematics.Maff
4 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
5 |
6 | case class PreferAll(preferences: Function[FriendlyUnitInfo, Double]*) extends UnitPreference {
7 | override def apply(unit: FriendlyUnitInfo): Double = {
8 | preferences.map(_(unit)).map(Maff.fastSigmoid01).sum
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/Information/Geography/Calculations/GetExits.scala:
--------------------------------------------------------------------------------
1 | package Information.Geography.Calculations
2 |
3 | import Information.Geography.Types.{Edge, Geo}
4 |
5 | object GetExits {
6 | def apply(geos: Iterable[Geo]): Set[Edge] = {
7 | geos
8 | .view
9 | .flatMap(_.edges)
10 | .filter(_.zones.exists(z => ! geos.view.flatMap(_.zones).exists(z==)))
11 | .toSet
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/Mathematics/Shapes/Circle.scala:
--------------------------------------------------------------------------------
1 | package Mathematics.Shapes
2 |
3 | import Mathematics.Points.Point
4 |
5 | object Circle {
6 |
7 | def apply(radius: Int): Seq[Point] =
8 | (-radius to radius).view.flatMap(x =>
9 | (-radius to radius).view.map(y =>
10 | (x, y, x * x + y * y <= radius * radius)))
11 | .filter(_._3)
12 | .map(point => Point(point._1, point._2))
13 | }
14 |
--------------------------------------------------------------------------------
/src/Planning/Plans/Plan.scala:
--------------------------------------------------------------------------------
1 | package Planning.Plans
2 |
3 | import Debugging.SimpleString
4 | import Macro.Allocation.Prioritized
5 |
6 | class Plan extends Prioritized with SimpleString {
7 |
8 | protected def onUpdate(): Unit = {}
9 |
10 | final def update(): Unit = {
11 | prioritize()
12 | onUpdate()
13 | }
14 |
15 | final def apply(): Unit = {
16 | update()
17 | }
18 | }
--------------------------------------------------------------------------------
/src/Information/Battles/Prediction/Skimulation/SkimulationTeam.scala:
--------------------------------------------------------------------------------
1 | package Information.Battles.Prediction.Skimulation
2 |
3 | trait SkimulationTeam {
4 | var skimMeanWarriorDistanceToEngage: Double = 0
5 | var skimStrengthTotal: Double = 0
6 | var skimStrengthAir: Double = 0
7 | var skimStrengthGround: Double = 0
8 | var skimStrengthVsAir: Double = 0
9 | var skimStrengthVsGround: Double = 0
10 | }
11 |
--------------------------------------------------------------------------------
/src/Placement/Templating/RequireAnything.scala:
--------------------------------------------------------------------------------
1 | package Placement.Templating
2 |
3 | class RequireAnything extends TemplatePointRequirement {
4 | override val buildableBefore : Boolean = false
5 | override val walkableBefore : Boolean = false
6 | override val buildableAfter : Boolean = true
7 | override val walkableAfter : Boolean = true
8 | override val toString : String = "Anything"
9 | }
10 |
--------------------------------------------------------------------------------
/src/Placement/Templating/RequireNothing.scala:
--------------------------------------------------------------------------------
1 | package Placement.Templating
2 |
3 | class RequireNothing extends TemplatePointRequirement {
4 | override val buildableBefore : Boolean = false
5 | override val walkableBefore : Boolean = false
6 | override val buildableAfter : Boolean = false
7 | override val walkableAfter : Boolean = false
8 | override val toString : String = "Nothing"
9 | }
10 |
--------------------------------------------------------------------------------
/src/Placement/Templating/RequireWalkable.scala:
--------------------------------------------------------------------------------
1 | package Placement.Templating
2 |
3 | class RequireWalkable extends TemplatePointRequirement {
4 | override val buildableBefore : Boolean = false
5 | override val walkableBefore : Boolean = true
6 | override val buildableAfter : Boolean = false
7 | override val walkableAfter : Boolean = true
8 | override val toString : String = "Walkable"
9 | }
10 |
--------------------------------------------------------------------------------
/src/Mathematics/Points/WalkTile.scala:
--------------------------------------------------------------------------------
1 | package Mathematics.Points
2 |
3 | import bwapi.WalkPosition
4 |
5 | case class WalkTile(argX: Int, argY: Int) extends AbstractPoint(argX, argY) {
6 |
7 | def bwapi: WalkPosition = new WalkPosition(x, y)
8 |
9 | def add(dx: Int, dy: Int): WalkTile = {
10 | WalkTile(x + dx, y + dy)
11 | }
12 | def add(point: Point): WalkTile = {
13 | add(point.x, point.y)
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/Micro/Targeting/FiltersSituational/TargetFilterWhitelist.scala:
--------------------------------------------------------------------------------
1 | package Micro.Targeting.FiltersSituational
2 |
3 | import Micro.Targeting.TargetFilter
4 | import ProxyBwapi.UnitInfo.{FriendlyUnitInfo, UnitInfo}
5 |
6 | case class TargetFilterWhitelist(units: Iterable[UnitInfo]) extends TargetFilter {
7 | def legal(actor: FriendlyUnitInfo, target: UnitInfo): Boolean = {
8 | units.exists(target==)
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "3rdparty/jbwapi"]
2 | path = 3rdparty/jbwapi
3 | url = https://github.com/JavaBWAPI/JBWAPI
4 | [submodule "3rdparty/mjson"]
5 | path = 3rdparty/mjson
6 | url = https://github.com/bolerio/mjson
7 | [submodule "3rdparty/jbweb"]
8 | path = 3rdparty/jbweb
9 | url = https://github.com/MrTate/JBWEB
10 | [submodule "3rdparty/javajps"]
11 | path = 3rdparty/javajps
12 | url = https://github.com/MrTate/JavaJPS
13 |
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/TerranStrategies/Fingerprint1RaxGas.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.TerranStrategies
2 |
3 | import Information.Fingerprinting.Generic._
4 | import Lifecycle.With
5 | import ProxyBwapi.Races.Terran
6 | import Utilities.Time.GameTime
7 |
8 | class Fingerprint1RaxGas extends FingerprintOr(
9 | With.fingerprints.oneFac,
10 | new FingerprintCompleteBy(Terran.Refinery, GameTime(2, 45), 1))
--------------------------------------------------------------------------------
/src/Micro/Actions/Commands/Attack.scala:
--------------------------------------------------------------------------------
1 | package Micro.Actions.Commands
2 |
3 | import Micro.Actions.Action
4 | import Micro.Agency.Commander
5 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
6 |
7 | object Attack extends Action {
8 | override def allowed(unit: FriendlyUnitInfo): Boolean = unit.canAttack && unit.agent.toAttack.isDefined
9 | override def perform(unit: FriendlyUnitInfo): Unit = Commander.attack(unit)
10 | }
11 |
--------------------------------------------------------------------------------
/src/Strategery/Selection/WeightedGame.scala:
--------------------------------------------------------------------------------
1 | package Strategery.Selection
2 |
3 | import Strategery.History.HistoricalGame
4 | import Strategery.Strategies.StrategyBranch
5 |
6 | class WeightedGame(val branch: StrategyBranch, val game: HistoricalGame) {
7 | val similarity : Double = branch.strategies.count(game.weEmployed).toDouble / branch.strategies.length
8 | val finalWeight : Double = similarity * game.weight
9 | }
10 |
--------------------------------------------------------------------------------
/src/Information/Grids/Movement/GridWalkable.scala:
--------------------------------------------------------------------------------
1 | package Information.Grids.Movement
2 |
3 | import Information.Grids.AbstractTypedGrid
4 | import Lifecycle.With
5 |
6 | class GridWalkable extends AbstractTypedGrid[Boolean] {
7 | @inline final def getUnchecked(i: Int): Boolean = With.grids.walkableTerrain.getUnchecked(i) && ! With.grids.unwalkableUnits.isSetUnchecked(i)
8 | final override val defaultValue: Boolean = false
9 | }
10 |
--------------------------------------------------------------------------------
/src/Micro/Targeting/FiltersRequired/TargetFilterType.scala:
--------------------------------------------------------------------------------
1 | package Micro.Targeting.FiltersRequired
2 |
3 | import Micro.Targeting.TargetFilter
4 | import ProxyBwapi.Races.{Protoss, Zerg}
5 | import ProxyBwapi.UnitInfo.{FriendlyUnitInfo, UnitInfo}
6 |
7 | object TargetFilterType extends TargetFilter {
8 | def legal(actor: FriendlyUnitInfo, target: UnitInfo): Boolean = target.isNone(Protoss.Interceptor, Zerg.Larva, Zerg.Egg)
9 | }
10 |
--------------------------------------------------------------------------------
/src/Information/Battles/ProcessingStates/BattleProcessState.scala:
--------------------------------------------------------------------------------
1 | package Information.Battles.ProcessingStates
2 |
3 | import Lifecycle.With
4 |
5 | trait BattleProcessState {
6 | protected def transitionTo(newState: BattleProcessState): Unit = {
7 | With.battles.setProcessingState(newState)
8 | }
9 |
10 | def step(): Unit
11 |
12 | def isFinalStep: Boolean = false
13 |
14 | val frameStarted: Int = With.frame
15 | }
16 |
--------------------------------------------------------------------------------
/src/Information/Geography/NeoGeo/Internal/NeoContinentBackend.scala:
--------------------------------------------------------------------------------
1 | package Information.Geography.NeoGeo.Internal
2 |
3 | import Information.Geography.NeoGeo.NeoContinent
4 | import java.awt.Color
5 |
6 | import scala.collection.mutable
7 |
8 | class NeoContinentBackend extends NeoContinent {
9 | val walks = new mutable.ArrayBuffer[Int]
10 | var color = new Color(0, 0, 0)
11 |
12 | override def walkable: Seq[Int] = walks
13 | }
14 |
--------------------------------------------------------------------------------
/src/Tactic/Tactics/TacticFloatBuildings.scala:
--------------------------------------------------------------------------------
1 | package Tactic.Tactics
2 |
3 | import Lifecycle.With
4 | import Planning.ResourceLocks.LockUnits
5 |
6 | class TacticFloatBuildings extends Tactic {
7 |
8 | val floaties: LockUnits = new LockUnits(this, u => ! u.flying && With.blackboard.floatableBuildings().exists(_(u)))
9 |
10 | def launch(): Unit = {
11 | floaties.acquire().foreach(_.intend(this).setShouldLiftoff())
12 | }
13 | }
--------------------------------------------------------------------------------
/src/Micro/Targeting/FiltersSituational/TargetFilterPotshot.scala:
--------------------------------------------------------------------------------
1 | package Micro.Targeting.FiltersSituational
2 |
3 | import Micro.Targeting.TargetFilter
4 | import ProxyBwapi.UnitInfo.{FriendlyUnitInfo, UnitInfo}
5 |
6 | object TargetFilterPotshot extends TargetFilter {
7 | override def legal(actor: FriendlyUnitInfo, target: UnitInfo): Boolean = target.unitClass.attacksOrCastsOrDetectsOrTransports && TargetFilterVisibleInRange.legal(actor, target)
8 | }
9 |
--------------------------------------------------------------------------------
/src/Gameplans/All/StandardGameplan.scala:
--------------------------------------------------------------------------------
1 | package Gameplans.All
2 |
3 | import Gameplans.Protoss.ProtossStandardGameplan
4 | import Gameplans.Terran.TerranStandardGameplan
5 | import Gameplans.Zerg.ZergStandardGameplan
6 | import Planning.Plans.SwitchOurRace
7 |
8 | class StandardGameplan extends SwitchOurRace(
9 | whenTerran = new TerranStandardGameplan,
10 | whenProtoss = new ProtossStandardGameplan,
11 | whenZerg = new ZergStandardGameplan)
--------------------------------------------------------------------------------
/src/Information/Battles/Prediction/Simulation/BehaviorDetect.scala:
--------------------------------------------------------------------------------
1 | package Information.Battles.Prediction.Simulation
2 |
3 | object BehaviorDetect extends SimulacrumBehavior {
4 | val fighting: Boolean = true
5 | override def act(simulacrum: Simulacrum): Unit = {
6 | simulacrum.targets.removeIf(t => ! t.cloaked && ! t.burrowed)
7 | if (simulacrum.targets.isEmpty) {
8 | simulacrum.doBehavior(BehaviorFlee)
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/Information/Battles/Prediction/Simulation/BehaviorFlee.scala:
--------------------------------------------------------------------------------
1 | package Information.Battles.Prediction.Simulation
2 |
3 | object BehaviorFlee extends SimulacrumBehavior {
4 | val fighting: Boolean = false
5 | @inline override def act(simulacrum: Simulacrum): Unit = {
6 | if ( ! simulacrum.canMove) {
7 | simulacrum.doBehavior(BehaviorIdle)
8 | return
9 | }
10 |
11 | // TODO: Flee most recent attacker
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/Tactic/Tactics/TacticGather.scala:
--------------------------------------------------------------------------------
1 | package Tactic.Tactics
2 |
3 | import Debugging.SimpleString
4 | import Lifecycle.With
5 | import Planning.ResourceLocks.LockUnits
6 | import Utilities.UnitFilters.IsWorker
7 |
8 | class TacticGather extends Tactic with SimpleString {
9 |
10 | val workerLock: LockUnits = new LockUnits(this, IsWorker)
11 |
12 | def launch(): Unit = {
13 | With.gathering.setWorkers(workerLock.acquire())
14 | }
15 | }
--------------------------------------------------------------------------------
/src/Information/Grids/Construction/GridBuildable.scala:
--------------------------------------------------------------------------------
1 | package Information.Grids.Construction
2 |
3 | import Information.Grids.AbstractTypedGrid
4 | import Lifecycle.With
5 |
6 | final class GridBuildable extends AbstractTypedGrid[Boolean] {
7 |
8 | @inline def getUnchecked(i: Int): Boolean = With.grids.buildableTerrain.getUnchecked(i) && ! With.grids.unwalkableUnits.isSetUnchecked(i)
9 |
10 | override val defaultValue: Boolean = false
11 | }
12 |
--------------------------------------------------------------------------------
/src/Information/Grids/Construction/GridBuildableTerrain.scala:
--------------------------------------------------------------------------------
1 | package Information.Grids.Construction
2 |
3 | import Information.Grids.ArrayTypes.AbstractGridArrayBoolean
4 | import Lifecycle.With
5 |
6 | final class GridBuildableTerrain extends AbstractGridArrayBoolean {
7 |
8 | override def onInitialization(): Unit = {
9 | indices.foreach(i => set(i, With.game.isBuildable(i % With.mapTileWidth, i / With.mapTileWidth)))
10 | }
11 | }
12 |
13 |
--------------------------------------------------------------------------------
/src/Planning/ResourceLocks/LockCurrencyFor.scala:
--------------------------------------------------------------------------------
1 | package Planning.ResourceLocks
2 |
3 | import Macro.Allocation.Prioritized
4 | import ProxyBwapi.Buildable
5 |
6 | class LockCurrencyFor(prioritized: Prioritized, buildableType: Buildable, upgradeLevel: Int = 1) extends LockCurrency(prioritized) {
7 | minerals = buildableType.mineralCost(upgradeLevel)
8 | gas = buildableType.gasCost(upgradeLevel)
9 | supply = buildableType.supplyRequired
10 | }
11 |
--------------------------------------------------------------------------------
/scripts/performance.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/bash
2 | echo "Good performance: $(find /c/Users/d/AppData/Roaming/scbw/games/*/logs_0 -name "bot.log" | xargs grep "performance was good" | wc -l)"
3 | echo "Dangerous performance: $(find /c/Users/d/AppData/Roaming/scbw/games/*/logs_0 -name "bot.log" | xargs grep "performance was DANGEROUS" | wc -l)"
4 | echo "Bad performance: $(find /c/Users/d/AppData/Roaming/scbw/games/*/logs_0 -name "bot.log" | xargs grep "performance was BAD" | wc -l)"
--------------------------------------------------------------------------------
/src/ProxyBwapi/Upgrades/Upgrades.scala:
--------------------------------------------------------------------------------
1 | package ProxyBwapi.Upgrades
2 |
3 | import Lifecycle.With
4 | import bwapi.UpgradeType
5 |
6 | object Upgrades {
7 | def all: Vector[Upgrade] = With.proxy.upgrades
8 | def get(upgrade: UpgradeType): Upgrade = With.proxy.upgradesById(upgrade.id)
9 | lazy val None: Upgrade = all.find(_.bwapiType == UpgradeType.None).get
10 | lazy val Unknown: Upgrade = all.find(_.bwapiType == UpgradeType.Unknown).get
11 | }
12 |
13 |
--------------------------------------------------------------------------------
/configs/PurpleWaveLocalMetal.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "human" : false,
3 | "ladder" : false,
4 | "livestream" : false,
5 | "tournament" : true,
6 | "roundrobin" : true,
7 | "elimination" : false,
8 | "pretraining" : false,
9 | "debugging" : true,
10 | "debugginglive" : true,
11 | "logstd" : true,
12 | "multiCPU" : true,
13 | "framemstarget" : 35,
14 | "framemslimit" : 35,
15 | "comments" : ""
16 | }
--------------------------------------------------------------------------------
/src/Mathematics/Physics/ForceMap.scala:
--------------------------------------------------------------------------------
1 | package Mathematics.Physics
2 |
3 | import Debugging.Visualizations.ForceLabel
4 |
5 | import scala.collection.mutable
6 |
7 | class ForceMap extends mutable.HashMap[ForceLabel, Force](){
8 | override def default(key: ForceLabel): Force = Forces.None
9 | def forces: Iterable[Force] = values
10 | def sum: Force = ForceMath.sum(forces)
11 |
12 | def allZero: Boolean = values.forall(f => f.x == 0 && f.y == 0)
13 | }
14 |
--------------------------------------------------------------------------------
/src/Micro/Actions/Terran/Liftoff.scala:
--------------------------------------------------------------------------------
1 | package Micro.Actions.Terran
2 |
3 | import Micro.Actions.Action
4 | import Micro.Agency.Commander
5 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
6 |
7 | object Liftoff extends Action {
8 |
9 | override def allowed(unit: FriendlyUnitInfo): Boolean = {
10 | unit.intent.shouldLiftoff && ! unit.flying
11 | }
12 |
13 | override def perform(unit: FriendlyUnitInfo) {
14 | Commander.lift(unit)
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Micro/Coordination/Pushing/ExplosionInfestedTerran.scala:
--------------------------------------------------------------------------------
1 | package Micro.Coordination.Pushing
2 |
3 | import Mathematics.Physics.Force
4 | import ProxyBwapi.UnitInfo.{FriendlyUnitInfo, UnitInfo}
5 |
6 | class ExplosionInfestedTerran(infested: UnitInfo) extends CircularPush(TrafficPriorities.Dodge, infested.pixel, 60) {
7 | override def force(recipient: FriendlyUnitInfo): Option[Force] = {
8 | if(recipient.flying) None else super.force(recipient)
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/ProxyBwapi/UnitClasses/UnitClasses.scala:
--------------------------------------------------------------------------------
1 | package ProxyBwapi.UnitClasses
2 |
3 | import Lifecycle.With
4 | import bwapi.UnitType
5 |
6 | object UnitClasses {
7 | def all: Vector[UnitClass] = With.proxy.unitClasses
8 | def get(unitType: UnitType): UnitClass = With.proxy.unitClassesById(unitType.id)
9 | lazy val None: UnitClass = all.find(_.bwapiType == UnitType.None).get
10 | lazy val Unknown: UnitClass = all.find(_.bwapiType == UnitType.Unknown).get
11 | }
12 |
--------------------------------------------------------------------------------
/src/Debugging/EnumerateUnits.scala:
--------------------------------------------------------------------------------
1 | package Debugging
2 |
3 | import ProxyBwapi.UnitInfo.UnitInfo
4 |
5 | object EnumerateUnits {
6 | def apply(units: Iterable[UnitInfo]): String = {
7 | val counts = units
8 | .toVector
9 | .map(_.unitClass)
10 | .groupBy(x => x)
11 | val output = counts
12 | .toSeq
13 | .sortBy(-_._2.size)
14 | .map(p => p._2.size + p._1.abbr)
15 | .mkString(".")
16 | output
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/Generic/FingerprintRace.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.Generic
2 |
3 | import Information.Fingerprinting.Fingerprint
4 | import Lifecycle.With
5 | import bwapi.Race
6 |
7 | class FingerprintRace(race: Race) extends Fingerprint {
8 | override def investigate: Boolean = With.enemies.exists(_.raceInitial == race)
9 | override def reason: String = f"$race: [${With.enemies.filter(_.raceInitial == race).map(_.name).mkString(", ")}]"
10 | }
11 |
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/ProtossStrategies/FingerprintBunkerRush.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.ProtossStrategies
2 |
3 | import Information.Fingerprinting.Generic._
4 | import Utilities.UnitFilters.{IsAll, IsProxied}
5 | import ProxyBwapi.Races.Terran
6 | import Utilities.Time.GameTime
7 |
8 | class FingerprintBunkerRush extends FingerprintCompleteBy(
9 | IsAll(Terran.Bunker, IsProxied),
10 | GameTime(5, 0)) {
11 |
12 | override val sticky = true
13 | }
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/TerranStrategies/Fingerprint2Fac.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.TerranStrategies
2 |
3 | import Information.Fingerprinting.Generic._
4 | import Lifecycle.With
5 | import ProxyBwapi.Races.Terran
6 | import Utilities.Time.GameTime
7 |
8 | class Fingerprint2Fac extends FingerprintOr(
9 | With.fingerprints.twoFacVultures,
10 | new FingerprintCompleteBy(Terran.Factory, GameTime(4, 40), 2), // 4:10 normally
11 | new FingerprintNFactories(2))
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/TerranStrategies/Fingerprint3Fac.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.TerranStrategies
2 |
3 | import Information.Fingerprinting.Generic._
4 | import Lifecycle.With
5 | import ProxyBwapi.Races.Terran
6 | import Utilities.Time.GameTime
7 |
8 | class Fingerprint3Fac extends FingerprintOr(
9 | With.fingerprints.threeFacVultures,
10 | new FingerprintCompleteBy(Terran.Factory, GameTime(5, 0), 3), // 4:40 normally
11 | new FingerprintNFactories(3))
--------------------------------------------------------------------------------
/src/Information/Grids/Floody/GridEnemyVision.scala:
--------------------------------------------------------------------------------
1 | package Information.Grids.Floody
2 |
3 | import Mathematics.Maff
4 | import ProxyBwapi.UnitInfo.UnitInfo
5 |
6 | final class GridEnemyVision extends AbstractGridFloody {
7 |
8 | override protected def include(unit: UnitInfo): Boolean = unit.isEnemy
9 |
10 | override protected def range(unit: UnitInfo): Int = if (unit.blind || ! unit.complete) 1 else Maff.div32(unit.sightPixels)
11 |
12 | override val margin: Int = 2
13 | }
--------------------------------------------------------------------------------
/src/Information/Grids/Floody/GridEnemyRangeAir.scala:
--------------------------------------------------------------------------------
1 | package Information.Grids.Floody
2 |
3 | import Mathematics.Maff
4 | import ProxyBwapi.UnitInfo.UnitInfo
5 |
6 | final class GridEnemyRangeAir extends AbstractGridFloody {
7 |
8 | override protected def include(unit: UnitInfo): Boolean = unit.isEnemy && unit.canAttackAir
9 |
10 | override protected def range(unit: UnitInfo): Int = Maff.div32(unit.pixelRangeAir.toInt)
11 |
12 | override val margin: Int = 3
13 | }
14 |
15 |
--------------------------------------------------------------------------------
/src/Micro/Agency/LocalSim.scala:
--------------------------------------------------------------------------------
1 | package Micro.Agency
2 |
3 | import Lifecycle.With
4 |
5 | class LocalSim {
6 |
7 | var lastFrame: Int = -1
8 | private var _shouldFight: Boolean = _
9 |
10 | class LocalSimState {
11 |
12 | }
13 |
14 | def shouldFight(): Boolean = {
15 | if (lastFrame < With.frame) {
16 | performLocalSim()
17 | }
18 | _shouldFight
19 | }
20 |
21 | private def performLocalSim(): Unit = {
22 |
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/Utilities/UnitPreferences/PreferTiers.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitPreferences
2 | import Mathematics.Maff
3 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
4 |
5 | case class PreferTiers(preferences: Function[FriendlyUnitInfo, Double]*) extends UnitPreference {
6 | override def apply(unit: FriendlyUnitInfo): Double = {
7 | preferences
8 | .zipWithIndex
9 | .map(pair => Maff.fastSigmoid01(pair._1(unit)) * Math.pow(10, -pair._2))
10 | .sum
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/ProtossStrategies/FingerprintCannonRush.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.ProtossStrategies
2 |
3 | import Information.Fingerprinting.Generic._
4 | import Utilities.UnitFilters.{IsAll, IsProxied}
5 | import ProxyBwapi.Races.Protoss
6 | import Utilities.Time.GameTime
7 |
8 | class FingerprintCannonRush extends FingerprintCompleteBy(
9 | IsAll(Protoss.PhotonCannon, IsProxied),
10 | GameTime(4, 30)) {
11 |
12 | override val sticky = true
13 | }
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/ProtossStrategies/FingerprintCoreBeforeZealot.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.ProtossStrategies
2 |
3 | import Information.Fingerprinting.Generic.FingerprintCompleteBy
4 | import ProxyBwapi.Races.Protoss
5 | import Utilities.Time.GameTime
6 |
7 | // Sample Core-on-14 Core completion time: 2:45
8 | // Sample ZCore Core completion time: 3:08
9 | class FingerprintCoreBeforeZealot extends FingerprintCompleteBy(Protoss.CyberneticsCore, GameTime(2, 57))
10 |
--------------------------------------------------------------------------------
/src/Information/Grids/Floody/GridEnemyRangeAirGround.scala:
--------------------------------------------------------------------------------
1 | package Information.Grids.Floody
2 |
3 | import Mathematics.Maff
4 | import ProxyBwapi.UnitInfo.UnitInfo
5 |
6 | final class GridEnemyRangeAirGround extends AbstractGridFloody {
7 |
8 | override protected def include(unit: UnitInfo): Boolean = unit.isEnemy && unit.canAttack
9 |
10 | override protected def range(unit: UnitInfo): Int = Maff.div32(unit.pixelRangeMax.toInt)
11 |
12 | override val margin: Int = 3
13 | }
14 |
--------------------------------------------------------------------------------
/src/Information/Grids/Floody/GridEnemyRangeGround.scala:
--------------------------------------------------------------------------------
1 | package Information.Grids.Floody
2 |
3 | import Mathematics.Maff
4 | import ProxyBwapi.UnitInfo.UnitInfo
5 |
6 | final class GridEnemyRangeGround extends AbstractGridFloody {
7 |
8 | override protected def include(unit: UnitInfo): Boolean = unit.isEnemy && unit.canAttackGround
9 |
10 | override protected def range(unit: UnitInfo): Int = Maff.div32(unit.pixelRangeGround.toInt)
11 |
12 | override val margin: Int = 3
13 | }
14 |
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsCombatSpellcaster.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 | import ProxyBwapi.Races.{Protoss, Terran, Zerg}
3 | import ProxyBwapi.UnitInfo.UnitInfo
4 |
5 | object IsCombatSpellcaster extends UnitFilter {
6 | override def apply(unit: UnitInfo): Boolean = unit.isAny(
7 | Terran.ScienceVessel,
8 | Terran.Medic,
9 | Protoss.HighTemplar,
10 | Protoss.Arbiter,
11 | Protoss.DarkArchon,
12 | Zerg.Queen,
13 | Zerg.Defiler
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/Information/Counting/MacroCounts.scala:
--------------------------------------------------------------------------------
1 | package Information.Counting
2 |
3 | import Performance.Cache
4 | import ProxyBwapi.UnitClasses.UnitClass
5 | import Utilities.CountMap
6 |
7 | class MacroCounts {
8 | def oursExtant: CountMap[UnitClass] = _oursExtant()
9 | def oursComplete: CountMap[UnitClass] = _oursComplete()
10 | private val _oursExtant = new Cache(() => MacroCounter.countOursExtant)
11 | private val _oursComplete = new Cache(() => MacroCounter.countOursComplete)
12 | }
13 |
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/Generic/FingerprintNot.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.Generic
2 |
3 | import Information.Fingerprinting.Fingerprint
4 |
5 | class FingerprintNot(fingerprints: Fingerprint*) extends Fingerprint {
6 |
7 | override val children: Seq[Fingerprint] = fingerprints
8 |
9 | override def reason: String = f"[${children.view.filter(_()).map(_.explanation).mkString("; ")}]"
10 |
11 | override def investigate: Boolean = ! fingerprints.exists(_())
12 | }
13 |
--------------------------------------------------------------------------------
/src/Strategery/Selection/StrategySelectionFixed.scala:
--------------------------------------------------------------------------------
1 | package Strategery.Selection
2 |
3 | import Strategery.Strategies.Strategy
4 |
5 | case class StrategySelectionFixed(strategies: Strategy*) extends StrategySelectionRecommended(StrategySelectionGreedy(), strategies: _*) {
6 | duration = 100000
7 | override def respectMap : Boolean = false
8 | override def respectHistory : Boolean = false
9 |
10 | override def toString: String = f"StrategySelectionFixed: $branchString"
11 | }
12 |
--------------------------------------------------------------------------------
/src/Strategery/Selection/StrategySelectionRandom.scala:
--------------------------------------------------------------------------------
1 | package Strategery.Selection
2 |
3 | import Lifecycle.With
4 | import Mathematics.Maff
5 | import Strategery.Strategies.StrategyBranch
6 |
7 | object StrategySelectionRandom extends StrategySelectionPolicy {
8 |
9 | def chooseBranch: StrategyBranch = {
10 | Maff.sampleWeighted(With.strategy.strategyBranchesLegal, (b: StrategyBranch) => b.explorationWeight).get
11 | }
12 |
13 | override def toString = "StrategySelectionRandom"
14 | }
--------------------------------------------------------------------------------
/src/Utilities/UnitCounters/CountExcept.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitCounters
2 |
3 | import Lifecycle.With
4 | import Mathematics.Maff
5 | import Performance.Cache
6 | import Utilities.UnitFilters.UnitFilter
7 |
8 | class CountExcept(buffer: Int, matcher: UnitFilter) extends UnitCounter {
9 | private val matched = new Cache(() => With.units.countOurs(matcher))
10 | override def minimum: Int = Maff.clamp01(matched() - buffer)
11 | override def maximum: Int = Math.max(0, matched() - buffer)
12 | }
--------------------------------------------------------------------------------
/src/Debugging/Visualizations/Views/Planning/ShowWall.scala:
--------------------------------------------------------------------------------
1 | package Debugging.Visualizations.Views.Planning
2 |
3 | import Debugging.Visualizations.Views.DebugView
4 | import Lifecycle.With
5 | import Placement.Access.PlaceLabels.Wall
6 |
7 | object ShowWall extends DebugView {
8 |
9 | override def renderMap(): Unit = {
10 | With.placement.fits
11 | .view
12 | .filter(_.template.points.exists(_.requirement.labels.contains(Wall)))
13 | .foreach(_.drawMap())
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/ProtossStrategies/FingerprintEarlyForge.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.ProtossStrategies
2 |
3 | import Information.Fingerprinting.Generic._
4 | import ProxyBwapi.Races.Protoss
5 | import Utilities.Time.GameTime
6 |
7 | class FingerprintEarlyForge extends FingerprintOr(
8 | new FingerprintCompleteBy(Protoss.Forge, GameTime(4, 0)),
9 | new FingerprintCompleteBy(Protoss.PhotonCannon, GameTime(5, 0))) {
10 |
11 | override val sticky = true
12 | }
13 |
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/ZergStrategies/Fingerprint10Hatch.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.ZergStrategies
2 |
3 | import Information.Fingerprinting.Generic.{FingerprintCompleteBy, FingerprintOr}
4 | import Lifecycle.With
5 | import Utilities.UnitFilters.IsHatchlike
6 | import Utilities.Time.Seconds
7 |
8 | class Fingerprint10Hatch extends FingerprintOr(
9 | new FingerprintCompleteBy(IsHatchlike, ZergTimings.TwelveHatch_HatchCompleteBy - Seconds(10), 2),
10 | With.fingerprints.tenHatchPool)
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/ZergStrategies/Fingerprint12HatchHatch.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.ZergStrategies
2 |
3 | import Information.Fingerprinting.Generic.FingerprintCompleteBy
4 | import Information.Fingerprinting.ZergStrategies.ZergTimings.TwelveHatch11Pool13Hatch_HatchCompleteBy
5 | import Utilities.UnitFilters.IsHatchlike
6 | import Utilities.Time.Seconds
7 |
8 | class Fingerprint12HatchHatch extends FingerprintCompleteBy(IsHatchlike, TwelveHatch11Pool13Hatch_HatchCompleteBy - Seconds(3), 3)
9 |
--------------------------------------------------------------------------------
/src/Micro/Actions/Terran/FinishConstruction.scala:
--------------------------------------------------------------------------------
1 | package Micro.Actions.Terran
2 |
3 | import Micro.Actions.Action
4 | import Micro.Agency.Commander
5 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
6 |
7 | object FinishConstruction extends Action {
8 |
9 | override def allowed(unit: FriendlyUnitInfo): Boolean = {
10 | unit.intent.toFinish.isDefined
11 | }
12 |
13 | override def perform(unit: FriendlyUnitInfo) {
14 | Commander.rightClick(unit, unit.intent.toFinish.get)
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/configs/PurpleWaveLocalDocker.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "human" : false,
3 | "ladder" : false,
4 | "livestream" : false,
5 | "tournament" : true,
6 | "roundrobin" : true,
7 | "elimination" : false,
8 | "pretraining" : false,
9 | "debugging" : true,
10 | "debugginglive" : false,
11 | "logstd" : true,
12 | "multiCPU" : true,
13 | "framemstarget" : 35,
14 | "framemslimit" : 35,
15 | "comments" : "SC-Docker does not enforce per-frame limits."
16 | }
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/Generic/FingerprintOr.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.Generic
2 |
3 | import Information.Fingerprinting.Fingerprint
4 |
5 | class FingerprintOr(fingerprints: Fingerprint*) extends Fingerprint {
6 |
7 | override val children: Seq[Fingerprint] = fingerprints
8 |
9 | override def reason: String = f"Matched children: [${children.view.filter(_()).map(_.explanation).mkString("; ")}]"
10 |
11 | override def investigate: Boolean = fingerprints.exists(_())
12 | }
13 |
--------------------------------------------------------------------------------
/src/Information/Grids/Floody/GridFriendlyDetection.scala:
--------------------------------------------------------------------------------
1 | package Information.Grids.Floody
2 |
3 | import Mathematics.Maff
4 | import ProxyBwapi.UnitInfo.UnitInfo
5 |
6 | final class GridFriendlyDetection extends AbstractGridFloody {
7 |
8 | override protected def include(unit: UnitInfo): Boolean = unit.complete && unit.unitClass.isDetector && ! unit.blind && unit.isFriendly
9 |
10 | override protected def range(unit: UnitInfo): Int = Maff.div32(unit.sightPixels)
11 |
12 | override val margin: Int = 2
13 | }
--------------------------------------------------------------------------------
/src/Micro/Coordination/Pushing/ExplosionEMP.scala:
--------------------------------------------------------------------------------
1 | package Micro.Coordination.Pushing
2 |
3 | import Mathematics.Physics.Force
4 | import ProxyBwapi.Bullets.BulletInfo
5 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
6 |
7 | class ExplosionEMP(emp: BulletInfo) extends CircularPush(TrafficPriorities.Dodge, emp.targetPixel.getOrElse(emp.pixel), 96) {
8 | override def force(unit: FriendlyUnitInfo): Option[Force] = {
9 | if(unit.energy <= 5 && unit.shieldPoints == 20) None else super.force(unit)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/Gameplans/Zerg/ZergStandardGameplan.scala:
--------------------------------------------------------------------------------
1 | package Gameplans.Zerg
2 |
3 | import Gameplans.All.ModalGameplan
4 | import Gameplans.Zerg.ZvP.ZergVsProtoss
5 | import Gameplans.Zerg.ZvR.ZergVsRandom
6 | import Gameplans.Zerg.ZvT.ZergVsTerran
7 | import Gameplans.Zerg.ZvZ.ZergVsZerg
8 | import Planning.Plans.SwitchEnemyRace
9 |
10 | class ZergStandardGameplan extends ModalGameplan(
11 | new ZergVsRandom,
12 | new SwitchEnemyRace(
13 | new ZergVsTerran,
14 | new ZergVsProtoss,
15 | new ZergVsZerg)
16 | )
--------------------------------------------------------------------------------
/src/Information/Battles/Prediction/Simulation/SimulationEventBehavior.scala:
--------------------------------------------------------------------------------
1 | package Information.Battles.Prediction.Simulation
2 | import Mathematics.Points.Pixel
3 |
4 | final case class SimulationEventBehavior(
5 | sim: Simulacrum,
6 | behaviorOld: SimulacrumBehavior,
7 | behaviorNew: SimulacrumBehavior)
8 | extends SimulationEvent(sim) {
9 |
10 | override def toString: String = f"$frame: ${sim.describe} transitions from $behaviorOld to $behaviorNew"
11 |
12 | override val to: Pixel = from
13 | }
14 |
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/Generic/FingerprintAnd.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.Generic
2 |
3 | import Information.Fingerprinting.Fingerprint
4 |
5 | class FingerprintAnd(fingerprints: Fingerprint*) extends Fingerprint {
6 |
7 | override val children: Seq[Fingerprint] = fingerprints
8 |
9 | override def reason: String = f"Unmatched children: [${children.view.filterNot(_()).map(_.explanation).mkString("; ")}]"
10 |
11 | override def investigate: Boolean = fingerprints.forall(_())
12 | }
13 |
--------------------------------------------------------------------------------
/src/Micro/Coordination/Pushing/ExplosionPsionicStorm.scala:
--------------------------------------------------------------------------------
1 | package Micro.Coordination.Pushing
2 |
3 | import Mathematics.Physics.Force
4 | import ProxyBwapi.Bullets.BulletInfo
5 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
6 |
7 | class ExplosionPsionicStorm(psionicStorm: BulletInfo) extends CircularPush(TrafficPriorities.Dodge, psionicStorm.pixel, 64) {
8 | override def force(recpient: FriendlyUnitInfo): Option[Force] = {
9 | if (recpient.unitClass.isBuilding) None else super.force(recpient)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/Utilities/UnitPreferences/PreferHatcheryWithThreeLarva.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitPreferences
2 |
3 | import Lifecycle.With
4 | import ProxyBwapi.Races.Zerg
5 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
6 |
7 | object PreferHatcheryWithThreeLarva extends UnitPreference {
8 |
9 | override def apply(unit: FriendlyUnitInfo): Double =
10 | Math.max(2, With.units
11 | .inTileRectangle(unit.tile.toRectangle.expand(3, 3))
12 | .count(u => u != unit && u.isFriendly && u.is(Zerg.Larva)))
13 | }
14 |
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/TerranStrategies/FingerprintWallIn.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.TerranStrategies
2 |
3 | import Information.Fingerprinting.Fingerprint
4 | import Lifecycle.With
5 | import Utilities.Time.GameTime
6 |
7 | class FingerprintWallIn extends Fingerprint {
8 | override protected def investigate: Boolean = With.frame < GameTime(3, 0)() && With.geography.zones.exists(z => z.walledIn && ! z.metro.exists(_.bases.exists(_.owner.isUs)))
9 | override protected def sticky: Boolean = true
10 | }
--------------------------------------------------------------------------------
/src/Placement/Templating/RequireGas.scala:
--------------------------------------------------------------------------------
1 | package Placement.Templating
2 |
3 | import ProxyBwapi.Races.{Protoss, Terran, Zerg}
4 |
5 | class RequireGas extends TemplatePointRequirement(Terran.Refinery, Protoss.Assimilator, Zerg.Extractor) {
6 | override val buildableBefore : Boolean = false
7 | override val walkableBefore : Boolean = false
8 | override val buildableAfter : Boolean = false
9 | override val walkableAfter : Boolean = false
10 | override val toString : String = "Anything"
11 | }
12 |
--------------------------------------------------------------------------------
/src/Utilities/DoQueue.scala:
--------------------------------------------------------------------------------
1 | package Utilities
2 |
3 | import scala.collection.mutable
4 |
5 | /**
6 | * A syntax-light queue of things to do.
7 | * The intended use case is something you want to do exactly once,
8 | * but may want to consider doing at multiple points.
9 | */
10 | class DoQueue(todo: (() => Unit)*) {
11 | val queue = new mutable.Queue[() => Unit]
12 | queue ++= todo
13 |
14 | def apply(): Unit = {
15 | if (queue.nonEmpty) {
16 | queue.dequeue()()
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/Micro/Coordination/Pushing/ExplosionIrradiateSplash.scala:
--------------------------------------------------------------------------------
1 | package Micro.Coordination.Pushing
2 |
3 | import Mathematics.Physics.Force
4 | import ProxyBwapi.UnitInfo.{FriendlyUnitInfo, UnitInfo}
5 |
6 | class ExplosionIrradiateSplash(burningMan: UnitInfo) extends CircularPush(TrafficPriorities.Dodge, burningMan.pixel, 64) {
7 | override def force(recipient: FriendlyUnitInfo): Option[Force] = {
8 | if (recipient == burningMan || ! recipient.unitClass.canBeIrradiateBurned) None else super.force(recipient)
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/Debugging/Visualizations/Views/Fun/ShowHappyVision.scala:
--------------------------------------------------------------------------------
1 | package Debugging.Visualizations.Views.Fun
2 |
3 | import Debugging.Visualizations.Views.Geography.ShowZones
4 | import Debugging.Visualizations.Views.DebugView
5 |
6 | object ShowHappyVision extends DebugView {
7 |
8 | def render() {
9 | ShowBlackScreen.renderScreen()
10 | ShowZones.renderMap()
11 | ShowHappyUnits.renderMap()
12 | ShowBulletsAsHearts.renderMap()
13 | ShowPlayerNames.renderScreen("Retro Arcade Happy Vision")
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/Information/Battles/Prediction/Simulation/BehaviorRepair.scala:
--------------------------------------------------------------------------------
1 | package Information.Battles.Prediction.Simulation
2 |
3 | object BehaviorRepair extends SimulacrumBehavior {
4 | val fighting: Boolean = true
5 | override def act(simulacrum: Simulacrum): Unit = {
6 | // TODO: Clear invalid targets
7 | // TODO: Sort targets
8 | simulacrum.targets.clear()
9 | if (simulacrum.targets.isEmpty) {
10 | simulacrum.behavior = BehaviorFlee
11 | simulacrum.act()
12 | return
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/Mathematics/Shapes/Box.scala:
--------------------------------------------------------------------------------
1 | package Mathematics.Shapes
2 |
3 | import Mathematics.Points.Point
4 |
5 | object Box {
6 | def apply(width: Int, height: Int): Seq[Point] = (
7 | (0 until width - 1 by 1).view.map(x => Point(x, 0))
8 | ++ (0 until height - 1 by 1).view.map(y => Point(width - 1, y))
9 | ++ (width - 1 until 0 by -1).view.map(x => Point(x, height - 1))
10 | ++ (height - 1 until 0 by -1).view.map(y => Point(0, y)))
11 | }
12 |
--------------------------------------------------------------------------------
/src/Mathematics/Shapes/RoundedBox.scala:
--------------------------------------------------------------------------------
1 | package Mathematics.Shapes
2 |
3 | import Mathematics.Points.Point
4 |
5 | object RoundedBox {
6 | def apply(width: Int, height: Int): IndexedSeq[Point] = (
7 | (1 until width - 1 by 1).map(x => Point(x, 0))
8 | ++ (1 until height - 1 by 1).map(y => Point(width - 1, y))
9 | ++ (width - 2 until 0 by -1).map(x => Point(x, height - 1))
10 | ++ (height - 2 until 0 by -1).map(y => Point(0, y)))
11 | }
12 |
--------------------------------------------------------------------------------
/src/Micro/Coordination/Pushing/ExplosionLurkerNow.scala:
--------------------------------------------------------------------------------
1 | package Micro.Coordination.Pushing
2 |
3 | import Mathematics.Points.Pixel
4 | import ProxyBwapi.Bullets.BulletInfo
5 |
6 | class ExplosionLurkerNow(spine: BulletInfo) extends LinearPush {
7 | override protected def source: Pixel = spine.pixel
8 |
9 | override protected def destination: Pixel = spine.targetPixel.getOrElse(source)
10 |
11 | override protected def sourceWidth: Double = 20
12 |
13 | override val priority: TrafficPriority = TrafficPriorities.Shove
14 | }
15 |
--------------------------------------------------------------------------------
/src/Placement/Architecture/ArchitecturalAssessment.scala:
--------------------------------------------------------------------------------
1 | package Placement.Architecture
2 |
3 | object ArchitecturalAssessment extends Enumeration {
4 | type ArchitecturalAssessment = Value
5 | val
6 | Accepted,
7 | Invalid,
8 | Unpowered,
9 | IsntBuildableTerrain,
10 | InaccessibleIsland,
11 | IsntGas,
12 | BlockedGas,
13 | IsntBasePosition,
14 | IsntLegalForTownHall,
15 | IsntBuildable,
16 | CreepMismatch,
17 | ViolatesResourceGap,
18 | BlockedByUnit
19 | = Value
20 | }
--------------------------------------------------------------------------------
/src/Utilities/UnitFilters/IsRecruitableForCombat.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitFilters
2 |
3 | import ProxyBwapi.Races.Zerg
4 | import ProxyBwapi.UnitInfo.UnitInfo
5 |
6 | object IsRecruitableForCombat extends UnitFilter {
7 | override def apply(unit: UnitInfo): Boolean = (
8 | unit.unitClass.orderable
9 | && ! unit.unitClass.isWorker
10 | && ! Zerg.Larva(unit)
11 | && unit.remainingCompletionFrames < 48
12 | && (unit.unitClass.canMove || unit.unitClass.isTank || (unit.unitClass.isBuilding && unit.flying)))
13 | }
14 |
--------------------------------------------------------------------------------
/src/Debugging/Visualizations/Views/Planning/ShowHistory.scala:
--------------------------------------------------------------------------------
1 | package Debugging.Visualizations.Views.Planning
2 |
3 | import Debugging.Visualizations.Rendering.DrawScreen
4 | import Debugging.Visualizations.Views.DebugView
5 | import Lifecycle.With
6 |
7 | object ShowHistory extends DebugView {
8 |
9 | override def renderScreen(): Unit = {
10 | DrawScreen.column(5,
11 | With.visualization.lineHeightSmall * 7
12 | , With.history.games.toVector.sortBy(-_.timestamp).take(30).map(_.toString))
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/src/Information/Battles/Prediction/Simulation/SimulationEventSleep.scala:
--------------------------------------------------------------------------------
1 | package Information.Battles.Prediction.Simulation
2 |
3 | import Mathematics.Points.Pixel
4 |
5 | final case class SimulationEventSleep(sim: Simulacrum, frames: Int, reason: Option[String] = None) extends SimulationEvent(sim) {
6 |
7 | override def toString: String = f"$frame: ${sim.describe} $from targeting ${describe(target)} ${describePixel(targetAt)} sleeps for $frames frames${reason.map(": " + _).getOrElse("")}"
8 |
9 | override val to: Pixel = from
10 | }
11 |
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/ZergStrategies/Fingerprint12Pool11Gas.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.ZergStrategies
2 |
3 | import Information.Fingerprinting.Generic.{FingerprintAnd, FingerprintGasCompleteBy}
4 | import Information.Fingerprinting.ZergStrategies.ZergTimings.TwelvePool11Gas_GasCompleteBy
5 | import Lifecycle.With
6 | import Utilities.Time.Seconds
7 |
8 | class Fingerprint12Pool11Gas extends FingerprintAnd(
9 | With.fingerprints.twelvePool,
10 | new FingerprintGasCompleteBy(TwelvePool11Gas_GasCompleteBy + Seconds(10)))
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/ZergStrategies/FingerprintOverpoolGas.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.ZergStrategies
2 |
3 | import Information.Fingerprinting.Generic.{FingerprintAnd, FingerprintGasCompleteBy}
4 | import Information.Fingerprinting.ZergStrategies.ZergTimings.Overpool9Gas_GasCompleteBy
5 | import Lifecycle.With
6 | import Utilities.Time.Seconds
7 |
8 | class FingerprintOverpoolGas extends FingerprintAnd(
9 | With.fingerprints.overpool,
10 | new FingerprintGasCompleteBy(Overpool9Gas_GasCompleteBy + Seconds(15)))
11 |
--------------------------------------------------------------------------------
/src/Information/Grids/Construction/GridBuildableTownHall.scala:
--------------------------------------------------------------------------------
1 | package Information.Grids.Construction
2 |
3 | import Information.Grids.ArrayTypes.AbstractGridArrayBoolean
4 | import Lifecycle.With
5 |
6 | class GridBuildableTownHall extends AbstractGridArrayBoolean {
7 |
8 | final override val defaultValue: Boolean = true
9 |
10 | override def onInitialization(): Unit = {
11 | reset()
12 | With.units.all.filter(_.unitClass.isResource).foreach(_.tileArea.expand(3, 3).tiles.foreach(set(_, false)))
13 | }
14 | }
15 |
16 |
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/Generic/FingerprintTechBy.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.Generic
2 |
3 | import Information.Fingerprinting.Fingerprint
4 | import Lifecycle.With
5 | import ProxyBwapi.Techs.Tech
6 | import Utilities.Time.GameTime
7 |
8 | class FingerprintTechBy(tech: Tech, gameTime: GameTime) extends Fingerprint {
9 | override def investigate: Boolean = With.frame < gameTime() && With.enemies.exists(_.hasTech(tech))
10 | override val sticky: Boolean = true
11 | override def reason: String = tech.toString
12 | }
13 |
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/TerranStrategies/Fingerprint2FacVultures.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.TerranStrategies
2 |
3 | import Information.Fingerprinting.Generic.{FingerprintArrivesBy, FingerprintOr}
4 | import ProxyBwapi.Races.Terran
5 | import Utilities.Time.GameTime
6 |
7 | class Fingerprint2FacVultures extends FingerprintOr(
8 | new FingerprintArrivesBy(Terran.Vulture, GameTime(4, 35), 2),
9 | new FingerprintArrivesBy(Terran.Vulture, GameTime(5, 50), 4),
10 | new FingerprintArrivesBy(Terran.Vulture, GameTime(6, 10), 6),
11 | )
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/ZergStrategies/Fingerprint3HatchSpeedling.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.ZergStrategies
2 |
3 | import Information.Fingerprinting.Generic.{FingerprintAnd, FingerprintUpgradeBy}
4 | import Lifecycle.With
5 | import ProxyBwapi.Races.Zerg
6 | import Utilities.Time.GameTime
7 |
8 | class Fingerprint3HatchSpeedling extends FingerprintAnd(
9 | With.fingerprints.threeHatchGas,
10 | new FingerprintUpgradeBy(Zerg.ZerglingSpeed, GameTime(5, 0))) {
11 |
12 | override protected val sticky: Boolean = true
13 | }
14 |
--------------------------------------------------------------------------------
/src/Utilities/SpinWait.scala:
--------------------------------------------------------------------------------
1 | package Utilities
2 |
3 | import java.lang.reflect.Method
4 |
5 | object SpinWait {
6 |
7 | // We want to use Thread.onSpinWait() if it's available,
8 | // but that's only in Java 9+
9 |
10 | private lazy val onSpinWait: Option[Method] = classOf[Thread].getDeclaredMethods.find(_.getName == "onSpinWait")
11 | def apply(): Unit = {
12 | if (onSpinWait.isDefined) {
13 | onSpinWait.get.invoke(Thread.currentThread())
14 | } else {
15 | Thread.sleep(0, 100000)
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/Debugging/Visualizations/Views/Planning/ShowFingerprints.scala:
--------------------------------------------------------------------------------
1 | package Debugging.Visualizations.Views.Planning
2 |
3 | import Debugging.Visualizations.Rendering.DrawScreen
4 | import Debugging.Visualizations.Views.DebugView
5 | import Lifecycle.With
6 |
7 | object ShowFingerprints extends DebugView {
8 |
9 | override def renderScreen(): Unit = {
10 | DrawScreen.text(
11 | 5,
12 | 5 * With.visualization.lineHeightSmall,
13 | "Matched:\n\n"
14 | + With.fingerprints.status.mkString("\n")
15 | )
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/Gameplans/Terran/TerranStandardGameplan.scala:
--------------------------------------------------------------------------------
1 | package Gameplans.Terran
2 |
3 | import Gameplans.All.ModalGameplan
4 | import Gameplans.Terran.TvP.TerranVsProtoss
5 | import Gameplans.Terran.TvR.TerranVsRandom
6 | import Gameplans.Terran.TvT.TerranVsTerran
7 | import Gameplans.Terran.TvZ.TerranVsZerg
8 | import Planning.Plans.SwitchEnemyRace
9 |
10 | class TerranStandardGameplan extends ModalGameplan(
11 | new TerranVsRandom,
12 | new SwitchEnemyRace(
13 | new TerranVsTerran,
14 | new TerranVsProtoss,
15 | new TerranVsZerg)
16 | )
17 |
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/ZergStrategies/Fingerprint10Hatch9Pool8Gas.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.ZergStrategies
2 |
3 | import Information.Fingerprinting.Generic.{FingerprintAnd, FingerprintGasCompleteBy}
4 | import Information.Fingerprinting.ZergStrategies.ZergTimings.TenHatch9Pool8Gas_GasCompleteBy
5 | import Lifecycle.With
6 | import Utilities.Time.Seconds
7 |
8 | class Fingerprint10Hatch9Pool8Gas extends FingerprintAnd(
9 | With.fingerprints.tenHatchPool,
10 | new FingerprintGasCompleteBy(TenHatch9Pool8Gas_GasCompleteBy + Seconds(15)))
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/ZergStrategies/Fingerprint1HatchGas.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.ZergStrategies
2 |
3 | import Information.Fingerprinting.Generic._
4 | import Information.Fingerprinting.ZergStrategies.ZergTimings.TwoHatchGasCompleteBy
5 | import Lifecycle.With
6 | import Utilities.Time.Seconds
7 |
8 | class Fingerprint1HatchGas extends FingerprintOr(
9 | new FingerprintGasCompleteBy(TwoHatchGasCompleteBy - Seconds(5)),
10 | With.fingerprints.ninePoolGas,
11 | With.fingerprints.overpoolGas,
12 | With.fingerprints.twelvePoolGas)
--------------------------------------------------------------------------------
/src/Information/Geography/NeoGeo/NeoBase.scala:
--------------------------------------------------------------------------------
1 | package Information.Geography.NeoGeo
2 |
3 | /**
4 | * A Base is a Region which contains a cluster of resources.
5 | * Each Base has a Foundation, which is an optimal location to construct a Command Center, Nexus, or Hatchery.
6 | */
7 | class NeoBase extends NeoRegion {
8 | private var _country: NeoCountry = _
9 | private var _metro: NeoMetro = _
10 | private var _natural: Option[NeoBase] = None
11 | private var _main: Option[NeoBase] = None
12 | private var _isStart: Boolean = false
13 | }
14 |
--------------------------------------------------------------------------------
/src/Micro/Targeting/FiltersRequired/TargetFilterExposed.scala:
--------------------------------------------------------------------------------
1 | package Micro.Targeting.FiltersRequired
2 |
3 | import Micro.Targeting.TargetFilter
4 | import ProxyBwapi.UnitInfo.{FriendlyUnitInfo, UnitInfo}
5 |
6 | object TargetFilterExposed extends TargetFilter {
7 |
8 | override def appliesTo(actor: FriendlyUnitInfo): Boolean = true
9 |
10 | // Avoid eating static anti-air shots unless necessary
11 | override def legal(actor: FriendlyUnitInfo, target: UnitInfo): Boolean = {
12 | target.tile.enemyRangeAgainst(actor) == 0
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/Information/Geography/Types/LabelGenerator.scala:
--------------------------------------------------------------------------------
1 | package Information.Geography.Types
2 |
3 | import scala.collection.mutable
4 | import scala.util.Random
5 |
6 | class LabelGenerator(labels: Iterable[String]) {
7 | private var repeats: Int = 1
8 | private val names = Random.shuffle(labels)
9 | private val nameQ = new mutable.Queue[String] ++ names
10 | def next(): String = {
11 | if (nameQ.isEmpty) {
12 | repeats += 1
13 | nameQ ++= names.map(name => f"$name $repeats")
14 | }
15 | nameQ.dequeue()
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/Information/Grids/Vision/GridScoutingPathsBases.scala:
--------------------------------------------------------------------------------
1 | package Information.Grids.Vision
2 |
3 | import Information.Grids.Movement.GridGroundDistance
4 | import Lifecycle.With
5 | import Mathematics.Points.Tile
6 |
7 | class GridScoutingPathsBases extends GridGroundDistance {
8 |
9 | override def origins: Vector[Tile] =
10 | With.geography.bases.map(_.heart).flatMap(a =>
11 | With.geography.bases.map(_.heart).filterNot(a==)
12 | .flatMap(With.paths.profileDistance(a, _).find.tiles))
13 | .flatten
14 | .distinct
15 | }
16 |
--------------------------------------------------------------------------------
/src/Information/Scouting/Scouting.scala:
--------------------------------------------------------------------------------
1 | package Information.Scouting
2 |
3 | import Performance.Tasks.TimedTask
4 |
5 | final class Scouting extends TimedTask
6 | with Debuts
7 | with EnemyTechs
8 | with EnemyScouting
9 | with BaseInference
10 | with Intrigue
11 | with Timings
12 | with Tugging {
13 | override protected def onRun(budgetMs: Long): Unit = {
14 | updateEnemyTechs()
15 | updateEnemyScouting()
16 | updateBaseInference()
17 | updateIntrigue()
18 | updateDebuts()
19 | updateTimings()
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/Mathematics/Maff.scala:
--------------------------------------------------------------------------------
1 | package Mathematics
2 |
3 | import Mathematics.Functions._
4 |
5 | object Maff
6 | extends Angles
7 | with Approximate
8 | with Bitshift
9 | with Convert
10 | with Polygons
11 | with Rectangles
12 | with Reduce
13 | with Sample
14 | with Sort {
15 | val inv8 : Double = 1 / 8.0
16 | val inv16 : Double = 1 / 16.0
17 | val inv32 : Double = 1 / 32.0
18 | val inv64 : Double = 1 / 64.0
19 | val inv128 : Double = 1 / 128.0
20 | val inv256 : Double = 1 / 256.0
21 | }
22 |
--------------------------------------------------------------------------------
/src/Micro/Heuristics/SpellTargets.scala:
--------------------------------------------------------------------------------
1 | package Micro.Heuristics
2 |
3 | import Lifecycle.With
4 | import ProxyBwapi.UnitInfo.{FriendlyUnitInfo, UnitInfo}
5 | import Utilities.?
6 |
7 | object SpellTargets {
8 |
9 | def legal(target: UnitInfo): Boolean = (
10 | ! target.invincible
11 | && ! target.stasised
12 | && target.likelyStillThere
13 | && (target.burrowed || With.framesSince(target.lastSeen) < ?(target.canMove, 24, 72)))
14 |
15 | def apply(caster: FriendlyUnitInfo): Seq[UnitInfo] = caster.matchups.allUnits.filter(legal)
16 | }
17 |
--------------------------------------------------------------------------------
/src/Tactic/Tactics/Tactic.scala:
--------------------------------------------------------------------------------
1 | package Tactic.Tactics
2 |
3 | import Macro.Allocation.Prioritized
4 | import Mathematics.Points.{Pixel, Points}
5 | import Planning.ResourceLocks.LockUnits
6 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
7 | import Tactic.Squads.FriendlyUnitGroup
8 |
9 | trait Tactic extends Prioritized with FriendlyUnitGroup {
10 |
11 | val lock: LockUnits = new LockUnits(this)
12 | var vicinity: Pixel = Points.middle
13 |
14 | @inline final def groupFriendlyUnits: Seq[FriendlyUnitInfo] = units
15 |
16 | def launch(): Unit
17 | }
18 |
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/ZergStrategies/Fingerprint12Hatch11Pool10Gas.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.ZergStrategies
2 |
3 | import Information.Fingerprinting.Generic.{FingerprintAnd, FingerprintGasCompleteBy}
4 | import Information.Fingerprinting.ZergStrategies.ZergTimings.TwelveHatch11Pool10Gas_GasCompleteBy
5 | import Lifecycle.With
6 | import Utilities.Time.Seconds
7 |
8 | class Fingerprint12Hatch11Pool10Gas extends FingerprintAnd(
9 | With.fingerprints.twelveHatchPool,
10 | new FingerprintGasCompleteBy(TwelveHatch11Pool10Gas_GasCompleteBy + Seconds(15)))
--------------------------------------------------------------------------------
/src/Gameplans/Protoss/ProtossStandardGameplan.scala:
--------------------------------------------------------------------------------
1 | package Gameplans.Protoss
2 |
3 | import Gameplans.All.ModalGameplan
4 | import Gameplans.Protoss.PvP.ProtossVsProtoss
5 | import Gameplans.Protoss.PvR.ProtossVsRandom
6 | import Gameplans.Protoss.PvT.ProtossVsTerran
7 | import Gameplans.Protoss.PvZ.ProtossVsZerg
8 | import Planning.Plans.SwitchEnemyRace
9 |
10 | class ProtossStandardGameplan extends ModalGameplan(
11 | new SwitchEnemyRace(
12 | new ProtossVsTerran,
13 | new ProtossVsProtoss,
14 | new ProtossVsZerg,
15 | new ProtossVsRandom)
16 | )
17 |
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/TerranStrategies/Fingerprint14CC.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.TerranStrategies
2 |
3 | import Information.Fingerprinting.Generic.{FingerprintAnd, FingerprintCompleteBy, FingerprintNot}
4 | import Lifecycle.With
5 | import ProxyBwapi.Races.Terran
6 | import Utilities.Time.GameTime
7 |
8 | class Fingerprint14CC extends FingerprintAnd(
9 | new FingerprintNot(With.fingerprints.oneRaxFE),
10 | new FingerprintCompleteBy(Terran.CommandCenter, GameTime(4, 0), 2)) {
11 | override def sticky: Boolean = With.frame > GameTime(4, 0)()
12 | }
13 |
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/TerranStrategies/FingerprintFD.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.TerranStrategies
2 |
3 | import Information.Fingerprinting.Generic._
4 | import Lifecycle.With
5 | import ProxyBwapi.Races.Terran
6 | import Utilities.Time.GameTime
7 |
8 | class FingerprintFD extends FingerprintAnd(
9 | With.fingerprints.oneFac,
10 | new FingerprintOr(
11 | new FingerprintArrivesBy(Terran.Marine, GameTime(5, 0), 5),
12 | new FingerprintCompleteBy(Terran.Marine, GameTime(4, 30), 5),
13 | new FingerprintCompleteBy(Terran.Marine, GameTime(6, 0), 6)))
--------------------------------------------------------------------------------
/src/Information/Grids/Movement/GridFlowField.scala:
--------------------------------------------------------------------------------
1 | package Information.Grids.Movement
2 |
3 | import Information.Grids.ArrayTypes.AbstractGridArray
4 | import Mathematics.Physics.Force
5 | import Mathematics.Points.Tile
6 |
7 | class GridFlowField(origin: Tile) extends AbstractGridArray[Force] {
8 |
9 | final override val defaultValue: Force = Force(0, 0)
10 | final override val values: Array[Force] = Array.fill(length)(defaultValue)
11 |
12 | override def onInitialization(): Unit = {
13 | tiles.foreach(t => set(t, t.slowGroundDirectionTo(origin)))
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/Utilities/UnitPreferences/PreferScout.scala:
--------------------------------------------------------------------------------
1 | package Utilities.UnitPreferences
2 | import Mathematics.Maff
3 | import Mathematics.Points.{Pixel, Points}
4 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
5 |
6 | class PreferScout(val to: Pixel*) extends UnitPreference {
7 | override def apply(unit: FriendlyUnitInfo): Double = {
8 | (unit.remainingOccupationFrames
9 | + Maff.orElse(to, Seq(Points.middle)).view.map(unit.framesToTravelTo).min
10 | + (if (unit.intent.toScoutTiles.nonEmpty) 0 else 240)
11 | + (if (unit.carrying) 160 else 0))
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/Micro/Targeting/FiltersRequired/TargetFilterScourge.scala:
--------------------------------------------------------------------------------
1 | package Micro.Targeting.FiltersRequired
2 |
3 | import Micro.Targeting.TargetFilter
4 | import ProxyBwapi.Races.{Protoss, Zerg}
5 | import ProxyBwapi.UnitInfo.{FriendlyUnitInfo, UnitInfo}
6 |
7 | object TargetFilterScourge extends TargetFilter {
8 | override def appliesTo(actor: FriendlyUnitInfo): Boolean = Zerg.Scourge(actor)
9 | def legal(actor: FriendlyUnitInfo, target: UnitInfo): Boolean = {
10 | if (target.unitClass.isBuilding) return false
11 | target.isNone(Protoss.Interceptor, Zerg.Overlord)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/Micro/Targeting/FiltersSituational/TargetFilterCombatants.scala:
--------------------------------------------------------------------------------
1 | package Micro.Targeting.FiltersSituational
2 |
3 | import Micro.Targeting.TargetFilter
4 | import ProxyBwapi.UnitInfo.{FriendlyUnitInfo, UnitInfo}
5 |
6 | object TargetFilterCombatants extends TargetFilter {
7 |
8 | // If we're fighting, target units that threaten to fight back
9 | def legal(actor: FriendlyUnitInfo, target: UnitInfo): Boolean = {
10 | target.unitClass.attacksOrCastsOrDetectsOrTransports || ( ! actor.team.exists(_.engagedUpon) && actor.matchups.pixelsToThreatRange.forall(_ > 96))
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Planning/ResourceLocks/LockCurrency.scala:
--------------------------------------------------------------------------------
1 | package Planning.ResourceLocks
2 |
3 | import Lifecycle.With
4 | import Macro.Allocation.Prioritized
5 |
6 | class LockCurrency(prioritized: Prioritized) {
7 |
8 | var minerals = 0
9 | var gas = 0
10 | var supply = 0
11 | var satisfied = false
12 | var expectedFrames = 0
13 | var owner: Prioritized = _
14 |
15 | def acquire(): Boolean = {
16 | owner = prioritized
17 | owner.prioritize()
18 | With.bank.request(this)
19 | satisfied
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/Micro/Actions/Scouting/DroneWarfare.scala:
--------------------------------------------------------------------------------
1 | package Micro.Actions.Scouting
2 |
3 | import Lifecycle.With
4 | import Micro.Actions.Action
5 | import Micro.Agency.Commander
6 | import Micro.Targeting.Target
7 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
8 |
9 | object DroneWarfare extends Action {
10 |
11 | override def allowed(unit: FriendlyUnitInfo): Boolean = unit.intent.toScoutTiles.nonEmpty && With.blackboard.droneWarfare()
12 |
13 | override protected def perform(unit: FriendlyUnitInfo): Unit = {
14 | Target.choose(unit)
15 | Commander.attack(unit)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/Generic/FingerprintUpgradeBy.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.Generic
2 |
3 | import Information.Fingerprinting.Fingerprint
4 | import Lifecycle.With
5 | import ProxyBwapi.Upgrades.Upgrade
6 | import Utilities.Time.GameTime
7 |
8 | class FingerprintUpgradeBy(upgrade: Upgrade, gameTime: GameTime, level: Int = 1) extends Fingerprint {
9 | override def investigate: Boolean = With.frame < gameTime() && With.enemies.exists(_.getUpgradeLevel(upgrade) >= level)
10 | override val sticky: Boolean = true
11 | override def reason: String = upgrade.toString
12 | }
13 |
--------------------------------------------------------------------------------
/src/Micro/Actions/Protoss/Shuttle/Shuttling.scala:
--------------------------------------------------------------------------------
1 | package Micro.Actions.Protoss.Shuttle
2 |
3 | import Mathematics.Maff
4 | import ProxyBwapi.Races.Protoss
5 | import ProxyBwapi.UnitInfo.UnitInfo
6 |
7 | object Shuttling {
8 | // How far is the pickup radius for a Shuttle?
9 | // It's "1" eg. 32 edge-to-edge pixels.
10 | // https://github.com/OpenBW/openbw/blob/master/bwgame.h#L5059
11 | val pickupRadiusEdge = 32
12 |
13 | def pickupRadiusCenter(other: UnitInfo): Int = {
14 | pickupRadiusEdge + Maff.div2(Protoss.Shuttle.dimensionMin + other.unitClass.dimensionMin)
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Mathematics/Shapes/Ring.scala:
--------------------------------------------------------------------------------
1 | package Mathematics.Shapes
2 |
3 | import Mathematics.Points.Point
4 | import Utilities.?
5 |
6 | object Ring {
7 |
8 | def apply(radius: Int): Seq[Point] = {
9 | if (radius == 0) return Vector(Point(0, 0))
10 | val rOut = radius * radius
11 | val rIn = ?(radius < 1, 0, (radius - 1) * (radius - 1))
12 | (-radius to radius).view.flatMap(x =>
13 | (-radius to radius).view.map(y =>
14 | (x, y, { val d = x * x + y * y; d <= rOut && d > rIn })))
15 | .filter(_._3)
16 | .map(point => Point(point._1, point._2))
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/Information/GameSense/GameSenses.scala:
--------------------------------------------------------------------------------
1 | package Information.GameSense
2 |
3 | object GameSenses {
4 | object EconAdvantage extends GameSense
5 | object EconDisadvantage extends GameSense
6 | object MuscleAdvantage extends GameSense
7 | object MuscleDisadvantage extends GameSense
8 | object MapControl extends GameSense
9 | object MapContained extends GameSense
10 | object CloakedCrisis extends GameSense
11 | object CloakedEdge extends GameSense
12 | object FlyingCrisis extends GameSense
13 | object FlyingEdge extends GameSense
14 | }
15 |
--------------------------------------------------------------------------------
/src/Information/Grids/Vision/GridScoutingPathsStartLocations.scala:
--------------------------------------------------------------------------------
1 | package Information.Grids.Vision
2 |
3 | import Information.Grids.Movement.GridGroundDistance
4 | import Lifecycle.With
5 | import Mathematics.Points.Tile
6 |
7 | class GridScoutingPathsStartLocations extends GridGroundDistance {
8 |
9 | override def origins: Vector[Tile] =
10 | With.geography.bases.filter(_.isMain).map(_.heart).flatMap(a =>
11 | With.geography.bases.filter(_.isMain).map(_.heart).filterNot(a==)
12 | .flatMap(With.paths.profileDistance(a, _).find.tiles))
13 | .flatten
14 | .distinct
15 | }
16 |
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/ProtossStrategies/FingerprintNexusFirst.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.ProtossStrategies
2 |
3 | import Information.Fingerprinting.Generic._
4 | import Lifecycle.With
5 | import ProxyBwapi.Races.Protoss
6 | import Utilities.Time.GameTime
7 |
8 | class FingerprintNexusFirst extends FingerprintCompleteBy(
9 | u => Protoss.Nexus(u) && (
10 | ! u.base.exists(_.isMain)
11 | || ! u.complete
12 | || With.scouting.enemyMain.exists( ! u.base.contains(_))),
13 | GameTime(3, 30), 2) {
14 |
15 | override def sticky: Boolean = With.frame > GameTime(3, 20)()
16 | }
17 |
--------------------------------------------------------------------------------
/src/Micro/Actions/Commands/Travel.scala:
--------------------------------------------------------------------------------
1 | package Micro.Actions.Commands
2 |
3 | import Micro.Actions.Action
4 | import Micro.Agency.Commander
5 | import Micro.Coordination.Pathing.MicroPathing
6 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
7 |
8 | object Travel extends Action {
9 | override def allowed(unit: FriendlyUnitInfo): Boolean = unit.canMove
10 | override def perform(unit: FriendlyUnitInfo): Unit = {
11 | if (unit.intent.canSneak) {
12 | MicroPathing.tryMovingAlongTilePath(unit, MicroPathing.getSneakyPath(unit))
13 | } else {
14 | Commander.move(unit)
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/Information/Battles/ProcessingStates/BattleProcessJudge.scala:
--------------------------------------------------------------------------------
1 | package Information.Battles.ProcessingStates
2 |
3 | import Information.Battles.Types.BattleJudgment
4 | import Lifecycle.With
5 |
6 | class BattleProcessJudge extends BattleProcessState {
7 | override def step(): Unit = {
8 |
9 | val unjudged = With.battles.nextBattles.find(_.judgement.isEmpty)
10 |
11 | if (unjudged.isDefined) {
12 | unjudged.get.judgement = Some(new BattleJudgment(unjudged.get))
13 | return
14 | }
15 |
16 | With.battles.measureReactionTime()
17 |
18 | transitionTo(new BattleProcessSwap)
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/Information/Grids/Floody/GridEnemyDetection.scala:
--------------------------------------------------------------------------------
1 | package Information.Grids.Floody
2 |
3 | import Mathematics.Maff
4 | import ProxyBwapi.UnitInfo.UnitInfo
5 | import Utilities.?
6 |
7 | final class GridEnemyDetection extends AbstractGridFloody {
8 |
9 | override protected def include(unit: UnitInfo): Boolean = unit.complete && unit.unitClass.isDetector && ! unit.blind && unit.isEnemy
10 |
11 | override protected def range(unit: UnitInfo): Int = ?(unit.unitClass.isBuilding, 8, Maff.div32(unit.sightPixels)) // Nominally 7 for buildings but 8 might help us avoid dumb DT suicides
12 |
13 | override val margin: Int = 2
14 | }
--------------------------------------------------------------------------------
/src/Micro/Actions/Basic/Addon.scala:
--------------------------------------------------------------------------------
1 | package Micro.Actions.Basic
2 |
3 | import Micro.Actions.Action
4 | import Micro.Agency.{BuildIntent, Commander}
5 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
6 |
7 | object Addon extends Action {
8 |
9 | def addonIntent(unit: FriendlyUnitInfo): Option[BuildIntent] = unit.intent.toBuild.find(b => b.unitClass.isAddon && b.startNow)
10 |
11 | override def allowed(unit: FriendlyUnitInfo): Boolean = addonIntent(unit).isDefined
12 |
13 | override def perform(unit: FriendlyUnitInfo): Unit = {
14 | addonIntent(unit).foreach(b => Commander.addon(unit, b.unitClass))
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Micro/Coordination/Coordinator.scala:
--------------------------------------------------------------------------------
1 | package Micro.Coordination
2 |
3 | import Lifecycle.With
4 | import Micro.Coordination.Pathing.GridPathOccupancy
5 | import Micro.Coordination.Pushing.Pushes
6 |
7 | class Coordinator {
8 |
9 | val damageTracker = new DamageTracker
10 | val occupancy = new GridPathOccupancy
11 | val pushes = new Pushes
12 | val healing = new Healing
13 |
14 | def onAgentCycle(): Unit = {
15 | damageTracker.update()
16 | occupancy.update()
17 | pushes.update()
18 | With.units.playerOwned.foreach(_.resetTargeting())
19 | healing.update()
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/Strategery/Strategies/AllChoices.scala:
--------------------------------------------------------------------------------
1 | package Strategery.Strategies
2 |
3 | import Strategery.Strategies.AllRaces.Sandbox
4 | import Strategery.Strategies.Protoss.ProtossChoices
5 | import Strategery.Strategies.Terran.TerranChoices
6 | import Strategery.Strategies.Zerg.ZergChoices
7 |
8 | object AllChoices {
9 | def treeVsKnownRace : Seq[Strategy] = TerranChoices.all ++ ProtossChoices.all ++ ZergChoices.all :+ Sandbox
10 | def treeVsRandom : Seq[Strategy] = TerranChoices.tvr ++ ProtossChoices.pvr ++ ZergChoices.zvr :+ Sandbox
11 | def tree : Seq[Strategy] = (treeVsKnownRace ++ treeVsRandom).distinct
12 | }
13 |
--------------------------------------------------------------------------------
/src/Information/Battles/Prediction/Simulation/ReportCard.scala:
--------------------------------------------------------------------------------
1 | package Information.Battles.Prediction.Simulation
2 |
3 | import Information.Battles.Types.Battle
4 |
5 | class ReportCard(val simulacrum: Simulacrum, val estimation: Battle) {
6 | val damageDealt : Double = simulacrum.damageDealt
7 | val damageReceived : Double = simulacrum.damageReceived
8 | val alive : Boolean = simulacrum.alive
9 | val kills : Int = simulacrum.kills
10 | val events : Iterable[SimulationEvent] = simulacrum.events.toVector
11 | }
12 |
13 |
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/ProtossStrategies/FingerprintGatewayFirst.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.ProtossStrategies
2 |
3 | import Information.Fingerprinting.Generic._
4 | import Lifecycle.With
5 | import ProxyBwapi.Races.Protoss
6 | import Utilities.Time.GameTime
7 |
8 | class FingerprintGatewayFirst extends FingerprintOr(
9 | With.fingerprints.oneGateCore,
10 | With.fingerprints.twoGate,
11 | With.fingerprints.fourGateGoon,
12 | new FingerprintCompleteBy(Protoss.Gateway, GameTime(2, 40)),
13 | new FingerprintArrivesBy(Protoss.Zealot, GameTime(3, 45))) {
14 |
15 | override val sticky = true
16 | }
17 |
--------------------------------------------------------------------------------
/src/Placement/Architecture/GridExclusion.scala:
--------------------------------------------------------------------------------
1 | package Placement.Architecture
2 |
3 | import Information.Grids.ArrayTypes.AbstractGridVersionedValue
4 | import Mathematics.Points.Tile
5 |
6 | class GridExclusion extends AbstractGridVersionedValue[Option[Exclusion]] {
7 | override val defaultValue: Option[Exclusion] = None
8 | override protected val values: Array[Option[Exclusion]] = Array.fill(length)(defaultValue)
9 | def excludes(tile: Tile, request: Option[BuildingPlacement] = None): Boolean = {
10 | if ( ! tile.valid) return true
11 | val i = tile.i
12 | isSet(i) && request != values(tile.i).flatMap(_.request)
13 | }
14 | }
--------------------------------------------------------------------------------
/src/ProxyBwapi/UnitInfo/Targeter.scala:
--------------------------------------------------------------------------------
1 | package ProxyBwapi.UnitInfo
2 |
3 | import Lifecycle.With
4 | import Micro.Targeting.TargetScoring
5 | import Performance.Cache
6 |
7 | import scala.collection.mutable
8 |
9 | trait Targeter {
10 |
11 | def targetScore(target: UnitInfo): Double = {
12 | targetScores.getOrElseUpdate(
13 | target.id,
14 | new Cache[Double](() =>
15 | With.units.getId(target.id)
16 | .map(target => TargetScoring.slow(this.asInstanceOf[FriendlyUnitInfo], target))
17 | .getOrElse(0.0)))()
18 | }
19 |
20 | val targetScores = new mutable.HashMap[Int, Cache[Double]]()
21 | }
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/Generic/FingerprintGasSteal.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.Generic
2 |
3 | import Information.Fingerprinting.Fingerprint
4 | import Lifecycle.With
5 | import ProxyBwapi.UnitInfo.UnitInfo
6 | import Utilities.Time.Minutes
7 |
8 | class FingerprintGasSteal extends Fingerprint {
9 | override protected def investigate: Boolean = stolenGas.nonEmpty
10 | override def lockAfter: Int = Minutes(5)()
11 | override def reason: String = f"Stolen: [${stolenGas.mkString(", ")}]"
12 | override val sticky = true
13 | protected def stolenGas: Vector[UnitInfo] = With.geography.ourMain.gas.filter(_.isEnemy)
14 | }
15 |
--------------------------------------------------------------------------------
/src/Information/Grids/Movement/GridUnwalkableUnits.scala:
--------------------------------------------------------------------------------
1 | package Information.Grids.Movement
2 |
3 | import Information.Grids.ArrayTypes.AbstractGridVersioned
4 | import Lifecycle.With
5 | import ProxyBwapi.Races.{Terran, Zerg}
6 |
7 | final class GridUnwalkableUnits extends AbstractGridVersioned {
8 |
9 | override protected def updateCells() {
10 | With.units.all
11 | .foreach(unit =>
12 | if ((unit.unitClass.isBuilding || unit.isAny(Zerg.Egg, Zerg.LurkerEgg))
13 | && ! unit.flying
14 | && ! unit.is(Terran.SiegeTankSieged)) {
15 | unit.tiles.foreach(stamp)
16 | })
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/Planning/Proxy/ProxyRequest.scala:
--------------------------------------------------------------------------------
1 | package Planning.Proxy
2 |
3 | import Lifecycle.With
4 | import Macro.Requests.RequestBuildable
5 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
6 | import Tactic.Squads.Squad
7 |
8 | class ProxyRequest(val request: RequestBuildable, val unit: Option[FriendlyUnitInfo], val squad: Option[Squad]) {
9 | val frameCreated: Int = With.frame
10 | def this(unit: FriendlyUnitInfo, requestBuildable: RequestBuildable) = {
11 | this(requestBuildable, Some(unit), None)
12 | }
13 | def this(squad: Squad, requestBuildable: RequestBuildable) = {
14 | this(requestBuildable, None, Some(squad))
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Planning/ResourceLocks/LockTiles.scala:
--------------------------------------------------------------------------------
1 | package Planning.ResourceLocks
2 |
3 | import Lifecycle.With
4 | import Macro.Allocation.Prioritized
5 | import Mathematics.Points.Tile
6 |
7 | class LockTiles(val owner: Prioritized) {
8 |
9 | private var _tiles: Seq[Tile] = Seq.empty
10 | var satisfied: Boolean = false
11 |
12 | def tiles: Seq[Tile] = _tiles
13 |
14 | def acquireTiles(tiles: Seq[Tile]): Boolean = {
15 | release()
16 | _tiles = tiles
17 | owner.prioritize()
18 | With.groundskeeper.satisfy(this)
19 | }
20 |
21 | def release(): Unit = {
22 | With.groundskeeper.release(this)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/Strategery/Rolling.scala:
--------------------------------------------------------------------------------
1 | package Strategery
2 |
3 | import Lifecycle.With
4 |
5 | import scala.collection.mutable
6 | import scala.util.Random
7 |
8 | trait Rolling {
9 | val rolls: mutable.HashMap[String, Boolean] = new mutable.HashMap
10 | def roll(key: String, probability: Double): Boolean = {
11 | if ( ! rolls.contains(key)) {
12 | val rolled = Random.nextDouble()
13 | val success = rolled <= probability
14 | With.logger.debug(f"Roll for $key ${if (success) "PASSED" else "FAILED"} (Rolled $rolled into probability $probability)")
15 | rolls(key) = success
16 | }
17 | rolls(key)
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/Mathematics/Points/AbstractPoint.scala:
--------------------------------------------------------------------------------
1 | package Mathematics.Points
2 |
3 | abstract class AbstractPoint(val x: Int, val y: Int) {
4 |
5 | @inline final def length : Double = Math.sqrt(lengthSquared)
6 | @inline final def lengthSquared : Double = x * x + y * y
7 |
8 | def direction: Direction = new Direction(this)
9 |
10 | protected final val radiansOverDegrees = 2.0 * Math.PI / 256.0
11 |
12 | @inline final def asPixel: Pixel = Pixel(x, y)
13 | @inline final def asTile: Tile = Tile(x, y)
14 | @inline final def asPoint: Point = Point(x, y)
15 |
16 | override def toString: String = "[" + x + ", " + y + "]"
17 | }
18 |
--------------------------------------------------------------------------------
/src/Micro/Actions/Terran/Scan.scala:
--------------------------------------------------------------------------------
1 | package Micro.Actions.Terran
2 |
3 | import Micro.Actions.Action
4 | import Micro.Agency.Commander
5 | import ProxyBwapi.Races.Terran
6 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
7 |
8 | object Scan extends Action {
9 |
10 | override def allowed(unit: FriendlyUnitInfo): Boolean = {
11 | unit.intent.toScan.isDefined
12 | }
13 |
14 | override def perform(unit: FriendlyUnitInfo): Unit = {
15 | Commander.useTechOnPixel(unit, Terran.ScannerSweep, unit.intent.toScan.get)
16 | // Ensure we don't spam scan in the absence of a new intention
17 | unit.intent.toScan = None
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/configs/PurpleWaveAIIDE.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "human" : false,
3 | "ladder" : false,
4 | "livestream" : false,
5 | "tournament" : true,
6 | "roundrobin" : true,
7 | "elimination" : false,
8 | "pretraining" : false,
9 | "debugging" : false,
10 | "debugginglive" : false,
11 | "logstd" : false,
12 | "multiCPU" : true,
13 | "framemstarget" : 35,
14 | "framemslimit" : 35,
15 | "comments" : "AIIDE enforces a 55ms frame duration. We set the limit lower due to 16ms timer resolution. We expect enough JVM memory for a framebuffer, and can dictate our memory ceiling through run_proxy.bat."
16 | }
--------------------------------------------------------------------------------
/configs/PurpleWaveSCHNAIL.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "human" : true,
3 | "ladder" : false,
4 | "livestream" : false,
5 | "tournament" : false,
6 | "roundrobin" : false,
7 | "elimination" : false,
8 | "pretraining" : false,
9 | "debugging" : false,
10 | "debugginglive" : false,
11 | "logstd" : false,
12 | "multiCPU" : true,
13 | "framemstarget" : 35,
14 | "framemslimit" : 35,
15 | "comments" : "SCHNAIL enforces a 55ms frame duration. We expect enough JVM memory for a framebuffer, and can dictate our memory ceiling through run_proxy.bat. Treating the limit as lower due to 16ms timer resolution"
16 | }
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/TerranStrategies/Fingerprint1BaseBioMech.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.TerranStrategies
2 |
3 | import Information.Fingerprinting.Generic.{FingerprintAnd, FingerprintOr}
4 | import Lifecycle.With
5 | import Utilities.Time.Minutes
6 |
7 | class Fingerprint1BaseBioMech extends FingerprintAnd(
8 | new FingerprintOr(
9 | With.fingerprints.bio,
10 | With.fingerprints.twoRaxAcad),
11 | new FingerprintOr(
12 | With.fingerprints.oneFac,
13 | With.fingerprints.twoFac,
14 | With.fingerprints.threeFac)) {
15 | override val sticky: Boolean = true
16 | override val lockAfter: Int = Minutes(6)()
17 | }
18 |
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/TerranStrategies/Fingerprint3FacVultures.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.TerranStrategies
2 |
3 | import Information.Fingerprinting.Generic.{FingerprintArrivesBy, FingerprintOr}
4 | import ProxyBwapi.Races.Terran
5 | import Utilities.Time.GameTime
6 |
7 | class Fingerprint3FacVultures extends FingerprintOr(
8 | // You can actually get 3 arriving by 5:13 by making 3 Vultures in a row out of an ordinary Factory timing
9 | //new FingerprintArrivesBy(Terran.Vulture, GameTime(5, 30), 3),
10 | new FingerprintArrivesBy(Terran.Vulture, GameTime(5, 50), 5),
11 | new FingerprintArrivesBy(Terran.Vulture, GameTime(6, 10), 8),
12 | )
--------------------------------------------------------------------------------
/src/Strategery/Selection/StrategySelectionDynamic.scala:
--------------------------------------------------------------------------------
1 | package Strategery.Selection
2 |
3 | import Lifecycle.With
4 | import Mathematics.Maff
5 | import Strategery.Strategies.StrategyBranch
6 |
7 | object StrategySelectionDynamic extends StrategySelectionPolicy {
8 |
9 | def chooseBranch: StrategyBranch = {
10 | sample(16)
11 | }
12 |
13 | def sample(probabilityExponent: Double): StrategyBranch = {
14 | val branches = Maff.orElse(With.strategy.strategyBranchesLegal, With.strategy.strategyBranchesAll).toSeq
15 | Maff.sampleWeighted(branches, (branch: StrategyBranch) => Math.pow(WinProbability(branch), probabilityExponent)).get
16 | }
17 | }
--------------------------------------------------------------------------------
/src/Debugging/Visualizations/Views/ShowStoryteller.scala:
--------------------------------------------------------------------------------
1 | package Debugging.Visualizations.Views
2 |
3 | import Debugging.Visualizations.Rendering.DrawScreen
4 | import Lifecycle.With
5 | import Utilities.Time.Seconds
6 |
7 | //import scala.collection.JavaConverters._
8 |
9 | object ShowStoryteller extends DebugView {
10 | val duration = Seconds(10)()
11 |
12 | override def renderScreen(): Unit = {
13 | val lines = With.storyteller.tales.view.filter(s => s.frame > 0 && With.framesSince(s.frame) < duration).flatMap(_.tale.lines).toVector
14 | DrawScreen.column(160, 331 - lines.length * (2 + With.visualization.lineHeightSmall), lines)
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Information/Battles/Prediction/Skimulation/SkimulationUnit.scala:
--------------------------------------------------------------------------------
1 | package Information.Battles.Prediction.Skimulation
2 |
3 | import ProxyBwapi.UnitInfo.UnitInfo
4 |
5 | trait SkimulationUnit {
6 | var skimDistanceToEngage : Double = _
7 | var skimStrength : Double = _
8 | var skimMagic : Double = _
9 | var skimDelay : Double = _
10 | var skimExtension : Double = _
11 | var skimPresence : Double = _
12 | // Only for debug/display purposes
13 | var skimStrengthDisplay : Double = _
14 | var skimPresenceDisplay : Double = _
15 | var skimTarget : Option[UnitInfo] = None
16 | }
17 |
--------------------------------------------------------------------------------
/src/Micro/Coordination/Pushing/UnitLinearGroundPush.scala:
--------------------------------------------------------------------------------
1 | package Micro.Coordination.Pushing
2 |
3 | import Mathematics.Physics.Force
4 | import Mathematics.Points.Pixel
5 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
6 | import Utilities.?
7 |
8 | class UnitLinearGroundPush(val priority: TrafficPriority, val pusher: FriendlyUnitInfo, val destination: Pixel) extends LinearPush {
9 | override protected def source: Pixel = pusher.pixel
10 | override protected val sourceWidth: Double = pusher.unitClass.dimensionMax
11 | override def force(recipient: FriendlyUnitInfo): Option[Force] = ?(recipient == pusher || recipient.flying, None, super.force(recipient))
12 | }
13 |
--------------------------------------------------------------------------------
/src/Information/Battles/Prediction/Simulation/SimulationEventMove.scala:
--------------------------------------------------------------------------------
1 | package Information.Battles.Prediction.Simulation
2 |
3 | import Debugging.Visualizations.Rendering.DrawMap
4 | import Mathematics.Points.Pixel
5 |
6 | final case class SimulationEventMove(sim: Simulacrum, to: Pixel, reason: Option[String] = None) extends SimulationEvent(sim) {
7 |
8 | override def toString: String = f"$frame: ${sim.describe} targeting ${describe(target)} ${describePixel(targetAt)} moves from ${sim.pixel} towards $to ${reason.map(": " + _).getOrElse("")}"
9 |
10 | override def draw(): Unit = {
11 | DrawMap.arrow(from, to, sim.realUnit.player.colorMedium)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/Micro/Targeting/FiltersRequired/TargetFilterVulture.scala:
--------------------------------------------------------------------------------
1 | package Micro.Targeting.FiltersRequired
2 |
3 | import Lifecycle.With
4 | import Micro.Targeting.TargetFilter
5 | import ProxyBwapi.Races.Terran
6 | import ProxyBwapi.UnitInfo.{FriendlyUnitInfo, UnitInfo}
7 | import Utilities.Time.Minutes
8 |
9 | object TargetFilterVulture extends TargetFilter {
10 | private val cutoff = Minutes(4)()
11 | override def appliesTo(actor: FriendlyUnitInfo): Boolean = Terran.Vulture(actor) && With.frame < cutoff
12 | override def legal(actor: FriendlyUnitInfo, target: UnitInfo): Boolean = {
13 | target.unitClass.canAttack || ! target.unitClass.isBuilding
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/Placement/Generation/TileGeneratorProximity.scala:
--------------------------------------------------------------------------------
1 | package Placement.Generation
2 |
3 | import Information.Geography.Types.Zone
4 | import Mathematics.Points.Tile
5 |
6 | import scala.collection.immutable.VectorIterator
7 |
8 | class TileGeneratorProximity(origin: Tile, zone: Zone, maximumDistance: Int = 256) extends TileGenerator {
9 | val tiles : Vector[Tile] = zone.tiles.view.filter(_.tileDistanceFast(origin) < maximumDistance).toVector.sortBy(_.tileDistanceSquared(origin))
10 | val iterator: VectorIterator[Tile] = tiles.iterator
11 |
12 | override def next(): Tile = iterator.next()
13 | override def hasNext: Boolean = iterator.hasNext
14 | }
15 |
--------------------------------------------------------------------------------
/src/Micro/Actions/Basic/Unstick.scala:
--------------------------------------------------------------------------------
1 | package Micro.Actions.Basic
2 |
3 | import Micro.Actions.Action
4 | import Micro.Agency.Commander
5 | import ProxyBwapi.Races.Protoss
6 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
7 |
8 | object Unstick extends Action {
9 |
10 | override def allowed(unit: FriendlyUnitInfo): Boolean = (
11 | unit.canMove
12 | && ! unit.flying
13 | && ! unit.loaded
14 | && ! unit.unitClass.floats
15 | && ! Protoss.Reaver(unit)
16 | && unit.canAttack
17 | && unit.seeminglyStuck
18 | )
19 |
20 | override protected def perform(unit: FriendlyUnitInfo): Unit = {
21 | Commander.stop(unit)
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/Strategery/Strategies/Protoss/PvRStrategies.scala:
--------------------------------------------------------------------------------
1 | package Strategery.Strategies.Protoss
2 |
3 | import Gameplans.Protoss.PvR.{PvR2Gate4Gate, PvRDT}
4 | import Planning.Plans.Plan
5 | import Strategery.Strategies.Strategy
6 | import bwapi.Race
7 |
8 | abstract class PvRStrategy extends Strategy {
9 | override def ourRaces : Seq[Race] = Vector(Race.Protoss)
10 | override def enemyRaces : Seq[Race] = Vector(Race.Unknown)
11 | }
12 |
13 | object PvR2Gate4Gate extends PvRStrategy {
14 | override def gameplan: Option[Plan] = Some(new PvR2Gate4Gate)
15 | }
16 |
17 | object PvRDT extends PvRStrategy {
18 | override def gameplan: Option[Plan] = Some(new PvRDT)
19 | }
--------------------------------------------------------------------------------
/src/Information/Battles/Types/JudgmentModifier.scala:
--------------------------------------------------------------------------------
1 | package Information.Battles.Types
2 |
3 | import Debugging.Visualizations.Colors
4 | import Utilities.?
5 | import bwapi.Color
6 |
7 | case class JudgmentModifier(
8 | var name : String = "Modifier",
9 | var color : Color = Colors.DarkGray,
10 | speedMultiplier : Double = 1,
11 | targetDelta : Double = 0) {
12 |
13 | override def toString: String = f"$name${format("S", 1, speedMultiplier)}${format("T", 0, targetDelta)}"
14 |
15 | private def format(name: String, default: Double, value: Double): String = {
16 | ?(value == default, "", f" $name: ${"%1.2f".format(value)}")
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/Generic/FingerprintExistsBy.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.Generic
2 |
3 | import Information.Fingerprinting.Fingerprint
4 | import Lifecycle.With
5 | import Utilities.UnitFilters.UnitFilter
6 | import Utilities.Time.GameTime
7 |
8 | class FingerprintExistsBy(unitMatcher: UnitFilter, gameTime: GameTime, quantity: Int = 1) extends Fingerprint {
9 | override def investigate: Boolean = With.frame < gameTime() && observed >= quantity
10 | protected def observed: Int = With.units.countEverEnemyP(unitMatcher)
11 | override def reason: String = f"$observed $unitMatcher exist by $gameTime"
12 | override val sticky: Boolean = true
13 | }
14 |
--------------------------------------------------------------------------------
/src/ProxyBwapi/Buildable.scala:
--------------------------------------------------------------------------------
1 | package ProxyBwapi
2 |
3 | import ProxyBwapi.Techs.Tech
4 | import ProxyBwapi.UnitClasses.UnitClass
5 | import ProxyBwapi.Upgrades.Upgrade
6 | import bwapi.Race
7 |
8 | trait Buildable {
9 | def race: Race
10 | def productionFrames(quantity: Int): Int
11 | def mineralCost(quantity: Int): Int
12 | def gasCost(quantity: Int): Int
13 | def supplyProvided: Int
14 | def supplyRequired: Int
15 |
16 | lazy val asUnit : Option[UnitClass] = Option(asInstanceOf[UnitClass])
17 | lazy val asTech : Option[Tech] = Option(asInstanceOf[Tech])
18 | lazy val asUpgrade : Option[Upgrade] = Option(asInstanceOf[Upgrade])
19 | }
20 |
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/ZergStrategies/Fingerprint2HatchGas.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.ZergStrategies
2 |
3 | import Information.Fingerprinting.Generic.{FingerprintAnd, FingerprintGasCompleteBy, FingerprintNot, FingerprintOr}
4 | import Information.Fingerprinting.ZergStrategies.ZergTimings.ThreeHatchGasCompleteBy
5 | import Lifecycle.With
6 | import Utilities.Time.Seconds
7 |
8 | class Fingerprint2HatchGas extends FingerprintAnd(
9 | new FingerprintNot(With.fingerprints.oneHatchGas),
10 | new FingerprintOr(
11 | new FingerprintGasCompleteBy(ThreeHatchGasCompleteBy - Seconds(5)),
12 | With.fingerprints.tenHatchPoolGas,
13 | With.fingerprints.twelveHatchPoolGas))
--------------------------------------------------------------------------------
/src/Mathematics/Points/Point.scala:
--------------------------------------------------------------------------------
1 | package Mathematics.Points
2 |
3 | import Mathematics.Maff
4 |
5 | case class Point(argX: Int, argY: Int) extends AbstractPoint(argX, argY) {
6 | @inline final def degreesTo(other: Point): Double = {
7 | radiansTo(other) * Maff.x2PiInv360
8 | }
9 | @inline final def radiansTo(other: Point): Double = {
10 | Maff.fastAtan2(other.y - y, other.x - x)
11 | }
12 |
13 | @inline def radiansToSlow(other: Pixel): Double = {
14 | Math.atan2(other.y - y, other.x - x)
15 | }
16 | @inline final def distanceSquared(other: Point): Double = {
17 | val dx = x - other.x
18 | val dy = y - other.y
19 | dx * dx + dy * dy
20 | }
21 | }
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/ZergStrategies/Fingerprint12Hatch11Pool.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.ZergStrategies
2 |
3 | import Information.Fingerprinting.Generic.{FingerprintAnd, FingerprintCompleteBy, FingerprintNot}
4 | import Information.Fingerprinting.ZergStrategies.ZergTimings.TwelveHatch13Hatch12Pool_PoolCompleteBy
5 | import Lifecycle.With
6 | import ProxyBwapi.Races.Zerg
7 | import Utilities.Time.Seconds
8 |
9 | class Fingerprint12Hatch11Pool extends FingerprintAnd(
10 | With.fingerprints.twelveHatch,
11 | new FingerprintNot(With.fingerprints.twelveHatchHatch),
12 | new FingerprintCompleteBy(Zerg.SpawningPool, TwelveHatch13Hatch12Pool_PoolCompleteBy - Seconds(3)))
13 |
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/ZergStrategies/Fingerprint2HatchMain.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.ZergStrategies
2 |
3 | import Information.Fingerprinting.Fingerprint
4 | import Lifecycle.With
5 | import Utilities.UnitFilters.IsHatchlike
6 | import ProxyBwapi.UnitInfo.UnitInfo
7 |
8 | class Fingerprint2HatchMain extends Fingerprint {
9 | override protected def investigate: Boolean = {
10 | hatcheries.forall(_.base.exists(_.isMain)) && hatcheries.size > 1
11 | }
12 |
13 | override def reason: String = hatcheries.mkString(", ")
14 |
15 | override val sticky = true
16 |
17 | protected def hatcheries: Iterable[UnitInfo] = With.units.enemy.filter(IsHatchlike)
18 | }
19 |
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/ZergStrategies/Fingerprint3HatchHydra.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.ZergStrategies
2 |
3 | import Information.Fingerprinting.Generic.{FingerprintAnd, FingerprintArrivesBy, FingerprintCompleteBy, FingerprintOr}
4 | import Lifecycle.With
5 | import ProxyBwapi.Races.Zerg
6 | import Utilities.Time.GameTime
7 |
8 | class Fingerprint3HatchHydra extends FingerprintAnd(
9 | With.fingerprints.threeHatchGas,
10 | new FingerprintOr(
11 | new FingerprintCompleteBy(Zerg.HydraliskDen, GameTime(5, 0)), // Earliest observed: 4:37
12 | new FingerprintCompleteBy(Zerg.Hydralisk, GameTime(5, 18)),
13 | new FingerprintArrivesBy(Zerg.Hydralisk, GameTime(5, 48))))
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/TerranStrategies/Fingerprint1RaxFE.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.TerranStrategies
2 |
3 | import Information.Fingerprinting.Generic.{FingerprintAnd, FingerprintCompleteBy, FingerprintOr}
4 | import ProxyBwapi.Races.Terran
5 | import Utilities.Time.GameTime
6 |
7 | class Fingerprint1RaxFE extends FingerprintAnd(
8 | new FingerprintOr(
9 | new FingerprintCompleteBy(Terran.Barracks, GameTime(3, 20)),
10 | new FingerprintCompleteBy(Terran.Marine, GameTime(3, 35)),
11 | new FingerprintCompleteBy(Terran.Bunker, GameTime(3, 39))),
12 | new FingerprintCompleteBy(Terran.CommandCenter, GameTime(4, 30), 2)) {
13 | override val sticky = true
14 | }
15 |
--------------------------------------------------------------------------------
/src/Macro/Scheduling/Scheduler.scala:
--------------------------------------------------------------------------------
1 | package Macro.Scheduling
2 |
3 | import Macro.Requests.{RequestAutosupply, RequestBuildable}
4 |
5 | import scala.collection.mutable
6 |
7 | class Scheduler {
8 | private val _requests = new mutable.ArrayBuffer[ScheduleItem]
9 |
10 | def reset(): Unit = {
11 | _requests.clear()
12 | }
13 |
14 | def request(requester: Any, theRequest: RequestBuildable): Unit = {
15 | if (theRequest.tech.isDefined || theRequest.quantity > 0 || theRequest == RequestAutosupply) {
16 | _requests += ScheduleItem(requester, theRequest)
17 | }
18 | }
19 |
20 | def requests: Vector[ScheduleItem] = {
21 | _requests.toVector
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/Performance/Cache.scala:
--------------------------------------------------------------------------------
1 | package Performance
2 |
3 | import Lifecycle.With
4 |
5 | class Cache[T](getValue: () => T, refreshPeriod: Int = 1) {
6 | private var nextUpdateFrame: Int = 0
7 | private var lastValue: T = _
8 | private val defaultValue: T = lastValue
9 |
10 | @inline final def apply(): T = {
11 | if (With.frame >= nextUpdateFrame) {
12 | nextUpdateFrame = With.frame + refreshPeriod
13 | lastValue = getValue()
14 | }
15 | lastValue
16 | }
17 |
18 | @inline final def invalidate(): Unit = {
19 | nextUpdateFrame = With.frame
20 | lastValue = defaultValue
21 | }
22 |
23 | override def toString: String = apply().toString
24 | }
25 |
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/ZergStrategies/Fingerprint3HatchMuta.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.ZergStrategies
2 |
3 | import Information.Fingerprinting.Generic.{FingerprintAnd, FingerprintCompleteByArrivesBy, FingerprintNot, FingerprintOr}
4 | import Lifecycle.With
5 | import ProxyBwapi.Races.Zerg
6 | import Utilities.Time.GameTime
7 |
8 | class Fingerprint3HatchMuta extends FingerprintAnd(
9 |
10 | new FingerprintNot(
11 | With.fingerprints.oneHatchMuta,
12 | With.fingerprints.twoHatchMuta),
13 |
14 | new FingerprintOr(
15 | new FingerprintCompleteByArrivesBy(Zerg.Spire, GameTime(7, 35)),
16 | new FingerprintCompleteByArrivesBy(Zerg.Mutalisk, GameTime(8, 0))))
17 |
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/ZergStrategies/Fingerprint9PoolHatch.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.ZergStrategies
2 |
3 | import Information.Fingerprinting.Generic._
4 | import Information.Fingerprinting.ZergStrategies.ZergTimings.NinePool13Hatch_HatchCompleteBy
5 | import Lifecycle.With
6 | import Utilities.UnitFilters.IsHatchlike
7 | import Utilities.Time.{GameTime, Seconds}
8 |
9 | class Fingerprint9PoolHatch extends FingerprintAnd(
10 | With.fingerprints.ninePool,
11 | new FingerprintNot(With.fingerprints.ninePoolGas),
12 | new FingerprintOr(
13 | new FingerprintCompleteBy(IsHatchlike, NinePool13Hatch_HatchCompleteBy + Seconds(5)),
14 | new FingerprintGasEmptyUntil(GameTime(1, 56))))
--------------------------------------------------------------------------------
/src/Micro/Actions/Scouting/Scout.scala:
--------------------------------------------------------------------------------
1 | package Micro.Actions.Scouting
2 |
3 | import Micro.Actions.Action
4 | import Micro.Agency.Commander
5 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
6 |
7 | object Scout extends Action {
8 |
9 | override def allowed(unit: FriendlyUnitInfo): Boolean = unit.agent.isScout
10 |
11 | override protected def perform(unit: FriendlyUnitInfo): Unit = {
12 | DroneWarfare(unit)
13 | Harass4PoolWorkers(unit)
14 | SabotageProxy(unit)
15 | KnockKnock(unit)
16 | PreserveScout(unit)
17 | AttackBuilder(unit)
18 | BlockConstruction(unit)
19 | Search(unit)
20 | SearchWhenBored(unit)
21 | Commander.move(unit)
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/Utilities/Time/FrameCount.scala:
--------------------------------------------------------------------------------
1 | package Utilities.Time
2 |
3 | abstract class FrameCount(frames: Int) {
4 |
5 | def apply(): Int = frames
6 | final def totalSeconds: Int = frames / 24
7 | final def seconds: Int = totalSeconds % 60
8 | final def minutes: Int = totalSeconds / 60
9 |
10 | final def +(other: FrameCount) : FrameCount = Frames(this() + other())
11 | final def -(other: FrameCount) : FrameCount = Frames(this() - other())
12 | final def +(other: Int) : FrameCount = Frames(this() + other)
13 | final def -(other: Int) : FrameCount = Frames(this() - other)
14 |
15 | final override def toString: String = minutes + ":" + "%02d".format(seconds)
16 | }
17 |
18 |
--------------------------------------------------------------------------------
/src/Information/Battles/Prediction/CPCount.scala:
--------------------------------------------------------------------------------
1 | package Information.Battles.Prediction
2 |
3 | import Information.Battles.Prediction.Simulation.Simulacrum
4 | import ProxyBwapi.UnitInfo.UnitInfo
5 |
6 | import scala.collection.mutable.ArrayBuffer
7 |
8 | object CPCount {
9 | @inline def apply(units: ArrayBuffer[UnitInfo], extract: Simulacrum => Double): Double = {
10 | var output = 0.0
11 | val length = units.length
12 | var i = 0
13 | while (i < length) {
14 | val simulacrum = units(i).simulacrum
15 | if (simulacrum.shouldScoreIfOurs || simulacrum.isEnemy) {
16 | output += extract(simulacrum)
17 | }
18 | i += 1
19 | }
20 | output
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/TerranStrategies/Fingerprint2PortWraith.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.TerranStrategies
2 |
3 | import Information.Fingerprinting.Generic._
4 | import ProxyBwapi.Races.Terran
5 | import Utilities.Time.GameTime
6 |
7 | class Fingerprint2PortWraith extends FingerprintOr(
8 | new FingerprintCompleteBy(Terran.Starport, GameTime(5, 15), 2),
9 | new FingerprintCompleteBy(Terran.Wraith, GameTime(5, 30), 2),
10 | new FingerprintCompleteBy(Terran.Wraith, GameTime(6, 10), 4),
11 | new FingerprintArrivesBy(Terran.Wraith, GameTime(5, 55), 2),
12 | new FingerprintArrivesBy(Terran.Wraith, GameTime(6, 35), 4)) {
13 |
14 | override val sticky = true
15 | }
16 |
--------------------------------------------------------------------------------
/src/Macro/Actions/BuildOnce.scala:
--------------------------------------------------------------------------------
1 | package Macro.Actions
2 |
3 | import Lifecycle.With
4 | import Macro.Requests.{RequestBuildable, RequestUnit}
5 |
6 | object BuildOnce {
7 | def apply(requester: Any, request: RequestBuildable): Unit = {
8 | With.scheduler.request(
9 | requester,
10 | if (request.unit.forall(_.isBuilding) || request.quantity <= 0) request else {
11 | val unit = request.unit.get
12 | val quantityLost = Math.max(0, With.productionHistory.doneAllTime(unit) - With.macroCounts.oursComplete(unit))
13 | val quantityToRequest = request.quantity - quantityLost
14 | RequestUnit(unit, quantityToRequest)
15 | })
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/Macro/Actions/SneakyCitadel.scala:
--------------------------------------------------------------------------------
1 | package Macro.Actions
2 |
3 | import Lifecycle.With
4 | import ProxyBwapi.Races.Protoss
5 | import Utilities.Time.Seconds
6 |
7 | object SneakyCitadel extends MacroActions {
8 | def apply(): Unit = {
9 | if (scoutCleared) {
10 | get(Protoss.CitadelOfAdun)
11 | cancel(Protoss.AirDamage)
12 | } else if (units(Protoss.CitadelOfAdun) == 0) {
13 | if (With.units.ours.find(_.upgradeProducing.contains(Protoss.AirDamage)).exists(_.remainingUpgradeFrames < Seconds(5)())) {
14 | cancel(Protoss.AirDamage)
15 | } else if ( ! upgradeStarted(Protoss.DragoonRange)) {
16 | get(Protoss.AirDamage)
17 | }
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/Performance/Timer.scala:
--------------------------------------------------------------------------------
1 | package Performance
2 |
3 | import Lifecycle.With
4 |
5 | class Timer(duration: Long = With.performance.msBeforeTarget) {
6 | private def now = With.performance.systemMillis
7 | val start: Long = now
8 | def elapsed: Long = if (With.performance.frameHitBreakpoint) 0 else now - start
9 | def remaining: Long = remainingUntil(start + duration)
10 | def remainingUntil(milliseconds: Long): Long =
11 | if (With.performance.frameHitBreakpoint)
12 | With.configuration.frameTargetMs
13 | else
14 | milliseconds - now
15 | def redLight : Boolean = remaining <= 0 && With.configuration.enablePerformancePauses
16 | def greenLight : Boolean = ! redLight
17 | }
18 |
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/Generic/FingerprintHasExpanded.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.Generic
2 |
3 | import Information.Fingerprinting.Fingerprint
4 | import Lifecycle.With
5 | import ProxyBwapi.Races.Terran
6 | import Utilities.Time.Forever
7 |
8 | class FingerprintHasExpanded(by: Int = Forever()) extends Fingerprint {
9 | override val sticky = true
10 | override def investigate: Boolean = With.frame < by && With.enemies.exists(e => {
11 | var output = e.bases.size > 1
12 | output ||= With.units.enemy.exists(u => Terran.CommandCenter(u) && u.player == e && ! u.base.exists(_.townHallTile == u.tileTopLeft))
13 | output ||= e.bases.exists( ! _.isMain)
14 | output
15 | })
16 | }
17 |
--------------------------------------------------------------------------------
/src/Information/Grids/Vision/GridLastSeen.scala:
--------------------------------------------------------------------------------
1 | package Information.Grids.Vision
2 |
3 | import Information.Grids.ArrayTypes.AbstractGridFramestamp
4 | import Lifecycle.With
5 | import Mathematics.Points.Tile
6 |
7 | class GridLastSeen extends AbstractGridFramestamp {
8 |
9 | def hasSeen(tile: Tile): Boolean = get(tile) > 0
10 | def hasSeen(i: Int): Boolean = get(i) > 0
11 |
12 | override protected def updateCells() {
13 | var x = 0
14 | while (x < With.mapTileWidth) {
15 | var y = 0
16 | while (y < With.mapTileHeight) {
17 | if (With.game.isVisible(x, y)) {
18 | stamp(x, y)
19 | }
20 | y += 1
21 | }
22 | x += 1
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/src/Micro/Actions/Scouting/PreserveScout.scala:
--------------------------------------------------------------------------------
1 | package Micro.Actions.Scouting
2 |
3 | import Micro.Actions.Action
4 | import Micro.Actions.Combat.Maneuvering.Retreat
5 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
6 |
7 | object PreserveScout extends Action {
8 |
9 | override def allowed(unit: FriendlyUnitInfo): Boolean = (
10 | (unit.matchups.framesOfSafety <= 24
11 | && unit.matchups.threats.exists( ! _.unitClass.isWorker))
12 | || unit.totalHealth < 6
13 | )
14 |
15 | override protected def perform(unit: FriendlyUnitInfo): Unit = {
16 | // FindBuildings can usually safely path around threats
17 | SearchWhenBored.delegate(unit)
18 | Retreat.delegate(unit)
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/ZergStrategies/Fingerprint12Pool.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.ZergStrategies
2 |
3 | import Information.Fingerprinting.Generic.{FingerprintAnd, FingerprintCompleteBy, FingerprintNot}
4 | import Information.Fingerprinting.ZergStrategies.ZergTimings.Latest_TwelvePool_PoolCompleteBy
5 | import Lifecycle.With
6 | import ProxyBwapi.Races.Zerg
7 |
8 | class Fingerprint12Pool extends FingerprintAnd(
9 | new FingerprintNot(With.fingerprints.fourPool),
10 | new FingerprintNot(With.fingerprints.ninePool),
11 | new FingerprintNot(With.fingerprints.overpool),
12 | new FingerprintCompleteBy(Zerg.SpawningPool, Latest_TwelvePool_PoolCompleteBy) // Going past 10 seconds intersects10h9p
13 | )
14 |
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/ZergStrategies/Fingerprint4Pool.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.ZergStrategies
2 |
3 | import Information.Fingerprinting.Generic.{FingerprintArrivesBy, FingerprintCompleteBy, FingerprintOr}
4 | import Information.Fingerprinting.ZergStrategies.ZergTimings.{Latest_FourPool_PoolCompleteBy, Latest_FourPool_ZerglingArrivesBy, Latest_FourPool_ZerglingCompleteBy}
5 | import ProxyBwapi.Races.Zerg
6 |
7 | class Fingerprint4Pool extends FingerprintOr(
8 | new FingerprintCompleteBy(Zerg.SpawningPool, Latest_FourPool_PoolCompleteBy),
9 | new FingerprintArrivesBy(Zerg.Zergling, Latest_FourPool_ZerglingArrivesBy),
10 | new FingerprintCompleteBy(Zerg.Zergling, Latest_FourPool_ZerglingCompleteBy))
--------------------------------------------------------------------------------
/src/Micro/Actions/Combat/Spells/WraithUncloak.scala:
--------------------------------------------------------------------------------
1 | package Micro.Actions.Combat.Spells
2 |
3 | import Lifecycle.With
4 | import Micro.Actions.Action
5 | import Micro.Agency.Commander
6 | import ProxyBwapi.Races.Terran
7 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
8 |
9 | object WraithUncloak extends Action {
10 |
11 | override def allowed(unit: FriendlyUnitInfo): Boolean = (
12 | unit.is(Terran.Wraith)
13 | && unit.cloaked
14 | && ! unit.matchups.enemies.exists(_.unitClass.attacksAir)
15 | && With.framesSince(unit.agent.lastCloak) > 24 * 10
16 | )
17 |
18 | override protected def perform(unit: FriendlyUnitInfo): Unit = {
19 | Commander.decloak(unit, Terran.GhostCloak)
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/Micro/Actions/Terran/GetRepairedBuilding.scala:
--------------------------------------------------------------------------------
1 | package Micro.Actions.Terran
2 |
3 | import Micro.Actions.Action
4 | import ProxyBwapi.Races.Terran
5 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
6 | import Utilities.?
7 |
8 | object GetRepairedBuilding extends Action {
9 |
10 | override def allowed(unit: FriendlyUnitInfo): Boolean = (
11 | unit.unitClass.isTerran
12 | && unit.unitClass.isBuilding
13 | && unit.complete
14 | && ?(
15 | unit.isAny(Terran.Bunker, Terran.MissileTurret),
16 | unit.hitPoints < unit.unitClass.maxHitPoints,
17 | unit.hitPoints * 2 < unit.unitClass.maxHitPoints))
18 |
19 | override def perform(unit: FriendlyUnitInfo): Unit = {
20 |
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/Debugging/Visualizations/Views/DebugView.scala:
--------------------------------------------------------------------------------
1 | package Debugging.Visualizations.Views
2 |
3 | import Debugging.ToString
4 | import Lifecycle.With
5 |
6 | abstract class DebugView {
7 |
8 | lazy val name: String = ToString(this).replace("Show", "")
9 |
10 | def renderScreen(): Unit = {}
11 | def renderMap(): Unit = {}
12 |
13 | def inUse: Boolean = (
14 | With.visualization.enabled
15 | && (With.visualization.map || With.visualization.screen)
16 | && With.visualization.views.contains(this)
17 | )
18 |
19 | def mapInUse: Boolean = {
20 | inUse && With.visualization.map
21 | }
22 |
23 | def screenInUse: Boolean = {
24 | inUse && With.visualization.screen
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/Information/Battles/Prediction/Simulation/BehaviorGather.scala:
--------------------------------------------------------------------------------
1 | package Information.Battles.Prediction.Simulation
2 |
3 | import Mathematics.Maff
4 | import Utilities.Time.Forever
5 |
6 | object BehaviorGather extends SimulacrumBehavior {
7 | val fighting: Boolean = false
8 | override def act(simulacrum: Simulacrum): Unit = {
9 | val base = Maff.minBy(simulacrum.player.bases)(b => simulacrum.pixel.walkablePixel.groundPixels(b.heart))
10 | base.foreach(b => {
11 | val to = b.heart.center
12 | if (simulacrum.pixelDistanceCenter(to) > 16) {
13 | simulacrum.move(to, Some("Gather"))
14 | } else {
15 | simulacrum.sleep(Forever(), Some("Gathering"))
16 | }
17 | })
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/Micro/Actions/Combat/Tactics/Potshot.scala:
--------------------------------------------------------------------------------
1 | package Micro.Actions.Combat.Tactics
2 |
3 | import Micro.Actions.Action
4 | import Micro.Targeting.Target
5 | import Micro.Agency.Commander
6 | import Micro.Targeting.FiltersSituational.TargetFilterPotshot
7 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
8 |
9 | object Potshot extends Action {
10 |
11 | override def allowed(unit: FriendlyUnitInfo): Boolean = (
12 | (unit.tile.enemyVulnerabilityGround > 0 || unit.canAttackAir)
13 | && unit.tile.enemyRangeAgainst(unit) > 0
14 | && unit.readyForAttackOrder)
15 |
16 | override def perform(unit: FriendlyUnitInfo): Unit = {
17 | Target.choose(unit, TargetFilterPotshot)
18 | Commander.attack(unit)
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/Debugging/Visualizations/Views/Battles/ShowTeams.scala:
--------------------------------------------------------------------------------
1 | package Debugging.Visualizations.Views.Battles
2 |
3 | import Debugging.Visualizations.Colors
4 | import Debugging.Visualizations.Rendering.DrawMap
5 | import Debugging.Visualizations.Views.DebugView
6 |
7 | object ShowTeams extends DebugView {
8 |
9 | override def renderMap(): Unit = {
10 | ShowBattles.localBattle.foreach(battle => {
11 | val team = battle.us
12 | val bright = Colors.BrightTeal
13 | val medium = Colors.MediumTeal
14 | val dark = Colors.DarkTeal
15 | DrawMap.circle(team.centroidAir, 16, bright)
16 | DrawMap.box(team.attackCentroidKey.subtract(16, 16), team.attackCentroidKey.add(16, 16), bright)
17 | })
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/Tactic/Tactics/TacticMeldDarchons.scala:
--------------------------------------------------------------------------------
1 | package Tactic.Tactics
2 |
3 | import Lifecycle.With
4 | import Mathematics.Maff
5 | import ProxyBwapi.Races.Protoss
6 |
7 | class TacticMeldDarchons extends Tactic {
8 |
9 | lock.matcher = Protoss.DarkTemplar
10 |
11 | def launch(): Unit = {
12 | lock.release() // Ditch units that are already Dark Archons
13 | if (With.blackboard.makeDarkArchons()) {
14 | lock.acquire()
15 | val partyCentral = Maff.minBy(With.geography.ourBases)(_.groundPixels(With.scouting.ourMuscleOrigin)).map(_.heart).getOrElse(With.geography.home).center
16 | units.foreach(_.intend(this)
17 | .setShouldMeld(true)
18 | .setTerminus(partyCentral))
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/Macro/Allocation/Priorities.scala:
--------------------------------------------------------------------------------
1 | package Macro.Allocation
2 |
3 | import Lifecycle.With
4 |
5 | import scala.collection.mutable
6 |
7 | class Priorities {
8 | private var _lastResetFrame: Int = -1
9 | private var _nextPriority: Int = 0
10 |
11 | val frameDelays: mutable.Queue[Int] = new mutable.Queue[Int]
12 |
13 | def lastResetFrame: Int = _lastResetFrame
14 |
15 | def nextPriority(): Int = {
16 | _nextPriority += 1
17 | _nextPriority - 1
18 | }
19 |
20 | def update() {
21 | frameDelays.enqueue(With.framesSince(_lastResetFrame))
22 | while(frameDelays.sum > 24 * 10) {
23 | frameDelays.dequeue()
24 | }
25 | _lastResetFrame = With.frame
26 | _nextPriority = 0
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Performance/Tasks/StateTasks.scala:
--------------------------------------------------------------------------------
1 | package Performance.Tasks
2 |
3 | import scala.collection.mutable
4 |
5 | class StateTasks {
6 | private val tasks = new mutable.HashMap[Class[_], DummyTask]()
7 | def get(state: Any): DummyTask = {
8 | val stateClass = state.getClass
9 | if ( ! tasks.contains(stateClass)) {
10 | tasks(stateClass) = new DummyTask(stateClass)
11 | }
12 | tasks(stateClass)
13 | }
14 |
15 | def safeToRun(state: Any, budgetMs: Long): Boolean = {
16 | get(state).safeToRun(budgetMs)
17 | }
18 |
19 | def run(state: Any, runFunction: () => Unit, budgetMs: Long): Unit = {
20 | val task = get(state)
21 | task.runFunction = runFunction
22 | task.run(budgetMs)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/ZergStrategies/Fingerprint3HatchGas.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.ZergStrategies
2 |
3 | import Information.Fingerprinting.Generic.{FingerprintAnd, FingerprintGasCompleteBy, FingerprintNot, FingerprintOr}
4 | import Information.Fingerprinting.ZergStrategies.ZergTimings.ThreeHatchGasCompleteBy
5 | import Lifecycle.With
6 | import Utilities.Time.Seconds
7 |
8 | class Fingerprint3HatchGas extends FingerprintAnd(
9 | new FingerprintNot(
10 | With.fingerprints.oneHatchGas,
11 | With.fingerprints.twoHatchGas),
12 | new FingerprintOr(
13 | With.fingerprints.twelveHatchHatch,
14 | With.fingerprints.twelveHatchPoolHatch,
15 | new FingerprintGasCompleteBy(ThreeHatchGasCompleteBy + Seconds(25))))
16 |
--------------------------------------------------------------------------------
/src/ProxyBwapi/Readme.md:
--------------------------------------------------------------------------------
1 | # ProxyBwapi
2 |
3 | ## Motivation
4 |
5 | BWAPI, as made accessible via BWMirror, has a few limitations:
6 |
7 | * BWAPI only exposes currently available information. Units in the fog of war are inaccessible
8 | * Native BWAPI calls through BWMirror have a substantial overhead. Even a simple call like Game.getFrameCount quickly becomes expensive
9 | * The raw BWAPI type APIs can be confusing and are easily misused (for example, getPixel (unit center) vs getTile (unit corner))
10 | * The raw BWAPI types aren't extensible
11 |
12 | For those reasons, the rest of PurpleWave interacts with ProxyBwapi. ProxyBwapi provides a faster, safer interface for interacting with the game state, and tracks information on units in the fog of war.
13 |
14 |
--------------------------------------------------------------------------------
/src/Information/Fingerprinting/Generic/FingerprintGasEmptyUntil.scala:
--------------------------------------------------------------------------------
1 | package Information.Fingerprinting.Generic
2 |
3 | import Information.Fingerprinting.Fingerprint
4 | import Lifecycle.With
5 | import ProxyBwapi.UnitInfo.UnitInfo
6 | import Utilities.Time.FrameCount
7 |
8 | class FingerprintGasEmptyUntil(time: FrameCount) extends Fingerprint {
9 | override protected def investigate: Boolean = matchingGas.isEmpty
10 | override def sticky: Boolean = With.scouting.enemyMain.isDefined && With.frame >= time()
11 | override def reason: String = f"Gasses: [${matchingGas.mkString(", ")}]"
12 | protected def matchingGas: Iterable[UnitInfo] = With.scouting.enemyMain.toVector.flatMap(_.gas.filter(gas => gas.player.isEnemy && gas.lastSeen < time()))
13 | }
14 |
--------------------------------------------------------------------------------
/src/Information/Geography/NeoGeo/MapIdentifier.scala:
--------------------------------------------------------------------------------
1 | package Information.Geography.NeoGeo
2 |
3 | import Mathematics.Maff
4 | import Mathematics.Points.{Pixel, Points}
5 |
6 | object MapIdentifier {
7 | def apply(mapString: String): String = {
8 | mapString.toLowerCase
9 | .replaceAll(".scm", "")
10 | .replaceAll(".scx", "")
11 | .replaceAll("kespa", "")
12 | .replaceAll("iccup", "")
13 | .replaceAll("neo", "")
14 | .replaceAll("new", "")
15 | .replaceAll("[^a-z]", "")
16 | }
17 |
18 | def clock(pixel: Pixel): String = {
19 | val output = Math.round(Maff.normalize0To2Pi(Points.middle.radiansTo(pixel)) * 6 / Math.PI).toInt.toString
20 | if (output == "0") "12" else output
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/configs/launch4jPurpleSimViz.xml:
--------------------------------------------------------------------------------
1 |
2 | false
3 | gui
4 |
5 | C:\p\pw\out\artifacts\PurpleSimViz.jar
6 | C:\p\pw\out\artifacts\PurpleSimViz.exe
7 |
8 |
9 | Debugging.PurpleSimViz
10 |
11 |
12 |
13 | false
14 | 1.8.0
15 | preferJre
16 | 64/32
17 |
18 | false
19 | false
20 |
21 |
--------------------------------------------------------------------------------
/src/Gameplans/Terran/TvE/BunkerRush.scala:
--------------------------------------------------------------------------------
1 | package Gameplans.Terran.TvE
2 |
3 | import Lifecycle.With
4 | import Macro.Actions.MacroActions
5 | import Placement.Access.PlaceLabels.DefendHall
6 | import Placement.Access.PlacementQuery
7 | import ProxyBwapi.Races.{Protoss, Terran}
8 | import Utilities.UnitFilters.IsWarrior
9 |
10 | object BunkerRush extends MacroActions {
11 | def apply(): Unit = {
12 | With.scouting.enemyNatural
13 | .filter(_.townHall.isDefined)
14 | .foreach(natural => {
15 | if (enemies(IsWarrior, Protoss.PhotonCannon) == 0) {
16 | attack()
17 | get(1, Terran.Bunker, new PlacementQuery(Terran.Bunker).requireBase(natural).preferLabelYes(DefendHall))
18 | }
19 | })
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/Macro/Actions/PumpShuttleAndReavers.scala:
--------------------------------------------------------------------------------
1 | package Macro.Actions
2 |
3 | import ProxyBwapi.Races.Protoss
4 |
5 | object PumpShuttleAndReavers extends MacroActions {
6 | def apply(reavers: Int = 50, shuttleFirst: Boolean = true): Unit = {
7 | if (shuttleFirst && ! haveComplete(Protoss.RoboticsSupportBay)) {
8 | once(Protoss.Shuttle)
9 | }
10 | (0 to reavers).foreach(i => {
11 | pump(Protoss.Reaver, i)
12 | pump(Protoss.Shuttle, (i + 1) / 2)
13 | })
14 | //pumpRatio(Protoss.Shuttle, 0, reavers / 2, Seq(Friendly(Protoss.Reaver, 0.5)))
15 | //pump(Protoss.Reaver, reavers)
16 | //pumpRatio(Protoss.Shuttle, 0, (reavers + 1) / 2, Seq(Flat(0.5), Friendly(Protoss.Reaver, 0.5)), round = Rounding.Down)
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/configs/PurpleWaveBASIL.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "human" : false,
3 | "ladder" : true,
4 | "livestream" : false,
5 | "tournament" : false,
6 | "roundrobin" : false,
7 | "elimination" : false,
8 | "pretraining" : false,
9 | "debugging" : false,
10 | "debugginglive" : false,
11 | "logstd" : false,
12 | "multiCPU" : false,
13 | "framemstarget" : 42,
14 | "framemslimit" : 60,
15 | "comments" : "BASIL does not enforce per-frame limits, but does cap games at 30 minutes. We are memory-capped which means a small framebuffer, but without per-frame limits this doesn't matter much. Here we explicitly target 42ms (real-time) speed. BASIL promises only one CPU per bot, though the bot observes 8 in practice."
16 | }
--------------------------------------------------------------------------------
/src/Information/Battles/Types/GroupCentroid.scala:
--------------------------------------------------------------------------------
1 | package Information.Battles.Types
2 |
3 | import Mathematics.Points.Pixel
4 | import Mathematics.Maff
5 | import ProxyBwapi.UnitInfo.UnitInfo
6 |
7 | object GroupCentroid {
8 | def air(units: Iterable[UnitInfo], extract: UnitInfo => Pixel): Pixel = Maff.centroid(units.view.map(extract))
9 | def ground(units: Iterable[UnitInfo], extract: UnitInfo => Pixel): Pixel = {
10 | val groundedUnits = Maff.orElse(units.view.filterNot(_.airborne), units.view.filterNot(_.flying))
11 | if (groundedUnits.isEmpty) return air(units, extract).walkablePixel
12 | val center = Maff.centroid(groundedUnits.map(extract))
13 | groundedUnits.map(extract).minBy(_.pixelDistanceSquared(center)).walkablePixel
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/ProxyBwapi/UnitTracking/IndexedSet.scala:
--------------------------------------------------------------------------------
1 | package ProxyBwapi.UnitTracking
2 |
3 | import scala.reflect.ClassTag
4 |
5 | final class IndexedSet[T: ClassTag] extends IndexedSeq[T] {
6 | private var _set: Set[T] = Set.empty
7 | private var _seq: IndexedSeq[T] = IndexedSeq.empty
8 | private def this(set: Set[T], seq: IndexedSeq[T]) {
9 | this
10 | _set = set
11 | _seq = seq
12 | }
13 | def this(other: Iterable[T]) {
14 | this
15 | _seq = other.toIndexedSeq
16 | _set = _seq.toSet
17 | }
18 |
19 | override def length: Int = _seq.length
20 | override def apply(idx: Int): T = _seq(idx)
21 | override def contains[Supertype >: T](elem: Supertype): Boolean = elem.isInstanceOf[T] && _set.contains(elem.asInstanceOf[T])
22 | }
23 |
--------------------------------------------------------------------------------
/src/Information/Battles/ProcessingStates/BattleProcessMatchupAnalysis.scala:
--------------------------------------------------------------------------------
1 | package Information.Battles.ProcessingStates
2 |
3 | import Lifecycle.With
4 | import ProxyBwapi.UnitInfo.UnitInfo
5 |
6 | import scala.collection.mutable
7 |
8 | class BattleProcessMatchupAnalysis extends BattleProcessState {
9 |
10 | lazy val units = new mutable.Queue[UnitInfo]
11 | units ++= With.battles.nextBattlesLocal.view.flatMap(_.teams.view.flatMap(_.units))
12 |
13 | override def step(): Unit = {
14 | if (units.isEmpty) {
15 | transitionTo(new BattleProcessComplete)
16 | return
17 | }
18 |
19 | val nextUnit = units.dequeue()
20 |
21 | // TODO: Create matchup analyses here so it doesn't clog up expectations of agency duration
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/Micro/Actions/Basic/Bunk.scala:
--------------------------------------------------------------------------------
1 | package Micro.Actions.Basic
2 |
3 | import Micro.Actions.Action
4 | import Micro.Agency.Commander
5 | import ProxyBwapi.Races.Terran
6 | import ProxyBwapi.UnitInfo.FriendlyUnitInfo
7 |
8 | object Bunk extends Action {
9 |
10 | override def allowed(unit: FriendlyUnitInfo): Boolean = {
11 | unit.agent.toBoard.exists(Terran.Bunker)
12 | }
13 |
14 | override def perform(unit: FriendlyUnitInfo) {
15 | if (unit.loaded) {
16 | if (unit.transport == unit.agent.toBoard) {
17 | Commander.doNothing(unit)
18 | } else {
19 | unit.transport.foreach(Commander.unload(_, unit))
20 | }
21 | } else {
22 | Commander.rightClick(unit, unit.agent.toBoard.get)
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/Strategery/Strategies/Protoss/ProtossFPM.scala:
--------------------------------------------------------------------------------
1 | package Strategery.Strategies.Protoss
2 |
3 | import Gameplans.Protoss.FPM.PvPFPM
4 | import Planning.Plans.Plan
5 | import Strategery.Strategies.Strategy
6 | import bwapi.Race
7 |
8 | class AbstractProtossFPM extends Strategy {
9 | setOurRace(Race.Protoss)
10 | setMoneyMap(true)
11 | }
12 |
13 | object PvTFPM extends AbstractProtossFPM {
14 | setEnemyRace(Race.Terran)
15 | }
16 |
17 | object PvPFPM extends AbstractProtossFPM {
18 | override def gameplan: Option[Plan] = Some(new PvPFPM)
19 | setEnemyRace(Race.Protoss)
20 | }
21 |
22 | object PvZFPM extends AbstractProtossFPM {
23 | setEnemyRace(Race.Zerg)
24 | }
25 |
26 | object PvRFPM extends AbstractProtossFPM {
27 | setEnemyRace(Race.Unknown)
28 | }
--------------------------------------------------------------------------------
/src/Information/Grids/Movement/GridWalkableTerrain.scala:
--------------------------------------------------------------------------------
1 | package Information.Grids.Movement
2 |
3 | import Information.Grids.ArrayTypes.AbstractGridArrayBoolean
4 | import Lifecycle.With
5 | import Mathematics.Points.Tile
6 | import Mathematics.Shapes.Square
7 | import Strategery.MapGroups
8 |
9 | class GridWalkableTerrain extends AbstractGridArrayBoolean {
10 |
11 | override def onInitialization(): Unit = {
12 | val walkableGoal = if (MapGroups.narrowRamp.exists(_())) 12 else 16
13 | indices.foreach(i => set(
14 | i,
15 | Square(4)
16 | .map(new Tile(i).topLeftWalk.add)
17 | .count(walkTile => With.game.isWalkable(walkTile.bwapi)) >= walkableGoal))
18 | }
19 |
20 | @inline final override def getUnchecked(i: Int): Boolean = values(i)
21 | }
22 |
--------------------------------------------------------------------------------