Skip to content

Instantly share code, notes, and snippets.

@rcgheorghe
Created September 18, 2015 02:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rcgheorghe/ce34ed6c3510dc80faf2 to your computer and use it in GitHub Desktop.
Save rcgheorghe/ce34ed6c3510dc80faf2 to your computer and use it in GitHub Desktop.
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