Hangman
The classic Hangman puzzle (game) is done here in 2 classes. The HangmanGUI
class is fairly complete with the user interface for playing the game. The other class is the HangmanPuzzle
which picks the words and keeps track of the guess. You will write the methods needed for the GUI to work. The constructor is provided. Note that it:
- Initializes the
answer
by randomly picking from thewords
array - Initializes a
boolean
array calledguessed
and sets its elements tofalse
using afor
loop. This is for keeping track which letter of theanswer
the player has found. - Initializes an
ArrayList<String>
calledwrongLetters
to hold the unsuccessful guesses.
Check List:
- Change the name of the Group from X to your group in the
HangmanGUI
method calledpaintComponent
- In the
HangmanPuzzle
class complete thegetAnswer
method that should return aString
answer
in upper case. - In the
HangmanPuzzle
class complete thenumberWrong
method that should return aint
with the number of items in thewrongLetters
Arraylist. - In the
HangmanPuzzle
class complete thegetBadGuesses
method that should return aString
which contains the elements ofwrongLetters
in a singleString
. You probably should use a loop and attach a space between eachString
inwrongLetters
- In the
HangmanPuzzle
class complete thehasWon
method that should return atrue
if the entireguessed
array is filled withtrue
, andfalse
otherwise. Another chance for you to make a loop... perhaps an "enhanced for" loop!
Challenges:
- Add to the list of words
- Keep track of the words already picked so you don't repeat words.
- Give the user one or more guesses. You have to make a new Polygon for the gallows for each guess.
HangmanGUI.java
import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Polygon; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.ArrayList; import javax.swing.JFrame; import javax.swing.JPanel; public class HangmanGUI extends JPanel implements KeyListener { public static int WIDTH=800; public static int HEIGHT=600; private Font titleFont, regularFont, largeFont, giantFont; private Polygon[] gallows; private HangmanPuzzle puzzle; private String message="Type a letter"; public static final int MAX_GUESSES=6; private int wins,losses; /** * GUI stands for Graphic User Interface, and is the * front end of the HangmanPuzzle. */ public HangmanGUI() { //initialize variables here... titleFont = new Font("Times", Font.BOLD, 18); regularFont = new Font("Helvetica", Font.PLAIN, 12); largeFont = new Font("Times", Font.BOLD, 60); giantFont = new Font("Times", Font.BOLD, 80); gallows = new Polygon[7];// scaffold, head, body, 2 arms, 2 legs gallows[0] = makeScaffold(52, 100, 12); gallows[1] = makeHead(130, 150, 35); gallows[2] = makeBody(155, 220, 5); gallows[3] = makeArmDown(130, 240, 5);//left arm gallows[4] = makeArmUp(200, 240, 5); //right arm gallows[5] = makeArmUp(130, 370, 5);//left leg gallows[6] = makeArmDown(200, 370, 5);//right leg puzzle = new HangmanPuzzle(); wins=0; losses=0; } /** * The main method starts the application and * so it ends on a window close. * */ public static void main(String[] args) { HangmanGUI app= new HangmanGUI(); JFrame window = new JFrame("Hangman"); window.addKeyListener(app); window.setSize(WIDTH, HEIGHT); window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); window.getContentPane().add(app); window.setVisible(true); } /** * The paint Component method is where to add drawing to * the screen * */ public void paintComponent(Graphics g){ super.paintComponent(g); g.setColor(Color.WHITE); g.fillRect(0, 0, getWidth(),getHeight()); g.setColor(Color.BLUE); g.setFont(titleFont); g.drawString("Hangman by Group X", 20, 20); g.setFont(regularFont); g.drawString("Version 1.0", 20, 40); if (puzzle.numberWrong()>0) { g.setFont(titleFont); g.setColor(Color.RED); g.drawString("You have tried: ", 400, 75); g.setFont(largeFont); g.drawString(puzzle.getBadGuesses(), 400, 150); } g.setColor(Color.BLACK); g.setFont(titleFont); g.drawString(" Wins: "+wins, 500, 20); g.drawString("Losses: "+losses, 500, 50); g.setFont(titleFont); g.drawString( (MAX_GUESSES-puzzle.numberWrong())+" guesses remain", 300, 480); g.drawString(message, 300, 460); g.setFont(giantFont); g.setColor(Color.BLACK); g.drawString(puzzle.clue(), 300, 400); g.setColor(Color.BLUE); int parts = Math.min(MAX_GUESSES, puzzle.numberWrong()); for (int i=0; i< 1+ parts; i++){ g.fillPolygon(gallows[i]); } } /** * The following Polygon returning methods help organizing * the code required to make the shapes of the game. */ public Polygon makeScaffold(int x,int y,int scale){ Polygon result = new Polygon(); result.addPoint(scale*0, scale*0); result.addPoint(scale*15, scale*0); result.addPoint(scale*15, scale*2); result.addPoint(scale*10, scale*2); result.addPoint(scale*10, scale*7); result.addPoint(scale*9, scale*7); result.addPoint(scale*9, scale*2); result.addPoint(scale*2, scale*2); result.addPoint(scale*2, scale*30); result.addPoint(scale*0, scale*30); result.translate(x, y); return result; } public Polygon makeHead(int x,int y,int scale){ Polygon result = new Polygon(); double angle=2*Math.PI/18.0; for (int i=0; i<18; i++){ int x0=(int) (scale+Math.round(scale*Math.cos(angle*i))); int y0=(int) (scale+Math.round(scale*Math.sin(angle*i))); result.addPoint(x0, y0); } result.translate(x, y); return result; } public Polygon makeArmDown(int x, int y, int scale){ Polygon result = new Polygon(); result.addPoint(scale*-5, scale*-5 ); result.addPoint(scale*5, scale*5 ); result.addPoint(scale*5, scale*1 ); result.addPoint(scale*-5, scale*-9 ); result.translate(x, y); return result; } public Polygon makeArmUp(int x, int y, int scale){ Polygon result = new Polygon(); result.addPoint(scale*-5, scale*5 ); result.addPoint(scale*5, scale*-5 ); result.addPoint(scale*5, scale*-9 ); result.addPoint(scale*-5, scale*1 ); result.translate(x, y); return result; } public Polygon makeBody(int x, int y, int scale){ Polygon result = new Polygon(); result.addPoint(scale*0, scale*0 ); result.addPoint(scale*0, scale*25 ); result.addPoint(scale*4, scale*25); result.addPoint(scale*4, scale*0 ); result.translate(x, y); return result; } /** * These 3 methods need to be declares to implement the KeyListener Interface * */ @Override public void keyTyped(KeyEvent e) { String letter = ""+e.getKeyChar(); if (puzzle.numberWrong() < MAX_GUESSES){ puzzle.checkGuess(letter); message = "You guessed "+letter; } if (puzzle.numberWrong() >= MAX_GUESSES){ message="Sorry - Try again- the word was "+puzzle.getAnswer(); puzzle = new HangmanPuzzle(); losses++; } if (puzzle.hasWon()){ message = "You won! the word was indeed "+puzzle.getAnswer()+"- try again"; puzzle = new HangmanPuzzle(); wins++; } repaint(); } @Override public void keyPressed(KeyEvent e) {} @Override public void keyReleased(KeyEvent e) {} }
HangmanPuzzle.java
import java.util.ArrayList; public class HangmanPuzzle { private String answer; private String[] words = {"quiz", "fax", "jinx", "fox", "jays","buff", "puff", "fizz", "huh", "babes"}; private boolean[] guessed; private ArrayList<String> wordList, wrongLetters; /** * The constructor initializes the boolean array, the wrongLetters ArrayList and picked randomly from the words array */ public HangmanPuzzle(){ answer = words[(int)(words.length*Math.random())]; guessed = new boolean[answer.length()]; for (int i=1; i<guessed.length; i++){ guessed[i]=false; } wrongLetters = new ArrayList<String>(); } public String getAnswer(){ // your code here } public int numberWrong(){ //your code here } public String getBadGuesses(){ //your code here } public boolean hasWon(){ //your code here } public void checkGuess(String s){ boolean found=false; for (int i=0; i<guessed.length; i++){ if (s.toUpperCase().equals(answer.substring(i, i+1).toUpperCase())){ guessed[i]=true; found=true; } } if (!found) wrongLetters.add(s.toUpperCase()); } public String clue(){ String result=""; for (int i=0; i<answer.length();i++){ if (guessed[i]){ result+=answer.substring(i, i+1).toUpperCase()+" "; }else{ result+="_ "; } } return result; } }