initital commit UwU
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
*.class
|
||||
115
HangmanGUI.java
Normal file
@ -0,0 +1,115 @@
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.io.*;
|
||||
import java.util.List;
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class HangmanGUI extends JFrame {
|
||||
private HangmanGame game;
|
||||
private JLabel wordLabel, historyLabel, statusLabel, imageLabel;
|
||||
private JTextField input;
|
||||
private JButton restartBtn;
|
||||
private JCheckBoxMenuItem showHistoryItem;
|
||||
private List<String> words;
|
||||
|
||||
public HangmanGUI() {
|
||||
setTitle("Swing Hangman");
|
||||
setDefaultCloseOperation(EXIT_ON_CLOSE);
|
||||
setSize(400, 500);
|
||||
setLayout(new BorderLayout());
|
||||
|
||||
loadWords();
|
||||
game = new HangmanGame(words);
|
||||
|
||||
// === Top Menu ===
|
||||
JMenuBar menuBar = new JMenuBar();
|
||||
JMenu settingsMenu = new JMenu("Settings");
|
||||
|
||||
JMenu triesMenu = new JMenu("Tries");
|
||||
int[] triesOptions = {3,6,9,12};
|
||||
for (int n : triesOptions) {
|
||||
JMenuItem item = new JMenuItem(n + " tries");
|
||||
item.addActionListener(e -> { game.setMaxErrors(n); resetGame(); });
|
||||
triesMenu.add(item);
|
||||
}
|
||||
showHistoryItem = new JCheckBoxMenuItem("Show history", true);
|
||||
showHistoryItem.addActionListener(e -> historyLabel.setVisible(showHistoryItem.isSelected()));
|
||||
|
||||
settingsMenu.add(triesMenu);
|
||||
settingsMenu.add(showHistoryItem);
|
||||
menuBar.add(settingsMenu);
|
||||
setJMenuBar(menuBar);
|
||||
|
||||
// === Panels ===
|
||||
JPanel top = new JPanel(new GridLayout(4, 1));
|
||||
wordLabel = new JLabel("", SwingConstants.CENTER);
|
||||
wordLabel.setFont(new Font("Monospaced", Font.BOLD, 24));
|
||||
historyLabel = new JLabel("", SwingConstants.CENTER);
|
||||
statusLabel = new JLabel("Tries left: " + (game.getMaxErrors() - game.getErrors()), SwingConstants.CENTER);
|
||||
imageLabel = new JLabel(new ImageIcon("img/hang0.png"), SwingConstants.CENTER);
|
||||
|
||||
input = new JTextField();
|
||||
input.setHorizontalAlignment(JTextField.CENTER);
|
||||
input.addActionListener(e -> handleGuess());
|
||||
restartBtn = new JButton("Restart");
|
||||
restartBtn.addActionListener(e -> resetGame());
|
||||
|
||||
top.add(wordLabel);
|
||||
top.add(historyLabel);
|
||||
top.add(statusLabel);
|
||||
top.add(input);
|
||||
|
||||
add(top, BorderLayout.NORTH);
|
||||
add(imageLabel, BorderLayout.CENTER);
|
||||
add(restartBtn, BorderLayout.SOUTH);
|
||||
|
||||
refresh();
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
private void loadWords() {
|
||||
words = new ArrayList<>();
|
||||
File f = new File("words.txt");
|
||||
if (f.exists()) {
|
||||
try (Scanner sc = new Scanner(f)) {
|
||||
while (sc.hasNext()) words.add(sc.next().trim());
|
||||
} catch (Exception e) { e.printStackTrace(); }
|
||||
}
|
||||
if (words.isEmpty()) {
|
||||
words = Arrays.asList("JAVA", "SWING", "SQUIRREL", "PYTHON", "FLUFFY");
|
||||
}
|
||||
}
|
||||
|
||||
private void handleGuess() {
|
||||
String text = input.getText().trim();
|
||||
if (text.length() == 0) return;
|
||||
char c = text.charAt(0);
|
||||
game.guess(c);
|
||||
input.setText("");
|
||||
refresh();
|
||||
}
|
||||
|
||||
private void refresh() {
|
||||
wordLabel.setText(game.getMaskedWord());
|
||||
historyLabel.setText("History: " + game.getHistory());
|
||||
statusLabel.setText("Tries left: " + (game.getMaxErrors() - game.getErrors()));
|
||||
imageLabel.setIcon(new ImageIcon("img/hang" + Math.min(game.getErrors(), 9) + ".png"));
|
||||
|
||||
if (game.isWon()) {
|
||||
JOptionPane.showMessageDialog(this, "Solved! Word was: " + game.getWord());
|
||||
} else if (game.isLost()) {
|
||||
JOptionPane.showMessageDialog(this, "Game Over! Word was: " + game.getWord());
|
||||
}
|
||||
}
|
||||
|
||||
private void resetGame() {
|
||||
game = new HangmanGame(words);
|
||||
refresh();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SwingUtilities.invokeLater(HangmanGUI::new);
|
||||
}
|
||||
}
|
||||
50
HangmanGame.java
Normal file
@ -0,0 +1,50 @@
|
||||
import java.util.*;
|
||||
|
||||
public class HangmanGame {
|
||||
private String word;
|
||||
private Set<Character> guessed = new HashSet<>();
|
||||
private int errors = 0;
|
||||
private int maxErrors = 9;
|
||||
|
||||
public HangmanGame(List<String> words) {
|
||||
this.word = words.get(new Random().nextInt(words.size())).toUpperCase();
|
||||
}
|
||||
|
||||
public void setMaxErrors(int max) { this.maxErrors = max; }
|
||||
public int getErrors() { return errors; }
|
||||
public int getMaxErrors() { return maxErrors; }
|
||||
|
||||
public boolean guess(char c) {
|
||||
c = Character.toUpperCase(c);
|
||||
if (guessed.contains(c)) return true;
|
||||
guessed.add(c);
|
||||
if (!word.contains(String.valueOf(c))) errors++;
|
||||
return isWon() || !isLost();
|
||||
}
|
||||
|
||||
public String getMaskedWord() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (char c : word.toCharArray()) {
|
||||
sb.append(guessed.contains(c) ? c : '_');
|
||||
sb.append(' ');
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String getHistory() {
|
||||
List<Character> list = new ArrayList<>(guessed);
|
||||
Collections.sort(list);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (char c : list) sb.append(c).append(' ');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public boolean isWon() {
|
||||
for (char c : word.toCharArray())
|
||||
if (!guessed.contains(c)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isLost() { return errors >= maxErrors; }
|
||||
public String getWord() { return word; }
|
||||
}
|
||||
BIN
img/hang0.png
Normal file
|
After Width: | Height: | Size: 285 B |
BIN
img/hang1.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
img/hang2.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
img/hang3.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
img/hang4.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
img/hang5.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
img/hang6.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
img/hang7.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
img/hang8.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
img/hang9.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |