Created
July 31, 2017 23:59
-
-
Save simbuerg/f1821a0f8564c30bb8b818a82a241d12 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.Comparator; | |
import java.util.LinkedList; | |
import java.util.List; | |
import bwapi.*; | |
public class SommerinoCamperino extends DefaultBWListener { | |
static class Line { | |
private double slope; | |
private double intercept; | |
public double getSlope() { | |
return slope; | |
} | |
public double getIntercept() { | |
return intercept; | |
} | |
public static Line fromObservations(List<Position> observations) { | |
double a = 0; | |
double b = 0; | |
int sum_xy = 0; | |
int sum_xx = 0; | |
int sum_x = 0; | |
int sum_y = 0; | |
int n = observations.size(); | |
// Slope: | |
for (Position pos : observations) { | |
sum_xy += pos.getX() * pos.getY(); | |
sum_xx += pos.getX() * pos.getX(); | |
sum_x += pos.getX(); | |
sum_y += pos.getY(); | |
} | |
a = (sum_xy - ((sum_x * sum_y) / n)) / (double) | |
((sum_xx - (sum_x^2)) / (double) n); | |
b = (sum_y - (a * sum_x)) / (double) n; | |
return new Line(a, b); | |
} | |
Line(double slope, double intercept) { | |
this.slope = slope; | |
this.intercept = intercept; | |
} | |
double eval(double x) { | |
return slope * x + intercept; | |
} | |
} | |
private Mirror mirror = new Mirror(); | |
private Game game; | |
private Player self; | |
enum State { | |
INIT, | |
NORMAL | |
} | |
private State state = State.INIT; | |
public void run() { | |
mirror.getModule().setEventListener(this); | |
mirror.startGame(); | |
} | |
@Override | |
public void onUnitCreate(Unit unit) {} | |
@Override | |
public void onStart() { | |
game = mirror.getGame(); | |
self = game.self(); | |
} | |
protected boolean attackEverythingInSight() { | |
Player enemy = game.enemy(); | |
List<Unit> eus = enemy.getUnits(); | |
if (!eus.isEmpty()) { | |
Unit eu = eus.get(0); | |
for (Unit myUnit : self.getUnits()) { | |
if (myUnit.getLastCommandFrame() >= game.getFrameCount() || myUnit.isAttackFrame()) | |
continue; | |
if (myUnit.getLastCommand().getUnitCommandType() == UnitCommandType.Attack_Unit) | |
continue; | |
myUnit.attack(eu); | |
} | |
return true; | |
} | |
return false; | |
} | |
@Override | |
public void onUnitDiscover(Unit u) { | |
if (!u.isVisible()) | |
return; | |
} | |
@Override | |
public void onUnitDestroy(Unit u) { | |
if (u.getPlayer() == self) { | |
game.sendText("OH SHIT!"); | |
} else { | |
attackEverythingInSight(); | |
} | |
} | |
private void spreadUnits(Game state, List<Unit> units, int distance) { | |
if (units.size() < 2) | |
return; | |
List<Position> wantPositions = new LinkedList<Position>(); | |
for (int i=0; i < units.size(); i++) { | |
Unit u0 = units.get(i); | |
Unit closest = u0; | |
int minDistance = -1; | |
for (int j=i+1; j < units.size(); j++) { | |
Unit u1 = units.get(j); | |
int curDistance = u0.getDistance(u1); | |
if (curDistance > distance) | |
continue; | |
if ((minDistance < 0) || (minDistance > curDistance)) { | |
minDistance = curDistance; | |
closest = u1; | |
} | |
} | |
int missingDistance = minDistance - distance; | |
Position wantPos = new Position( | |
u0.getX() + missingDistance * Math.abs((closest.getX() - u0.getX())), | |
u0.getY() + missingDistance * Math.abs((closest.getY() - u0.getY()))); | |
if (u0.isIdle() && (u0.getDistance(wantPos) > distance)) | |
u0.move(wantPos); | |
wantPositions.add(wantPos); | |
} | |
int offset = 0; | |
for (Position pos : wantPositions) { | |
state.drawCircleMap(pos, 2, bwapi.Color.Cyan); | |
state.drawTextScreen(10, 30+offset, pos.toString()); | |
offset += 10; | |
} | |
} | |
private void alignUnits(Game state, List<Unit> units, TilePosition pos) { | |
if (units.size() < 2) | |
return; | |
units.sort(new Comparator<Unit>() { | |
@Override | |
public int compare(Unit o1, Unit o2) { | |
int comp = o1.getX() - o2.getX(); | |
if (comp == 0) | |
comp = o1.getY() - o2.getY(); | |
return comp; | |
} | |
}); | |
List<Position> positions = new LinkedList<Position>(); | |
for (Unit u : units) { | |
positions.add(u.getPosition()); | |
} | |
Line current = Line.fromObservations(positions); | |
Unit u0 = units.get(0); | |
Unit u1 = units.get(units.size() - 1); | |
state.drawLineMap(new Position(u0.getX(), (int)current.eval(u0.getX())), | |
new Position(u1.getX(), (int)current.eval(u1.getX())), | |
bwapi.Color.Orange); | |
} | |
private void attackMoveTo(Game state, List<Unit> units, Position to) { | |
for (Unit u : units) { | |
if (!u.isIdle()) | |
continue; | |
u.attack(to); | |
} | |
} | |
private void drawEnemies(Game state, Player enemy) { | |
for (Unit e : enemy.getUnits()) { | |
if (!e.isVisible()) | |
continue; | |
state.drawBoxMap(e.getX() - 2, e.getY() - 2, e.getX() + 2, e.getY() + 2, bwapi.Color.Red); | |
} | |
} | |
private void drawOrders(Game state, List<Unit> units) { | |
for (Unit u : units) { | |
if (u.isIdle()) | |
continue; | |
Position pos = u.getOrderTargetPosition(); | |
bwapi.Color c = bwapi.Color.Green; | |
UnitCommandType ty = u.getLastCommand().getUnitCommandType(); | |
if (ty == UnitCommandType.Attack_Move || ty == UnitCommandType.Attack_Unit) | |
c = bwapi.Color.Red; | |
game.drawLineMap(u.getPosition(), pos, c); | |
} | |
} | |
@Override | |
public void onFrame() { | |
game.drawTextScreen(10, 10, "Playing as " + self.getName() + " - " + self.getRace()); | |
Player enemy = game.enemy(); | |
drawEnemies(game, enemy); | |
drawOrders(game, self.getUnits()); | |
switch (state) { | |
case INIT: | |
alignUnits(game, self.getUnits(), enemy.getStartLocation()); | |
spreadUnits(game, self.getUnits(), 3); | |
state = State.NORMAL; | |
break; | |
case NORMAL: | |
if (!attackEverythingInSight()) { | |
attackMoveTo(game, self.getUnits(), enemy.getStartLocation().toPosition()); | |
} | |
break; | |
} | |
} | |
public static void main(String[] args) { | |
new SommerinoCamperino().run(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment