Skip to content

Instantly share code, notes, and snippets.

@simbuerg
Created July 31, 2017 23:59
Show Gist options
  • Save simbuerg/f1821a0f8564c30bb8b818a82a241d12 to your computer and use it in GitHub Desktop.
Save simbuerg/f1821a0f8564c30bb8b818a82a241d12 to your computer and use it in GitHub Desktop.
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