-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBoardFrame.java
400 lines (367 loc) · 12.2 KB
/
BoardFrame.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Point2D;
import java.awt.geom.RectangularShape;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.text.*;
/**
* A frame component that contains the view and controller components
* of the mancala game
* @author .Brendon Yim, Bikram Singh, and Jason Chee
* Professor Kim
* CS151
*
* Project solution
* copyright 2015
* version 1
*
*/
@SuppressWarnings("serial")
/**
* The view and frame that shows the mancala game visually
*/
public class BoardFrame extends JFrame implements ChangeListener
{
private Model model;
private int[] data;
private Strategy s;
JPanel boardPanel;
final JButton undoBtn;
boolean gameOver;
/**
* Constructor that takes model as a parameter
* @param model
*/
public BoardFrame(Model model)
{
this.model = model;
data = model.getData();
gameOver = false;
initScreen();
setLayout(new BorderLayout());
setLocation(300, 200);
// undoBtn is a controller that resets the turn and last state of board
undoBtn = new JButton("Undo : "+ this.model.getUndoCounter());
undoBtn.setPreferredSize(new Dimension(80, 50));
undoBtn.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
if(BoardFrame.this.model.getUndoCounter() != 0)
{
BoardFrame.this.model.undo();
undoBtn.setText("Undo : "+ BoardFrame.this.model.getUndoCounter());
}else;
}
});
JPanel undoPanel = new JPanel();
undoPanel.add(undoBtn);
// end of undoBtn code
add(boardPanel, BorderLayout.CENTER);
add(undoPanel, BorderLayout.SOUTH);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setResizable(false);
setVisible(true);
}
/**
* Is called from the model when data is changed, updates members and view
* of this class. Checks if the game is over.
* @param e ChangeEvent object
*/
public void stateChanged(ChangeEvent e)
{
// update the view: accessors and repaint
data = model.getData();
repaint();
if(model.isFinish() && !gameOver)
{
gameOver = true;
JFrame frame = new JFrame("Declare Winner");
if (model.declareWinner() == 1)
JOptionPane.showMessageDialog(frame, "A is the winner!!!");
else if (model.declareWinner() == 2)
JOptionPane.showMessageDialog(frame, "B is the winner!!!");
else
JOptionPane.showMessageDialog(frame, "It is a tie!!!");
}
}
/**
* Initial Option Panes that lets user select style and number of stones
*/
public void initScreen()
{
Object[] options = { "Style A", "Style B" };
int input = JOptionPane.showOptionDialog(null, "Choose a Board Style:", "Board Styles", JOptionPane.DEFAULT_OPTION,
JOptionPane.DEFAULT_OPTION, null, options, options[0]);
if (input == 0)
{
boardPanel = boardContextDoWork(new StrategyGreen());
} else if (input == 1)
{
boardPanel = boardContextDoWork(new StrategyBrown());// change later
} else
{
System.exit(0);
}
Object[] optionStones = { "3", "4" };
int inputStones = JOptionPane.showOptionDialog(null, "Choose Number of Stones:", "Initial Stones",
JOptionPane.DEFAULT_OPTION, JOptionPane.DEFAULT_OPTION, null,
optionStones, optionStones[0]);
if (inputStones == 0)
{
model.refreshBoard(3);
} else if (inputStones == 1)
{
model.refreshBoard(4);
} else
{
System.exit(0);
}
}
/**
* Returns a JPanel that represents the mancala board using strategy
* pattern to insert style.
* @param strat concrete strategy
* @return JPanel containing both users' pits as controllers
*/
public JPanel boardContextDoWork(Strategy strat)
{
this.s = strat;
Color boardColor = s.getBoardColor();
Color fontColor = s.getFontColor();
Font font = s.getFont();
JPanel panCenter = new JPanel();
JPanel panLeft = new JPanel();
JPanel panRight = new JPanel();
panCenter.setLayout(new GridLayout(2, 6, 10, 10));
// B6 to B1 Controllers
for (int i = 12; i > 6; i--)
{
final Pits temp = new Pits(i);
final int pit = i;
final JLabel tempLabel = new JLabel(temp);
tempLabel.addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent e)
{
if (Model.player == 1)
{
JFrame frame = new JFrame();
JOptionPane.showMessageDialog(frame, "Player A's turn!");
} else if (model.data[pit] == 0)
{
JFrame frame = new JFrame();
JOptionPane.showMessageDialog(frame, "Pit is Empty try another one.");
} else
{
if (temp.pitShape.contains(e.getPoint()))
{
model.move(pit); //mutator
undoBtn.setText("Undo : "+model.getUndoCounter());
model.display();
}
}
}
});
JPanel tempPanel = new JPanel(new BorderLayout());
JTextPane textPane = new JTextPane();
textPane.setEditable(false);
textPane.setBackground(boardColor);
textPane.setForeground(fontColor);
textPane.setFont(font);
textPane.setText("B" + (i - 6));
StyledDocument doc = textPane.getStyledDocument();
SimpleAttributeSet center = new SimpleAttributeSet();
StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER);
doc.setParagraphAttributes(0, doc.getLength(), center, false);
tempPanel.add(textPane, BorderLayout.NORTH);
tempPanel.add(tempLabel, BorderLayout.SOUTH);
panCenter.add(tempPanel, BorderLayout.SOUTH);
tempPanel.setBackground(boardColor);
}
//A1 to A6 Controllers
for (int i = 0; i < 6; i++)
{
final Pits newPits = new Pits(i);
JLabel label = new JLabel(newPits);
final int pit = i;
label.addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent e)
{
if (Model.player == 2)
{
JFrame frame = new JFrame();
JOptionPane.showMessageDialog(frame, "Player B's turn!");
} else if (model.data[pit] == 0)
{
JFrame frame = new JFrame();
JOptionPane.showMessageDialog(frame, "Pit is Empty try another one.");
} else
{
if (newPits.pitShape.contains(e.getPoint()))
{
model.move(pit); //mutator
undoBtn.setText("Undo : "+model.getUndoCounter());
model.display();
}
}
}
});
JPanel tempPanel = new JPanel(new BorderLayout());
tempPanel.add(label, BorderLayout.NORTH);
JTextPane textPane = new JTextPane();
textPane.setBackground(boardColor);
textPane.setForeground(fontColor);
textPane.setFont(font);
textPane.setEditable(false);
textPane.setText("A" + (i + 1));
StyledDocument doc = textPane.getStyledDocument();
SimpleAttributeSet center = new SimpleAttributeSet();
StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER);
doc.setParagraphAttributes(0, doc.getLength(), center, false);
tempPanel.add(textPane, BorderLayout.SOUTH);
tempPanel.setBackground(boardColor);
panCenter.add(tempPanel, BorderLayout.SOUTH);
}
//left text pane
JTextPane paneLeft = new JTextPane();
paneLeft.setBackground(boardColor);
paneLeft.setForeground(fontColor);
paneLeft.setFont(font);
paneLeft.setEditable(false);
paneLeft.setText("M\nA\nN\nC\nA\nL\nA\n \nB");
//right text pane
JTextPane paneRight = new JTextPane();
paneRight.setBackground(boardColor);
paneRight.setForeground(fontColor);
paneRight.setFont(font);
paneRight.setEditable(false);
paneRight.setText("M\nA\nN\nC\nA\nL\nA\n \nA");
//Add text panes to left and right panels
panLeft.setLayout(new BorderLayout());
panRight.setLayout(new BorderLayout());
panLeft.add(paneLeft, BorderLayout.WEST);
panRight.add(paneRight, BorderLayout.EAST);
panLeft.add(new JLabel(new Pits(13)), BorderLayout.EAST);
panRight.add(new JLabel(new Pits(6)), BorderLayout.WEST);
//add the 2 mancala panels and pit panel to larger displayPanel
JPanel displayPanel = new JPanel();
displayPanel.add(panLeft, BorderLayout.WEST);
displayPanel.add(panCenter, BorderLayout.CENTER);
displayPanel.add(panRight, BorderLayout.EAST);
//set color
panCenter.setBackground(boardColor);
panLeft.setBackground(boardColor);
panRight.setBackground(boardColor);
displayPanel.setBackground(boardColor);
// return display panel which contains the containers and elements created
return displayPanel;
}
/**
* Represents a pit object, knows if a mouse click is contained within the
* pit shape. Painted with stones inside.
* Is called from the doWork() method, so utilizes the concrete strategy.
* @author jasonchee
*
*/
private class Pits implements Icon
{
Shape pitShape;
// Shape stoneShape = s.getStoneShape();
int pitNum = 0;
/**
* constructor for pit Icon
* @param pitNum index in data array
*/
public Pits(int pitNum)
{
this.pitNum = pitNum;
}
/**
* Checks if mouse click is inside the controller
* @param point mouse location
* @return does the pit shape contain mouse location
*/
public boolean contains(Point2D point)
{
return pitShape.contains(point);
// somehow magically make this work for mouse listener..
}
/**
* returns the height of the icon
* @return height of icon
*/
public int getIconHeight()
{
if (pitNum == 6 || pitNum == 13)
{
return s.getManH();
} else
{
return s.getPitH();
}
}
/**
* returns width of icon
* @return width of icon
*/
public int getIconWidth()
{
if (pitNum == 6 || pitNum == 13)
{
return s.getManW();
} else
{
return s.getPitW();
}
}
/**
* icon is painted with correct number of stones in the pit/mancala
* @param c properties for painting
* @param g graphics object
* @param x x location of icon
* @param y y location of icon
*/
public void paintIcon(Component c, Graphics g, int x, int y)
{
int iterateNum = data[pitNum];
if (iterateNum > 5)
{
iterateNum = 5;
}
Graphics2D g2 = (Graphics2D) g;
if (pitNum == 6 || pitNum == 13)
{
pitShape = s.getMancalaShape();
g2.setColor(s.getPitColor());
g2.fill(pitShape);
for (int i = 0; i < data[pitNum]; i++)
{
RectangularShape temp = s.getStoneShape(i, data[pitNum], true);
g2.setColor(s.getStoneColor());
g2.draw(temp);
g2.fill(temp);
}
} else
{
pitShape = s.getPitShape();
g2.setColor(s.getPitColor());
g2.fill(pitShape);
for (int i = 0; i < data[pitNum]; i++)
{
RectangularShape temp = s.getStoneShape(i, data[pitNum], false);
g2.setColor(s.getStoneColor());
g2.draw(temp);
g2.fill(temp);
}
}
}
}
}