10 date 2008.05.17.03.29.37; author rmh3093; state Exp;
15 date 2008.05.16.23.04.18; author rmh3093; state Exp;
20 date 2008.05.16.22.06.44; author rmh3093; state Exp;
25 date 2008.04.30.04.10.52; author rmh3093; state Exp;
30 date 2008.04.26.15.45.41; author rmh3093; state Exp;
36 @initial commit, mostly working
42 @add semi-random movement pattern
46 * FrenzyController.java
49 * $Id: FrenzyController.java,v 1.4 2008/05/16 23:04:18 rmh3093 Exp rmh3093 $
52 * $Log: FrenzyController.java,v $
53 * Revision 1.4 2008/05/16 23:04:18 rmh3093
54 * implement scrolling pane for last consumed object
56 * Revision 1.3 2008/05/16 22:06:44 rmh3093
57 * meets final submission goals
59 * Revision 1.2 2008/04/30 04:10:52 rmh3093
60 * break out random number generator, first attempt at moving enemies
62 * Revision 1.1 2008/04/26 15:45:41 rmh3093
68 Copyright (c) 2008, Ryan M. Hope
71 Redistribution and use in source and binary forms, with or without modification,
72 are permitted provided that the following conditions are met:
74 * Redistributions of source code must retain the above copyright notice,
75 this list of conditions and the following disclaimer.
76 * Redistributions in binary form must reproduce the above copyright notice,
77 this list of conditions and the following disclaimer in the documentation
78 and/or other materials provided with the distribution.
79 * Neither the name of the project nor the names of its contributors may be
80 used to endorse or promote products derived from this software without
81 specific prior written permission.
83 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
84 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
85 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
86 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
87 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
88 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
89 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
90 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
92 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
95 import java.awt.event.*;
96 import java.util.TreeSet;
99 * Controls the Frenzy view and updates the model
103 public class FrenzyController {
105 // Random number generator
106 private BetterRandom betterRandom;
108 private FrenzyModel f_model;
109 private FrenzyView f_view;
112 * Create a new Frenzy Controller
114 * @@param f_model the Frenzy game f_model
115 * @@param f_view the Frenzy game f_view
117 FrenzyController(FrenzyModel f_model, FrenzyView f_view,
118 BetterRandom betterRandom) {
119 this.f_model = f_model;
120 this.f_view = f_view;
121 this.betterRandom = betterRandom;
123 // Add player to board in random position
124 f_model.player = new FrenzyPlayer();
127 // Add listeners to f_view
128 f_view.addQuitListener(new QuitListener());
129 f_view.addResetListener(new ResetListener());
130 f_view.addSpawnListener(new SpawnListener());
131 f_view.addPauseListener(new PauseListener());
132 f_view.addPlayerControlsListener(new PlayerControlsListener());
133 f_view.addEnemySpawnListener(new SpawnListener());
134 f_view.addFasterEnemyListener(new FasterEnemyListener());
135 f_view.addSlowerEnemyListener(new SlowerEnemyListener());
138 private void resumeGame() {
139 TreeSet<String> keys =
140 new TreeSet<String>(f_model.enemies.keySet());
141 for (String key : keys) {
142 FrenzyEnemy enemy = f_model.enemies.get(key);
144 synchronized (enemy.moverThread) {
145 enemy.moverThread.notifyAll();
147 // Sleep for a random amount of time so that when enemies wake up
148 // from sleeping they dont look like they are moving in sync
150 Thread.sleep(betterRandom.rand.nextInt(50));
151 } catch (InterruptedException e) {
155 synchronized (f_view.enemySpawnerThread) {
156 f_view.enemySpawnerThread.notifyAll();
160 protected synchronized void spawnEnemy() {
161 if (f_model.gamestate) {
162 // Can't spawn new enemies if there are no unique ASCII characters
163 if (f_model.enemyCount < FrenzyModel.MAX_ENIMES) {
167 int num = betterRandom.rand.nextInt(255);
169 // These characters don't print
170 if (num < 33 || ((num > 126) && (num < 161)) || num == 173)
173 // Can't use players symbol
174 if (String.valueOf((char)num) == FrenzyPlayer.symbol)
177 // The symbol for the new enemy
178 String symbol = String.valueOf((char)num);
180 // Check to make sure the symbol is already in use
181 if (f_model.enemies.containsKey(symbol)) continue;
183 // Find a random unoccupied location for the enemy to spawn
187 x = betterRandom.rand.nextInt(f_model.getBoardSize());
188 y = betterRandom.rand.nextInt(f_model.getBoardSize());
189 if (f_view.boardSquares[y][x].isOccupied() ==
190 FrenzyModel.OCCUPANT.NONE) {
195 int move_x = betterRandom.rand.nextInt(2);
196 int move_y = betterRandom.rand.nextInt(2);
197 FrenzyEnemy.MOVEMENT_PATTERN mp = null;
198 // Spawn the new enemy
199 if ((move_x == 1) && (move_y == 1)) {
200 mp = FrenzyEnemy.MOVEMENT_PATTERN.NE;
201 } else if ((move_x == 1) && (move_y == 0)) {
202 mp = FrenzyEnemy.MOVEMENT_PATTERN.SE;
203 } else if ((move_x == 0) && (move_y == 1)) {
204 mp = FrenzyEnemy.MOVEMENT_PATTERN.NW;
205 } else if ((move_x == 0) && (move_y == 0)) {
206 mp = FrenzyEnemy.MOVEMENT_PATTERN.SW;
209 new FrenzyEnemy(f_model, x, y, symbol, mp,
210 betterRandom.rand.nextInt(3),
211 new EnemyMover(), betterRandom);
212 f_model.enemies.put(symbol, enemy);
213 f_view.addOccupant(enemy, f_view.boardSquares[y][x]);
214 f_model.increaseEnemyCount();
215 enemy.moverThread.start();
221 synchronized (f_view.enemySpawnerThread) {
223 f_view.enemySpawnerThread.wait();
224 } catch (InterruptedException e) {
231 * Handles moving the Frenzy player around the game board
235 class PlayerControlsListener implements KeyListener {
237 public void keyPressed(KeyEvent e) {
240 public void keyTyped(KeyEvent e) {
243 // Only perform an action on the release of the key
244 public void keyReleased(KeyEvent e) {
246 if (f_model.gamestate) {
248 int keycode = e.getKeyCode();
251 int x_old = f_model.player.getXposition();
252 int y_old = f_model.player.getYposition();
253 if ((keycode > 36 && keycode < 41) && f_model.gamestate) {
255 // Remove player from current location
256 f_view.removeOccupant(f_view.boardSquares[y_old][x_old]);
263 x_new = f_model.boardsize-1;
268 f_model.player.setXposition(x_new);
274 y_new = f_model.boardsize-1;
279 f_model.player.setYposition(y_new);
284 if (x_old == f_model.boardsize-1) {
290 f_model.player.setXposition(x_new);
295 if (y_old == f_model.boardsize-1) {
301 f_model.player.setYposition(y_new);
305 // If new location is occupied by an enemy, eat it
306 if (f_view.boardSquares[y_new][x_new].isOccupied() ==
307 FrenzyModel.OCCUPANT.ENEMY) {
311 f_view.boardSquares[y_new][x_new].getText();
312 f_model.player.eatEnemy();
313 f_model.decreaseEnemyCount();
314 if (f_model.player.getConsumedCount() > 0 &&
315 f_model.enemyCount==0) {
316 f_model.gamestate = false;
317 f_view.statusLabel.setText("Game over.");
320 // Remove key from list so that the symbol can be reused
321 f_model.enemies.remove(key);
323 // ====================================================
324 // These should be handled by events
326 // Update the last action display
327 f_view.lastActionArea.setText(
328 f_model.player.getSymbol() + " ate " + key +
329 "\n" + f_view.lastActionArea.getText());
331 // Update the consumed enemy count display
332 int count = f_model.player.getConsumedCount();
333 f_view.consumedLabel.setText(String.valueOf(count));
335 // ====================================================
338 // Add player to new square
339 f_view.addOccupant(f_model.player,
340 f_view.boardSquares[y_new][x_new]);
347 * Handles quitting Frenzy
351 class QuitListener implements ActionListener {
352 public void actionPerformed(ActionEvent e) {
359 * Handles resetting Frenzy
363 class ResetListener implements ActionListener {
364 public void actionPerformed(ActionEvent e) {
365 f_model.gamestate = true;
366 f_view.statusLabel.setText("Game Running!");
367 f_view.pauseControl.setSelected(false);
368 f_model.player.setConsumedCount(0);
369 f_view.consumedLabel.setText("0");
370 if (f_model.player.dead) {
372 f_model.player.dead = false;
379 * Handles resetting Frenzy
383 class PauseListener implements ActionListener {
384 public void actionPerformed(ActionEvent e) {
385 if (f_view.pauseControl.isSelected()) {
386 f_model.gamestate = false;
387 f_view.statusLabel.setText("Game Paused!");
389 f_model.gamestate = true;
390 if (!f_model.player.dead) resumeGame();
391 f_view.statusLabel.setText("Game Running!");
397 * Handles spawning of new enemies
401 class SpawnListener implements ActionListener {
403 public void actionPerformed(ActionEvent e) {
404 if (f_model.gamestate) spawnEnemy();
410 * Handles increasing enemy speed
414 class FasterEnemyListener implements ActionListener {
416 public void actionPerformed(ActionEvent e) {
417 f_model.enemyMoveInterval = f_model.enemyMoveInterval - 10;
423 * Handles decreasing enemy speed
427 class SlowerEnemyListener implements ActionListener {
429 public void actionPerformed(ActionEvent e) {
430 f_model.enemyMoveInterval = f_model.enemyMoveInterval + 10;
436 * Handles moving enemies
442 public synchronized void move(String symbol) {
443 FrenzyEnemy enemy = f_model.enemies.get(symbol);
444 FrenzyEnemy eaten = null;
446 int x = enemy.getXposition();
447 int y = enemy.getYposition();
448 FrenzyModel.OCCUPANT occupant_t =
449 f_view.boardSquares[y][x].isOccupied();
450 if (occupant_t != FrenzyModel.OCCUPANT.NONE) {
451 String occupant = f_view.boardSquares[y][x].getText();
452 if (occupant_t == FrenzyModel.OCCUPANT.PLAYER) {
453 f_model.gamestate = false;
454 f_model.player.dead = true;
455 f_view.statusLabel.setText("Game over.");
457 eaten = f_model.enemies.get(occupant);
460 System.out.println("Oh no!");
464 f_model.enemies.remove(occupant);
466 f_view.lastActionArea.setText(
467 symbol + " ate " + occupant +
468 "\n" + f_view.lastActionArea.getText());
470 f_view.removeOccupant(
471 f_view.boardSquares[enemy.Yposition_old][enemy.Xposition_old]);
472 f_view.addOccupant(enemy, f_view.boardSquares[y][x]);
478 private void spawnPlayer() {
480 int x = betterRandom.rand.nextInt(f_model.boardsize);
481 int y = betterRandom.rand.nextInt(f_model.boardsize);
482 if (f_view.boardSquares[y][x].isOccupied() ==
483 FrenzyModel.OCCUPANT.NONE) {
484 f_model.player.setXposition(x);
485 f_model.player.setYposition(y);
489 f_view.spawnPlayer();
497 @implement scrolling pane for last consumed object
502 * $Id: FrenzyController.java,v 1.3 2008/05/16 22:06:44 rmh3093 Exp rmh3093 $
512 @meets final submission goals
517 * $Id: FrenzyController.java,v 1.2 2008/04/30 04:10:52 rmh3093 Exp $
521 f_view.lastActionLabel.setText(
522 f_model.player.getSymbol() + " ate " + key);
525 f_view.lastActionLabel.setText(
526 symbol + " ate " + occupant);
532 @break out random number generator, first attempt at moving enemies
537 * $Id: FrenzyController.java,v 1.1 2008/04/26 15:45:41 rmh3093 Exp rmh3093 $
542 f_model.player = new FrenzyPlayer(
543 betterRandom.rand.nextInt(f_model.boardsize),
544 betterRandom.rand.nextInt(f_model.boardsize));
549 private synchronized void spawnEnemy() {
552 if (f_model.enimies.containsKey(symbol)) continue;
555 f_model.enimies.put(symbol, enemy);
559 if (!f_view.pauseControl.isSelected()) {
562 f_model.enimies.remove(key);
568 public void move(String symbol) {
569 FrenzyEnemy enemy = f_model.enimies.get(symbol);
572 f_model.player.died = true;
575 eaten = f_model.enimies.get(occupant);
578 while (eaten != null && eaten.moverThread.isAlive()) {
598 import java.io.FileInputStream;
599 import java.io.FileNotFoundException;
600 import java.io.IOException;
601 import java.util.Random;
605 protected FrenzyModel m_model;
606 protected FrenzyView m_view;
608 private int boardsize = -1;
610 FrenzyController(FrenzyModel model, FrenzyView view) {
613 boardsize = m_model.getBoardSize();
615 // Get better random numbers
616 File urandom = new File("/dev/urandom");
617 byte[] seed = new byte[4];
618 if (urandom.exists()) {
619 FileInputStream streamer = null;
621 streamer = new FileInputStream(urandom);
622 } catch (FileNotFoundException e) {
627 } catch (IOException e) {
631 for (int i = 0; i < 4; i++) {
632 int shift = (4 - 1 - i) * 8;
633 value += (seed[i] & 0x000000FF) << shift;
635 rand = new Random(value);
641 m_model.player = m_model.new Player(rand.nextInt(model.getBoardSize()),
642 rand.nextInt(model.getBoardSize()));
645 // Add listeners to view
646 view.addQuitListener(new QuitListener());
647 view.addResetListener(new ResetListener());
648 view.addSpawnListener(new SpawnListener());
649 view.addPlayerControlsListener(new PlayerControlsListener());
657 int keycode = e.getKeyCode();
660 int x_old = m_model.player.getXposition();
661 int y_old = m_model.player.getYposition();
662 if (keycode > 36 && keycode < 41) {
663 m_view.removeOccupant(m_view.boardSquares[y_old][x_old]);
673 m_model.player.setXposition(x_new);
683 m_model.player.setYposition(y_new);
686 if (x_old == boardsize-1) {
692 m_model.player.setXposition(x_new);
695 if (y_old == boardsize-1) {
701 m_model.player.setYposition(y_new);
704 if (m_view.boardSquares[y_new][x_new].isOccupied() ==
705 FrenzyModel.OCCUPANT.ENEMY) {
706 String key = m_view.boardSquares[y_new][x_new].getText();
707 m_model.player.eatEnimie();
708 m_model.enimies.remove(key);
709 m_view.lastActionLabel.setText(m_model.player.getSymbol() +
711 int count = m_model.player.getConsumedCount();
712 m_view.consumedLabel.setText(String.valueOf(count));
714 m_view.addOccupant(m_model.player,
715 m_view.boardSquares[y_new][x_new]);
726 if (m_model.enimieCount <= FrenzyModel.MAX_ENIMES) {
728 int num = rand.nextInt(127);
729 if (num < 33) continue;
730 if ((char)num == 'P') continue;
731 String symbol = String.valueOf((char)num);
732 if (m_model.enimies.containsKey(symbol)) continue;
736 x = rand.nextInt(m_model.getBoardSize());
737 y = rand.nextInt(m_model.getBoardSize());
738 if (m_view.boardSquares[y][x].isOccupied() ==
739 FrenzyModel.OCCUPANT.NONE) {
744 FrenzyModel.Enemy enemy =
745 m_model.new Enemy(x, y, symbol);
746 m_model.enimies.put(symbol, enemy);
747 m_view.addOccupant(enemy, m_view.boardSquares[y][x]);
748 m_model.enimieCount++;