forgot to add Level.java
[AntiTD.git] / src / se / umu / cs / dit06ajnajs / map / Level.java
blob4e131ce5604a0d9f16438017e31f43eab7593080
1 package se.umu.cs.dit06ajnajs.map;
3 import java.awt.Dimension;
4 import java.awt.Graphics;
5 import java.awt.Image;
6 import java.awt.Point;
7 import java.awt.image.BufferedImage;
8 import java.util.ArrayList;
9 import java.util.List;
10 import java.util.logging.Logger;
12 import se.umu.cs.dit06ajnajs.AntiTD;
13 import se.umu.cs.dit06ajnajs.NoActiveStartSquareException;
14 import se.umu.cs.dit06ajnajs.agent.Direction;
15 import java.util.Collection;
16 import se.umu.cs.dit06ajnajs.agent.Tower;
18 /**
19 * Describe class <code>Level</code> here.
21 * @author Anton Johansson, dit06ajn@cs.umu.se
22 * Andreas Jacobsson, dit06ajs@cs.umu.se
23 * @version 1.0
25 public class Level {
26 private static Logger logger = Logger.getLogger("AntiTD");
28 private String name;
29 private int goalSum;
30 private int currentSum;
31 private int squareSize;
32 private int width;
33 private int height;
34 private int numCol;
35 private int numRow;
36 private MapSquare[][] squareMatrix;
37 private GoalSquare[] goalSquares;
38 private StartSquare[] startSquares;
39 private Collection<Tower> towers;
41 public Level(String name, MapSquare[][] squareMatrix) {
42 this(name, squareMatrix, null);
46 public Level(String name, MapSquare[][] squareMatrix, Collection<Tower> towers) {
47 this.name = name;
48 this.squareSize = AntiTD.SQUARE_SIZE;
49 this.squareMatrix = squareMatrix;
50 this.goalSum = 5; //TODO this should be set from XML-document
51 this.currentSum = 0;
52 try {
53 this.numCol = squareMatrix.length;
54 this.numRow = squareMatrix[0].length;
55 } catch(NullPointerException e) {
56 //TODO Felmeddelande
57 e.printStackTrace();
58 return;
61 // Add towers to TowerSquares
62 if (towers != null) {
63 for (Tower tower : towers) {
64 addTower(tower);
66 this.towers = towers;
69 // Set width and height for map
70 this.width = squareSize * numCol;
71 this.height = squareSize * numRow;
73 this.goalSquares = extractGoalSquares();
74 this.startSquares = extractStartSquares();
75 // Make all startSquares observe each other
76 for (StartSquare s1 : startSquares) {
77 for (StartSquare s2 : startSquares) {
78 if (s1 != s2) {
79 logger.info("StartSquare observable: " + s1
80 + ", is observed by " + s2);
81 s2.addObserver(s1);
86 initTurnSquares();
89 public MapSquare getMapSquareAtPoint(int x, int y) {
90 return getMapSquareAtPoint(new Point(x, y));
93 public MapSquare getMapSquareAtPoint(Point point) {
94 //TODO testa algoritmen
95 int x = point.x;
96 int y = point.y;
98 if (x > width || y > height) {
99 throw new IllegalArgumentException("Position is " +
100 "outside of map bounds.");
103 int col = x / AntiTD.SQUARE_SIZE;
104 int row = y / AntiTD.SQUARE_SIZE;
106 return squareMatrix[col][row];
109 public void setMapSquareAtPoint(int x, int y, MapSquare mapSquare) {
110 setMapSquareAtPoint(new Point(x, y), mapSquare);
113 public void setMapSquareAtPoint(Point point, MapSquare mapSquare) {
114 int x = point.x;
115 int y = point.y;
117 if (x > width || y > height) {
118 throw new IllegalArgumentException("Position is " +
119 "outside of map bounds.");
122 int col = x / AntiTD.SQUARE_SIZE;
123 int row = y / AntiTD.SQUARE_SIZE;
125 squareMatrix[col][row] = mapSquare;
128 public Image getMapImage() {
129 Image backgroundImage = new BufferedImage(width, height,
130 BufferedImage.TYPE_INT_RGB);
131 Graphics g = backgroundImage.getGraphics();
133 for (MapSquare[] row : squareMatrix) {
134 for (MapSquare square : row) {
135 square.paint(g);
138 return backgroundImage;
141 public Dimension getDimension() {
142 return new Dimension(width, height);
145 private GoalSquare[] extractGoalSquares() {
146 List<GoalSquare> squares = new ArrayList<GoalSquare>();
147 for (MapSquare[] row : squareMatrix) {
148 for (MapSquare square : row) {
149 if (square instanceof GoalSquare) {
150 squares.add((GoalSquare) square);
154 GoalSquare[] goalSquares = squares.toArray(new GoalSquare[squares.size()]);
155 //arr = list.toArray(new MyBean[list.size()]);
156 return goalSquares;
160 * Extract all StartSquares from this Level.
162 * @return All StartSquares in this Level.
164 private StartSquare[] extractStartSquares() {
165 List<StartSquare> squares = new ArrayList<StartSquare>();
166 for (MapSquare[] row : squareMatrix) {
167 for (MapSquare square : row) {
168 if (square instanceof StartSquare) {
169 squares.add((StartSquare) square);
173 StartSquare[] startSquares = squares.toArray(new StartSquare[squares.size()]);
174 //arr = list.toArray(new MyBean[list.size()]);
175 return startSquares;
178 private TowerSquare getRandomFreeTowerSquare() {
179 List<TowerSquare> squares = extractTowerSquares();
180 List<TowerSquare> freeSquares = new ArrayList<TowerSquare>();
182 for (TowerSquare square : squares) {
183 if (square.isAvailable()) {
184 freeSquares.add(square);
187 if (freeSquares.isEmpty()) {
188 // TODO What should happen if there are no free towersquares?
189 return null;
191 int index = (int) (freeSquares.size()*Math.random());
192 return freeSquares.get(index);
195 public List<TowerSquare> extractTowerSquares() {
196 // TODO What should happen if there are no towersquares?
197 List<TowerSquare> squares = new ArrayList<TowerSquare>();
198 for (MapSquare[] row : squareMatrix) {
199 for (MapSquare square : row) {
200 if (square instanceof TowerSquare) {
201 squares.add((TowerSquare) square);
205 return squares;
209 * Extract all MapSquare of type TurnSquare from this Level.
211 * @return All TurnSquares in this Level.
213 public List<TurnSquare> extractTurnSquares() {
214 // TODO What should happen if there are no TurnSquares?
215 List<TurnSquare> squares = new ArrayList<TurnSquare>();
216 for (MapSquare[] row : squareMatrix) {
217 for (MapSquare square : row) {
218 if (square instanceof TurnSquare) {
219 squares.add((TurnSquare) square);
223 return squares;
226 // TODO: test implementation.
228 * @param square
229 * @param range Should an int describing how many MapSquares away from
230 * specified MapSquares to return.
231 * @return
233 public List<MapSquare> getNeighbours(MapSquare square, int range) {
234 List<MapSquare> neighbours = new ArrayList<MapSquare>();
235 int col = square.getX() / AntiTD.SQUARE_SIZE;
236 int row = square.getY() / AntiTD.SQUARE_SIZE;
238 int scanWidth = range * 2 + 1;
240 int colLeft = col - range;
241 int rowTop = row - range;
243 logger.info("Range: " + range + ", colLeft: " + colLeft
244 + ", rowTop: " + rowTop + ", scanWidth: " + scanWidth);
246 // TODO: square is added as neighbours to itself.
248 for (int tmpRow = rowTop;
249 tmpRow < scanWidth + rowTop;
250 tmpRow++) {
252 for (int tmpCol = colLeft;
253 tmpCol < scanWidth + colLeft;
254 tmpCol++) {
256 if (tmpCol >= 0 && tmpCol < numCol
257 && tmpRow >= 0 && tmpRow < numRow
258 && (tmpRow != row || tmpCol != col)) {
259 logger.info("Adding neigbour for: " + square + "\n"
260 + " At col: " + tmpCol + ", row: " + tmpRow);
261 neighbours.add(squareMatrix[tmpCol][tmpRow]);
265 logger.info(neighbours.size() + " neighbours found.");
266 return neighbours;
269 private void initTurnSquares() {
270 // TODO: Write tests
271 for (TurnSquare turnSquare : extractTurnSquares()) {
272 int col = turnSquare.getX() / AntiTD.SQUARE_SIZE;
273 int row = turnSquare.getY() / AntiTD.SQUARE_SIZE;
274 if (row - 1 >= 0
275 && squareMatrix[col][row - 1] instanceof PathSquare) {
276 turnSquare.addDirection(Direction.UP);
278 if (col + 1 < numCol
279 && squareMatrix[col + 1][row] instanceof PathSquare) {
280 turnSquare.addDirection(Direction.RIGHT);
282 if (row + 1 < numRow
283 && squareMatrix[col][row + 1] instanceof PathSquare) {
284 turnSquare.addDirection(Direction.DOWN);
286 if (col - 1 >= 0
287 && squareMatrix[col - 1][row] instanceof PathSquare) {
288 turnSquare.addDirection(Direction.LEFT);
293 public GoalSquare[] getGoalSquares() {
294 return this.goalSquares;
297 public StartSquare[] getStartSquares() {
298 return this.startSquares;
302 * Gets the name of this Level.
304 * @return The name of this Level.
306 public String getName() {
307 return this.name;
311 * Returns an Array representation of this map.
313 * @return An Array representation of this map.
315 public MapSquare[][] toArray() {
316 return squareMatrix;
319 public StartSquare getActiveStartSquare() {
320 for (StartSquare square : startSquares) {
321 if (square.isActive()) {
322 return square;
325 throw new NoActiveStartSquareException();
328 public void addTower(Tower t) {
329 TowerSquare square = getRandomFreeTowerSquare();
330 if (square != null) {
331 System.out.println("Adding tower!");
332 System.out.println("Free TowerSquare has point @ (" + square.getX() + ", " + square.getY() + ")");
333 System.out.println("Free TowerSquare has centerpoint @ (" + square.getCenterX() + ", " + square.getCenterY() + ")");
334 // If there is a free square, place tower in the center of square
335 Point tPos = new Point(square.getCenterX() - (t.getWidth()/2)
336 , square.getCenterY() - (t.getHeight()/2));
337 t.setPostition(tPos);
338 square.setTower(t);
340 System.out.println("Tower placed @ (" + tPos.x + ", " + tPos.y + ")");
342 //Register as observer for the neighbours in range
343 int shootRange = t.getRange();
344 int squareRange =
345 (int) Math.ceil((shootRange - AntiTD.SQUARE_SIZE*0.5)
346 / (AntiTD.SQUARE_SIZE));
348 List<MapSquare> neighbours
349 = getNeighbours(square, squareRange);
350 logger.info("There are >" + neighbours.size()
351 + "< neighbours in range >" + t.getRange() + "< pixels");
353 for (MapSquare neighbour: neighbours) {
354 if (neighbour instanceof PathSquare) {
355 logger.info("Adding tower-observer: " + t
356 + " to: " + neighbour);
357 neighbour.addObserver(t);
360 } else {
361 throw new IllegalArgumentException("No available towersquares");
365 public Collection<Tower> getTowers() {
366 return this.towers;
369 public int getCurrentSum() {
370 return this.currentSum;