1 package se
.umu
.cs
.dit06ajnajs
.level
;
3 import java
.awt
.Dimension
;
4 import java
.awt
.Graphics
;
7 import java
.awt
.image
.BufferedImage
;
8 import java
.util
.ArrayList
;
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
;
19 * Describe class <code>Level</code> here.
21 * @author Anton Johansson, dit06ajn@cs.umu.se
22 * Andreas Jacobsson, dit06ajs@cs.umu.se
26 private static Logger logger
= Logger
.getLogger("AntiTD");
29 private int unitsToWin
;
30 private int clearedUnits
;
31 private int squareSize
;
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 Collection
<Tower
> towers
, int unitsToWin
) {
43 this(name
, squareMatrix
);
45 // Add towers to TowerSquares
47 this.unitsToWin
= unitsToWin
;
48 for (Tower tower
: towers
) {
53 public Level(String name
, MapSquare
[][] squareMatrix
) {
55 this.squareSize
= AntiTD
.SQUARE_SIZE
;
56 this.squareMatrix
= squareMatrix
;
57 this.clearedUnits
= 0;
59 this.numCol
= squareMatrix
.length
;
60 this.numRow
= squareMatrix
[0].length
;
61 } catch(NullPointerException e
) {
67 // Set width and height for map
68 this.width
= squareSize
* numCol
;
69 this.height
= squareSize
* numRow
;
71 this.goalSquares
= extractGoalSquares();
72 this.startSquares
= extractStartSquares();
73 // Make all startSquares observe each other
74 for (StartSquare s1
: startSquares
) {
75 for (StartSquare s2
: startSquares
) {
77 logger
.info("StartSquare observable: " + s1
78 + ", is observed by " + s2
);
86 public void resetLevel() {
87 this.clearedUnits
= 0;
88 // Set one StartSquare as active
89 startSquares
[0].click();
93 public MapSquare
getMapSquareAtPoint(int x
, int y
) {
94 return getMapSquareAtPoint(new Point(x
, y
));
97 public MapSquare
getMapSquareAtPoint(Point point
) {
98 //TODO testa algoritmen
102 if (x
> width
|| y
> height
108 int col
= x
/ AntiTD
.SQUARE_SIZE
;
109 int row
= y
/ AntiTD
.SQUARE_SIZE
;
111 return squareMatrix
[col
][row
];
114 public void setMapSquareAtPoint(int x
, int y
, MapSquare mapSquare
) {
115 setMapSquareAtPoint(new Point(x
, y
), mapSquare
);
118 public void setMapSquareAtPoint(Point point
, MapSquare mapSquare
) {
122 if (x
> width
|| y
> height
) {
123 throw new IllegalArgumentException("Position is " +
124 "outside of map bounds.");
127 int col
= x
/ AntiTD
.SQUARE_SIZE
;
128 int row
= y
/ AntiTD
.SQUARE_SIZE
;
130 squareMatrix
[col
][row
] = mapSquare
;
133 public Image
getMapImage() {
134 logger
.info("------> getMapImage() -> " + Thread
.currentThread().toString());
135 Image backgroundImage
= new BufferedImage(width
, height
,
136 BufferedImage
.TYPE_INT_RGB
);
137 Graphics g
= backgroundImage
.getGraphics();
139 for (MapSquare
[] row
: squareMatrix
) {
140 for (MapSquare square
: row
) {
144 return backgroundImage
;
147 public Dimension
getDimension() {
148 return new Dimension(width
, height
);
151 private GoalSquare
[] extractGoalSquares() {
152 List
<GoalSquare
> squares
= new ArrayList
<GoalSquare
>();
153 for (MapSquare
[] row
: squareMatrix
) {
154 for (MapSquare square
: row
) {
155 if (square
instanceof GoalSquare
) {
156 squares
.add((GoalSquare
) square
);
160 GoalSquare
[] goalSquares
= squares
.toArray(new GoalSquare
[squares
.size()]);
161 //arr = list.toArray(new MyBean[list.size()]);
166 * Extract all StartSquares from this Level.
168 * @return All StartSquares in this Level.
170 private StartSquare
[] extractStartSquares() {
171 List
<StartSquare
> squares
= new ArrayList
<StartSquare
>();
172 for (MapSquare
[] row
: squareMatrix
) {
173 for (MapSquare square
: row
) {
174 if (square
instanceof StartSquare
) {
175 squares
.add((StartSquare
) square
);
179 StartSquare
[] startSquares
= squares
.toArray(new StartSquare
[squares
.size()]);
180 //arr = list.toArray(new MyBean[list.size()]);
184 private TowerSquare
getRandomFreeTowerSquare() {
185 List
<TowerSquare
> squares
= extractTowerSquares();
186 List
<TowerSquare
> freeSquares
= new ArrayList
<TowerSquare
>();
188 for (TowerSquare square
: squares
) {
189 if (square
.isAvailable()) {
190 freeSquares
.add(square
);
193 if (freeSquares
.isEmpty()) {
194 // TODO What should happen if there are no free towersquares?
197 int index
= (int) (freeSquares
.size()*Math
.random());
198 return freeSquares
.get(index
);
201 public List
<TowerSquare
> extractTowerSquares() {
202 // TODO What should happen if there are no towersquares?
203 List
<TowerSquare
> squares
= new ArrayList
<TowerSquare
>();
204 for (MapSquare
[] row
: squareMatrix
) {
205 for (MapSquare square
: row
) {
206 if (square
instanceof TowerSquare
) {
207 squares
.add((TowerSquare
) square
);
215 * Extract all MapSquare of type TurnSquare from this Level.
217 * @return All TurnSquares in this Level.
219 public List
<TurnSquare
> extractTurnSquares() {
220 // TODO What should happen if there are no TurnSquares?
221 List
<TurnSquare
> squares
= new ArrayList
<TurnSquare
>();
222 for (MapSquare
[] row
: squareMatrix
) {
223 for (MapSquare square
: row
) {
224 if (square
instanceof TurnSquare
) {
225 squares
.add((TurnSquare
) square
);
232 // TODO: test implementation.
235 * @param range Should an int describing how many MapSquares away from
236 * specified MapSquares to return.
239 public List
<MapSquare
> getNeighbours(MapSquare square
, int range
) {
240 List
<MapSquare
> neighbours
= new ArrayList
<MapSquare
>();
241 int col
= square
.getX() / AntiTD
.SQUARE_SIZE
;
242 int row
= square
.getY() / AntiTD
.SQUARE_SIZE
;
244 int scanWidth
= range
* 2 + 1;
246 int colLeft
= col
- range
;
247 int rowTop
= row
- range
;
249 logger
.info("Range: " + range
+ ", colLeft: " + colLeft
250 + ", rowTop: " + rowTop
+ ", scanWidth: " + scanWidth
);
252 // TODO: square is added as neighbours to itself.
254 for (int tmpRow
= rowTop
;
255 tmpRow
< scanWidth
+ rowTop
;
258 for (int tmpCol
= colLeft
;
259 tmpCol
< scanWidth
+ colLeft
;
262 if (tmpCol
>= 0 && tmpCol
< numCol
263 && tmpRow
>= 0 && tmpRow
< numRow
264 && (tmpRow
!= row
|| tmpCol
!= col
)) {
265 logger
.info("Adding neigbour for: " + square
+ "\n"
266 + " At col: " + tmpCol
+ ", row: " + tmpRow
);
267 neighbours
.add(squareMatrix
[tmpCol
][tmpRow
]);
271 logger
.info(neighbours
.size() + " neighbours found.");
275 private void initTurnSquares() {
277 for (TurnSquare turnSquare
: extractTurnSquares()) {
278 int col
= turnSquare
.getX() / AntiTD
.SQUARE_SIZE
;
279 int row
= turnSquare
.getY() / AntiTD
.SQUARE_SIZE
;
281 && squareMatrix
[col
][row
- 1] instanceof PathSquare
) {
282 turnSquare
.addDirection(Direction
.UP
);
285 && squareMatrix
[col
+ 1][row
] instanceof PathSquare
) {
286 turnSquare
.addDirection(Direction
.RIGHT
);
289 && squareMatrix
[col
][row
+ 1] instanceof PathSquare
) {
290 turnSquare
.addDirection(Direction
.DOWN
);
293 && squareMatrix
[col
- 1][row
] instanceof PathSquare
) {
294 turnSquare
.addDirection(Direction
.LEFT
);
299 public GoalSquare
[] getGoalSquares() {
300 return this.goalSquares
;
303 public StartSquare
[] getStartSquares() {
304 return this.startSquares
;
308 * Gets the name of this Level.
310 * @return The name of this Level.
312 public String
getName() {
317 * Returns an Array representation of this map.
319 * @return An Array representation of this map.
321 public MapSquare
[][] toArray() {
325 public StartSquare
getActiveStartSquare() {
326 for (StartSquare square
: startSquares
) {
327 if (square
.isActive()) {
331 throw new NoActiveStartSquareException();
334 public void addTower(Tower t
) {
335 TowerSquare square
= getRandomFreeTowerSquare();
336 if (square
!= null) {
337 //System.out.println("Adding tower!");
338 //System.out.println("Free TowerSquare has point @ (" + square.getX() + ", " + square.getY() + ")");
339 //System.out.println("Free TowerSquare has centerpoint @ (" + square.getCenterX() + ", " + square.getCenterY() + ")");
340 // If there is a free square, place tower in the center of square
341 Point tPos
= new Point(square
.getCenterX() - (t
.getWidth()/2)
342 , square
.getCenterY() - (t
.getHeight()/2));
343 t
.setPostition(tPos
);
346 System
.out
.println("Tower placed @ (" + tPos
.x
+ ", " + tPos
.y
+ ")");
348 //Register as observer for the neighbours in range
349 int shootRange
= t
.getRange();
351 (int) Math
.ceil((shootRange
- AntiTD
.SQUARE_SIZE
*0.5)
352 / (AntiTD
.SQUARE_SIZE
));
354 List
<MapSquare
> neighbours
355 = getNeighbours(square
, squareRange
);
356 logger
.info("There are >" + neighbours
.size()
357 + "< neighbours in range >" + t
.getRange() + "< pixels");
359 for (MapSquare neighbour
: neighbours
) {
360 if (neighbour
instanceof PathSquare
) {
361 logger
.info("Adding tower-observer: " + t
362 + " to: " + neighbour
);
363 neighbour
.addObserver(t
);
367 throw new IllegalArgumentException("No available towersquares");
371 public Collection
<Tower
> getTowers() {
378 public void resetTowers() {
379 for (Tower tower
: this.towers
) {
384 public int getUnitsToWin() {
385 return this.unitsToWin
;
389 * Returns the number of units that have reached a goalsquare
390 * @return The number of units that have reached a goalsquare
393 public int getNumOfClearedUnits() {
394 return this.clearedUnits
;
398 * Adds to the number of units that have reached a goalsquare
399 * @param num Number of new units that have reached a goalsquare
401 public void addClearedUnits(int num
) {
402 this.clearedUnits
+= num
;