Source code: com/adorphuye/othello/gui/Board.java
1 package com.adorphuye.othello.gui;
2
3 import java.util.*;
4 import java.awt.*;
5 import java.awt.event.*;
6 import com.adorphuye.othello.gui.board.*;
7
8 /** This class is the visual representation of an Othello (also known as Reversi) board.
9 */
10 public class Board extends Canvas implements BoardListener
11 {
12 private BoardCellRenderer renderer = new DefaultBoardCellRenderer();
13 private BoardDataModel data = null;
14
15 public static final int HORIZONTAL_CELL_SIZE = 28;
16 public static final int VERTICAL_CELL_SIZE = 28;
17
18 public static Image[] imgs = new Image[14];
19
20 private Vector colorMap = new Vector();
21
22 /** Creates a new instance of this class.
23 */
24 public Board()
25 {
26 super();
27 }
28
29 /**
30 * @param i
31 * @return */
32 private String lz(int i)
33 {
34 String s = String.valueOf(i);
35 if(i<10)
36 s = "0"+s;
37 return s;
38 }
39
40 /**
41 * @return */
42 public Dimension getPreferredSize()
43 {
44 return new Dimension(HORIZONTAL_CELL_SIZE*getXIntervals(),
45 VERTICAL_CELL_SIZE*getYIntervals());
46 }
47
48 /**
49 * @return */
50 public Dimension getMaximumSize()
51 {
52 return getPreferredSize();
53 }
54
55 /**
56 * @return */
57 public Dimension getMinimumSize()
58 {
59 return getPreferredSize();
60 }
61
62 /**
63 * @param key
64 * @param obj */
65 public void putMapping(int key, Object obj)
66 {
67 colorMap.insertElementAt(obj,key);
68 }
69
70 /**
71 * @param key
72 * @return */
73 public Object getMapping(int key)
74 {
75 if(key<0 || key>(colorMap.size()))
76 {
77 return null;
78 }
79
80 return colorMap.elementAt(key);
81 }
82
83 /**
84 * @param key */
85 public void removeColourMap(Object key)
86 {
87 colorMap.removeElement(key);
88 }
89
90 /**
91 * @param p
92 * @return */
93 public Point toBoardCoordinate(Point p)
94 {
95 return new Point((p.x*getXIntervals())/getSize().width,(p.y*getYIntervals())/getSize().height);
96 }
97
98 /**
99 * @param p
100 * @return */
101 public Point toCanvasCoordinates(Point p)
102 {
103 return new Point(p.x*getXIntervals(),p.y*getYIntervals());
104 }
105
106 /** Sets the renderer that will be used to render game pieces on this board.
107 * @see com.adorphuye.othello.gui.board.BoardCellRenderer
108 * @param r the new renderer to use
109 */
110 public void setCellRenderer(BoardCellRenderer r)
111 {
112 renderer = r;
113 }
114
115 /** Returns the current renderer used by this board to render game pieces.
116 * @return the renderer currently in use
117 */
118 public BoardCellRenderer getCellRenderer()
119 {
120 return renderer;
121 }
122
123 /**
124 * @param m */
125 public void setModel(BoardDataModel m)
126 {
127 data = m;
128 data.addBoardListener(this);
129 data.setBoard(this);
130 }
131
132 /**
133 * @return */
134 public BoardDataModel getModel()
135 {
136 return data;
137 }
138
139 /**
140 * @return */
141 public int getXIntervals()
142 {
143 if(data!=null && data.getData()!=null)
144 {
145 return data.getData().length;
146 }
147 return 1;
148 }
149
150 /**
151 * @return */
152 public int getYIntervals()
153 {
154 if(data!=null && data.getData()!=null && data.getData()[0]!=null)
155 {
156 return data.getData()[0].length;
157 }
158 return 1;
159 }
160
161 /**
162 * @param g */
163 public void update(Graphics g)
164 {
165 paint(g);
166 }
167
168 private Image img = null;
169 private Image cmg = null;
170 private Graphics gBuffer=null;
171 private Graphics cBuffer=null;
172
173 /**
174 * @param p */
175 public void repaint(Point p)
176 {
177 }
178
179 /**
180 * @param g */
181 public void paint(Graphics g)
182 {
183 try
184 {
185 int mx = getBounds().width-1;
186 int my = getBounds().height-1;
187 if(mx<1 || my<1)
188 {
189 return;
190 }
191 int dx = getXIntervals();
192 int dy = getYIntervals();
193 int sx = mx/dx;
194 int sy = my/dy;
195 int x = 0;
196 int y = 0;
197
198 if(img==null)
199 {
200 img = createImage(mx,my);
201 cmg = createImage(sx,sy);
202 gBuffer = img.getGraphics();
203 cBuffer = cmg.getGraphics();
204 }
205
206
207 gBuffer.clearRect(0,0,mx,my);
208 Component comp = null;
209
210 if(data!=null)
211 {
212 for(int i=0;i<dy;i++)
213 {
214 x = sx*i;
215 for(int j=0;j<dx;j++)
216 {
217 /*if(animating && theEvent.getPoint().x!=x && theEvent.getPoint().y!=y)
218 {
219 continue;
220 }*/
221 y = sy*j;
222 Color col = new Color(64,128,64);
223 Object cell;
224 cell = getMapping(data.getDataAt(new Point(i,j)));
225 if(animating && theEvent.getPoint().x==i && theEvent.getPoint().y==j)
226 {
227 cell = imgs[frameNum];
228 }
229
230 if(getModel().getCurrentSide() instanceof com.adorphuye.othello.player.AIPlayer)
231 {
232 comp = renderer.getBoardCellRenderer(this,false,cell,new Point(0,0));
233 }
234 else
235 {
236 comp = renderer.getBoardCellRenderer(this,false,cell,
237 new Point(0,getModel().flips(new Point(i,j),getModel().getCurrentSide().getIndex()).size()));
238 }
239 comp.setBackground(col);
240 comp.setSize(sx,sy);
241 comp.paint(cBuffer);
242 gBuffer.drawImage(cmg,x,y,sx,sy,this);
243 }
244 }
245 }
246 gBuffer.drawRect(0,0,(sx*dx)-1,(sy*dy)-1);
247 g.drawImage(img,0,0,mx,my,this);
248
249 }
250 catch(Exception e)
251 {
252 e.printStackTrace();
253 }
254 }
255
256 private int BOARD_2_BOARD = 0;
257 private int BOARD_2_BLACK = 1;
258 private int BOARD_2_WHITE = 2;
259 private int BLACK_2_WHITE = 3;
260 private int WHITE_2_BLACK = 4;
261
262 private int[][] path = new int[][]
263 {
264 { 0, 0},
265 { 7,13},
266 { 6, 0},
267 {13, 0},
268 { 0,13}
269 };
270
271 private boolean animating = false;
272 private BoardEvent theEvent = null;
273 private int frameNum = 0;
274
275 /**
276 * @param evt */
277 public void boardChanged(BoardEvent evt)
278 {
279 if(evt.getType()==BoardEvent.PIECEUPDATE)
280 {
281 try
282 {
283 theEvent = evt;
284 int ob = getModel().getDataAt(evt.getPoint());
285 int start=0;
286 int end=14;
287
288 if(ob == 0 && evt.getPlayer().getIndex()==1)
289 {
290 start=7;
291 end=13;
292 }
293 if(ob == 0 && evt.getPlayer().getIndex()==2)
294 {
295 start=6;
296 end=1;
297 }
298 if(ob == 2 && evt.getPlayer().getIndex()==1)
299 {
300 start=1;
301 end=13;
302 }
303 if(ob == 1 && evt.getPlayer().getIndex()==2)
304 {
305 start=13;
306 end=1;
307 }
308
309
310 animating = true;
311 if(start>end)
312 {
313 for(int i=start-1;i>=end;i--)
314 // for(int i=0;i<14;i+=1)
315 {
316 frameNum = i;
317 Thread.currentThread().sleep(20);
318 repaint();
319 }
320 }
321 else
322 {
323 for(int i=start;i<end;i++)
324 // for(int i=0;i<14;i+=1)
325 {
326 frameNum = i;
327 Thread.currentThread().sleep(20);
328 repaint();
329 }
330 }
331 animating = false;
332 theEvent = null;
333 }catch(Exception e)
334 {e.printStackTrace();}
335 }
336 if(evt.getType()==BoardEvent.HASPLAYED)
337 {
338 try
339 {
340 Thread.currentThread().sleep(50);
341 }catch(Exception e)
342 {}
343 }
344 repaint();
345 }
346
347 /**
348 * @param param
349 * @param param1
350 * @param param2
351 * @param param3 */
352 public void reshape(int param, int param1, int param2, int param3)
353 {
354 param2 = Math.min(param2,getPreferredSize().width);
355 param3 = Math.min(param3,getPreferredSize().height);
356 super.reshape(param, param1, param2, param3);
357 }
358 }