Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 42 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
# Number Guessing Game

A simple number guessing game where you try to guess a randomly generated number. The game will tell you if your guess is too high or too low until you find the correct number.
A simple number guessing game where you try to guess a randomly generated number. The game features both a user-friendly graphical interface (GUI) and a classic console mode. The GUI provides visual feedback with color-coded hints and tracks your progress in real-time.

**Features:**
- 🎮 Modern Swing-based GUI (default)
- 💻 Classic console mode (use `--console` flag)
- 🎯 Visual feedback with color coding
- 📊 Real-time guess counter
- ⌨️ Keyboard shortcuts for quick navigation
- 🌍 Cross-platform compatible (Windows, macOS, Linux)

## Installation & Running

Expand Down Expand Up @@ -66,11 +74,40 @@ Run `run.sh`

### How to Play

The game now features both a graphical user interface (GUI) and a console mode.

#### GUI Mode (Default)

1. Start the game using one of the methods above
2. Enter your guess when prompted
3. The game will tell you if your guess is too high or too low
4. Keep guessing until you find the correct number
5. The game will display how many guesses it took you
2. A window will appear with the game interface
3. Enter your guess in the text field and click "Submit Guess" or press Enter
4. The game will provide visual feedback:
- Blue text indicates your guess was too low
- Orange text indicates your guess was too high
- Green text indicates you guessed correctly!
5. The number of guesses is displayed and updated in real-time
6. When you guess correctly, click "New Game" to play again
7. Use the menu bar for additional options:
- File → New Game (Ctrl+N): Start a new game
- File → Exit: Close the application
- Help → About: View game information

#### Console Mode

To run the classic console version, use the `--console` or `-c` flag:

```bash
java -jar app.jar --console
# or
./run.sh --console # Linux/Mac
run.bat --console # Windows
```

In console mode:
1. Enter your guess when prompted
2. The game will tell you if your guess is too high or too low
3. Keep guessing until you find the correct number
4. The game will display how many guesses it took you

## Development

Expand Down
303 changes: 285 additions & 18 deletions app/src/main/java/io/github/project516/NumberGuessingGame/GUI.java
Original file line number Diff line number Diff line change
@@ -1,39 +1,306 @@
package io.github.project516.NumberGuessingGame;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

// TODO

/**
* Graphical User Interface for the Number Guessing Game. This class creates and manages the game's
* window and UI components. Currently under development.
* window and UI components using Java Swing. Provides a user-friendly interface for playing the
* number guessing game with visual feedback and menu options.
*/
public class GUI {
public class GUI extends JFrame {
// Game state
private int targetNumber;
private int numberOfGuesses;
private RandomNumber randomGenerator;
private CheckGuess guessChecker;
private GameInfo gameInfo;

// UI Components
private JTextField guessField;
private JButton submitButton;
private JButton newGameButton;
private JLabel feedbackLabel;
private JLabel promptLabel;
private JLabel guessCountLabel;
private JPanel mainPanel;

/**
* Constructs the GUI and initializes all components. Sets up the game window with proper layout
* and starts a new game.
*/
public GUI() {
super("Number Guessing Game");

// Initialize game objects
randomGenerator = new RandomNumber();
guessChecker = new CheckGuess();
gameInfo = new GameInfo();

// Set up the frame
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(500, 400);
setLocationRelativeTo(null); // Center on screen
setResizable(false);

// Create menu bar
createMenuBar();

// Create main panel
createMainPanel();

// Start new game
startNewGame();

setVisible(true);
}

/** Creates and configures the menu bar with File and Help menus. */
private void createMenuBar() {
JMenuBar menuBar = new JMenuBar();

// File menu
JMenu fileMenu = new JMenu("File");
fileMenu.setMnemonic(KeyEvent.VK_F);

JMenuItem newGameItem = new JMenuItem("New Game", KeyEvent.VK_N);
newGameItem.setAccelerator(
KeyStroke.getKeyStroke(KeyEvent.VK_N, InputEvent.CTRL_DOWN_MASK));
newGameItem.addActionListener(e -> startNewGame());
fileMenu.add(newGameItem);

fileMenu.addSeparator();

JMenuItem exitItem = new JMenuItem("Exit", KeyEvent.VK_X);
exitItem.addActionListener(e -> System.exit(0));
fileMenu.add(exitItem);

// Help menu
JMenu helpMenu = new JMenu("Help");
helpMenu.setMnemonic(KeyEvent.VK_H);

JMenuItem aboutItem = new JMenuItem("About", KeyEvent.VK_A);
aboutItem.addActionListener(e -> showAboutDialog());
helpMenu.add(aboutItem);

menuBar.add(fileMenu);
menuBar.add(helpMenu);

setJMenuBar(menuBar);
}

/** Creates and configures the main game panel with all UI components. */
private void createMainPanel() {
mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));

// Title label
JLabel titleLabel = new JLabel("Number Guessing Game");
titleLabel.setFont(new Font("Arial", Font.BOLD, 24));
titleLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
mainPanel.add(titleLabel);

mainPanel.add(Box.createRigidArea(new Dimension(0, 20)));

// Instructions label
JLabel instructionsLabel = new JLabel("Guess a number between 1 and 100!");
instructionsLabel.setFont(new Font("Arial", Font.PLAIN, 14));
instructionsLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
mainPanel.add(instructionsLabel);

mainPanel.add(Box.createRigidArea(new Dimension(0, 30)));

// Guess count label
guessCountLabel = new JLabel("Number of guesses: 0");
guessCountLabel.setFont(new Font("Arial", Font.PLAIN, 12));
guessCountLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
mainPanel.add(guessCountLabel);

mainPanel.add(Box.createRigidArea(new Dimension(0, 20)));

// Prompt label
promptLabel = new JLabel("Enter your guess:");
promptLabel.setFont(new Font("Arial", Font.PLAIN, 14));
promptLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
mainPanel.add(promptLabel);

mainPanel.add(Box.createRigidArea(new Dimension(0, 10)));

// Input panel
JPanel inputPanel = new JPanel();
inputPanel.setLayout(new FlowLayout(FlowLayout.CENTER));

guessField = new JTextField(10);
guessField.setFont(new Font("Arial", Font.PLAIN, 16));
guessField.addActionListener(e -> submitGuess());
inputPanel.add(guessField);

submitButton = new JButton("Submit Guess");
submitButton.setFont(new Font("Arial", Font.PLAIN, 14));
submitButton.addActionListener(e -> submitGuess());
inputPanel.add(submitButton);

mainPanel.add(inputPanel);

mainPanel.add(Box.createRigidArea(new Dimension(0, 20)));

// Feedback label
feedbackLabel = new JLabel(" ");
feedbackLabel.setFont(new Font("Arial", Font.BOLD, 16));
feedbackLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
mainPanel.add(feedbackLabel);

mainPanel.add(Box.createRigidArea(new Dimension(0, 30)));

// New game button
newGameButton = new JButton("New Game");
newGameButton.setFont(new Font("Arial", Font.PLAIN, 14));
newGameButton.setAlignmentX(Component.CENTER_ALIGNMENT);
newGameButton.addActionListener(e -> startNewGame());
newGameButton.setVisible(false);
mainPanel.add(newGameButton);

add(mainPanel);
}

/** Starts a new game by resetting the game state and UI components. */
private void startNewGame() {
targetNumber = randomGenerator.number(100);
numberOfGuesses = 0;

guessField.setEnabled(true);
submitButton.setEnabled(true);
newGameButton.setVisible(false);

guessField.setText("");
feedbackLabel.setText(" ");
feedbackLabel.setForeground(Color.BLACK);
updateGuessCount();

guessField.requestFocus();
}

/** Processes the user's guess and updates the UI with feedback. */
private void submitGuess() {
String input = guessField.getText().trim();

if (input.isEmpty()) {
showFeedback("Please enter a number!", Color.RED);
return;
}

int guess;
try {
guess = Integer.parseInt(input);
} catch (NumberFormatException e) {
showFeedback("Invalid input! Please enter a valid number.", Color.RED);
guessField.setText("");
return;
}

try {
guessChecker.check(guess);
} catch (IllegalArgumentException e) {
showFeedback(e.getMessage(), Color.RED);
guessField.setText("");
return;
}

numberOfGuesses++;
updateGuessCount();

if (guess > targetNumber) {
showFeedback("Too high! Try a lower number.", new Color(255, 140, 0)); // Orange
} else if (guess < targetNumber) {
showFeedback("Too low! Try a higher number.", new Color(30, 144, 255)); // Blue
} else {
// Correct guess
showFeedback("Congratulations! You guessed it!", new Color(0, 128, 0)); // Green
guessField.setEnabled(false);
submitButton.setEnabled(false);
newGameButton.setVisible(true);
newGameButton.requestFocus();

// Show congratulations dialog
String message =
String.format(
"You guessed the number in %d %s!",
numberOfGuesses, numberOfGuesses == 1 ? "guess" : "guesses");
JOptionPane.showMessageDialog(
this, message, "Congratulations!", JOptionPane.INFORMATION_MESSAGE);
}

guessField.setText("");
guessField.requestFocus();
}

/**
* Creates and displays the main game window. Sets up a JFrame with a centered label showing the
* game title.
* Updates the feedback label with the provided message and color.
*
* @param message the feedback message to display
* @param color the color to use for the message
*/
void createWindow() {
JFrame jframe = new JFrame("Number Guessing Game");
JLabel jlabel = new JLabel("Number Guessing Game", SwingConstants.CENTER);
// JButton jbutton = new JButton("Start game!");
private void showFeedback(String message, Color color) {
feedbackLabel.setText(message);
feedbackLabel.setForeground(color);
}

jframe.getContentPane().add(jlabel, BorderLayout.CENTER);
/** Updates the guess count label to reflect the current number of guesses. */
private void updateGuessCount() {
guessCountLabel.setText("Number of guesses: " + numberOfGuesses);
}

jframe.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); // Exit on close
jframe.setSize(300, 300);
/** Displays the About dialog with game information. */
private void showAboutDialog() {
String message =
String.format(
"Number Guessing Game\n\n"
+ "Version: %s\n"
+ "Author: %s\n\n"
+ "Project URL:\n%s\n\n"
+ "Online Documentation:\n%s",
getVersion(),
gameInfo.author(),
gameInfo.projectURL(),
gameInfo.onlineJavadoc());

jframe.setVisible(true); // Set visible
JOptionPane.showMessageDialog(
this, message, "About Number Guessing Game", JOptionPane.INFORMATION_MESSAGE);
}

/**
* Gets the version of the application.
*
* @return the version string
*/
private String getVersion() {
ReadVersionFile versionReader = new ReadVersionFile();
try {
return versionReader.readVersion();
} catch (Exception e) {
return "Unknown";
}
}

/**
* Creates and displays the GUI window. This method should be called on the Event Dispatch
* Thread for thread safety.
*/
public void createWindow() {
// This method is kept for backwards compatibility
// The constructor already makes the window visible
}

/**
* Test method for the GUI. Creates a GUI instance and displays the window for testing purposes.
* Main method for testing the GUI. Creates and displays the game window on the Event Dispatch
* Thread.
*
* @param args command line arguments (not used)
*/
public static void main(String[] args) { // Test GUI
GUI gui = new GUI();
gui.createWindow();
public static void main(String[] args) {
// Use SwingUtilities to ensure thread safety
SwingUtilities.invokeLater(() -> new GUI());
}
}
Loading
Loading