F:\java\knim-game\sources\ru\ifmo\knim\screens\GameScreen.java
|
1 /**
2 * @(#)GameScreen.java
3 *
4 * Copyright Anthony Yakovlev <yakovlev@rain.ifmo.ru> and Michail Lukin <michail@users.msn.com>
5 */
6
7 package ru.ifmo.knim.screens;
8
9 import com.evelopers.unimod.core.stateworks.Event;
10 import com.evelopers.unimod.runtime.ModelEngine;
11 import com.evelopers.unimod.runtime.context.Parameter;
12 import com.evelopers.unimod.runtime.context.StateMachineContextImpl;
13
14 import javax.swing.*;
15 import java.awt.*;
16 import java.awt.event.*;
17 import java.io.File;
18 import java.io.FileInputStream;
19 import java.io.FileNotFoundException;
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.net.URL;
23 import java.util.MissingResourceException;
24 import java.util.PropertyResourceBundle;
25 import java.util.ResourceBundle;
26
27 import ru.ifmo.knim.providers.*;
28 import ru.ifmo.knim.main.*;
29
30 /**
31 * Main screen of the application (singleton)
32 *
33 * @author Anthony Yakovlev
34 * @author Michail Lukin
35 */
36 public class GameScreen extends JFrame implements ActionListener {
37
38 static GameScreen screen = new GameScreen();
39 static final int MAX_LAYOUTS = 7;
40
41 ModelEngine engine;
42
43 JPanel contentPane;
44 JMenuItem exitItem, aboutItem, restartItem, mmoveItem;
45 JRadioButtonMenuItem dffEasyItem, dffHardItem, dffMediumItem;
46 JRadioButtonMenuItem [] layType;
47 JMenu gameMenu, helpMenu, difficultyItem, layoutMenu;
48 ButtonGroup dffGroup, layGroup;
49
50 FishControlPanel gamePanel;
51 StatusPanel statusPanel;
52
53 JMenuBar menuBar;
54 JButton newGameLabel;
55 ImageIcon iconStone;
56 static ResourceBundle bundle;
57
58 public static GameScreen getScreen() {
59 return screen;
60 }
61
62 private GameScreen() {
63 URL url = getClass().getResource("/stone.gif" ); // There was a historical c:\test\stone.gif...
64
65 // old code
66 if (url == null) {
67 iconStone = new ImageIcon("c:\\temp\\stone.gif");
68 }
69
70 enableEvents(AWTEvent.WINDOW_EVENT_MASK);
71 jbInit();
72 }
73
74 /**
75 * Makes apropriate changes according to a move
76 * @param move
77 */
78 public void takeStones(MoveResult move) {
79 GamePlay.getGamePlay().getGameInfo().takeStones(move.takenFrom, move.nTaken);
80 gamePanel.takeStones(move.takenFrom, move.nTaken);
81 }
82
83 public void actionPerformed (ActionEvent e) {
84 //
85 // Catch menu items
86 //
87 if (e.getSource() == exitItem) {
88 fireEvent(InterfaceEventProvider.E6, null);
89 } else if (e.getSource() == aboutItem) {
90 fireEvent(InterfaceEventProvider.E5, null);
91 } else if (e.getSource() == restartItem) {
92 fireEvent(InterfaceEventProvider.E2, null);
93 }
94
95 //
96 // Perform a move
97 //
98 if (e.getSource() == mmoveItem || e.getSource() == newGameLabel) {
99 fireEvent(InterfaceEventProvider.E3, new Parameter("Move", getMove()));
100 }
101
102 //
103 // Select difficulty
104 //
105
106 GameInfo gameInfo = GamePlay.getGamePlay().getGameInfo();
107 if (e.getSource() == dffEasyItem) {
108 gameInfo.setGetDifficulty(GameInfo.DIFFICULTY_EASY);
109 fireEvent(InterfaceEventProvider.E4, new Parameter("Difficulty", new Integer(GameInfo.DIFFICULTY_EASY)));
110 } else if (e.getSource() == dffHardItem){
111 gameInfo.setGetDifficulty(GameInfo.DIFFICULTY_HARD);
112 fireEvent(InterfaceEventProvider.E4, new Parameter("Difficulty", new Integer(GameInfo.DIFFICULTY_HARD)));
113 } else if (e.getSource() == dffMediumItem) {
114 gameInfo.setGetDifficulty(GameInfo.DIFFICULTY_MEDIUM);
115 fireEvent(InterfaceEventProvider.E4, new Parameter("Difficulty", new Integer(GameInfo.DIFFICULTY_MEDIUM)));
116 }
117
118 int [] [] config = {
119 {3, 4, 5},
120 {1, 2},
121 {2, 3, 9},
122 {1, 3, 5, 7},
123 {4, 8, 12, 12},
124 {2, 4, 6, 8, 10},
125 {4, 6, 6, 7, 8, 9, 10, 11, 12}
126 };
127
128
129 for (int i = 0; i < MAX_LAYOUTS; i++) {
130 if (e.getSource() == layType [i]) {
131 gameInfo.setStones(config [i]);
132 gamePanel.redoLayout(gameInfo);
133 performLayout();
134 fireEvent(InterfaceEventProvider.E7, null);
135 }
136 }
137 }
138
139 /**
140 * Fires event to apropriate handler
141 * @param eventName - the event name
142 * @param parameter - the parameters
143 */
144 private void fireEvent(String eventName, Parameter parameter) {
145 if (engine != null) {
146 if (parameter == null) {
147 engine.getEventManager().handle(new Event(eventName), StateMachineContextImpl.create());
148 } else {
149 engine.getEventManager().handle(new Event(eventName, new Parameter[]{parameter}), StateMachineContextImpl.create());
150 }
151 }
152 }
153
154 /**
155 * Inits connector with state machine and event engine
156 */
157 public void init(ModelEngine engine) {
158 this.engine = engine;
159 fireEvent(InterfaceEventProvider.E2, null);
160 }
161
162 /**
163 * Gavna kusok
164 */
165 private void jbInit() {
166 //
167 // Get content pane
168 //
169 contentPane = (JPanel) this.getContentPane();
170 contentPane.setLayout(null);
171
172 gamePanel = new FishControlPanel(iconStone, GamePlay.getGamePlay().getGameInfo(), 10);
173 gamePanel.setLocation(10, 10);
174 contentPane.add(gamePanel);
175
176 //
177 // Customize frame
178 //
179 setResizable(false);
180 setTitle("Classical Nim game");
181
182 //
183 // Customize menus
184 //
185 menuBar = new JMenuBar();
186 gameMenu = new JMenu("Game");
187 helpMenu = new JMenu("Help");
188 gameMenu.setMnemonic('g');
189 helpMenu.setMnemonic('H');
190
191 //
192 // Customize menu items
193 //
194 exitItem = new JMenuItem("Exit");
195 exitItem.setMnemonic('e');
196 exitItem.setAccelerator(KeyStroke.getKeyStroke('E'));
197
198 aboutItem = new JMenuItem("About");
199 aboutItem.setMnemonic('a');
200 aboutItem.setAccelerator(KeyStroke.getKeyStroke('A'));
201
202 restartItem = new JMenuItem("New game");
203 restartItem.setMnemonic('r');
204 restartItem.setAccelerator(KeyStroke.getKeyStroke('R'));
205
206 mmoveItem = new JMenuItem("Take stones");
207 mmoveItem.setMnemonic('g');
208 mmoveItem.setAccelerator(KeyStroke.getKeyStroke('G'));
209
210 difficultyItem = new JMenu("Difficulty");
211 dffEasyItem = new JRadioButtonMenuItem("Easy (2 odds given)");
212 dffEasyItem.setSelected(true);
213 dffHardItem = new JRadioButtonMenuItem("Hard (Honest game)");
214 dffMediumItem = new JRadioButtonMenuItem("Medium (1 odd given)");
215
216 String [] config = {
217 "Traditional (3-4-5)",
218 "Novice (1-2)",
219 "Amateur's (2-3-9)",
220 "Marienbad (1-3-5-7)",
221 "Marienbad-Plus (4-8-12-12)",
222 "Even (2-4-6-8-10)",
223 "Professional (4-6-6-7-8-9-9-10-11-12)",
224 };
225
226 layGroup = new ButtonGroup();
227 dffGroup = new ButtonGroup();
228
229 layType = new JRadioButtonMenuItem [MAX_LAYOUTS];
230 for (int i = 0; i < MAX_LAYOUTS; i++) {
231 layType [i] = new JRadioButtonMenuItem(config [i]);
232 layGroup.add( layType[i] );
233 }
234 layType[0].setSelected(true);
235
236 dffGroup.add(dffEasyItem);
237 dffGroup.add(dffHardItem);
238 dffGroup.add(dffMediumItem);
239
240 layoutMenu = new JMenu("Layout");
241
242 exitItem.addActionListener(this);
243 aboutItem.addActionListener(this);
244 restartItem.addActionListener(this);
245 mmoveItem.addActionListener(this);
246 dffEasyItem.addActionListener(this);
247 dffHardItem.addActionListener(this);
248 dffMediumItem.addActionListener(this);
249 layoutMenu.addActionListener(this);
250
251 for (int i = 0; i < MAX_LAYOUTS; i++) {
252 layType [i].addActionListener(this);
253 layoutMenu.add( layType[i] );
254 }
255
256 difficultyItem.add(dffEasyItem);
257 difficultyItem.add(dffMediumItem);
258 difficultyItem.add(dffHardItem);
259
260 gameMenu.add(restartItem);
261 gameMenu.add(new JSeparator());
262 menuBar.add(gameMenu);
263 menuBar.add(helpMenu);
264 gameMenu.add(mmoveItem);
265 gameMenu.add(difficultyItem);
266 gameMenu.add(layoutMenu);
267 gameMenu.add(new JSeparator());
268 gameMenu.add(exitItem);
269 helpMenu.add(aboutItem);
270
271 setJMenuBar(menuBar);
272
273 //
274 // Add images
275 //
276 newGameLabel = new JButton("Take stones");
277 contentPane.add(newGameLabel);
278 newGameLabel.addActionListener(this);
279
280 statusPanel = new StatusPanel(gamePanel.getWidth() + gamePanel.getX() + 20, 18);
281 statusPanel.updateStatus("Your move.");
282 contentPane.add(statusPanel);
283
284 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
285
286 restartIface();
287 }
288
289 /**
290 * Gets move.
291 * @return
292 */
293 public int [] getMove () {
294 return gamePanel.getMove();
295 }
296
297 /**
298 * Hello.
299 */
300 protected void processWindowEvent(WindowEvent e) {
301 if (e.getID() == WindowEvent.WINDOW_CLOSING) {
302 fireEvent(InterfaceEventProvider.E6, null);
303 }
304 }
305
306 /**
307 * Restarts all interface to initial states
308 */
309 public void restartIface () {
310 GamePlay.getGamePlay().getGameInfo().restartGame();
311 gamePanel.reset();
312 performLayout();
313
314 // push timer
315 fireEvent(GameEventProvider.E24, null);
316 }
317
318 /**
319 * Updates status bar text
320 * @param text - a new text for the status bar
321 */
322 public void updateStatus (String text) {
323 statusPanel.updateStatus(text);
324 }
325
326 public void updateStatus(MoveResult move) {
327 updateStatus("Computer made a move. He took " + move.nTaken + " stones from " + (move.takenFrom + 1) + " row");
328 }
329
330 public void performLayout() {
331 newGameLabel.setBounds(gamePanel.getX(), gamePanel.getHeight() + gamePanel.getY(), gamePanel.getWidth() - gamePanel.getX() + 10, 50);
332
333 statusPanel.updateStatus("Your move");
334 statusPanel.setLocation(0, newGameLabel.getY() + newGameLabel.getHeight() + 2);
335 statusPanel.setSize(gamePanel.getWidth() + gamePanel.getX() + 20, 18);
336
337 setSize(gamePanel.getWidth() + gamePanel.getX() + 20,
338 gamePanel.getY() + gamePanel.getHeight() + statusPanel.getHeight() + newGameLabel.getHeight() + 50);
339
340 setVisible(true);
341 }
342 }
343
344