12 import java.util.ArrayList; |
12 import java.util.ArrayList; |
13 |
13 |
14 import javax.swing.JPanel; |
14 import javax.swing.JPanel; |
15 |
15 |
16 public class Board extends JPanel { |
16 public class Board extends JPanel { |
17 static final long serialVersionUID = 1L; |
17 static final long serialVersionUID = 1L; |
18 |
18 |
19 protected boolean UNDO_DEBUG = false; |
19 protected boolean UNDO_DEBUG = false; |
20 |
20 |
21 protected Piece board_pieces[]; |
21 protected Piece board_pieces[]; |
22 private Piece pieces[]; |
22 private Piece pieces[]; |
23 |
23 |
24 protected ArrayList<History> stack; |
24 protected ArrayList<History> stack; |
25 protected int moveNr; |
25 protected int moveNr; |
26 |
26 |
27 protected static final int EMPTY = 0; |
27 protected static final int EMPTY = 0; |
28 |
28 |
29 Color color_black; |
29 Color color_black; |
30 Color color_white; |
30 Color color_white; |
31 |
31 |
32 int iHeight; |
32 int iHeight; |
33 int iWidth; |
33 int iWidth; |
34 int xPos; |
34 int xPos; |
35 int yPos; |
35 int yPos; |
36 |
36 |
37 boolean black; |
37 boolean black; |
38 boolean blacksTurn; |
38 boolean blacksTurn; |
39 |
39 |
40 MouseListener listener; |
40 MouseListener listener; |
41 |
41 |
42 /** |
42 /** |
43 * The init method initializes an empty board with a history. |
43 * The init method initializes an empty board with a history. |
44 */ |
44 */ |
45 public void init() { |
45 public void init() { |
46 int i; |
46 int i; |
47 pieces = new Piece[64]; |
47 pieces = new Piece[64]; |
48 |
48 |
49 for (i = 0; i < 64; i++) { |
49 for (i = 0; i < 64; i++) { |
50 pieces[i] = new Piece(null, null, EMPTY, 0); |
50 pieces[i] = new Piece(null, null, EMPTY, 0); |
51 } |
51 } |
52 |
52 |
53 xPos = 0; |
53 xPos = 0; |
54 yPos = 0; |
54 yPos = 0; |
55 |
55 |
56 black = false; |
56 black = false; |
57 blacksTurn = false; |
57 blacksTurn = false; |
58 board_pieces = getPieces(pieces); |
58 board_pieces = getPieces(pieces); |
59 stack = new ArrayList<History>(); |
59 stack = new ArrayList<History>(); |
60 moveNr = 0; |
60 moveNr = 0; |
61 } |
61 } |
62 |
62 |
63 public Board(int w, int h) { |
63 public Board(int w, int h) { |
64 iWidth = w; |
64 iWidth = w; |
65 iHeight = h; |
65 iHeight = h; |
66 color_white = new Color(255, 255, 255); |
66 color_white = new Color(255, 255, 255); |
67 color_black = new Color(50, 100, 200); |
67 color_black = new Color(50, 100, 200); |
68 setPreferredSize(new Dimension(8 * iWidth, 8 * iHeight)); |
68 setPreferredSize(new Dimension(8 * iWidth, 8 * iHeight)); |
69 |
69 |
70 init(); |
70 init(); |
71 listener = new MouseListener(iWidth, iHeight); |
71 listener = new MouseListener(iWidth, iHeight); |
72 addMouseListener(listener); |
72 addMouseListener(listener); |
73 } |
73 } |
74 |
74 |
75 /** |
75 /** |
76 * getPiece returns a Piece-Object from the Board Cache. It might not be |
76 * getPiece returns a Piece-Object from the Board Cache. It might not be |
77 * visible on the current board. |
77 * visible on the current board. |
78 */ |
78 */ |
79 public Piece getPiece(int t) { |
79 public Piece getPiece(int t) { |
80 return pieces[t]; |
80 return pieces[t]; |
81 } |
81 } |
82 |
82 |
83 /** |
83 /** |
84 * setPiece sets a Piece-Object into the Board Cache and will not be |
84 * setPiece sets a Piece-Object into the Board Cache and will not be |
85 * visible. |
85 * visible. |
86 */ |
86 */ |
87 protected void setPiece(int t, Piece p) { |
87 protected void setPiece(int t, Piece p) { |
88 pieces[t] = p; |
88 pieces[t] = p; |
89 } |
89 } |
90 |
90 |
91 protected Piece[] getPieces() { |
91 protected Piece[] getPieces() { |
92 return getPieces(pieces); |
92 return getPieces(pieces); |
93 } |
93 } |
94 |
94 |
95 private Piece[] getPieces(Piece[] which_pieces) { |
95 private Piece[] getPieces(Piece[] which_pieces) { |
96 Piece[] p = new Piece[64]; |
96 Piece[] p = new Piece[64]; |
97 int i; |
97 int i; |
98 |
98 |
99 for (i = 0; i < 64; i++) |
99 for (i = 0; i < 64; i++) |
100 p[i] = new Piece(which_pieces[i]); |
100 p[i] = new Piece(which_pieces[i]); |
101 |
101 |
102 return p; |
102 return p; |
103 } |
103 } |
104 |
104 |
105 protected void setPieces(Piece[] p) { |
105 protected void setPieces(Piece[] p) { |
106 pieces = p; |
106 pieces = p; |
107 } |
107 } |
108 |
108 |
109 /** |
109 /** |
110 * needed in paint(Graphics g) |
110 * needed in paint(Graphics g) |
111 */ |
111 */ |
112 private Image getBoardImage(int i) { |
112 private Image getBoardImage(int i) { |
113 return board_pieces[i].image; |
113 return board_pieces[i].image; |
114 } |
114 } |
115 |
115 |
116 /** |
116 /** |
117 * getMouseListener returns a valid MouseListener for this Board. |
117 * getMouseListener returns a valid MouseListener for this Board. |
118 */ |
118 */ |
119 public MouseListener getMouseListener() { |
119 public MouseListener getMouseListener() { |
120 return listener; |
120 return listener; |
121 } |
121 } |
122 |
122 |
123 /** |
123 /** |
124 * currentMove returns the current stack.size(). |
124 * currentMove returns the current stack.size(). |
125 */ |
125 */ |
126 public int currentMove() { |
126 public int currentMove() { |
127 return stack.size(); |
127 return stack.size(); |
128 } |
128 } |
129 |
129 |
130 /** |
130 /** |
131 * returns the color of piece[i]. |
131 * returns the color of piece[i]. |
132 */ |
132 */ |
133 public String getColor(int i) { |
133 public String getColor(int i) { |
134 return pieces[i].color; |
134 return pieces[i].color; |
135 } |
135 } |
136 |
136 |
137 /** |
137 /** |
138 * returns the current Value of a particular piece. |
138 * returns the current Value of a particular piece. |
139 */ |
139 */ |
140 public int getValue(int i) { |
140 public int getValue(int i) { |
141 return pieces[i].value; |
141 return pieces[i].value; |
142 } |
142 } |
143 |
143 |
144 /** |
144 /** |
145 * Defined Integer Constants: EMTPY = 0 |
145 * Defined Integer Constants: EMTPY = 0 |
146 */ |
146 */ |
147 public int getType(int i) { |
147 public int getType(int i) { |
148 return pieces[i].type; |
148 return pieces[i].type; |
149 } |
149 } |
150 |
150 |
151 public boolean isEmpty(int i) { |
151 public boolean isEmpty(int i) { |
152 if (pieces[i].type == EMPTY) |
152 if (pieces[i].type == EMPTY) |
153 return true; |
153 return true; |
154 return false; |
154 return false; |
155 } |
155 } |
156 |
156 |
157 boolean BoardisEmpty(int i) { |
157 boolean BoardisEmpty(int i) { |
158 if (board_pieces[i].type == EMPTY) |
158 if (board_pieces[i].type == EMPTY) |
159 return true; |
159 return true; |
160 return false; |
160 return false; |
161 } |
161 } |
162 |
162 |
163 /** |
163 /** |
164 * blacksTurn = true -> Black moves blacksTurn = false -> White moves |
164 * blacksTurn = true -> Black moves blacksTurn = false -> White moves |
165 */ |
165 */ |
166 public boolean isBlacksTurn() { |
166 public boolean isBlacksTurn() { |
167 return blacksTurn; |
167 return blacksTurn; |
168 } |
168 } |
169 |
169 |
170 public void setBlacksTurn(boolean b) { |
170 public void setBlacksTurn(boolean b) { |
171 blacksTurn = b; |
171 blacksTurn = b; |
172 } |
172 } |
173 |
173 |
174 /** |
174 /** |
175 * returns true, when piece[i] is white |
175 * returns true, when piece[i] is white |
176 */ |
176 */ |
177 public boolean isWhite(int i) { |
177 public boolean isWhite(int i) { |
178 if (isEmpty(i)) |
178 if (isEmpty(i)) |
179 return false; |
179 return false; |
180 |
180 |
181 if (pieces[i].color.equals("white")) |
181 if (pieces[i].color.equals("white")) |
182 return true; |
182 return true; |
183 return false; |
183 return false; |
184 } |
184 } |
185 |
185 |
186 /** |
186 /** |
187 * returns true, when piece[i] is black |
187 * returns true, when piece[i] is black |
188 */ |
188 */ |
189 public boolean isBlack(int i) { |
189 public boolean isBlack(int i) { |
190 if (isEmpty(i)) |
190 if (isEmpty(i)) |
191 return false; |
191 return false; |
192 |
192 |
193 if (pieces[i].color.equals("black")) |
193 if (pieces[i].color.equals("black")) |
194 return true; |
194 return true; |
195 return false; |
195 return false; |
196 } |
196 } |
197 |
197 |
198 /** |
198 /** |
199 * returns true, when both pieces have opposite colors |
199 * returns true, when both pieces have opposite colors |
200 */ |
200 */ |
201 public boolean isEnemy(int t, int o) { |
201 public boolean isEnemy(int t, int o) { |
202 if (isEmpty(t)) |
202 if (isEmpty(t)) |
203 return false; |
203 return false; |
204 |
204 |
205 if (!pieces[t].color.equals(pieces[o].color)) |
205 if (!pieces[t].color.equals(pieces[o].color)) |
206 return true; |
206 return true; |
207 return false; |
207 return false; |
208 } |
208 } |
209 |
209 |
210 /** |
210 /** |
211 * returns true, when both pieces have the same color |
211 * returns true, when both pieces have the same color |
212 */ |
212 */ |
213 public boolean isSamePiece(int t, int o) { |
213 public boolean isSamePiece(int t, int o) { |
214 if (isEmpty(t)) |
214 if (isEmpty(t)) |
215 return false; |
215 return false; |
216 |
216 |
217 if (pieces[t].color.equals(pieces[o].color)) |
217 if (pieces[t].color.equals(pieces[o].color)) |
218 return true; |
218 return true; |
219 return false; |
219 return false; |
220 } |
220 } |
221 |
221 |
222 /** |
222 /** |
223 * This function checks for the color of the piece at piece[i] and returns |
223 * This function checks for the color of the piece at piece[i] and returns |
224 * true, if the color matches the current Turn. |
224 * true, if the color matches the current Turn. |
225 */ |
225 */ |
226 public boolean validTurn(int i) { |
226 public boolean validTurn(int i) { |
227 if (isEmpty(i)) |
227 if (isEmpty(i)) |
228 return false; |
228 return false; |
229 |
229 |
230 if (getColor(i).equals("white") && isBlacksTurn()) |
230 if (getColor(i).equals("white") && isBlacksTurn()) |
231 return false; |
231 return false; |
232 if (getColor(i).equals("black") && !isBlacksTurn()) |
232 if (getColor(i).equals("black") && !isBlacksTurn()) |
233 return false; |
233 return false; |
234 return true; |
234 return true; |
235 } |
235 } |
236 |
236 |
237 /** |
237 /** |
238 * simulates a "valid" move or returns false. all changes are relative to |
238 * simulates a "valid" move or returns false. all changes are relative to |
239 * pieces and will not be painted. This method sets internal variables for |
239 * pieces and will not be painted. This method sets internal variables for |
240 * the rochade() method, which will be overidden. |
240 * the rochade() method, which will be overidden. |
241 */ |
241 */ |
242 public boolean simulateMove(int t, int o) { |
242 public boolean simulateMove(int t, int o) { |
243 if (!validMove(t, o)) { |
243 if (!validMove(t, o)) { |
244 return false; |
244 return false; |
245 } |
245 } |
246 |
246 |
247 push(pieces[t], t, pieces[o], o); |
247 push(pieces[t], t, pieces[o], o); |
248 |
248 |
249 pieces[t] = new Piece(pieces[o]); |
249 pieces[t] = new Piece(pieces[o]); |
250 pieces[o] = new Piece(null, null, EMPTY, 0); |
250 pieces[o] = new Piece(null, null, EMPTY, 0); |
251 |
251 |
252 return true; |
252 return true; |
253 } |
253 } |
254 |
254 |
255 /** |
255 /** |
256 * Moves a Piece on the Board at Point p |
256 * Moves a Piece on the Board at Point p |
257 */ |
257 */ |
258 public boolean move(Point p) { |
258 public boolean move(Point p) { |
259 int t; |
259 int t; |
260 int o; |
260 int o; |
261 |
261 |
262 t = (p.endy * 8) + p.endx; |
262 t = (p.endy * 8) + p.endx; |
263 o = (p.starty * 8) + p.startx; |
263 o = (p.starty * 8) + p.startx; |
264 |
264 |
265 if (t < 0 || t > 63) |
265 if (t < 0 || t > 63) |
266 return false; |
266 return false; |
267 if (o < 0 || o > 63) |
267 if (o < 0 || o > 63) |
268 return false; |
268 return false; |
269 |
269 |
270 if (validTurn(o)) |
270 if (validTurn(o)) |
271 return doMove(t, o); |
271 return doMove(t, o); |
272 |
272 |
273 System.out.println("It's not your turn!"); |
273 System.out.println("It's not your turn!"); |
274 return false; |
274 return false; |
275 } |
275 } |
276 |
276 |
277 /** |
277 /** |
278 * Moves one half-move backward. |
278 * Moves one half-move backward. |
279 */ |
279 */ |
280 public void backwards() { |
280 public void backwards() { |
281 History h1; |
281 History h1; |
282 History h2; |
282 History h2; |
283 |
283 |
284 if (moveNr < 2) |
284 if (moveNr < 2) |
285 return; |
285 return; |
286 |
286 |
287 moveNr -= 2; |
287 moveNr -= 2; |
288 |
288 |
289 h1 = stack.get(moveNr); |
289 h1 = stack.get(moveNr); |
290 h2 = stack.get(moveNr + 1); |
290 h2 = stack.get(moveNr + 1); |
291 |
291 |
292 board_pieces[h1.pos] = h1.piece; |
292 board_pieces[h1.pos] = h1.piece; |
293 board_pieces[h2.pos] = h2.piece; |
293 board_pieces[h2.pos] = h2.piece; |
294 |
294 |
295 repaint(); |
295 repaint(); |
296 } |
296 } |
297 |
297 |
298 /** |
298 /** |
299 * Moves one half-move forward. |
299 * Moves one half-move forward. |
300 */ |
300 */ |
301 public void forward() { |
301 public void forward() { |
302 History h1; |
302 History h1; |
303 History h2; |
303 History h2; |
304 |
304 |
305 if (moveNr > stack.size() - 2) |
305 if (moveNr > stack.size() - 2) |
306 return; |
306 return; |
307 |
307 |
308 h1 = stack.get(moveNr); |
308 h1 = stack.get(moveNr); |
309 h2 = stack.get(moveNr + 1); |
309 h2 = stack.get(moveNr + 1); |
310 |
310 |
311 board_pieces[h1.pos] = h2.piece; |
311 board_pieces[h1.pos] = h2.piece; |
312 board_pieces[h2.pos] = new Piece(null, null, EMPTY, 0); |
312 board_pieces[h2.pos] = new Piece(null, null, EMPTY, 0); |
313 |
313 |
314 moveNr += 2; |
314 moveNr += 2; |
315 repaint(); |
315 repaint(); |
316 } |
316 } |
317 |
317 |
318 /** |
318 /** |
319 * pushes 2 pieces onto the stack. |
319 * pushes 2 pieces onto the stack. |
320 */ |
320 */ |
321 public void push(Piece p1, int t, Piece p2, int o) { |
321 public void push(Piece p1, int t, Piece p2, int o) { |
322 stack.add(new History(p1, t, isBlacksTurn())); |
322 stack.add(new History(p1, t, isBlacksTurn())); |
323 stack.add(new History(p2, o, isBlacksTurn())); |
323 stack.add(new History(p2, o, isBlacksTurn())); |
324 } |
324 } |
325 |
325 |
326 /** |
326 /** |
327 * pop: undo the push operation. |
327 * pop: undo the push operation. |
328 */ |
328 */ |
329 public void undo() { |
329 public void undo() { |
330 History h1; |
330 History h1; |
331 History h2; |
331 History h2; |
332 int size = stack.size(); |
332 int size = stack.size(); |
333 |
333 |
334 if (size < 2) |
334 if (size < 2) |
335 return; |
335 return; |
336 |
336 |
337 h1 = stack.remove(size - 1); |
337 h1 = stack.remove(size - 1); |
338 h2 = stack.remove(size - 2); |
338 h2 = stack.remove(size - 2); |
339 |
339 |
340 pieces[h1.pos] = h1.piece; |
340 pieces[h1.pos] = h1.piece; |
341 pieces[h2.pos] = h2.piece; |
341 pieces[h2.pos] = h2.piece; |
342 |
342 |
343 /* Reset the current player */ |
343 /* Reset the current player */ |
344 setBlacksTurn(h2.turn); |
344 setBlacksTurn(h2.turn); |
345 } |
345 } |
346 |
346 |
347 /** |
347 /** |
348 * This method must be implemented in your "GameBoard" Return value: TRUE: |
348 * This method must be implemented in your "GameBoard" Return value: TRUE: |
349 * the move IS possible Return value: FALSE: the move IS NOT possible |
349 * the move IS possible Return value: FALSE: the move IS NOT possible |
350 */ |
350 */ |
351 public boolean validMove(int t, int o) { |
351 public boolean validMove(int t, int o) { |
352 System.out.println("public boolean validMove(int t, int o): Implement me"); |
352 System.out.println("public boolean validMove(int t, int o): Implement me"); |
353 return false; |
353 return false; |
354 } |
354 } |
355 |
355 |
356 /** |
356 /** |
357 * This method must be implemented in your "GameBoard" Return value: TRUE: |
357 * This method must be implemented in your "GameBoard" Return value: TRUE: |
358 * the move was performed Return value: FALSE: the move was not performed |
358 * the move was performed Return value: FALSE: the move was not performed |
359 */ |
359 */ |
360 public boolean doMove(int t, int o) { |
360 public boolean doMove(int t, int o) { |
361 System.out.println("public boolean doMove(int t, int o): Implement me"); |
361 System.out.println("public boolean doMove(int t, int o): Implement me"); |
362 return false; |
362 return false; |
363 } |
363 } |
364 |
364 |
365 public void update(Graphics g) { |
365 public void update(Graphics g) { |
366 paint(g); |
366 paint(g); |
367 } |
367 } |
368 |
368 |
369 public void paint(Graphics g) { |
369 public void paint(Graphics g) { |
370 for (int i = 0; i < 8; i++) { |
370 for (int i = 0; i < 8; i++) { |
371 for (int j = 0; j < 8; j++) { |
371 for (int j = 0; j < 8; j++) { |
372 if (black == true) { |
372 if (black == true) { |
373 g.setColor(color_black); |
373 g.setColor(color_black); |
374 g.fillRect(xPos, yPos, iWidth, iHeight); |
374 g.fillRect(xPos, yPos, iWidth, iHeight); |
375 black = false; |
375 black = false; |
376 } else { |
376 } else { |
377 g.setColor(color_white); |
377 g.setColor(color_white); |
378 g.fillRect(xPos, yPos, iWidth, iHeight); |
378 g.fillRect(xPos, yPos, iWidth, iHeight); |
379 black = true; |
379 black = true; |
380 } |
380 } |
381 if (!BoardisEmpty((i * 8) + j)) |
381 if (!BoardisEmpty((i * 8) + j)) |
382 g.drawImage(getBoardImage((i * 8) + j), xPos + 5, yPos, this); |
382 g.drawImage(getBoardImage((i * 8) + j), xPos + 5, yPos, this); |
383 xPos += iWidth; |
383 xPos += iWidth; |
384 } |
384 } |
385 xPos = 0; |
385 xPos = 0; |
386 yPos += iHeight; |
386 yPos += iHeight; |
387 black = !black; |
387 black = !black; |
388 } |
388 } |
389 xPos = 0; |
389 xPos = 0; |
390 yPos = 0; |
390 yPos = 0; |
391 } |
391 } |
392 } |
392 } |