package propra2012.gruppe33.bomberman.ai.ninja; import java.awt.Point; import propra2012.gruppe33.bomberman.ai.AIControl; import propra2012.gruppe33.bomberman.ai.AIProcessor; public class Bot implements AIProcessor { /** * Is now serializable. */ private static final long serialVersionUID = 1L; /** * the abstract data type Pathfinder is used to create a grid structure. As * a result the dijkstra algorithm can be easily implemented. map is the * base frame for the grid. */ private Pathfinder[][] map; /** * Is only used to determine whether the bot was already initialized or not. * Only used in process */ private boolean initialized; /** * The destined path on which the bot is walking. Is used by * AIControl.setPath and AIControl.getPath. */ private Point[] path; /** * The position the bot is standing on. May only be accommodated by the * method positionChanged(). */ private Point position; /** * The method that actually guides the bot. */ @Override public void process(float timeSinceLastFrame, AIControl aiControl) { /* * Since the class only needs to initialized once. This submethod should * only be called once for every bot. * * It initializes map, chains the connections between the pathfinders * and sets the speed. */ if (!initialized) { position = new Point(0, 0); map = new Pathfinder[aiControl.fields().length][aiControl.fields()[0].length]; initialized = true; for (int y = 0; y < map.length; y++) { for (int x = 0; x < map[0].length; x++) { if (aiControl.fields()[y][x] != null) { map[y][x] = new Pathfinder(x, y); } } } for (int y = 0; y < map.length; y++) { for (int x = 0; x < map[0].length; x++) { if (map[y][x] == null) { continue; } if ((y - 1 >= 0) && (map[y - 1][x] != null)) { map[y][x].setNorth(map[y - 1][x]); map[y][x].setSpeedNorth(aiControl.edgeWeight(map[y][x], map[y - 1][x])); } else { map[y][x].setNorth(map[y][x]); } if ((x + 1 < map[y].length) && (map[y][x + 1] != null)) { map[y][x].setEast(map[y][x + 1]); map[y][x].setSpeedEast(aiControl.edgeWeight(map[y][x], map[y][x + 1])); } else { map[y][x].setEast(map[y][x]); } if ((y + 1 < map.length) && (map[y + 1][x] != null)) { map[y][x].setSouth(map[y + 1][x]); map[y][x].setSpeedSouth(aiControl.edgeWeight(map[y][x], map[y + 1][x])); } else { map[y][x].setSouth(map[y][x]); } if ((x - 1 >= 0) && (map[y][x - 1] != null)) { map[y][x].setWest(map[y][x - 1]); map[y][x].setSpeedWest(aiControl.edgeWeight(map[y][x], map[y][x - 1])); } else { map[y][x].setWest(map[y][x]); } } } } if ((positionChanged(aiControl.activePosition())) && (aiControl.hasFieldChanged()) && aiControl.isResting()) { reinitialize(); map[position.y][position.x].setDistance(0); map[position.y][position.x].dijkstra(0); // checks where is aen enemy player and moves the bot to this // position. for (int y = 0; y < aiControl.fields().length; y++) { for (int x = 0; x < aiControl.fields()[y].length; x++) { if (aiControl.fields()[x][y] != null) { for (int z = 0; z < aiControl.fields()[x][y].length; z++) { if (aiControl.fields()[x][y][z] == AIControl.PLAYER) { aiControl.setPath(getPath(map[y][x])); return; } } } } } } /* * from here on: further implementation * * checkfields implementieren (checkt wo items, bomben, spieler in * näherere umgebung um den bot liegen) * * checkbombpath implementieren (checkt ob auf dem aktuellen path bomben * liegen, die möglicherweise den bot töten könnten */ } /** * After a successful execution of dijkstra algorithm distance and count may * be wrong for the next one. This method resets them on default values. */ private void reinitialize() { for (int y = 0; y < map.length; y++) { for (int x = 0; x < map[0].length; x++) { if (map[y][x] == null) { continue; } map[y][x].setVisited(false); map[y][x].setPredecessor(null); map[y][x].setDistance(1000); map[y][x].setCount(0); } } } /** * Generates the path from the "goal pathfinder" to the "start pathfinder" * by using the number of steps needed to get there. * * @param goal * This Pathfinder is thelocation that the bot should walk to * from his current location. * @return the path from current location to the goal location. */ private Point[] getPath(Pathfinder goal) { int i = 0; path = new Point[goal.getCount()]; while (!goal.getPredecessor().equals(position)) { path[path.length - i - 1] = goal; goal = goal.getPredecessor(); i++; } path[0] = goal; return path; } /** * Controls whether the position on the map of the bot has changed since the * last call. * * @param activePosition * the actual position of the bot. Can only be determined by * aiControl. May be differ from this.position. * @return true if the position has changed or false if not. */ private Boolean positionChanged(Point activePosition) { if (!position.equals(activePosition)) { position = activePosition; return true; } else { return false; } } // Alte Funktionen die evtl. noch brauchbar sind, werden vor abschluss // gelöscht. Ebenso wird die gesammte Dokumentation vor abschluss auf // Englisch umgestellt! // public void initialize(int[][][] fields) { // for (int y = 0; y < fields.length; y++) { // for (int x = 0; x < fields[0].length; x++) { // if (fields[y][x] != null) { // // map[y][x] = new Pathfinder; // } // } // } // } // // private void pathfind(Point[][] field, Point start, Point goal) { // ArrayList<Pathfinder> crowd = new ArrayList<Pathfinder>(); // Pathfinder[][] map = new Pathfinder[field.length][field[0].length]; // // for (int i = 0; i < map.length; i++) { // for (int j = 0; j < map[0].length; j++) { // map[i][j].setDistance(1000); // crowd.add(map[i][j]); // } // } // map[start.y][start.x].setDistance(0); // // } }