import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import core.Position; import core.map.FieldType; import core.player.PlayerController; import core.ai.AiPlayerInfo; import core.ai.AiMapInfo; import core.player.Player.Action; public class FieserBot extends PlayerController { // E I A O // Class Node is used in AStern. class Node { public Position pos; public int f, g, h; public Node von; public Node(Position pos, Position z) { this.pos = pos; this.von = null; f = 0; g = 0; h = Math.abs(pos.x - z.x) + Math.abs(pos.y - z.y); } public void setVon(Node von) { this.von = von; g = von.g + 1; f = h + g; } } // declare all the attributes List open = new LinkedList(); List closed = new ArrayList(); List pfad = new ArrayList(); List Feld = new ArrayList(); AiMapInfo karte; Position ziel; int goalNumber = 0; int walkTimer = 0, startTimer = 0; int MatchNumber; // The bots name public String getName() { return "FieserBot"; } // The bots author public String getAuthor() { return "Sebastian Wende"; } // P E M K public void check(Position a, Node current, AiMapInfo map) { boolean notinclosed = true; for (int i = 0; i < closed.size(); i++) { if (a.equals(closed.get(i).pos)) notinclosed = false; } boolean notinopen = true; for (int i = 0; i < open.size(); i++) { if (a.equals(open.get(i).pos)) notinopen = false; } if ((map.getField(a).equals(FieldType.STABLE_FIELD) || map.getField(a).equals(FieldType.ACTION_FIELD_FLAG) || map .getField(a).equals(FieldType.UNSTABLE_FIELD)) && notinclosed) { if (notinopen) { open.add(new Node(a, ziel)); open.get(open.size() - 1).von = current; } else { for (int i = 0; i < open.size(); i++) { if (a.equals(open.get(i).pos)) if (current.g + 1 < open.get(i).g) open.get(i).von = current; } } } } public boolean inlist(List a, Position b) { for (int i = 0; i < a.size(); i++) { if (a.get(i).equals(b) || !karte.getField(b).equals(FieldType.STABLE_FIELD)) return true; } return false; } public Action walk(Position Ziel, AiPlayerInfo ownPlayer, AiMapInfo map) { open.clear(); closed.clear(); pfad.clear(); AStern(map, ownPlayer); if (pfad.get(pfad.size() - 1).pos.x - ownPlayer.getPosition().x > 0) return Action.MOVE_RIGHT; if (pfad.get(pfad.size() - 1).pos.x - ownPlayer.getPosition().x < 0) return Action.MOVE_LEFT; if (pfad.get(pfad.size() - 1).pos.y - ownPlayer.getPosition().y > 0) return Action.MOVE_DOWN; if (pfad.get(pfad.size() - 1).pos.y - ownPlayer.getPosition().y < 0) return Action.MOVE_UP; return Action.DO_NOTHING; } public void AStern(AiMapInfo map, AiPlayerInfo ownPlayer) { Node current; open.add(new Node(ownPlayer.getPosition(), ziel)); while ((closed.isEmpty() || !closed.get(closed.size() - 1).pos .equals(ziel)) && open.isEmpty() == false) { current = open.get(0); for (int i = 0; i < open.size(); i++) { if (current.f > open.get(i).f) current = open.get(i); } closed.add(current); for (int i = 0; i < open.size(); i++) { if (current == open.get(i)) open.remove(i); } check(current.pos.up(), current, map); check(current.pos.right(), current, map); check(current.pos.down(), current, map); check(current.pos.left(), current, map); } Node lsg = closed.get(closed.size() - 1); while (lsg.von != null) { pfad.add(lsg); lsg = lsg.von; } } // U G O I public void onMatchStarted(int matchNumber, int numTotalMatches, AiMapInfo map, AiPlayerInfo[] enemies, AiPlayerInfo ownPlayer) { MatchNumber = matchNumber; goalNumber = 0; } public Position getFlag(AiMapInfo map) { for (int i = 0; i < map.getWidth(); i++) { for (int j = 0; j < map.getHeight(); j++) { if (map.getField(new Position(i, j)) == FieldType.ACTION_FIELD_FLAG) { return new Position(i, j); } } } return null; } public void getGoal(AiMapInfo map, AiPlayerInfo[] enemies) { if (map.isParkourMap()) { ziel = getFlag(map); } else { switch (this.goalNumber) { case 0: ziel = enemies[0].getPosition(); break; case 1: ziel.x = 10; ziel.y = map.getHeight() - 2; break; case 2: ziel.x = map.getWidth() - 2; ziel.y = map.getHeight() - 2; break; case 3: ziel.x = map.getWidth() - 2; ziel.y = 1; break; case 4: ziel.x = map.getWidth() - 4; ziel.y = map.getHeight() - 4; break; default: ziel.x = map.getWidth() - 4; ziel.y = map.getHeight() - 4; } } } public Action slowWalk(AiMapInfo map, AiPlayerInfo[] enemies, AiPlayerInfo ownPlayer) { this.walkTimer++; if (this.walkTimer <= 14) { return Action.DO_NOTHING; } else { walkTimer = 0; getGoal(map, enemies); return walk(ziel, ownPlayer, map); } } // S R L T //Ze Brain public Action think(AiMapInfo map, AiPlayerInfo[] enemies, AiPlayerInfo ownPlayer) { // Wait 4 turns. No crash with CarefulBot. Less Exceptions. if (startTimer <= 4) { startTimer++; return Action.DO_NOTHING; } // ****Choose goalNumber**** // 0 (default) - follow CarefulBot // 1 - all the way down after reaching the top // 2-4 - try not to die so fast if (ownPlayer.getPosition().y == 1) { this.goalNumber = 1; } if (ownPlayer.getPosition().y == map.getHeight() - 2) { this.goalNumber = 2; } if (ownPlayer.getPosition().y == map.getHeight() - 2 && ownPlayer.getPosition().x == map.getWidth() - 2) { this.goalNumber = 3; } if (ownPlayer.getPosition().y == 0 && ownPlayer.getPosition().x == map.getWidth() - 2) { this.goalNumber = 4; } // For goals 0 and 1, walk as fast as you can to cut of a piece of the // map if (this.goalNumber < 2) { getGoal(map, enemies); return walk(ziel, ownPlayer, map); } // For goals 2 - 4, walk slowly. And hopefully CarefulBot dies first! // Muahaha! return slowWalk(map, enemies, ownPlayer); } }