fix formatting + launching JavaFX application launching

This commit is contained in:
SowinskiBraeden committed 2025-11-29 16:07:26 -08:00
1 parent 972ef0c8d9
commit 5f779cb027
12 files changed
+186 -70

No files matched your search

+21
View File
@@ -19,3 +19,24 @@ Correct Second Attempts: 1
Incorrect Attempts: 8 Incorrect Attempts: 8
Total Score: 3 Total Score: 3
Date and Time: 2025-11-29 15:05:40
Games Played: 1
Correct First Attempts: 0
Correct Second Attempts: 0
Incorrect Attempts: 10
Score: 0 points
Date and Time: 2025-11-29 15:09:31
Games Played: 1
Correct First Attempts: 0
Correct Second Attempts: 0
Incorrect Attempts: 10
Score: 0 points
Date and Time: 2025-11-29 15:29:31
Games Played: 1
Correct First Attempts: 0
Correct Second Attempts: 0
Incorrect Attempts: 10
Score: 0 points
@@ -4,6 +4,9 @@ package ca.bcit.comp2522.project;
* AscendingPlacement contains the logical and * AscendingPlacement contains the logical and
* validation of placing an integer in an array * validation of placing an integer in an array
* of integers following an ascending order. * of integers following an ascending order.
*
* @author Braeden Sowinski
* @version 1.0.0
*/ */
public class AscendingPlacement public class AscendingPlacement
extends PlacementRule extends PlacementRule
@@ -22,8 +25,11 @@ public class AscendingPlacement
* @return if the value is in a valid placement * @return if the value is in a valid placement
*/ */
@Override @Override
public boolean isValidPlacement(int[] positions, int index, int value) public boolean isValidPlacement(
{ final int[] positions,
final int index,
final int value
) {
for (int i = 0; i < positions.length; i++) for (int i = 0; i < positions.length; i++)
{ {
if (positions[i] == FIRST) if (positions[i] == FIRST)
@@ -55,8 +61,10 @@ public class AscendingPlacement
* without violating the ascending rule * without violating the ascending rule
*/ */
@Override @Override
public boolean canPlaceNext(int[] positions, int nextValue) public boolean canPlaceNext(
{ final int[] positions,
final int nextValue
) {
for (int i = 0; i < positions.length; i++) for (int i = 0; i < positions.length; i++)
{ {
if (positions[i] != FIRST) if (positions[i] != FIRST)
@@ -4,7 +4,7 @@ import java.util.Random;
/** /**
* Country class stores a country's * Country class stores a country's
* name, capital city name, and NUMBER_OF_FACTS * name, capital city name
* about the country. * about the country.
* *
* @author Braeden Sowinski * @author Braeden Sowinski
@@ -12,8 +12,6 @@ import java.util.Random;
*/ */
public class Country public class Country
{ {
private static final int NUMBER_OF_FACTS = 3;
private final String name; private final String name;
private final String capitalCityName; private final String capitalCityName;
private final String[] facts; private final String[] facts;
@@ -5,6 +5,9 @@ package ca.bcit.comp2522.project;
* to represent some two-dimensional board, * to represent some two-dimensional board,
* it stores the width and height of board * it stores the width and height of board
* and must have a reset method. * and must have a reset method.
*
* @author Braeden Sowinski
* @version 1.0.0
*/ */
public abstract class GameBoard public abstract class GameBoard
{ {
+100 -34
View File
@@ -1,62 +1,128 @@
package ca.bcit.comp2522.project; package ca.bcit.comp2522.project;
import java.io.File;
import java.io.IOException;
import java.util.Scanner; import java.util.Scanner;
/** /**
* Main program entry to access a games menu, * Main launcher for the games application.
* users can select from 3 games. Word Game, * Provides a CLI for selecting WordGame, NumberGame,
* Number Game, or My Game (Minesweeper) * or Minesweeper, launching JavaFX games in separate
* JVM processes for lifecycle stability.
* *
* @author Braeden Sowinski * @author Braeden Sowinski
* @version 1.0.0 * @version 1.0.1
*/ */
public class Main public class Main
{ {
/** /**
* main program entry * Program entry point for the CLI menu.
* @param args from the command line *
* @param args command-line arguments. Optional:
* --jfxlib=/path/to/javafx-sdk/lib
*/ */
public static void main(final String[] args) public static void main(final String[] args)
{ {
final String javafxLib;
javafxLib = System.getProperty("jdk.module.path");
if (javafxLib == null)
{
System.err.println(
"JavaFX library path missing.\n" +
"Provide with:\n" +
" 1) VM option: -Djfxlib=/path/to/javafx/lib\n" +
" 2) Or program arg: --jfxlib=/path/to/javafx/lib"
);
return;
}
final Scanner scanner; final Scanner scanner;
boolean running;
scanner = new Scanner(System.in); scanner = new Scanner(System.in);
running = true;
boolean run = true; while (running)
{
do {
final String input;
System.out.println("Select a game: ");
System.out.println("Word Game (W)"); System.out.println("Word Game (W)");
System.out.println("Number Game (N)"); System.out.println("Number Game (N)");
System.out.println("My Game (M)"); System.out.println("Minesweeper (M)");
System.out.println("Quit (Q)"); System.out.println("Quit (Q)");
System.out.print("> "); System.out.print("> ");
input = scanner.nextLine().toUpperCase(); final String choice;
switch (input) { choice = scanner.nextLine().trim().toUpperCase();
case "W":
System.out.println("Word game...");
break;
case "N":
System.out.println("Number game...");
break;
case "M":
System.out.println("My game...");
break;
case "Q":
System.out.println("Quitting...");
run = false;
break;
default:
System.out.println("Invalid input: " + input);
break;
}
} while (run); switch (choice)
{
case "W" -> runWordGame(scanner);
case "N" -> launchJavaFxApp("ca.bcit.comp2522.project.NumberGame", javafxLib);
case "M" -> launchJavaFxApp("ca.bcit.comp2522.project.MyGame", javafxLib);
case "Q" -> running = false;
default -> System.out.println("Invalid selection.");
}
}
}
scanner.close(); /**
* Runs the WordGame inside the CLI environment.
*
* @param scanner shared scanner for System.in
*/
private static void runWordGame(final Scanner scanner)
{
try
{
final WordGame game;
game = new WordGame();
game.runTrivia(scanner);
}
catch (final IOException e)
{
System.err.println("Unable to start WordGame.");
}
}
/**
* Launches a JavaFX Application subclass in a new
* JVM process.
*
* @param mainClass fully-qualified class name
* @param javafxLib path to JavaFX lib directory
*/
private static void launchJavaFxApp(
final String mainClass,
final String javafxLib
) {
final String javaBin;
final String cp;
final ProcessBuilder pb;
javaBin = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java";
cp = System.getProperty("java.class.path");
pb = new ProcessBuilder(
javaBin,
"--module-path", javafxLib,
"--add-modules", "javafx.controls,javafx.fxml",
"--enable-native-access=javafx.graphics",
"-cp", cp,
mainClass
);
pb.inheritIO();
try
{
final Process p;
p = pb.start();
p.waitFor();
}
catch (final IOException | InterruptedException e)
{
Thread.currentThread().interrupt();
}
} }
} }
@@ -1,14 +1,6 @@
package ca.bcit.comp2522.project; package ca.bcit.comp2522.project;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.time.format.DateTimeFormatter;
import java.util.Random; import java.util.Random;
import java.util.Scanner;
import java.util.function.Consumer; import java.util.function.Consumer;
/** /**
@@ -36,10 +28,6 @@ public class Mines extends GameBoard
public static final int FLAG = 1; public static final int FLAG = 1;
public static final int FLAG_QUESTION = 2; public static final int FLAG_QUESTION = 2;
private static final int INITIAL_BEST_SCORE = Integer.MAX_VALUE;
private static final String SCORE_FILE_NAME = "minesweeper-score.txt";
private static final Random RANDOM_GENERATOR; private static final Random RANDOM_GENERATOR;
static static
@@ -196,6 +196,8 @@ public class MinesScore
final String difficulty, final String difficulty,
final boolean randomMode final boolean randomMode
) { ) {
validateDifficulty(difficulty);
final DateTimeFormatter formatter; final DateTimeFormatter formatter;
formatter = DateTimeFormatter.ofPattern(DATE_PATTERN); formatter = DateTimeFormatter.ofPattern(DATE_PATTERN);
+24 -2
View File
@@ -130,6 +130,10 @@ public class MinesUI
this.timerRunning = false; this.timerRunning = false;
} }
/*
* showInfo displays an info popup
* about the random mode
*/
private void showInfo(final Window window) private void showInfo(final Window window)
{ {
final Stage popup; final Stage popup;
@@ -172,6 +176,12 @@ public class MinesUI
* game mode, and field size. * game mode, and field size.
* @param primaryStage to display main menu to * @param primaryStage to display main menu to
*/ */
/**
* showMainMenu displays main menu to choose
* game mode and field size.
*
* @param primaryStage to display main menu on
*/
public void showMainMenu(final Stage primaryStage) public void showMainMenu(final Stage primaryStage)
{ {
final Label titleLabel; final Label titleLabel;
@@ -181,6 +191,7 @@ public class MinesUI
final Label modeLabel; final Label modeLabel;
final Button toggleModeButton; final Button toggleModeButton;
final Button modeInfoButton; final Button modeInfoButton;
final Button quitButton;
final HBox modeButtons; final HBox modeButtons;
final VBox root; final VBox root;
final Scene scene; final Scene scene;
@@ -202,6 +213,8 @@ public class MinesUI
modeLabel = new Label("Random Mode: OFF"); modeLabel = new Label("Random Mode: OFF");
toggleModeButton = new Button("Toggle Random Mode"); toggleModeButton = new Button("Toggle Random Mode");
modeInfoButton = new Button("?"); modeInfoButton = new Button("?");
quitButton = new Button("Quit");
modeButtons = new HBox(MENU_PADDING, toggleModeButton, modeInfoButton); modeButtons = new HBox(MENU_PADDING, toggleModeButton, modeInfoButton);
toggleModeButton.setOnAction(e -> { toggleModeButton.setOnAction(e -> {
@@ -209,7 +222,10 @@ public class MinesUI
modeLabel.setText("Random Mode: " + (this.randomMode ? "ON" : "OFF")); modeLabel.setText("Random Mode: " + (this.randomMode ? "ON" : "OFF"));
}); });
modeInfoButton.setOnAction(e -> showInfo(primaryStage.getOwner())); modeInfoButton.setOnAction(e -> showInfo(primaryStage));
quitButton.setFont(MENU_FONT);
quitButton.setOnAction(e -> primaryStage.close());
easyButton.setOnAction(e -> startGame( easyButton.setOnAction(e -> startGame(
EASY_WIDTH, EASY_WIDTH,
@@ -250,7 +266,8 @@ public class MinesUI
mediumButton, mediumButton,
hardButton, hardButton,
modeLabel, modeLabel,
modeButtons modeButtons,
quitButton
); );
scene = new Scene(root, WINDOW_WIDTH, WINDOW_HEIGHT); scene = new Scene(root, WINDOW_WIDTH, WINDOW_HEIGHT);
@@ -739,4 +756,9 @@ public class MinesUI
button.setMouseTransparent(true); button.setMouseTransparent(true);
button.setFocusTraversable(false); button.setFocusTraversable(false);
} }
public Stage getGameStage()
{
return this.gameStage;
}
} }
@@ -1,6 +1,7 @@
package ca.bcit.comp2522.project; package ca.bcit.comp2522.project;
import javafx.application.Application; import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.Scene; import javafx.scene.Scene;
import javafx.scene.layout.GridPane; import javafx.scene.layout.GridPane;
@@ -142,8 +143,10 @@ public class NumberGame
* @param title of the popup * @param title of the popup
* @param message to show the user * @param message to show the user
*/ */
private void showPopup(final String title, final String message) private void showPopup(
{ final String title,
final String message
) {
final Stage popup; final Stage popup;
final VBox layout; final VBox layout;
final HBox buttonLayout; final HBox buttonLayout;
@@ -316,15 +319,16 @@ public class NumberGame
showPopup("You Won!", "Congratulations! You placed all numbers correctly."); showPopup("You Won!", "Congratulations! You placed all numbers correctly.");
} }
/* /*
* handlePress of button to place number * handlePress of button to place number
* in that cell * in that cell
* @param button pressed * @param button pressed
* @param index of button to place value * @param index of button to place value
*/ */
private void handlePress(final Button button, final int index) private void handlePress(
{ final Button button,
final int index
) {
button.setText("" + this.currentNumber); button.setText("" + this.currentNumber);
button.setMouseTransparent(true); button.setMouseTransparent(true);
button.setFocusTraversable(false); button.setFocusTraversable(false);
@@ -24,8 +24,8 @@ public class RandomNumberGenerator
*/ */
public RandomNumberGenerator( public RandomNumberGenerator(
final int min, final int min,
final int max) final int max
{ ) {
this.random = new Random(); this.random = new Random();
this.min = min; this.min = min;
@@ -148,15 +148,15 @@ public class WordGame
* *
* Once a user is done playing, score from all rounds is * Once a user is done playing, score from all rounds is
* saved and high-scores are calculated. * saved and high-scores are calculated.
*
* @param scanner to receive input
*/ */
public void runTrivia() public void runTrivia(final Scanner scanner)
{ {
final Scanner scanner;
Score score; Score score;
boolean continuePlaying; boolean continuePlaying;
continuePlaying = true; continuePlaying = true;
scanner = new Scanner(System.in);
final int[] scores; final int[] scores;
int gamesPlayed; int gamesPlayed;
@@ -182,7 +182,7 @@ public class WordGame
do do
{ {
System.out.println("\nDo you want to play again?"); System.out.println("\nDo you want to play again? (yes/no)");
System.out.print("> "); System.out.print("> ");
final String playAgain; final String playAgain;
@@ -206,8 +206,6 @@ public class WordGame
} while (continuePlaying); } while (continuePlaying);
scanner.close();
final List<Score> history; final List<Score> history;
history = Score.readScoresFromFile(SCORE_PATH); history = Score.readScoresFromFile(SCORE_PATH);
@@ -258,6 +256,12 @@ public class WordGame
throw new RuntimeException(e); throw new RuntimeException(e);
} }
test.runTrivia(); final Scanner scanner;
scanner = new Scanner(System.in);
test.runTrivia(scanner);
scanner.close();
} }
} }
+1 -1
View File
@@ -65,7 +65,7 @@ public class World
* World constructor creates a hashmap * World constructor creates a hashmap
* where the key is a Country name, and * where the key is a Country name, and
* the value is the Country object. * the value is the Country object.
* @throws IOException * @throws IOException if failed to read Countries
*/ */
public World() public World()
throws IOException throws IOException