222 lines
6.3 KiB
Java
222 lines
6.3 KiB
Java
package GUI;
|
|
|
|
import domain.*;
|
|
import GUI.HitoriDialogManager;
|
|
import javafx.application.Platform;
|
|
import java.util.*;
|
|
|
|
public class GameUIController {
|
|
private final HitoriGameMoves gameMoves;
|
|
private final GameSolver gameSolver;
|
|
private final domain.HitoriGameTimer gameTimer;
|
|
private final HitoriGameScores gameScores;
|
|
private final GUI.HitoriDialogManager dialogManager;
|
|
private final GUI.HitoriBoardPanel boardPanel;
|
|
private final GUI.HitoriControlPanel controlPanel;
|
|
private final GUI.HitoriScorePanel scorePanel;
|
|
private Timer guiTimer;
|
|
private boolean isPaused;
|
|
|
|
public GameUIController(int[][] initialBoard, HitoriDialogManager dialogManager) {
|
|
this.gameMoves = new HitoriGameMoves(initialBoard);
|
|
this.gameSolver = new GameSolver(initialBoard);
|
|
this.gameTimer = new domain.HitoriGameTimer();
|
|
this.gameScores = new HitoriGameScores();
|
|
this.dialogManager = dialogManager;
|
|
this.isPaused = false;
|
|
|
|
this.boardPanel = new GUI.HitoriBoardPanel(gameMoves, gameSolver, this);
|
|
this.controlPanel = new GUI.HitoriControlPanel(this);
|
|
this.scorePanel = new GUI.HitoriScorePanel(this);
|
|
|
|
startTimer();
|
|
loadHighScores();
|
|
}
|
|
|
|
public void handleLeftClick(int row, int col) {
|
|
gameMoves.markCellAsBlack(row, col);
|
|
updateUI();
|
|
|
|
|
|
}
|
|
|
|
public void handleRightClick(int row, int col) {
|
|
gameMoves.markCellAsWhite(row, col);
|
|
updateUI();
|
|
|
|
|
|
}
|
|
|
|
public void togglePause() {
|
|
isPaused = !isPaused;
|
|
if (isPaused) {
|
|
gameTimer.pauseTimer();
|
|
controlPanel.setPauseButtonText("Resume");
|
|
boardPanel.setDisable(true);
|
|
} else {
|
|
gameTimer.startTimer();
|
|
controlPanel.setPauseButtonText("Pause");
|
|
boardPanel.setDisable(false);
|
|
}
|
|
updateTimerLabel();
|
|
}
|
|
|
|
public void resetGame() {
|
|
gameMoves.reset();
|
|
gameTimer.resetTimer();
|
|
updateUI();
|
|
}
|
|
|
|
public void undo() {
|
|
if (gameMoves.undo()) {
|
|
updateUI();
|
|
}
|
|
}
|
|
|
|
public void redo() {
|
|
if (gameMoves.redo()) {
|
|
updateUI();
|
|
}
|
|
}
|
|
|
|
public void newGame() {
|
|
stopTimer();
|
|
// Notify main application to show board selection
|
|
}
|
|
|
|
public void checkSolution() {
|
|
if (gameSolver.isSolved()) {
|
|
handleWin();
|
|
} else {
|
|
dialogManager.showAlert("Not Solved", "The current solution is not correct. Keep trying!");
|
|
}
|
|
}
|
|
|
|
public void showErrors() {
|
|
List<int[]> errors = gameSolver.findIncorrectBlackMarks();
|
|
if (errors.isEmpty()) {
|
|
dialogManager.showAlert("No Errors", "No rule violations found in current black markings.");
|
|
return;
|
|
}
|
|
|
|
boardPanel.showErrors();
|
|
StringBuilder message = new StringBuilder("Found " + errors.size() + " error(s):\n");
|
|
for (int[] pos : errors) {
|
|
message.append(String.format("Row %d, Column %d\n", pos[0] + 1, pos[1] + 1));
|
|
}
|
|
dialogManager.showAlert("Errors Found", message.toString());
|
|
}
|
|
|
|
public void saveGame() {
|
|
// Implementation for saving game state
|
|
dialogManager.showAlert("Game Saved", "Your game has been saved successfully.");
|
|
}
|
|
|
|
public void deleteHighScores() {
|
|
if (dialogManager.confirmDeleteHighScores()) {
|
|
gameScores.deleteHighScores();
|
|
updateHighScoreDisplay();
|
|
dialogManager.showAlert("High Scores Deleted", "All high scores have been deleted successfully.");
|
|
}
|
|
}
|
|
|
|
private void handleWin() {
|
|
stopTimer();
|
|
Optional<String> playerName = dialogManager.askForPlayerName();
|
|
if (playerName.isPresent() && !playerName.get().trim().isEmpty()) {
|
|
gameScores.addHighScore(playerName.get(), gameTimer.getElapsedTimeInSeconds(), gameMoves.getMistakeCount());
|
|
updateHighScoreDisplay();
|
|
dialogManager.showAlert("Congratulations!", String.format(
|
|
"You've solved the puzzle!\nTime: %ds\nMistakes: %d",
|
|
gameTimer.getElapsedTimeInSeconds(),
|
|
gameMoves.getMistakeCount()
|
|
));
|
|
|
|
isPaused = false;
|
|
boardPanel.setDisable(false);
|
|
controlPanel.setPauseButtonText("Pause");
|
|
|
|
if (dialogManager.confirmNewGame()) {
|
|
newGame();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void startTimer() {
|
|
if (guiTimer != null) {
|
|
guiTimer.cancel();
|
|
}
|
|
gameTimer.startTimer();
|
|
guiTimer = new Timer(true);
|
|
guiTimer.scheduleAtFixedRate(new TimerTask() {
|
|
@Override
|
|
public void run() {
|
|
Platform.runLater(() -> {
|
|
if (!isPaused) {
|
|
updateTimerLabel();
|
|
}
|
|
});
|
|
}
|
|
}, 0, 1000);
|
|
}
|
|
|
|
private void stopTimer() {
|
|
if (guiTimer != null) {
|
|
guiTimer.cancel();
|
|
guiTimer = null;
|
|
}
|
|
gameTimer.stopTimer();
|
|
}
|
|
|
|
private void updateUI() {
|
|
boardPanel.updateBoard();
|
|
updateMistakeLabel();
|
|
}
|
|
|
|
private void updateTimerLabel() {
|
|
controlPanel.updateTimerLabel(gameTimer.getElapsedTimeInSeconds());
|
|
}
|
|
|
|
private void updateMistakeLabel() {
|
|
controlPanel.updateMistakeLabel(gameMoves.getMistakeCount());
|
|
}
|
|
|
|
private void updateHighScoreDisplay() {
|
|
scorePanel.updateHighScores(String.join("\n", gameScores.getHighScoresWithAverage()));
|
|
}
|
|
|
|
private void loadHighScores() {
|
|
gameScores.loadHighScoresFromFile();
|
|
updateHighScoreDisplay();
|
|
}
|
|
|
|
public Set<String> convertErrorsToSet(List<int[]> errors) {
|
|
Set<String> errorPositions = new HashSet<>();
|
|
for (int[] pos : errors) {
|
|
errorPositions.add(pos[0] + "," + pos[1]);
|
|
}
|
|
return errorPositions;
|
|
}
|
|
|
|
public boolean isPaused() {
|
|
return isPaused;
|
|
}
|
|
|
|
public void cleanup() {
|
|
stopTimer();
|
|
saveGame();
|
|
}
|
|
|
|
public HitoriBoardPanel getBoardPanel() {
|
|
return boardPanel;
|
|
}
|
|
|
|
public HitoriControlPanel getControlPanel() {
|
|
return controlPanel;
|
|
}
|
|
|
|
public HitoriScorePanel getScorePanel() {
|
|
return scorePanel;
|
|
}
|
|
}
|