Hangman was built as a desktop program, so it only works on a laptop or desktop computer, with a keyboard.
Starting Java in your browser… the first load can take a few seconds.
My 2022 Java Swing word game, compiled from the original code and running in your browser. It runs on CheerpJ, which runs Java desktop apps in the browser. The Quit button won’t close this page.
Main.java (the original code)
import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
final Hangman wnd = new Hangman();
wnd.setVisible(true);
});
}
}
class Hangman extends JFrame {
static final int[] numberOfTries = new int[30];
static List<String> wordsMissed = new ArrayList<>();
static int wordsAttempted = 0;
static int wordsGotten = 0;
static int points = 0;
static boolean doneWord = false;
static int questionIndex = 0;
static int bonusLetterIndex;
static JTextField[] letterInputs;
static JLabel[] triesLabel;
static AnswerLabel correctAnswer = new AnswerLabel();
static ScoreLabel scoreLabel = new ScoreLabel(points);
static AttemptedLabel attemptedLabel = new AttemptedLabel(wordsAttempted);
static GottenLabel gottenLabel = new GottenLabel(wordsGotten);
static JPanel wordSection = new JPanel();
public Hangman() {
super("Hangman (by Eeman😉)");
super.setLayout(new GridLayout(2, 1));
super.setBackground(Color.black);
setSize(1350, 650);
JPanel gameSection = new JPanel();
gameSection.setLayout(new GridBagLayout());
JPanel instructions = getInstructions();
displayWord();
JPanel buttons = getButtons();
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 0;
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.weightx = 0.5;
constraints.gridy = 0;
constraints.gridheight = 3;
gameSection.add(instructions, constraints);
constraints.gridy = 3;
constraints.gridheight = 3;
gameSection.add(wordSection, constraints);
constraints.gridy = 6;
constraints.gridheight = 2;
gameSection.add(buttons, constraints);
super.add(gameSection);
JPanel scoreSection = new JPanel();
scoreSection.setBackground(Color.black);
scoreSection.setLayout(new GridLayout(3, 1));
scoreSection.add(attemptedLabel);
scoreSection.add(gottenLabel);
scoreSection.add(scoreLabel);
super.add(scoreSection);
}
private JPanel getInstructions() {
JPanel instructions = new JPanel();
instructions.setLayout(new GridLayout(3, 1));
instructions.setBorder(new EmptyBorder(10, 10, 10, 10));
instructions.setBackground(Color.WHITE);
JLabel instruction1 = new JLabel("Guess the word from the hint given below. Each box you see below is for a single letter. A letter in the word has been given to you.");
instruction1.setHorizontalAlignment(JLabel.CENTER);
JLabel instruction2 = new JLabel("Use the 'check' button to check if what you entered is correct. You do not need to enter all the letters before checking. The button works no matter the number of letters you've entered.");
instruction2.setHorizontalAlignment(JLabel.CENTER);
JLabel instruction3 = new JLabel("You only have three tries for each letter.");
instruction3.setHorizontalAlignment(JLabel.CENTER);
instructions.add(instruction1);
instructions.add(instruction2);
instructions.add(instruction3);
return instructions;
}
public void displayWord() {
String word = getWords()[questionIndex];
wordSection.removeAll();
wordSection.setPreferredSize(new Dimension(1350, 250));
wordSection.setLayout(new GridBagLayout());
JPanel hintPanel = new JPanel();
JPanel wordPanel = new JPanel();
// Set hint to word hint and add it to panel
JLabel hint = new JLabel();
hint.setText("HINT: " + getQuestions().get(word));
hint.setHorizontalAlignment(JLabel.CENTER);
hint.setFont(hint.getFont().deriveFont(16f));
hint.setForeground(Color.red);
hintPanel.add(hint);
// Set number of tries (3 for each letter)
int currentWordLength = word.length();
triesLabel = new JLabel[currentWordLength];
bonusLetterIndex = 1 + (int) ((currentWordLength - 1) * Math.random());
for (int i = 0; i <= (currentWordLength - 1); i++) {
numberOfTries[i] = 3; // Do it in 'anotherWord' method
if (i != bonusLetterIndex) {
triesLabel[i] = new JLabel("Tries left: " + numberOfTries[i]);
} else {
triesLabel[i] = new JLabel();
}
triesLabel[i].setForeground(Color.white);
wordPanel.add(triesLabel[i]);
}
// Create section for inputs for each letter
wordPanel.setLayout(new GridLayout(3, currentWordLength));
wordPanel.setBackground(Color.BLACK);
letterInputs = new JTextField[currentWordLength];
for (int i = 0; i <= (currentWordLength - 1); i++) {
letterInputs[i] = new JTextField();
// Handle empty characters in strings
if (Character.toString(word.charAt(i)).isEmpty()) {
letterInputs[i].setEditable(false);
letterInputs[i].setBackground(Color.black);
continue;
}
letterInputs[i].setHorizontalAlignment(JLabel.CENTER);
letterInputs[i].setFont(letterInputs[i].getFont().deriveFont(20f));
letterInputs[i].setPreferredSize(new Dimension(letterInputs[i].getWidth(), 300));
wordPanel.add(letterInputs[i]);
}
// Display bonus letter
char bonus = word.charAt(bonusLetterIndex);
letterInputs[bonusLetterIndex].setText(Character.toString(bonus).toUpperCase());
letterInputs[bonusLetterIndex].setEditable(false);
letterInputs[bonusLetterIndex].setBackground(Color.white);
numberOfTries[bonusLetterIndex] = 0;
// Create space for correct answer and make it centered on the screen
JLabel answerLabel = new JLabel("Correct answer: ");
answerLabel.setHorizontalAlignment(JLabel.RIGHT);
answerLabel.setForeground(Color.WHITE);
if (currentWordLength % 2 == 0) {
for (int i = 0; i <= ((currentWordLength - 3) / 2); i++) {
wordPanel.add(new JLabel(""));
}
wordPanel.add(answerLabel);
wordPanel.add(correctAnswer);
for (int i = 0; i <= ((currentWordLength - 3) / 2); i++) {
wordPanel.add(new JLabel(""));
}
} else {
for (int i = 0; i <= (((double) (currentWordLength - 3) / 2) - 0.5); i++) {
wordPanel.add(new JLabel(""));
}
wordPanel.add(answerLabel);
wordPanel.add(correctAnswer);
for (int i = 0; i <= (((double) (currentWordLength - 3) / 2) + 0.5); i++) {
wordPanel.add(new JLabel(""));
}
}
GridBagConstraints constraints = new GridBagConstraints();
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.weightx = 0.5;
constraints.gridx = 0;
constraints.gridy = 0;
constraints.gridheight = 1;
wordSection.add(hintPanel, constraints);
constraints.gridy = 1;
constraints.gridheight = 3;
wordSection.add(wordPanel, constraints);
wordSection.revalidate();
}
public JPanel getButtons() {
JPanel buttons = new JPanel();
buttons.setLayout(new GridLayout(1, 4));
buttons.setBorder(new EmptyBorder(30, 30, 30, 30));
buttons.setBackground(Color.BLACK);
JButton checkButton = new JButton("Check");
checkButton.addActionListener(e -> check());
getRootPane().setDefaultButton(checkButton);
checkButton.setMnemonic(KeyEvent.VK_ENTER);
JButton nextButton = new JButton("Next word");
nextButton.addActionListener(e -> anotherWord());
JButton quitButton = new JButton("Quit");
quitButton.addActionListener(e -> System.exit(0));
buttons.add(checkButton);
buttons.add(nextButton);
buttons.add(quitButton);
return buttons;
}
void check() {
String word = getWords()[questionIndex];
int currentWordLength = word.length();
boolean done = true;
for (int i = 0; i < currentWordLength; i++) {
// Skip bonus letter
if (i == bonusLetterIndex || numberOfTries[i] == 0)
continue;
String input = letterInputs[i].getText();
// If there was any input at all, process the input
if (!input.isEmpty()) {
// Mark the word as attempted if not marked already
if (!doneWord) {
wordsAttempted++;
doneWord = true;
}
// Check if input is correct
if (input.equalsIgnoreCase(Character.toString(word.charAt(i)))) {
letterInputs[i].setBackground(Color.GREEN);
letterInputs[i].setEditable(false);
points += numberOfTries[i];
numberOfTries[i] = 0;
triesLabel[i].setText("Correct!");
} else {
letterInputs[i].setBackground((((Color.RED.brighter()).brighter()).brighter()).brighter());
numberOfTries[i]--;
if (numberOfTries[i] == 0) {
letterInputs[i].setEditable(false);
wordsMissed.add(word);
}
triesLabel[i].setText("Tries left: " + numberOfTries[i]);
}
}
// Check if we're done with word using number of tries
if (numberOfTries[i] > 0) {
done = false;
}
}
if (done) {
correctAnswer.showAnswer(word.toUpperCase());
if (!wordsMissed.contains(word))
wordsGotten++;
}
updateBoard();
}
void anotherWord() {
questionIndex++;
doneWord = false;
correctAnswer.setText("");
displayWord();
}
static String[] getWords() {
return getQuestions().keySet().toArray(new String[0]);
}
static HashMap<String, String> getQuestions() {
return new HashMap<>() {{
put("barber", "I shave every day, but my beard stays the same.");
put("bank", "I have branches, but no fruit, trunk or leaves.");
put("darkness", "The more of me there is, the less you see.");
put("coffin", "The man who built me doesn't want me, the man who buys me doesn't want me, and the person that uses me doesn't even know that he's using me.");
put("hole", "I get bigger when more is taken away");
put("breath", "I’m light as a feather, yet the strongest person can’t hold me for five minutes.");
put("staircase", "I go up and down but I don’t move.");
put("cold", "You can catch me, but you can't throw me.");
put("library", "I am the building with the most stories.");
put("legs", "We have bottoms at our tops.");
put("dozens", "I've got six letters, remove one and twelve remains.");
put("noon", "I can be turned backward and upside down but I'll still remain the same.");
put("Chicago", "I am 3/7 chicken, 2/3 cat and half goat.");
put("silence", "I am so fragile, saying my name breaks me.");
put("mirror", "If you drop me I’m sure to crack, but give me a smile and I’ll always smile back.");
put("fire", "I am always hungry and will die if not fed, but whatever I touch will soon turn red.");
put("map", "I have lakes with no water, mountains with no stone and cities with no buildings.");
put("traffic light", "Three eyes have I, all in a row; when the red one opens, all freeze like the snow.");
put("footsteps", "The more of me you take, the more of me you leave behind.");
put("shirt", "I have a neck and no head, two arms and no hands.");
put("iceberg", "I am lighter than what I am made of, more of me is hidden than is seen.");
put("thumb", "I am shorter than the rest, but when you're happy you raise me up like I'm the best.");
put("seven", "I am odd, but if you take away a letter from me I become even.");
put("mushroom", "I am a room with no walls or corners.");
put("live", "Spelled forward I’m what you do every day, spelled backward I’m something you hate.");
put("time", "Until I am measured, I am not known. Yet how you miss me when I have flown.");
put("envelope", "I only contain one letter.");
put("watermelon", "When handling me, you go at red and stop at green.");
put("promise", "If you don’t keep me, I’ll break.");
put("matchstick", "I kiss my mother before I die.");
put("trouble", "I am easy to get into but hard to get out of.");
put("wrong", "I am the only word in the dictionary that is spelt wrong.");
put("teapot", "I begin with T, end with T, and I have T in me.");
put("future", "I am always in front of you but you can't see me.");
put("candle", "I’m tall when I’m young, I’m short when I’m old.");
put("short", "I become shorter when you add 2 letters to me.");
put("tongue", "I taste better than I smell.");
put("fart", "Sometimes I am born in silence, Other times, no. I am unseen, But I make my presence known. In time, I fade without a trace. I harm no one, but I am unpopular with all.");
put("doorbell", "You answer me even though I never ask any questions.");
put("record", "Break me and I get better; set me and I'm harder to break.");
put("ton", "Forward, I am heavy; backward, I am not.");
put("kitten", "I have a head like a cat and feet like a cat, but I am not a cat.");
put("battery", "I have no life, but I can die.");
put("soap", "I shrink smaller every time I take a bath.");
put("rain", "I fall often but never get hurt");
put("screw", "I like to twirl my body but keep my head up high. After I go in, everything becomes tight.");
put("paint", "I am a kind of coat that can only be put on when wet.");
put("blackboard", "I am white when I'm dirty.");
put("die", "I have got 6 heads and 21 eyes");
put("book", "I teach without walking.");
}};
}
void updateBoard() {
attemptedLabel.update(wordsAttempted);
gottenLabel.update(wordsGotten);
scoreLabel.updateScore(points);
}
}
class AnswerLabel extends JLabel {
AnswerLabel() {
super();
this.setText("");
this.setHorizontalAlignment(JLabel.LEFT);
this.setFont(this.getFont().deriveFont(20f));
this.setForeground(Color.WHITE);
}
public void showAnswer(String answer) {
this.setText(answer);
}
}
class ScoreSectionLabel extends JLabel {
ScoreSectionLabel() {
super();
this.setHorizontalAlignment(JLabel.CENTER);
this.setForeground(Color.white);
this.setFont(this.getFont().deriveFont(50f));
}
}
class ScoreLabel extends ScoreSectionLabel {
ScoreLabel(int points) {
super();
this.setText("Score: " + points);
}
public void updateScore(int points) {
this.setText("Score: " + points);
}
}
class AttemptedLabel extends ScoreSectionLabel {
AttemptedLabel(int attempted) {
super();
this.setText("Words attempted: " + attempted);
}
public void update(int attempted) {
this.setText("Words attempted: " + attempted);
}
}
class GottenLabel extends ScoreSectionLabel {
GottenLabel(int gotten) {
super();
this.setText("Words gotten: " + gotten);
}
public void update(int gotten) {
this.setText("Words gotten: " + gotten);
}
}