diff --git a/my-bot/AttackAnalysis.java b/my-bot/AttackAnalysis.java new file mode 100644 index 0000000..4c2f23f --- /dev/null +++ b/my-bot/AttackAnalysis.java @@ -0,0 +1,150 @@ +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class AttackAnalysis { + + private Ants ants; + private int cols; + private int rows; + private int[][] mine; + private Map> mineTile; + private int[][] theirs; + private Map> theirsTile; + private MyBot bot; + + public AttackAnalysis(Ants ants, MyBot myBot) { + this.ants = ants; + this.rows = ants.getRows(); + this.cols = ants.getCols(); + this.bot = myBot; + mine = new int[rows][cols]; + theirs = new int[rows][cols]; + mineTile = new HashMap>(); + theirsTile = new HashMap>(); + } + + public void process() { + for (Tile my : ants.getMyAnts()) { + for (Tile t : tileswithinradius(my)) { + mine[t.getRow()][t.getCol()] += 1; + addTiletoMineMap(t, my); + } + } + for (Tile thei : ants.getEnemyAnts()) { + for (Tile t : tileswithinradius(thei)) { + theirs[t.getRow()][t.getCol()] += 1; + addTiletoTheirsMap(t, thei); + } + } + } + + private void addTiletoTheirsMap(Tile t, Tile thei) { + if (!theirsTile.containsKey(t)) { + theirsTile.put(t, new ArrayList()); + } + theirsTile.get(t).add(thei); + } + + private void addTiletoMineMap(Tile t, Tile my) { + if (!mineTile.containsKey(t)) { + mineTile.put(t, new ArrayList()); + } + mineTile.get(t).add(my); + } + + public void decideAttacks() { + for (Tile my : ants.getMyAnts()) { + for (Tile neigh : ants.possibleNextStates(my)) { + if (theirs[neigh.getRow()][neigh.getCol()] > 1) { + int numberEnemies = theirs[neigh.getRow()][neigh.getCol()]; + for (Tile enemy : theirsTile.get(neigh)) { + for (Tile enemyneigh : ants.possibleNextStates(enemy)) { + if (mineTile.get(enemyneigh) != null + && mineTile.get(enemyneigh).contains(my)) { + if (mine[enemyneigh.getRow()][enemyneigh + .getCol()] > numberEnemies) { + } else if (mine[enemyneigh.getRow()][enemyneigh + .getCol()] < numberEnemies) { + fugir(my, enemy); + break; + } else { + } + } else { + } + } + } + } + } + } + } + + private void fugir(Tile my, Tile enemy) { + Aim d = getOppositeDirection(ants.getDirections(my, enemy).get(0)); + bot.doMoveDirection(my, d); + } + + private Aim getOppositeDirection(Aim aim) { + switch (aim) { + case EAST: + return Aim.WEST; + case NORTH: + return Aim.SOUTH; + case SOUTH: + return Aim.NORTH; + case WEST: + return Aim.EAST; + default: + break; + } + throw new RuntimeException("OPPS"); + } + + public void printMine() { + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + System.err.print(mine[i][j]); + } + System.err.println(""); + } + } + + public void printTheirs() { + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + System.err.print(theirs[i][j]); + } + System.err.println(""); + } + } + + private List tileswithinradius(Tile my) { + List res = new ArrayList<>(); + int mx = (int) Math.sqrt(ants.getAttackRadius2()) + 1; + for (int row = -mx; row <= mx; ++row) { + for (int col = -mx; col <= mx; ++col) { + double d = Math.pow((Math.abs(row) - 1), 2.0) + + Math.pow((Math.abs(col) - 1), 2.0); + double d2 = row * row + col * col; + if (d <= ants.getAttackRadius2() + 1 + && d2 >= ants.getAttackRadius2()) { + int mrow = my.getRow() + row; + int mcol = my.getCol() + col; + if (mrow < 0) { + mrow += rows; + } else { + mrow = mrow % rows; + } + if (mcol < 0) { + mcol += cols; + } else { + mcol = mcol % cols; + } + res.add(new Tile(mrow, mcol)); + } + } + } + return res; + } +} diff --git a/my-bot/DiffusionMap.java b/my-bot/DiffusionMap.java index c7d689a..3b1faec 100644 --- a/my-bot/DiffusionMap.java +++ b/my-bot/DiffusionMap.java @@ -7,13 +7,13 @@ import java.util.Comparator; public class DiffusionMap { - + private double[][] values; private Ants ants; private int rows; private int cols; - public DiffusionMap(Ants ants){ + public DiffusionMap(Ants ants) { this.ants = ants; rows = ants.getRows(); cols = ants.getCols(); @@ -21,56 +21,71 @@ public DiffusionMap(Ants ants){ init(ants); } - public void clear(){ + public void clear() { values = new double[rows][cols]; } - public Comparator getComparator(){ + public Comparator getComparator() { return new TileComparator(this, ants); } - public double getValue(Tile t){ + public double getValue(Tile t) { int row = t.getRow(); int col = t.getCol(); - if(row < 0 || row >= rows){ - row = (row+rows)%rows; + if (row < 0 || row >= rows) { + row = (row + rows) % rows; } - if(col < 0 || col >= cols){ - col = (col+cols)%cols; + if (col < 0 || col >= cols) { + col = (col + cols) % cols; } return values[row][col]; } - public double getValue(int row, int col){ - if(row < 0 || row >= rows){ - row = (row+rows)%rows; + public double getValue(int row, int col) { + if (row < 0 || row >= rows) { + row = (row + rows) % rows; } - if(col < 0 || col >= cols){ - col = (col+cols)%cols; + if (col < 0 || col >= cols) { + col = (col + cols) % cols; } return values[row][col]; } - public void addValue(Tile t, double val){ + public void addValue(Tile t, double val) { values[t.getRow()][t.getCol()] += val; } - public boolean addElement(Tile t,double value, double decreaseFactor, double k){ + public boolean addElement(Tile t, double value, double decreaseFactor, + double k) { + return addElement(t, value, decreaseFactor, k, true); + } + + public boolean addElement(Tile t, double value, double decreaseFactor, + double k, boolean ignoreWater) { Queue tiles = new LinkedList<>(); Queue vals = new LinkedList<>(); Set alreadyUsed = new HashSet<>(); tiles.add(t); vals.add(value); - while(!tiles.isEmpty()){ + while (!tiles.isEmpty()) { Tile n = tiles.poll(); double val = vals.poll(); alreadyUsed.add(n); addValue(n, val); - if(val*k > 1){ - for(Tile no : ants.possibleNextStates(n)){ - if(!alreadyUsed.contains(no) && ants.isPassable(no)){ - tiles.add(no); - vals.add(val/decreaseFactor); + if (val * k > 1) { + if (ignoreWater) { + for (Tile no : ants.possibleNextStates(n)) { + if (!alreadyUsed.contains(no) && (ants.isPassable(no))) { + tiles.add(no); + vals.add(val / decreaseFactor); + } + } + }else{ + for (Tile no : ants.getNeighbors(n)) { + if (!alreadyUsed.contains(no) && (ants.isPassable(no))) { + tiles.add(no); + vals.add(val / decreaseFactor); + } } } } @@ -78,52 +93,53 @@ public boolean addElement(Tile t,double value, double decreaseFactor, double k){ return true; } - public void init(Ants ants){ + public void init(Ants ants) { } - public String toString(){ + public String toString() { StringBuffer sb = new StringBuffer(); - for(int i=0;ibestValue){ + if (n > bestValue) { bestValue = n; bestDirection = a; } } } - if(bestValue > values[row][col]){ + if (bestValue > values[row][col]) { return bestDirection; } return null; } - public void print(PrintStream ps, int rowstart, int rowend, int colStart, int colEnd){ - for(int r = rowstart; r < rowend; r++){ + public void print(PrintStream ps, int rowstart, int rowend, int colStart, + int colEnd) { + for (int r = rowstart; r < rowend; r++) { StringBuffer sb = new StringBuffer(); - for(int c = colStart;c < colEnd; c++){ - sb.append(String.format("%2.0f", getValue(r,c))+" "); + for (int c = colStart; c < colEnd; c++) { + sb.append(String.format("%2.0f", getValue(r, c)) + " "); } ps.println(sb); } diff --git a/my-bot/MinMax.java b/my-bot/MinMax.java new file mode 100644 index 0000000..d2a02ba --- /dev/null +++ b/my-bot/MinMax.java @@ -0,0 +1,125 @@ +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class MinMax { + + private List myAnts; + private List theirAnts; + private Ants ants; + private static HashMap> aims = new HashMap<>(); + + public MinMax(List myAnts, List theirAnts, Ants ants){ + this.myAnts = myAnts; + this.theirAnts = theirAnts; + this.ants = ants; + } + + public HashMap bestCalls() { + int worst = Integer.MIN_VALUE; + List wcal = null; + System.err.println("Starting"); + for (List cal : myPossibleCalls()) { + System.err.println(cal); + int best = Integer.MAX_VALUE; + for (List hcal : theirPossibleCalls()) { + int cur = saldo(cal, hcal); + if (cur < best) { + best = cur; + } + } + if (best > worst) { + worst = best; + wcal = cal; + } + } + HashMap calls = new HashMap<>(); + for (int i = 0; i < myAnts.size(); i++) { + calls.put(myAnts.get(i), wcal.get(i)); + } + return calls; + } + + private int saldo(List cal, List hcal) { + int saldo = 0; + List myNewPositions = new ArrayList<>(); + List theirNewPositions = new ArrayList<>(); + for (int i = 0; i < myAnts.size(); i++) { + myNewPositions.add(ants.getTile(myAnts.get(i), cal.get(i))); + } + for (int i = 0; i < theirAnts.size(); i++) { + theirNewPositions.add(ants.getTile(theirAnts.get(i), hcal.get(i))); + } + HashMap distances = new HashMap<>(); + HashMap> effects = new HashMap<>(); + for(Tile my : myNewPositions){ + distances.put(my, 0); + effects.put(my, new ArrayList()); + } + for(Tile th : theirNewPositions){ + distances.put(th, 0); + effects.put(th, new ArrayList()); + } + for(Tile my : myNewPositions){ + for(Tile th : theirNewPositions){ + if(ants.getDistance(my, th)> myPossibleCalls() { + return possibleCalls(0, myAnts.size()); + } + + private List> theirPossibleCalls() { + return possibleCalls(0, theirAnts.size()); + } + + private List> possibleCalls(int i, int max) { + List> res = new ArrayList>(); + if (i == max - 1) { + for (Aim a : Aim.values()) { + List t = new ArrayList<>(); + t.add(a); + res.add(t); + } + } else { + for (Aim a : Aim.values()) { + for (List rc : possibleCalls(i + 1, max)) { + List t = new ArrayList<>(); + t.add(a); + for (Aim aa : rc) { + t.add(aa); + } + res.add(t); + } + } + } + return res; + } + +} diff --git a/my-bot/MyBot.java b/my-bot/MyBot.java index a97f231..2d14805 100644 --- a/my-bot/MyBot.java +++ b/my-bot/MyBot.java @@ -36,10 +36,10 @@ public static void main(String[] args) throws IOException { private DiffusionMap spacingAnts; private Set unseenTiles; private Queue frontier; - private boolean goFrontier = false;// a + private boolean goFrontier = false;// aaaa private HashSet processedFrontier; - private boolean doMoveDirection(Tile antLoc, Aim direction) { + public boolean doMoveDirection(Tile antLoc, Aim direction) { Ants ants = getAnts(); // Track all moves, prevent collisions Tile newLoc = ants.getTile(antLoc, direction); @@ -52,9 +52,9 @@ private boolean doMoveDirection(Tile antLoc, Aim direction) { } } - private boolean doMoveDirectionIDontCare(Tile antLoc, Aim direction) { + public boolean doMoveDirectionIDontCare(Tile antLoc, Aim direction) { Ants ants = getAnts(); - // Track all moves, prevent collisions, I dont care + // Track all moves, prevent collisions, I dont carea Tile newLoc = ants.getTile(antLoc, direction); if (!orders.containsKey(newLoc)) { ants.issueOrder(antLoc, direction); @@ -65,9 +65,9 @@ private boolean doMoveDirectionIDontCare(Tile antLoc, Aim direction) { } } - private boolean doMoveLocation(Tile antLoc, Tile destLoc) { + public boolean doMoveLocation(Tile antLoc, Tile destLoc) { Ants ants = getAnts(); - // Track targets to prevent 2 ants to the same location + // Track targets to prevent 2 ants to the same locationaa List directions = ants.getDirections(antLoc, destLoc); for (Aim direction : directions) { if (doMoveDirection(antLoc, direction)) { @@ -77,7 +77,7 @@ private boolean doMoveLocation(Tile antLoc, Tile destLoc) { return false; } - private boolean doMoveLocationIDontCare(Tile antLoc, Tile destLoc) { + public boolean doMoveLocationIDontCare(Tile antLoc, Tile destLoc) { Ants ants = getAnts(); // Track targets to prevent 2 ants to the same location List directions = ants.getDirections(antLoc, destLoc); @@ -92,7 +92,7 @@ private boolean doMoveLocationIDontCare(Tile antLoc, Tile destLoc) { @Override public void doTurn() { Ants ants = getAnts(); - orders.clear(); + orders.clear();// aaa if (foodMap == null) { foodMap = new DiffusionMap(ants); enemyHillMap = new DiffusionMap(ants); @@ -124,6 +124,12 @@ public void doTurn() { } } } + + AttackAnalysis aa = new AttackAnalysis(ants, this); + aa.process(); + + aa.decideAttacks(); + // remove any tiles that can be seen, run each turn for (Iterator locIter = unseenTiles.iterator(); locIter.hasNext();) { Tile next = locIter.next(); @@ -131,7 +137,7 @@ public void doTurn() { locIter.remove(); } } - int count = 0; + int count = 0;// a while (count < frontier.size()) { Tile t = frontier.poll(); if (!unseenTiles.contains(t)) { @@ -151,7 +157,8 @@ public void doTurn() { exploreMap.addElement(t, 4000, 3, 1); } for (Tile myHill : ants.getMyHills()) { - orders.put(myHill, null); + if (ants.getMyAnts().size() > 5) + orders.put(myHill, null); } // find close food; @@ -160,8 +167,15 @@ public void doTurn() { int numberofMyHills = ants.getMyHills().size(); for (Tile ma : ants.getMyAnts()) { - spacingAnts.addElement(ma, -200, 2, -1); + spacingAnts.addElement(ma, -200, 2, -1, false); + for (Tile n : ants.getNeighbors(ma)) { + for (Tile n2 : ants.getNeighbors(n)) { + if (!ants.isPassable(n2)) + spacingAnts.addElement(n2, -100, 10, -1, false); + } + } } + // System.err.println(spacingAnts); for (Tile foodLoc : ants.getFoodTiles()) { foodMap.addElement(foodLoc, 2000, 3, 1); @@ -184,7 +198,6 @@ public void doTurn() { && !ants.getEnemyHills().contains(hillLoc)) { eliminatedHills.add(hillLoc); } else { - System.err.println("Not eliminated hill - " + hillLoc); enemyHillMap.addElement(hillLoc, 100000, 2, 1); } } @@ -259,10 +272,6 @@ public void doTurn() { } } } - System.err.println("My hill: " + countGoForMyHill); - System.err.println("Enemy hill: " + countGoForEnemyHill); - System.err.println("Food : " + countGoForFood); - System.err.println("Space: " + countGoForSpace); } } diff --git a/play_one_game.sh b/play_one_game.sh index 5f2714e..c9f49b7 100755 --- a/play_one_game.sh +++ b/play_one_game.sh @@ -1,2 +1,2 @@ #!/usr/bin/env sh -tools/playgame.py --player_seed 42 --end_wait=0.25 --verbose --log_dir game_logs --turns 1000 --map_file tools/maps/random_walk/random_walk_04p_02.map "java -jar my-bot/MyBot.jar" "python tools/sample_bots/python/HunterBot.py" "python tools/sample_bots/python/LeftyBot.py" "python tools/sample_bots/python/HunterBot.py" --verbose -e +tools/playgame.py --player_seed 42 --end_wait=0.25 --verbose --log_dir game_logs --turns 1000 --map_file tools/maps/random_walk/random_walk_04p_02.map "java -jar my-bot/MyBot.jar" "python tools/sample_bots/python/HunterBot.py" "java -jar tools/sample_bots/old.jar" "python tools/sample_bots/python/HunterBot.py" --verbose -e diff --git a/play_one_game_maze.sh b/play_one_game_maze.sh index a75f1f1..d3b9ff0 100755 --- a/play_one_game_maze.sh +++ b/play_one_game_maze.sh @@ -1,2 +1,2 @@ #!/usr/bin/env sh -tools/playgame.py --player_seed 42 --end_wait=0.25 --verbose --log_dir game_logs --turns 1000 --map_file tools/maps/maze/maze_04p_01.map "java -jar my-bot/MyBot.jar" "python tools/sample_bots/python/HunterBot.py" "python tools/sample_bots/python/LeftyBot.py" "python tools/sample_bots/python/HunterBot.py" --verbose -e +tools/playgame.py --player_seed 42 --end_wait=0.25 --verbose --log_dir game_logs --turns 1000 --map_file tools/maps/maze/maze_04p_01.map "java -jar my-bot/MyBot.jar" "python tools/sample_bots/python/HunterBot.py" "java -jar tools/sample_bots/old.jar" "python tools/sample_bots/python/HunterBot.py" --verbose -e diff --git a/tools/sample_bots/old.jar b/tools/sample_bots/old.jar new file mode 100644 index 0000000..8800a1e Binary files /dev/null and b/tools/sample_bots/old.jar differ diff --git a/tutorial.sh b/tutorial.sh index f4f908f..f54787a 100755 --- a/tutorial.sh +++ b/tutorial.sh @@ -1 +1 @@ -python tools/playgame.py --map_file tools/maps/example/tutorial1.map "java -jar my-bot/MyBot.jar" "python tools/sample_bots/python/HunterBot.py" --log_dir game_logs --turns 100 --scenario --player_seed 42 --verbose -e +python tools/playgame.py --map_file tools/maps/example/tutorial1.map "java -jar my-bot/MyBot.jar" "python tools/sample_bots/python/HunterBot.py" --log_dir game_logs --turns 200 --scenario --player_seed 42 --verbose -e