start mines + fix WordGame + nearly finish NumberGame
This commit is contained in:
4 files changed
+661
-253
No files matched your search
@@ -1,15 +1,314 @@
|
|||||||
package ca.bcit.comp2522.project;
|
package ca.bcit.comp2522.project;
|
||||||
|
|
||||||
import javafx.application.Application;
|
import javafx.application.Application;
|
||||||
|
import javafx.geometry.Insets;
|
||||||
|
import javafx.geometry.Pos;
|
||||||
|
import javafx.scene.Scene;
|
||||||
|
import javafx.scene.control.Button;
|
||||||
|
import javafx.scene.control.Label;
|
||||||
|
import javafx.scene.input.MouseButton;
|
||||||
|
import javafx.scene.layout.GridPane;
|
||||||
|
import javafx.scene.layout.VBox;
|
||||||
|
import javafx.scene.text.Font;
|
||||||
|
import javafx.scene.text.FontWeight;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
public class Mines extends Application
|
public class Mines extends Application
|
||||||
{
|
{
|
||||||
|
private static final int FONT_SIZE = 18;
|
||||||
|
private static final Font FONT = Font.font("Arial", FontWeight.BOLD, FONT_SIZE);
|
||||||
|
|
||||||
|
private static final int WINDOW_WIDTH = 1920;
|
||||||
|
private static final int WINDOW_HEIGHT = 1080;
|
||||||
|
private static final int BUTTON_WIDTH = 60;
|
||||||
|
private static final int BUTTON_HEIGHT = 60;
|
||||||
|
private static final int EASY_WIDTH = 8;
|
||||||
|
private static final int EASY_HEIGHT = 8;
|
||||||
|
private static final int HARD_WIDTH = 36;
|
||||||
|
private static final int HARD_HEIGHT = 16;
|
||||||
|
private static final int PADDING = 20;
|
||||||
|
private static final int GAME_PADDING = 5;
|
||||||
|
private static final int VERTICAL_MARGIN = 15;
|
||||||
|
|
||||||
|
private static final int EASY_MINES = 10;
|
||||||
|
private static final int HARD_MINES = 99;
|
||||||
|
private static final int MINE = -1;
|
||||||
|
private static final int NO_MINE = 0;
|
||||||
|
|
||||||
|
private static final int MIN_OFFSET = -1;
|
||||||
|
private static final int MAX_OFFSET = 1;
|
||||||
|
private static final int SELF_OFFSET = 0;
|
||||||
|
private static final int FIRST_ROW = 0;
|
||||||
|
private static final int FIRST_COL = 0;
|
||||||
|
|
||||||
|
private static final int NO_FLAG = 0;
|
||||||
|
private static final int FLAG = 1;
|
||||||
|
private static final int FLAG_QUESTION = 2;
|
||||||
|
|
||||||
|
private static final int DEFAULT_BUTTON = -2;
|
||||||
|
private static final Map<Integer, String> BUTTON_THEMES = new HashMap<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
BUTTON_THEMES.put(-2, "-fx-background-color: #b3b3b3; -fx-text-fill: black;");
|
||||||
|
BUTTON_THEMES.put(-1, "-fx-background-color: #d9d9d9; -fx-text-fill: black;");
|
||||||
|
BUTTON_THEMES.put(0, "-fx-background-color: #d9d9d9; -fx-text-fill: black;");
|
||||||
|
BUTTON_THEMES.put(1, "-fx-background-color: #c8ffbf; -fx-text-fill: black;");
|
||||||
|
BUTTON_THEMES.put(2, "-fx-background-color: #edfc9f; -fx-text-fill: black;");
|
||||||
|
BUTTON_THEMES.put(3, "-fx-background-color: #fad08c; -fx-text-fill: black;");
|
||||||
|
BUTTON_THEMES.put(4, "-fx-background-color: #f59338; -fx-text-fill: black;");
|
||||||
|
BUTTON_THEMES.put(5, "-fx-background-color: #ff644d; -fx-text-fill: black;");
|
||||||
|
BUTTON_THEMES.put(6, "-fx-background-color: #ff644d; -fx-text-fill: black;");
|
||||||
|
BUTTON_THEMES.put(7, "-fx-background-color: #ff644d; -fx-text-fill: black;");
|
||||||
|
BUTTON_THEMES.put(8, "-fx-background-color: #ff644d; -fx-text-fill: black;");
|
||||||
|
}
|
||||||
|
|
||||||
|
private int[] field;
|
||||||
|
private boolean[] revealed;
|
||||||
|
private int[] flagged;
|
||||||
|
private Button[] buttons;
|
||||||
|
private int width;
|
||||||
|
private int height;
|
||||||
|
private int flags;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start(final Stage s)
|
public void start(final Stage stage)
|
||||||
{
|
{
|
||||||
s.setTitle("MineSweeper Random");
|
final Label title;
|
||||||
s.show();
|
title = new Label("Select Game Size");
|
||||||
|
title.setStyle("-fx-font-size: 20px; -fx-font-weight: bold;");
|
||||||
|
|
||||||
|
final Button smallBtn;
|
||||||
|
final Button largeBtn;
|
||||||
|
|
||||||
|
smallBtn = new Button("8 × 8 (Beginner)");
|
||||||
|
largeBtn = new Button("36 × 16 (Expert)");
|
||||||
|
|
||||||
|
smallBtn.setPrefWidth(BUTTON_WIDTH);
|
||||||
|
largeBtn.setPrefWidth(BUTTON_WIDTH);
|
||||||
|
|
||||||
|
smallBtn.setOnAction(e -> startGame(EASY_WIDTH, EASY_HEIGHT, EASY_MINES));
|
||||||
|
largeBtn.setOnAction(e -> startGame(HARD_WIDTH, HARD_HEIGHT, HARD_MINES));
|
||||||
|
|
||||||
|
final VBox root;
|
||||||
|
root = new VBox(VERTICAL_MARGIN);
|
||||||
|
|
||||||
|
root.setPadding(new Insets(PADDING));
|
||||||
|
root.setAlignment(Pos.CENTER);
|
||||||
|
root.getChildren().addAll(title, smallBtn, largeBtn);
|
||||||
|
|
||||||
|
final Scene scene = new Scene(root, WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||||
|
stage.setTitle("Random Mines - A Minesweeper Game");
|
||||||
|
stage.setResizable(false);
|
||||||
|
stage.setScene(scene);
|
||||||
|
stage.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void forEachNeighbor(final int index, final java.util.function.IntConsumer action)
|
||||||
|
{
|
||||||
|
final int row = index / width;
|
||||||
|
final int col = index % width;
|
||||||
|
|
||||||
|
for (int dr = MIN_OFFSET; dr <= MAX_OFFSET; dr++)
|
||||||
|
{
|
||||||
|
for (int dc = MIN_OFFSET; dc <= MAX_OFFSET; dc++)
|
||||||
|
{
|
||||||
|
if (dr == SELF_OFFSET && dc == SELF_OFFSET)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int nr = row + dr;
|
||||||
|
final int nc = col + dc;
|
||||||
|
|
||||||
|
if (nr < FIRST_ROW || nr >= height ||
|
||||||
|
nc < FIRST_COL || nc >= width)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int neighborIndex = nr * width + nc;
|
||||||
|
action.accept(neighborIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateField(final int mines)
|
||||||
|
{
|
||||||
|
this.revealed = new boolean[width * height];
|
||||||
|
this.field = new int[width * height];
|
||||||
|
this.flagged = new int[width * height];
|
||||||
|
|
||||||
|
final Random rand;
|
||||||
|
int placed;
|
||||||
|
|
||||||
|
rand = new Random();
|
||||||
|
placed = NO_MINE;
|
||||||
|
|
||||||
|
while (placed < mines)
|
||||||
|
{
|
||||||
|
final int index;
|
||||||
|
index = rand.nextInt(width * height);
|
||||||
|
|
||||||
|
if (this.field[index] != MINE)
|
||||||
|
{
|
||||||
|
this.field[index] = MINE;
|
||||||
|
placed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < field.length; i++)
|
||||||
|
{
|
||||||
|
if (this.field[i] == MINE)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int[] count = { NO_MINE };
|
||||||
|
|
||||||
|
forEachNeighbor(i, neighborIndex -> {
|
||||||
|
if (this.field[neighborIndex] == MINE)
|
||||||
|
{
|
||||||
|
count[SELF_OFFSET]++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.field[i] = count[SELF_OFFSET];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void popFieldVoid(final int index)
|
||||||
|
{
|
||||||
|
forEachNeighbor(index, neighborIndex -> {
|
||||||
|
|
||||||
|
if (!revealed[neighborIndex])
|
||||||
|
{
|
||||||
|
reveal(neighborIndex);
|
||||||
|
|
||||||
|
if (field[neighborIndex] == NO_MINE)
|
||||||
|
{
|
||||||
|
popFieldVoid(neighborIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startGame(
|
||||||
|
final int width,
|
||||||
|
final int height,
|
||||||
|
final int mines
|
||||||
|
) {
|
||||||
|
this.flags = NO_FLAG;
|
||||||
|
this.buttons = new Button[width * height];
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
|
||||||
|
generateField(mines);
|
||||||
|
|
||||||
|
final Stage gameStage;
|
||||||
|
final VBox box;
|
||||||
|
final GridPane grid;
|
||||||
|
|
||||||
|
gameStage = new Stage();
|
||||||
|
box = new VBox();
|
||||||
|
grid = createGrid(width, height);
|
||||||
|
|
||||||
|
box.getChildren().add(grid);
|
||||||
|
box.setAlignment(Pos.CENTER);
|
||||||
|
|
||||||
|
final Scene scene;
|
||||||
|
scene = new Scene(box, WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||||
|
|
||||||
|
gameStage.setScene(scene);
|
||||||
|
gameStage.setTitle("Random Mines " + width + "x" + height);
|
||||||
|
gameStage.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void flag(final int index)
|
||||||
|
{
|
||||||
|
this.flagged[index] = (this.flagged[index] + FLAG) % (FLAG_QUESTION + FLAG);
|
||||||
|
|
||||||
|
final String buttonText;
|
||||||
|
|
||||||
|
buttonText = this.flagged[index] == FLAG ? "F" :
|
||||||
|
this.flagged[index] == FLAG_QUESTION ? "?" : "";
|
||||||
|
|
||||||
|
this.buttons[index].setText(buttonText);
|
||||||
|
|
||||||
|
this.flags = this.flagged[index] == FLAG ? this.flags + FLAG : this.flags - FLAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
private GridPane createGrid(final int width, final int height)
|
||||||
|
{
|
||||||
|
final GridPane grid;
|
||||||
|
grid = new GridPane();
|
||||||
|
|
||||||
|
grid.setPadding(new Insets(GAME_PADDING));
|
||||||
|
grid.setHgap(GAME_PADDING);
|
||||||
|
grid.setVgap(GAME_PADDING);
|
||||||
|
|
||||||
|
for (int i = 0; i < width; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < height; j++)
|
||||||
|
{
|
||||||
|
final Button button;
|
||||||
|
final int index;
|
||||||
|
|
||||||
|
index = (j * width) + i;
|
||||||
|
button = new Button();
|
||||||
|
|
||||||
|
button.setFont(FONT);
|
||||||
|
button.setPrefSize(BUTTON_WIDTH, BUTTON_HEIGHT);
|
||||||
|
button.setStyle(BUTTON_THEMES.get(DEFAULT_BUTTON));
|
||||||
|
button.setOnMouseEntered(e -> button.setCursor(javafx.scene.Cursor.HAND));
|
||||||
|
button.setOnMouseExited(e -> button.setCursor(javafx.scene.Cursor.DEFAULT));
|
||||||
|
button.setOnMouseClicked(e -> {
|
||||||
|
if (e.getButton() == MouseButton.PRIMARY) {
|
||||||
|
reveal(index);
|
||||||
|
}
|
||||||
|
else if (e.getButton() == MouseButton.SECONDARY) {
|
||||||
|
flag(index);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
grid.add(button, i, j);
|
||||||
|
this.buttons[index] = button;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return grid;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void reveal(final int index)
|
||||||
|
{
|
||||||
|
if (this.revealed[index])
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String buttonText;
|
||||||
|
final Button button;
|
||||||
|
|
||||||
|
button = this.buttons[index];
|
||||||
|
|
||||||
|
buttonText = "" + (this.field[index] == MINE ? "*" :
|
||||||
|
this.field[index] == NO_MINE ? " " :
|
||||||
|
this.field[index]);
|
||||||
|
|
||||||
|
button.setText(buttonText);
|
||||||
|
button.setStyle(BUTTON_THEMES.get(this.field[index]));
|
||||||
|
button.setMouseTransparent(true);
|
||||||
|
button.setFocusTraversable(false);
|
||||||
|
|
||||||
|
this.revealed[index] = true;
|
||||||
|
|
||||||
|
if (this.field[index] == NO_MINE)
|
||||||
|
{
|
||||||
|
popFieldVoid(index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(final String[] args)
|
public static void main(final String[] args)
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ import java.util.Random;
|
|||||||
|
|
||||||
public class NumberGame extends Application
|
public class NumberGame extends Application
|
||||||
{
|
{
|
||||||
|
private static final int STARTING_NUMBERS_PLACED = 0;
|
||||||
|
private static final int INDEX_OFFSET = 1;
|
||||||
private static final int FONT_SIZE = 24;
|
private static final int FONT_SIZE = 24;
|
||||||
private static final int WINDOW_WIDTH = 700;
|
private static final int WINDOW_WIDTH = 700;
|
||||||
private static final int WINDOW_HEIGHT = 600;
|
private static final int WINDOW_HEIGHT = 600;
|
||||||
@@ -24,39 +26,39 @@ public class NumberGame extends Application
|
|||||||
private static final int GRID_HEIGHT = 4;
|
private static final int GRID_HEIGHT = 4;
|
||||||
private static final int BUTTON_WIDTH = 200;
|
private static final int BUTTON_WIDTH = 200;
|
||||||
private static final int BUTTON_HEIGHT = 160;
|
private static final int BUTTON_HEIGHT = 160;
|
||||||
private static final int RANDOM_NUMBERS = 20;
|
private static final int TOTAL_NUMBERS = 20;
|
||||||
private static final int MIN_RAND_NUM = 1;
|
private static final int MIN_RAND_NUM = 1;
|
||||||
private static final int MAX_RAND_NUM = 1001;
|
private static final int MAX_RAND_NUM = 1001;
|
||||||
private static final Font FONT = Font.font("Arial", FontWeight.BOLD, FONT_SIZE);
|
private static final Font FONT = Font.font("Arial", FontWeight.BOLD, FONT_SIZE);
|
||||||
private static final int STARTING_NUMBER_INDEX = 0;
|
|
||||||
|
|
||||||
private int currentIndex = STARTING_NUMBER_INDEX;
|
private int numbersPlaced;
|
||||||
|
|
||||||
private int[] numbers;
|
|
||||||
private Label numberLabel;
|
private Label numberLabel;
|
||||||
|
private int currentNumber;
|
||||||
|
private int[] positions;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start(final Stage stage)
|
public void start(final Stage stage)
|
||||||
{
|
{
|
||||||
final Random rand = new Random();
|
this.numbersPlaced = STARTING_NUMBERS_PLACED;
|
||||||
|
this.currentNumber = generateRandomNumber();
|
||||||
|
this.positions = new int[GRID_WIDTH * GRID_HEIGHT];
|
||||||
|
|
||||||
numbers = new int[RANDOM_NUMBERS];
|
this.numberLabel = new Label("Next number: " + this.currentNumber + " - Select a slot.");
|
||||||
for (int i = 0; i < RANDOM_NUMBERS; i++) {
|
this.numberLabel.setFont(FONT);
|
||||||
numbers[i] = rand.nextInt(MAX_RAND_NUM - MIN_RAND_NUM) + MIN_RAND_NUM;
|
this.numberLabel.setMaxWidth(Double.MAX_VALUE);
|
||||||
}
|
this.numberLabel.setAlignment(Pos.CENTER);
|
||||||
|
|
||||||
numberLabel = new Label("Next number: " + numbers[currentIndex] + " - Select a slot.");
|
final VBox root;
|
||||||
numberLabel.setFont(FONT);
|
root = new VBox();
|
||||||
numberLabel.setMaxWidth(Double.MAX_VALUE);
|
root.getChildren().add(this.numberLabel);
|
||||||
numberLabel.setAlignment(Pos.CENTER);
|
|
||||||
|
|
||||||
final VBox root = new VBox(10);
|
final GridPane grid;
|
||||||
root.getChildren().add(numberLabel);
|
grid = createGrid();
|
||||||
|
|
||||||
final GridPane grid = createGrid();
|
|
||||||
root.getChildren().add(grid);
|
root.getChildren().add(grid);
|
||||||
|
|
||||||
final Scene scene = new Scene(root, WINDOW_WIDTH, WINDOW_HEIGHT);
|
final Scene scene;
|
||||||
|
scene = new Scene(root, WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||||
|
|
||||||
stage.setScene(scene);
|
stage.setScene(scene);
|
||||||
stage.setTitle("20 Number Challenge");
|
stage.setTitle("20 Number Challenge");
|
||||||
stage.setResizable(false);
|
stage.setResizable(false);
|
||||||
@@ -65,28 +67,26 @@ public class NumberGame extends Application
|
|||||||
|
|
||||||
private GridPane createGrid()
|
private GridPane createGrid()
|
||||||
{
|
{
|
||||||
final GridPane grid = new GridPane();
|
final GridPane grid;
|
||||||
|
grid = new GridPane();
|
||||||
|
|
||||||
grid.setPadding(new Insets(GRID_PADDING));
|
grid.setPadding(new Insets(GRID_PADDING));
|
||||||
grid.setHgap(GRID_PADDING);
|
grid.setHgap(GRID_PADDING);
|
||||||
grid.setVgap(GRID_PADDING);
|
grid.setVgap(GRID_PADDING);
|
||||||
|
|
||||||
final Button[] buttons;
|
|
||||||
|
|
||||||
buttons = new Button[GRID_WIDTH * GRID_HEIGHT];
|
|
||||||
|
|
||||||
for (int i = 0; i < GRID_HEIGHT; i++)
|
for (int i = 0; i < GRID_HEIGHT; i++)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < GRID_WIDTH; j++)
|
for (int j = 0; j < GRID_WIDTH; j++)
|
||||||
{
|
{
|
||||||
final Button button = new Button("[]");
|
final Button button;
|
||||||
|
final int index;
|
||||||
|
|
||||||
|
button = new Button("[]");
|
||||||
|
index = (j * GRID_HEIGHT) + i;
|
||||||
|
|
||||||
button.setFont(FONT);
|
button.setFont(FONT);
|
||||||
button.setPrefSize(BUTTON_WIDTH, BUTTON_HEIGHT);
|
button.setPrefSize(BUTTON_WIDTH, BUTTON_HEIGHT);
|
||||||
|
button.setOnAction(e -> handlePress(button, index));
|
||||||
final int index;
|
|
||||||
index = i * GRID_WIDTH + j;
|
|
||||||
buttons[index] = button;
|
|
||||||
|
|
||||||
button.setOnAction(e -> handlePress(button));
|
|
||||||
|
|
||||||
grid.add(button, i, j);
|
grid.add(button, i, j);
|
||||||
}
|
}
|
||||||
@@ -95,20 +95,104 @@ public class NumberGame extends Application
|
|||||||
return grid;
|
return grid;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handlePress(final Button button)
|
private int generateRandomNumber()
|
||||||
{
|
{
|
||||||
button.setText("" + numbers[currentIndex]);
|
final Random rand;
|
||||||
|
rand = new Random();
|
||||||
|
return rand.nextInt(MAX_RAND_NUM - MIN_RAND_NUM) + MIN_RAND_NUM;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void triggerFailed()
|
||||||
|
{
|
||||||
|
this.numberLabel.setText("Next number: " + this.currentNumber + " - Impossible to place next number");
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean canBePlaced()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < positions.length; i++) {
|
||||||
|
|
||||||
|
if (this.positions[i] != STARTING_NUMBERS_PLACED)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int left;
|
||||||
|
left = Integer.MIN_VALUE;
|
||||||
|
|
||||||
|
for (int j = i - INDEX_OFFSET; j >= STARTING_NUMBERS_PLACED; j--)
|
||||||
|
{
|
||||||
|
if (this.positions[j] != STARTING_NUMBERS_PLACED)
|
||||||
|
{
|
||||||
|
left = this.positions[j];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int right;
|
||||||
|
right = Integer.MAX_VALUE;
|
||||||
|
for (int j = i + INDEX_OFFSET; j < this.positions.length; j++)
|
||||||
|
{
|
||||||
|
if (this.positions[j] != STARTING_NUMBERS_PLACED) {
|
||||||
|
right = this.positions[j];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (left < currentNumber && currentNumber < right) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handlePress(final Button button, final int index)
|
||||||
|
{
|
||||||
|
button.setText("" + this.currentNumber);
|
||||||
button.setDisable(true);
|
button.setDisable(true);
|
||||||
|
this.numbersPlaced++;
|
||||||
|
|
||||||
currentIndex++;
|
this.positions[index] = this.currentNumber;
|
||||||
|
|
||||||
if (currentIndex < RANDOM_NUMBERS) {
|
// Detect bad placement
|
||||||
numberLabel.setText("Next number: " + numbers[currentIndex] + " - Select a slot.");
|
for (int i = 0; i < GRID_WIDTH * GRID_HEIGHT; i++)
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
numberLabel.setText("All numbers placed!");
|
final boolean largerBelow;
|
||||||
|
final boolean smallerAbove;
|
||||||
|
|
||||||
|
largerBelow = i < index &&
|
||||||
|
this.positions[i] != STARTING_NUMBERS_PLACED &&
|
||||||
|
this.positions[i] > this.positions[index];
|
||||||
|
|
||||||
|
smallerAbove = i > index &&
|
||||||
|
this.positions[i] != STARTING_NUMBERS_PLACED &&
|
||||||
|
this.positions[i] < this.positions[index];
|
||||||
|
|
||||||
|
if (largerBelow || smallerAbove)
|
||||||
|
{
|
||||||
|
triggerFailed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.numbersPlaced >= TOTAL_NUMBERS)
|
||||||
|
{
|
||||||
|
this.numberLabel.setText("All numbers placed!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.currentNumber = generateRandomNumber();
|
||||||
|
|
||||||
|
final boolean canPlaceNext;
|
||||||
|
canPlaceNext = canBePlaced();
|
||||||
|
|
||||||
|
if (!canPlaceNext)
|
||||||
|
{
|
||||||
|
triggerFailed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.numberLabel.setText("Next number: " + this.currentNumber + " - Select a slot.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(final String[] args)
|
public static void main(final String[] args)
|
||||||
|
|||||||
@@ -0,0 +1,219 @@
|
|||||||
|
package ca.bcit.comp2522.project;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
public class WordGame
|
||||||
|
{
|
||||||
|
private static final String SCORE_PATH = "./data/score.txt";
|
||||||
|
private static final int NUMBER_OF_QUESTIONS = 10;
|
||||||
|
private static final int QUESTION_NUM_OFFSET = 1;
|
||||||
|
private static final int QUEST_ASK_CAPITAL = 0;
|
||||||
|
private static final int QUEST_ASK_COUNTRY = 1;
|
||||||
|
private static final int QUEST_ASK_FACT = 2;
|
||||||
|
private static final int QUESTION_TYPES = 3;
|
||||||
|
private static final int MAX_ATTEMPTS = 2;
|
||||||
|
private static final int FIRST_ATTEMPT = 0;
|
||||||
|
private static final int SPLIT_DATE = 0;
|
||||||
|
private static final int SPLIT_TIME = 1;
|
||||||
|
private static final int FIRST_ATTEMPT_SCORE = 0;
|
||||||
|
private static final int SECOND_ATTEMPT_SCORE = 1;
|
||||||
|
private static final int INCORRECT_SCORE = 2;
|
||||||
|
private static final int DEFAULT_SCORE = 0;
|
||||||
|
|
||||||
|
private final World world;
|
||||||
|
|
||||||
|
public WordGame()
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
this.world = new World();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void checkAnswer(
|
||||||
|
final String correctAnswer,
|
||||||
|
final Scanner scanner,
|
||||||
|
final int[] scores
|
||||||
|
) {
|
||||||
|
for (int i = 0; i < MAX_ATTEMPTS; i++)
|
||||||
|
{
|
||||||
|
final String answer;
|
||||||
|
|
||||||
|
System.out.print("> ");
|
||||||
|
answer = scanner.nextLine();
|
||||||
|
|
||||||
|
if (answer.equalsIgnoreCase(correctAnswer))
|
||||||
|
{
|
||||||
|
if (i == FIRST_ATTEMPT)
|
||||||
|
{
|
||||||
|
scores[FIRST_ATTEMPT_SCORE]++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scores[SECOND_ATTEMPT_SCORE]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("CORRECT!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("INCORRECT!");
|
||||||
|
}
|
||||||
|
|
||||||
|
scores[INCORRECT_SCORE]++;
|
||||||
|
System.out.printf("The correct answer was %s\n", correctAnswer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startTrivia(
|
||||||
|
final Scanner scanner,
|
||||||
|
final int[] scores
|
||||||
|
) {
|
||||||
|
for (int i = 0; i < NUMBER_OF_QUESTIONS; i++)
|
||||||
|
{
|
||||||
|
System.out.printf("Question %d:\n", i + QUESTION_NUM_OFFSET);
|
||||||
|
|
||||||
|
final Random rand;
|
||||||
|
final Country country;
|
||||||
|
final int questionType;
|
||||||
|
|
||||||
|
rand = new Random();
|
||||||
|
|
||||||
|
country = this.world.getRandomCountry();
|
||||||
|
questionType = rand.nextInt(QUESTION_TYPES);
|
||||||
|
|
||||||
|
switch (questionType)
|
||||||
|
{
|
||||||
|
case QUEST_ASK_CAPITAL:
|
||||||
|
System.out.println("What is the country of the following capital?");
|
||||||
|
System.out.println(country.getCapital());
|
||||||
|
|
||||||
|
checkAnswer(country.getName(), scanner, scores);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QUEST_ASK_COUNTRY:
|
||||||
|
System.out.println("What is the capital of the following country?");
|
||||||
|
System.out.println(country.getName());
|
||||||
|
|
||||||
|
checkAnswer(country.getCapital(), scanner, scores);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QUEST_ASK_FACT:
|
||||||
|
System.out.println("What is the country of the following fact?");
|
||||||
|
System.out.println(country.getRandomFact());
|
||||||
|
|
||||||
|
checkAnswer(country.getName(), scanner, scores);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void runTrivia()
|
||||||
|
{
|
||||||
|
final Scanner scanner;
|
||||||
|
Score score;
|
||||||
|
boolean continuePlaying;
|
||||||
|
|
||||||
|
continuePlaying = true;
|
||||||
|
scanner = new Scanner(System.in);
|
||||||
|
|
||||||
|
final int[] scores;
|
||||||
|
int gamesPlayed;
|
||||||
|
|
||||||
|
scores = new int[]{DEFAULT_SCORE,DEFAULT_SCORE,DEFAULT_SCORE};
|
||||||
|
gamesPlayed = DEFAULT_SCORE;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
gamesPlayed++;
|
||||||
|
|
||||||
|
this.startTrivia(scanner, scores);
|
||||||
|
|
||||||
|
score = new Score(
|
||||||
|
LocalDateTime.now(),
|
||||||
|
gamesPlayed,
|
||||||
|
scores[FIRST_ATTEMPT_SCORE],
|
||||||
|
scores[SECOND_ATTEMPT_SCORE],
|
||||||
|
scores[INCORRECT_SCORE]
|
||||||
|
);
|
||||||
|
|
||||||
|
System.out.println(score);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
System.out.println("\nDo you want to play again?");
|
||||||
|
System.out.print("> ");
|
||||||
|
|
||||||
|
final String playAgain;
|
||||||
|
playAgain = scanner.nextLine();
|
||||||
|
|
||||||
|
if (playAgain.equalsIgnoreCase("no"))
|
||||||
|
{
|
||||||
|
continuePlaying = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (playAgain.equalsIgnoreCase("yes"))
|
||||||
|
{
|
||||||
|
// break inner do-while loop
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.out.printf("Invalid option \"%s\"\n", playAgain);
|
||||||
|
}
|
||||||
|
} while (true);
|
||||||
|
|
||||||
|
} while (continuePlaying);
|
||||||
|
|
||||||
|
scanner.close();
|
||||||
|
|
||||||
|
final List<Score> history;
|
||||||
|
|
||||||
|
history = Score.readScoresFromFile(SCORE_PATH);
|
||||||
|
Score.appendScoreToFile(score, SCORE_PATH);
|
||||||
|
|
||||||
|
if (Score.isHighScore(score, history))
|
||||||
|
{
|
||||||
|
System.out.printf(
|
||||||
|
"CONGRATULATIONS! You have a new high score with an average of %.2f points per game; ",
|
||||||
|
score.calculateAverage()
|
||||||
|
);
|
||||||
|
|
||||||
|
final Score prevHighScore;
|
||||||
|
prevHighScore = Score.getHighScore(history);
|
||||||
|
|
||||||
|
if (prevHighScore == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.printf(
|
||||||
|
"the previous record was %.2f points per game ",
|
||||||
|
prevHighScore.calculateAverage()
|
||||||
|
);
|
||||||
|
|
||||||
|
System.out.printf(
|
||||||
|
"on %s at %s.\n",
|
||||||
|
prevHighScore.getDateTimePlayed().split(" ")[SPLIT_DATE],
|
||||||
|
prevHighScore.getDateTimePlayed().split(" ")[SPLIT_TIME]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(final String[] args)
|
||||||
|
{
|
||||||
|
final WordGame test;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
test = new WordGame();
|
||||||
|
}
|
||||||
|
catch (final IOException e)
|
||||||
|
{
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
test.runTrivia();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,14 +6,12 @@ import java.io.IOException;
|
|||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.Scanner;
|
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -22,25 +20,10 @@ import java.util.stream.Stream;
|
|||||||
*/
|
*/
|
||||||
public class World
|
public class World
|
||||||
{
|
{
|
||||||
private static final String SCORE_PATH = "./data/score.txt";
|
private static final String BASE_PATH = "./data/facts";
|
||||||
private static final String BASE_PATH = "./data/facts";
|
private static final int COUNTRY_PARAM = 0;
|
||||||
private static final int COUNTRY_PARAM = 0;
|
private static final int CAPITAL_PARAM = 1;
|
||||||
private static final int CAPITAL_PARAM = 1;
|
private static final int NUMBER_OF_FACTS = 3;
|
||||||
private static final int NUMBER_OF_FACTS = 3;
|
|
||||||
private static final int NUMBER_OF_QUESTIONS = 10;
|
|
||||||
private static final int QUESTION_NUM_OFFSET = 1;
|
|
||||||
private static final int QUEST_ASK_CAPITAL = 0;
|
|
||||||
private static final int QUEST_ASK_COUNTRY = 1;
|
|
||||||
private static final int QUEST_ASK_FACT = 2;
|
|
||||||
private static final int QUESTION_TYPES = 3;
|
|
||||||
private static final int MAX_ATTEMPTS = 2;
|
|
||||||
private static final int FIRST_ATTEMPT = 0;
|
|
||||||
private static final int SPLIT_DATE = 0;
|
|
||||||
private static final int SPLIT_TIME = 1;
|
|
||||||
private static final int FIRST_ATTEMPT_SCORE = 0;
|
|
||||||
private static final int SECOND_ATTEMPT_SCORE = 1;
|
|
||||||
private static final int INCORRECT_SCORE = 2;
|
|
||||||
private static final int DEFAULT_SCORE = 0;
|
|
||||||
|
|
||||||
private final Map<String, Country> countries;
|
private final Map<String, Country> countries;
|
||||||
|
|
||||||
@@ -72,11 +55,12 @@ public class World
|
|||||||
{
|
{
|
||||||
this.countries = new HashMap<>();
|
this.countries = new HashMap<>();
|
||||||
|
|
||||||
try (Stream<Path> walk = Files.walk(Paths.get(BASE_PATH)))
|
try (final Stream<Path> walk = Files.walk(Paths.get(BASE_PATH)))
|
||||||
{
|
{
|
||||||
List<Path> filesInFolder = walk
|
final List<Path> filesInFolder;
|
||||||
.filter(Files::isRegularFile)
|
filesInFolder = walk
|
||||||
.toList();
|
.filter(Files::isRegularFile)
|
||||||
|
.toList();
|
||||||
|
|
||||||
for (final Path file : filesInFolder)
|
for (final Path file : filesInFolder)
|
||||||
{
|
{
|
||||||
@@ -106,195 +90,17 @@ public class World
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkAnswer(
|
public Country getRandomCountry()
|
||||||
final String correctAnswer,
|
|
||||||
final Scanner scanner,
|
|
||||||
final int[] scores
|
|
||||||
) {
|
|
||||||
for (int i = 0; i < MAX_ATTEMPTS; i++)
|
|
||||||
{
|
|
||||||
final String answer;
|
|
||||||
|
|
||||||
System.out.print("> ");
|
|
||||||
answer = scanner.nextLine();
|
|
||||||
|
|
||||||
if (answer.equalsIgnoreCase(correctAnswer))
|
|
||||||
{
|
|
||||||
if (i == FIRST_ATTEMPT)
|
|
||||||
{
|
|
||||||
scores[FIRST_ATTEMPT_SCORE]++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
scores[SECOND_ATTEMPT_SCORE]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
System.out.println("CORRECT!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
System.out.println("INCORRECT!");
|
|
||||||
}
|
|
||||||
|
|
||||||
scores[INCORRECT_SCORE]++;
|
|
||||||
System.out.printf("The correct answer was %s\n", correctAnswer);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startTrivia(
|
|
||||||
final Scanner scanner,
|
|
||||||
final int[] scores
|
|
||||||
) {
|
|
||||||
for (int i = 0; i < NUMBER_OF_QUESTIONS; i++)
|
|
||||||
{
|
|
||||||
System.out.printf("Question %d:\n", i + QUESTION_NUM_OFFSET);
|
|
||||||
|
|
||||||
final Random rand;
|
|
||||||
final Country country;
|
|
||||||
final String key;
|
|
||||||
final List<String> keys;
|
|
||||||
final int questionType;
|
|
||||||
|
|
||||||
rand = new Random();
|
|
||||||
|
|
||||||
keys = new ArrayList<>(this.countries.keySet());
|
|
||||||
key = keys.get(rand.nextInt(keys.size()));
|
|
||||||
|
|
||||||
questionType = rand.nextInt(QUESTION_TYPES);
|
|
||||||
country = this.countries.get(key);
|
|
||||||
|
|
||||||
switch (questionType)
|
|
||||||
{
|
|
||||||
case QUEST_ASK_CAPITAL:
|
|
||||||
System.out.println("What is the country of the following capital?");
|
|
||||||
System.out.println(country.getCapital());
|
|
||||||
|
|
||||||
checkAnswer(country.getName(), scanner, scores);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case QUEST_ASK_COUNTRY:
|
|
||||||
System.out.println("What is the capital of the following country?");
|
|
||||||
System.out.println(country.getName());
|
|
||||||
|
|
||||||
checkAnswer(country.getCapital(), scanner, scores);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case QUEST_ASK_FACT:
|
|
||||||
System.out.println("What is the country of the following fact?");
|
|
||||||
System.out.println(country.getRandomFact());
|
|
||||||
|
|
||||||
checkAnswer(country.getName(), scanner, scores);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void runTrivia()
|
|
||||||
{
|
{
|
||||||
final Scanner scanner;
|
final Random rand;
|
||||||
Score score;
|
final String key;
|
||||||
boolean continuePlaying;
|
final List<String> keys;
|
||||||
|
|
||||||
continuePlaying = true;
|
rand = new Random();
|
||||||
scanner = new Scanner(System.in);
|
|
||||||
|
|
||||||
final int[] scores;
|
keys = new ArrayList<>(this.countries.keySet());
|
||||||
int gamesPlayed;
|
key = keys.get(rand.nextInt(keys.size()));
|
||||||
|
|
||||||
scores = new int[]{DEFAULT_SCORE,DEFAULT_SCORE,DEFAULT_SCORE};
|
return this.countries.get(key);
|
||||||
gamesPlayed = DEFAULT_SCORE;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
gamesPlayed++;
|
|
||||||
|
|
||||||
this.startTrivia(scanner, scores);
|
|
||||||
|
|
||||||
score = new Score(
|
|
||||||
LocalDateTime.now(),
|
|
||||||
gamesPlayed,
|
|
||||||
scores[FIRST_ATTEMPT_SCORE],
|
|
||||||
scores[SECOND_ATTEMPT_SCORE],
|
|
||||||
scores[INCORRECT_SCORE]
|
|
||||||
);
|
|
||||||
|
|
||||||
System.out.println(score);
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
System.out.println("\nDo you want to play again?");
|
|
||||||
System.out.print("> ");
|
|
||||||
|
|
||||||
final String playAgain;
|
|
||||||
playAgain = scanner.nextLine();
|
|
||||||
|
|
||||||
if (playAgain.equalsIgnoreCase("no"))
|
|
||||||
{
|
|
||||||
continuePlaying = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (playAgain.equalsIgnoreCase("yes"))
|
|
||||||
{
|
|
||||||
// break inner do-while loop
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
System.out.printf("Invalid option \"%s\"\n", playAgain);
|
|
||||||
}
|
|
||||||
} while (true);
|
|
||||||
|
|
||||||
} while (continuePlaying);
|
|
||||||
|
|
||||||
scanner.close();
|
|
||||||
|
|
||||||
final List<Score> history;
|
|
||||||
|
|
||||||
history = Score.readScoresFromFile(SCORE_PATH);
|
|
||||||
Score.appendScoreToFile(score, SCORE_PATH);
|
|
||||||
|
|
||||||
if (Score.isHighScore(score, history))
|
|
||||||
{
|
|
||||||
System.out.printf(
|
|
||||||
"CONGRATULATIONS! You have a new high score with an average of %.2f points per game; ",
|
|
||||||
score.calculateAverage()
|
|
||||||
);
|
|
||||||
|
|
||||||
final Score prevHighScore;
|
|
||||||
prevHighScore = Score.getHighScore(history);
|
|
||||||
|
|
||||||
if (prevHighScore == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
System.out.printf(
|
|
||||||
"the previous record was %.2f points per game ",
|
|
||||||
prevHighScore.calculateAverage()
|
|
||||||
);
|
|
||||||
|
|
||||||
System.out.printf(
|
|
||||||
"on %s at %s.\n",
|
|
||||||
prevHighScore.getDateTimePlayed().split(" ")[SPLIT_DATE],
|
|
||||||
prevHighScore.getDateTimePlayed().split(" ")[SPLIT_TIME]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(final String[] args)
|
|
||||||
{
|
|
||||||
final World test;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
test = new World();
|
|
||||||
}
|
|
||||||
catch (final IOException e)
|
|
||||||
{
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
test.runTrivia();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user