Created
September 18, 2015 02:36
-
-
Save rcgheorghe/ce34ed6c3510dc80faf2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.*; | |
import java.awt.BorderLayout; | |
import java.awt.FlowLayout; | |
import java.awt.event.ActionEvent; | |
import java.awt.event.ActionListener; | |
import java.awt.event.KeyAdapter; | |
import java.awt.event.KeyEvent; | |
import java.awt.event.KeyListener; | |
import javax.swing.JButton; | |
import javax.swing.JLabel; | |
import javax.swing.JPanel; | |
import java.awt.*; | |
import java.awt.event.*; | |
import java.awt.image.*; | |
import java.io.* ; | |
import javax.imageio.*; | |
import javax.swing.*; | |
// play the "Hunt the Wumpus" game | |
// puropse of the game is to find the wupus and kill it | |
public class HuntTheWumpus{ | |
// controls whether the simulation is playing, paused, or exiting | |
private enum GameState { PLAY, STOP, REPLAY } | |
private GameState state; | |
private enum ArrowState {ARMED, DISARMED} | |
private ArrowState bow; | |
// simulation control | |
private int iteration; | |
// the number of milliseconds to pause between iterations. | |
private int pause; | |
// the landscape | |
private Landscape landscape; | |
//the display | |
private LandscapeDisplay display; | |
// text message displayed when the user performs a certain action | |
private JLabel textMessage; | |
// the hunter | |
private Hunter hunter; | |
// the monster | |
private Wumpus wumpus; | |
// the cave | |
private Graph cave; | |
// the room that the player fires at | |
private Vertex target; | |
//the dimensions of the cave | |
private int side; | |
//constructor method | |
public HuntTheWumpus(int size) | |
{ | |
// create the landscape | |
this.landscape = new Landscape(10, 20 ); | |
this.pause=1000; | |
this.side=size; | |
cave=new Graph(); | |
for(int i=0;i<Math.pow(size,2);i++){ | |
landscape.addAgent(new Vertex()); | |
} | |
for(Vertex v:landscape.getAgents()) | |
cave.addVertex(v); | |
//initialize the map | |
//connect any vertices that are adjacent | |
for( Vertex v1 : cave.getVertices() ){ | |
for( Vertex v2 : cave.getVertices() ){ | |
// test to see if two vertices are adjacent in the same row | |
if( cave.getIndex(v1)%(Math.sqrt(cave.vertexCount())) == | |
cave.getIndex(v2)%(Math.sqrt(cave.vertexCount())) + 1 && | |
(int)(cave.getIndex(v1)/(Math.sqrt(cave.vertexCount()))) == | |
(int)(cave.getIndex(v2)/(Math.sqrt(cave.vertexCount()))) ){ | |
cave.addEdge( v1, Vertex.Direction.EAST, v2 ); | |
} | |
// test to see if two vertices are adjacent in the same column | |
else if( (int)(cave.getIndex(v1)/(Math.sqrt(cave.vertexCount()))) == | |
(int)(cave.getIndex(v2)/(Math.sqrt(cave.vertexCount()))) +1 && | |
cave.getIndex(v1)%(Math.sqrt(cave.vertexCount())) == | |
cave.getIndex(v2)%(Math.sqrt(cave.vertexCount())) ){ | |
cave.addEdge( v1, Vertex.Direction.SOUTH, v2 ); | |
} | |
} | |
} | |
// create the hunter and wumpus | |
Random rand=new Random(); | |
int num1 = rand.nextInt( cave.vertexCount() ); | |
int num2 = rand.nextInt( cave.vertexCount() ); | |
//don't let the hunter start in a room unconnected | |
//run dijsktra's algorithm to determine the cost between the 2 rooms | |
cave.shortestPath( cave.getVertex(num2)); | |
while( cave.getVertex(num1).getCost() == Integer.MAX_VALUE || num1 == num2 ){ | |
num1 = rand.nextInt( cave.vertexCount() ); | |
num2 = rand.nextInt( cave.vertexCount() ); | |
// recalculate the length of the path between the rooms | |
cave.shortestPath( cave.getVertex(num2)); | |
} | |
// starting rooms of the hunter and wumpus | |
this.hunter = new Hunter( this.cave.getVertex(num1) ); | |
this.landscape.addHunter(this.hunter); | |
this.wumpus = new Wumpus( this.cave.getVertex(num2) ); | |
this.landscape.addWumpus(this.wumpus); | |
// create the display | |
if (this.display != null) | |
this.display.dispose(); | |
this.display = new LandscapeDisplay(landscape, 64); | |
this.state = GameState.PLAY; | |
this.bow=ArrowState.DISARMED; | |
this.setupUI(); | |
} | |
//start a new game | |
public void replay(){ | |
this.landscape.reset(); | |
this.pause=1000; | |
cave=new Graph(); | |
for(int i=0;i<Math.pow(side,2);i++){ | |
landscape.addAgent(new Vertex()); | |
} | |
for(Vertex v:landscape.getAgents()) | |
cave.addVertex(v); | |
//initialize the map | |
//connect any vertices that are adjacent | |
for( Vertex v1 : cave.getVertices() ){ | |
for( Vertex v2 : cave.getVertices() ){ | |
// test to see if two vertices are adjacent in the same row | |
if( cave.getIndex(v1)%(Math.sqrt(cave.vertexCount())) == | |
cave.getIndex(v2)%(Math.sqrt(cave.vertexCount())) + 1 && | |
(int)(cave.getIndex(v1)/(Math.sqrt(cave.vertexCount()))) == | |
(int)(cave.getIndex(v2)/(Math.sqrt(cave.vertexCount()))) ){ | |
cave.addEdge( v1, Vertex.Direction.EAST, v2 ); | |
} | |
// test to see if two vertices are adjacent in the same column | |
else if( (int)(cave.getIndex(v1)/(Math.sqrt(cave.vertexCount()))) == | |
(int)(cave.getIndex(v2)/(Math.sqrt(cave.vertexCount()))) +1 && | |
cave.getIndex(v1)%(Math.sqrt(cave.vertexCount())) == | |
cave.getIndex(v2)%(Math.sqrt(cave.vertexCount())) ){ | |
cave.addEdge( v1, Vertex.Direction.SOUTH, v2 ); | |
} | |
} | |
} | |
// create the hunter and wumpus | |
Random rand=new Random(); | |
int num1 = rand.nextInt( cave.vertexCount() ); | |
int num2 = rand.nextInt( cave.vertexCount() ); | |
//don't let the hunter start in a room unconnected | |
//run dijsktra's algorithm to determine the cost between the 2 rooms | |
cave.shortestPath( cave.getVertex(num2)); | |
while( cave.getVertex(num1).getCost() == Integer.MAX_VALUE || num1 == num2 ){ | |
num1 = rand.nextInt( cave.vertexCount() ); | |
num2 = rand.nextInt( cave.vertexCount() ); | |
// recalculate the length of the path between the rooms | |
cave.shortestPath( cave.getVertex(num2)); | |
} | |
// starting rooms of the hunter and wumpus | |
this.hunter = new Hunter( this.cave.getVertex(num1) ); | |
this.landscape.addHunter(this.hunter); | |
this.wumpus = new Wumpus( this.cave.getVertex(num2) ); | |
this.landscape.addWumpus(this.wumpus); | |
this.state = GameState.PLAY; | |
this.bow=ArrowState.DISARMED; | |
this.setupUI(); | |
} | |
private void setupUI() | |
{ | |
// add elements to the UI | |
this.textMessage = new JLabel("Your text here."); | |
JButton quit = new JButton("Quit"); | |
JButton newgame = new JButton("New Game"); | |
JPanel panel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); | |
panel.add(this.textMessage); | |
panel.add(quit); | |
panel.add(newgame); | |
this.display.add(panel, BorderLayout.SOUTH); | |
this.display.pack(); | |
// listen for keystrokes | |
Control control = new Control(); | |
quit.addActionListener(control); | |
newgame.addActionListener(control); | |
this.display.addKeyListener(control); | |
this.display.setFocusable(true); | |
this.display.requestFocus(); | |
} | |
public void iterate() | |
{ | |
this.iteration++; | |
// if the hunter has walked into the room of the wumpus | |
if (this.hunter.getRoom()==this.wumpus.getRoom()) | |
//he dies | |
this.hunter.setDead(); | |
// if the hunter is dead | |
if (!this.hunter.isAlive()){ | |
//the game is over | |
this.wumpus.setVisible(true); | |
//print the results; | |
this.textMessage.setText("the wumpus ate you"); | |
} | |
//if the wumpus is dead | |
if (!this.wumpus.isAlive()){ | |
//the game is over | |
this.wumpus.setVisible(true); | |
//print the results; | |
this.textMessage.setText("you killed the wumpus"); | |
} | |
if(target!=null && this.bow==ArrowState.ARMED){ | |
if(target==this.wumpus.getRoom()) | |
this.wumpus.setDead(); | |
//otherwise the wumpus hears the arrow and eats the hunter | |
else | |
this.wumpus.killHunter( this.hunter.getRoom() ); | |
} | |
if (this.state == GameState.PLAY) | |
{ | |
// update the landscape, display | |
this.display.repaint(); | |
} | |
if(this.state == GameState.REPLAY){ | |
replay(); | |
this.state=GameState.PLAY; | |
} | |
// pause for refresh | |
try | |
{ | |
Thread.sleep(this.pause); | |
} | |
catch (InterruptedException ie) | |
{ | |
// do threads get insomnia? | |
ie.printStackTrace(); | |
} | |
} | |
// move the hunter in some direction | |
public void moveHunter(Vertex.Direction dir){ | |
int move=0; | |
//determine how much to move depending on the direction | |
if(dir==Vertex.Direction.NORTH) | |
move=-(int)Math.sqrt(cave.vertexCount()); | |
else if(dir==Vertex.Direction.SOUTH) | |
move=(int)Math.sqrt(cave.vertexCount()); | |
else if(dir==Vertex.Direction.EAST) | |
move=1; | |
else if(dir==Vertex.Direction.WEST) | |
move=-1; | |
//if the move is within the limits of the cave, and there is a connection, then move | |
if(this.cave.getIndex(this.hunter.getRoom())+move>=0 && | |
this.cave.getIndex(this.hunter.getRoom())+move<this.cave.vertexCount() && | |
this.hunter.getRoom().isConnected(this.cave.getVertex(this.cave.getIndex(this.hunter.getRoom())+move))){ | |
Vertex newroom =this.cave.getVertex(this.cave.getIndex(this.hunter.getRoom())+move); | |
this.hunter.moveRoom(newroom); | |
} | |
} | |
public void armArrow(){ | |
this.bow=ArrowState.ARMED; | |
this.hunter.armBow(); | |
} | |
public void disarmArrow(){ | |
this.bow=ArrowState.DISARMED; | |
this.hunter.disarmBow(); | |
} | |
public void fire(Vertex.Direction dir){ | |
int move=0; | |
//determine where the arrow will hit depending on the direction | |
if(dir==Vertex.Direction.NORTH) | |
move=-(int)Math.sqrt(cave.vertexCount()); | |
else if(dir==Vertex.Direction.SOUTH) | |
move=(int)Math.sqrt(cave.vertexCount()); | |
else if(dir==Vertex.Direction.EAST) | |
move=1; | |
else if(dir==Vertex.Direction.WEST) | |
move=-1; | |
this.target=this.cave.getVertex(this.cave.getIndex(this.hunter.getRoom())+move); | |
} | |
public static void main(String[] args) | |
{ | |
// initialize the simulation | |
HuntTheWumpus sim = new HuntTheWumpus(5); | |
sim.pause=250; | |
// print simulation information as well | |
// run simulation until terminated | |
while (sim.state != GameState.STOP) | |
{ | |
sim.iterate(); | |
} | |
// clean up and close the application | |
sim.display.dispose(); | |
} | |
/** | |
* Provides simple keyboard control to the simulation by implementing | |
* the KeyListener interface. | |
*/ | |
private class Control extends KeyAdapter implements ActionListener | |
{ | |
/** | |
* Controls the simulation in response to key presses. | |
*/ | |
public void keyTyped(KeyEvent e) | |
{ if (("" + e.getKeyChar()).equalsIgnoreCase("f")) | |
{ | |
armArrow(); | |
System.out.println("*** Hunter is preparing to fire ***"); | |
} | |
if (("" + e.getKeyChar()).equalsIgnoreCase("u")) | |
{ | |
disarmArrow(); | |
System.out.println("*** Arc unarmed ***"); | |
} | |
if (bow==ArrowState.ARMED){ | |
if (("" + e.getKeyChar()).equalsIgnoreCase("w")) | |
{ | |
fire(Vertex.Direction.NORTH); | |
System.out.println("*** shot north ***"); | |
} | |
else if (("" + e.getKeyChar()).equalsIgnoreCase("s")) | |
{ | |
fire(Vertex.Direction.SOUTH); | |
System.out.println("*** shot south ***"); | |
} | |
else if (("" + e.getKeyChar()).equalsIgnoreCase("a")) | |
{ | |
fire(Vertex.Direction.WEST); | |
System.out.println("*** shot west ***"); | |
} | |
else if (("" + e.getKeyChar()).equalsIgnoreCase("d")) | |
{ | |
fire(Vertex.Direction.EAST); | |
System.out.println("*** shot east ***"); | |
} | |
} | |
else if(bow==ArrowState.DISARMED){ | |
if (("" + e.getKeyChar()).equalsIgnoreCase("w")) | |
{ | |
moveHunter(Vertex.Direction.NORTH); | |
System.out.println("*** moved up ***"); | |
} | |
else if (("" + e.getKeyChar()).equalsIgnoreCase("s")) | |
{ | |
moveHunter(Vertex.Direction.SOUTH); | |
System.out.println("*** moved down ***"); | |
} | |
else if (("" + e.getKeyChar()).equalsIgnoreCase("a")) | |
{ | |
moveHunter(Vertex.Direction.WEST); | |
System.out.println("*** moved left ***"); | |
} | |
else if (("" + e.getKeyChar()).equalsIgnoreCase("d")) | |
{ | |
moveHunter(Vertex.Direction.EAST); | |
System.out.println("*** moved right ***"); | |
} | |
} | |
if (("" + e.getKeyChar()).equalsIgnoreCase("q")) | |
{ | |
state = GameState.STOP; | |
System.out.println("*** Simulation ended ***"); | |
} | |
if (("" + e.getKeyChar()).equalsIgnoreCase("r")) | |
{ | |
state = GameState.REPLAY; | |
System.out.println("*** New game ***"); | |
} | |
} | |
public void actionPerformed(ActionEvent event) | |
{ | |
System.out.println(event.getActionCommand()); | |
if (event.getActionCommand().equalsIgnoreCase("Quit")) | |
{ | |
state = GameState.STOP; | |
} | |
if (event.getActionCommand().equalsIgnoreCase("New Game")) | |
{ | |
state = GameState.REPLAY; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment