Source code: com/adorphuye/othello/gui/board/DefaultBoardDataModel.java
1 package com.adorphuye.othello.gui.board;
2
3 import com.adorphuye.othello.player.*;
4 import com.adorphuye.othello.gui.*;
5 import java.util.*;
6 import java.awt.*;
7
8 public class DefaultBoardDataModel implements BoardDataModel
9 {
10 public static final int ON_BOARD = -1;
11 public static final int OFF_BOARD = -2;
12 public static final int EMPTY = 0;
13
14 private int[][] data;
15 private Vector listeners = new Vector();
16 private Board board = null;
17 private Point lastMove = null;
18
19 /**
20 * @param dat */
21 public DefaultBoardDataModel(int[][] dat)
22 {
23 setData(dat);
24 }
25
26 /**
27 * @param dat */
28 public void setData(int[][] dat)
29 {
30 data = dat;
31 fireBoardChanged(new BoardEvent(BoardEvent.REFRESH,null,null,new Point(-1,-1)));
32 }
33
34 /**
35 * @return */
36 public int[][] getData()
37 {
38 return data;
39 }
40
41 /**
42 * @param p
43 * @param obj */
44 public void setDataAt(Point p, int obj)
45 {
46 if(!inBounds(p))
47 {
48 return;
49 }
50 lastMove = new Point(p);
51 fireBoardChanged(new BoardEvent(BoardEvent.PIECEUPDATE,null,sides[obj-1],p));
52 getData()[p.x][p.y] = obj;
53 }
54
55 /**
56 * @param p
57 * @return */
58 public int getDataAt(Point p)
59 {
60 if(!inBounds(p))
61 {
62 return OFF_BOARD;
63 }
64 return getData()[p.x][p.y];
65 }
66
67 /**
68 * @param l */
69 public void addBoardListener(BoardListener l)
70 {
71 listeners.addElement(l);
72 }
73
74 /**
75 * @param l */
76 public void removeBoardListener(BoardListener l)
77 {
78 listeners.removeElement(l);
79 }
80
81 /**
82 * @param evt */
83 public void fireBoardChanged(BoardEvent evt)
84 {
85 Enumeration enum = listeners.elements();
86 while(enum.hasMoreElements())
87 {
88 BoardListener b = ((BoardListener)enum.nextElement());
89 b.boardChanged(evt);
90 }
91 }
92
93 /**
94 * @return */
95 public int getMovesLeft()
96 {
97 int moves = 0;
98 int i=0,j=0;
99
100 for(i=0;i<data.length;i++)
101 for(j=0;j<data[0].length;j++)
102 {
103 if(data[i][j]>EMPTY)
104 {
105 moves++;
106 }
107 }
108
109 return (i*j)-moves;
110 }
111
112 private synchronized Vector setcan(int sid)
113 {
114 Vector moves = new Vector();
115 if(getData()!=null && getData()[0]!=null)
116 for(int i=0;i<getData().length;i++)
117 {
118 for(int j = 0;j<getData()[0].length;j++)
119 {
120 Point p = new Point(i,j);
121 int obj = getDataAt(p);
122
123 if(obj==EMPTY)
124 {
125 Vector vec = flips(p,sid);
126 boolean bb=vec.size()>0;
127 if(bb)
128 moves.addElement(p);
129 }
130 }
131 }
132 return moves;
133 }
134
135 /**
136 * @param p
137 * @param sid
138 * @return */
139 public Vector flips(Point p, int sid)
140 {
141 Vector hs = new Vector();
142
143 if(getDataAt(p)==EMPTY)
144 {
145 for(int l=0;l<8;l++)
146 {
147 Vector s = count(p,l,sid);
148 for(int k=0;k<s.size();k++)
149 {
150 hs.addElement(s.elementAt(k));
151 }
152 }
153 }
154 return hs;
155 }
156
157 private final static int[][] dirs =
158 {
159 {-1, 0, 1,-1, 1,-1, 0, 1},
160 {-1,-1,-1, 0, 0, 1, 1, 1}
161 };
162
163 private final static String[] sdirs =
164 {
165 "NW","N","NE","W","E","SW","S","SE"
166 };
167
168 public static final int VALID_MOVE = 0;
169 public static final int INVALID_MOVE = 1;
170 public static final int ILLEGAL_MOVE = 2;
171
172 /**
173 * @param p
174 * @return */
175 public boolean inBounds(Point p)
176 {
177 if(data!=null)
178 {
179 boolean b = p.x>=0 &&
180 p.y>=0 &&
181 p.x<data.length &&
182 p.y<data[0].length;
183 return b;
184 }
185 return false;
186 }
187
188 /**
189 * @param p
190 * @return */
191 public int legalMove(Point p)
192 {
193 if(inBounds(p))
194 {
195 if(getData()[p.x][p.y]==EMPTY)
196 {
197 return VALID_MOVE;
198 }
199 else
200 {
201 return INVALID_MOVE;
202 }
203 }
204 return ILLEGAL_MOVE;
205 }
206
207 /**
208 * count the flips that would happen if you put a
209 * stone at position c and looking in the direction dir.
210 */
211 private Vector count(Point p, int dir, int sid)
212 {
213 Vector hs = new Vector();
214 int x = p.x;
215 int y = p.y;
216
217 while(inBounds(new Point(x,y)))
218 {
219 x+=dirs[0][dir];
220 y+=dirs[1][dir];
221 Point pp = new Point(x,y);
222
223 if(inBounds(pp)
224 && getDataAt(pp)!=sid
225 && getDataAt(pp)!=EMPTY)
226 {
227 hs.addElement(pp);
228 }
229 else
230 {
231 if(!inBounds(pp))
232 {
233 return new Vector();
234 }
235 if(getDataAt(pp)==sid)
236 {
237 return hs;
238 }
239 return new Vector();
240 }
241 }
242 return new Vector();
243 }
244
245 /**
246 * @param obj
247 * @return */
248 public Vector getPossibleMoves(int obj)
249 {
250 return setcan(obj);
251 }
252
253 /**
254 * @return */
255 public int getMovesMade()
256 {
257 return -1;
258 }
259
260 /**
261 * @return */
262 public Object clone()
263 {
264 DefaultBoardDataModel copy = null;
265 if(getData()!=null)
266 {
267 copy = new DefaultBoardDataModel((int[][])getData().clone());
268 }
269 else
270 {
271 copy = new DefaultBoardDataModel(new int[8][8]);
272 }
273 copy.setSides(getSides());
274 return copy;
275 }
276
277 /**
278 * @return */
279 public Player getCurrentSide()
280 {
281 return ((PlayerDecorator)sides[currentSide]).getPlayer();
282 }
283
284 /**
285 * @param data */
286 public void setSides(Player[] data)
287 {
288 sides = data;
289 currentSide = 0;
290 }
291
292 /**
293 * @return */
294 public Point getLastMove()
295 {
296 return lastMove;
297 }
298
299 private int[] passtable;
300
301 /**
302 * @param p */
303 public void pass(Player p)
304 {
305 if(passtable==null)
306 {
307 passtable = new int[getSides().length];
308 }
309 passtable[p.getIndex()-1]++;
310 }
311
312 public void nextSide()
313 {
314 if(passtable==null)
315 {
316 passtable = new int[getSides().length];
317 }
318
319 fireBoardChanged(new BoardEvent(BoardEvent.HASPLAYED,null,getCurrentSide(),getLastMove()));
320
321 if(getMovesLeft()==0 )
322 {
323 return;
324 }
325
326 int sum = 0;
327 for(int i=0;i<passtable.length;i++)
328 {
329 sum+=passtable[i];
330 }
331
332 if(sum>=passtable.length)
333 {
334 System.err.println("game over");
335 }
336
337 if(!(getCurrentSide().getIndex()-1>passtable.length || getCurrentSide().getIndex()-1<0))
338 {
339 passtable[getCurrentSide().getIndex()-1] = 0;
340 currentSide = ( currentSide + 1 ) % sides.length;
341 fireBoardChanged(new BoardEvent(BoardEvent.WILLPLAY,null,getCurrentSide(),getLastMove()));
342 getCurrentSide().play();
343 }
344 }
345
346 public Player[] getSides()
347 {
348 return sides;
349 }
350
351 public Board getBoard()
352 {
353 return board;
354 }
355
356 public void setBoard(Board b)
357 {
358 board = b;
359 }
360
361 public synchronized void reset()
362 {
363 int w=getData().length;
364 int h=getData()[0].length;
365 for(int i=0;i<sides.length;i++)
366 {
367 sides[i].reset();
368 }
369 data = null;
370 System.gc();
371 setData(new int[w][h]);
372 }
373
374 private Player[] sides = null;
375 private int currentSide = -1;
376 }