Skip to content

Commit 7e6ea7b

Browse files
committed
added basics of all puzzles
1 parent 70a419b commit 7e6ea7b

File tree

10 files changed

+834
-4
lines changed

10 files changed

+834
-4
lines changed
Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
package com.escapegame;
2+
3+
import java.io.File;
4+
import java.io.FileOutputStream;
5+
import java.io.IOException;
6+
import java.io.OutputStream;
7+
import java.net.URL;
8+
import java.util.Properties;
9+
import java.util.ResourceBundle;
10+
11+
import javafx.fxml.FXML;
12+
import javafx.fxml.Initializable;
13+
import javafx.scene.control.Alert;
14+
import javafx.scene.control.Button;
15+
import javafx.scene.control.Label;
16+
import javafx.scene.control.TextField;
17+
import javafx.scene.image.Image;
18+
import javafx.scene.image.ImageView;
19+
import javafx.scene.layout.HBox;
20+
import javafx.scene.layout.StackPane;
21+
22+
public class AnagramPuzzleController implements Initializable {
23+
24+
@FXML private StackPane rootPane;
25+
@FXML private ImageView backgroundImage;
26+
@FXML private TextField answerField;
27+
@FXML private Button btnSubmit, btnHint, btnSave, btnQuit;
28+
@FXML private Label statusLabel, hintsLabel, categoryLabel, promptLabel;
29+
@FXML private HBox heartsBox;
30+
31+
// Game state
32+
private int attemptsLeft = 3;
33+
private int hintsLeft = 3;
34+
private int nextHintIndex = 0;
35+
private boolean solved = false;
36+
37+
String [] HINTS = {
38+
//get from json
39+
};
40+
String [] ACCEPTED_ANSWERS = {
41+
//get from json
42+
};
43+
44+
private final File SAVE_FILE = new File(System.getProperty("user.home"), ".escapegame_anagram.properties");
45+
46+
private static final String RESOURCE_PATH = "/images/background.png";
47+
private static final String DEV_FALLBACK = "file:/mnt/data/Screenshot 2025-11-19 204918.png";
48+
49+
@Override
50+
public void initialize(URL location, ResourceBundle resources) {
51+
System.out.println("AnagramPuzzleController.initialize() start");
52+
53+
boolean loaded = false;
54+
55+
try {
56+
URL res = getClass().getResource(RESOURCE_PATH);
57+
if (res != null) {
58+
Image img = new Image(res.toExternalForm());
59+
backgroundImage.setImage(img);
60+
loaded = true;
61+
System.out.println("Loaded background from resource path.");
62+
}
63+
} catch (Exception ex) {
64+
System.err.println("Error loading resource image: " + ex.getMessage());
65+
}
66+
67+
// Fallback to local file for development
68+
if (!loaded) {
69+
try {
70+
Image img = new Image(DEV_FALLBACK);
71+
backgroundImage.setImage(img);
72+
System.out.println("Loaded background from dev fallback.");
73+
loaded = true;
74+
} catch (Exception ex) {
75+
System.err.println("Error loading dev fallback image: " + ex.getMessage());
76+
}
77+
}
78+
79+
if (!loaded) {
80+
statusLabel.setText("Background image not found (resource nor dev path).");
81+
}
82+
83+
backgroundImage.fitWidthProperty().bind(rootPane.widthProperty());
84+
backgroundImage.fitHeightProperty().bind(rootPane.heightProperty());
85+
backgroundImage.setPreserveRatio(false);
86+
87+
hintsLabel.setText(hintsLeft + " hint(s) available");
88+
refreshHearts();
89+
loadSave();
90+
91+
System.out.println("AnagramPuzzleController.initialize() done");
92+
}
93+
94+
// Draw hearts based on remaining attempts
95+
private void refreshHearts() {
96+
heartsBox.getChildren().clear();
97+
for (int i = 0; i < attemptsLeft; i++) {
98+
Label heart = new Label("\u2764");
99+
heart.setStyle("-fx-text-fill: #ff4d6d; -fx-font-size: 20px;");
100+
heartsBox.getChildren().add(heart);
101+
}
102+
if (attemptsLeft <= 0) {
103+
btnSubmit.setDisable(true);
104+
answerField.setDisable(true);
105+
}
106+
}
107+
108+
@FXML
109+
private void onSubmit() {
110+
if (solved) {
111+
statusLabel.setText("You already solved the anagram puzzle.");
112+
return;
113+
}
114+
115+
String answer = (answerField.getText() == null) ? "" : answerField.getText().trim().toLowerCase();
116+
if (answer.isEmpty()) {
117+
statusLabel.setText("Please type an answer before submitting.");
118+
return;
119+
}
120+
121+
boolean correct = false;
122+
for (String a : ACCEPTED_ANSWERS) {
123+
if (a.equals(answer)) {
124+
correct = true;
125+
break;
126+
}
127+
}
128+
129+
if (correct) {
130+
solved = true;
131+
statusLabel.setText("Correct! You solved the puzzle.");
132+
btnSubmit.setDisable(true);
133+
btnHint.setDisable(true);
134+
answerField.setDisable(true);
135+
//new Alert(Alert.AlertType.INFORMATION, "Congratulations — you solved the puzzle!").showAndWait();
136+
try {
137+
App.setRoot("opened5");
138+
} catch (IOException e) {
139+
e.printStackTrace();
140+
}
141+
saveProgress();
142+
} else {
143+
attemptsLeft--;
144+
refreshHearts();
145+
if (attemptsLeft <= 0) {
146+
statusLabel.setText("No attempts left. The correct answer was: ");
147+
btnSubmit.setDisable(true);
148+
answerField.setDisable(true);
149+
new Alert(Alert.AlertType.WARNING, "Out of attempts!").showAndWait();
150+
saveProgress();
151+
} else {
152+
statusLabel.setText("Incorrect. Attempts left: " + attemptsLeft);
153+
}
154+
}
155+
}
156+
157+
@FXML
158+
private void onHint() {
159+
if (solved) {
160+
statusLabel.setText("You already solved the puzzle.");
161+
return;
162+
}
163+
if (hintsLeft <= 0) {
164+
statusLabel.setText("No hints remaining.");
165+
return;
166+
}
167+
168+
String hint = HINTS[Math.min(nextHintIndex, HINTS.length - 1)];
169+
nextHintIndex++;
170+
hintsLeft--;
171+
hintsLabel.setText(hintsLeft + " hint(s) available");
172+
173+
new Alert(Alert.AlertType.INFORMATION, hint).showAndWait();
174+
saveProgress();
175+
}
176+
177+
@FXML
178+
private void onSave() {
179+
statusLabel.setText(saveProgress() ? "Progress saved." : "Save failed.");
180+
}
181+
182+
@FXML
183+
private void onQuit() {
184+
try {
185+
App.setRoot("opened5");
186+
} catch (IOException e) {
187+
e.printStackTrace();
188+
}
189+
}
190+
191+
private boolean saveProgress() {
192+
try {
193+
Properties p = new Properties();
194+
p.setProperty("attemptsLeft", String.valueOf(attemptsLeft));
195+
p.setProperty("hintsLeft", String.valueOf(hintsLeft));
196+
p.setProperty("solved", String.valueOf(solved));
197+
p.setProperty("nextHintIndex", String.valueOf(nextHintIndex));
198+
try (OutputStream os = new FileOutputStream(SAVE_FILE)) {
199+
p.store(os, "Matching puzzle save");
200+
}
201+
return true;
202+
} catch (Exception e) {
203+
System.err.println("Save error: " + e.getMessage());
204+
return false;
205+
}
206+
}
207+
208+
private void loadSave() {
209+
try {
210+
if (!SAVE_FILE.exists()) return;
211+
Properties p = new Properties();
212+
p.load(new java.io.FileInputStream(SAVE_FILE));
213+
attemptsLeft = Integer.parseInt(p.getProperty("attemptsLeft", "3"));
214+
hintsLeft = Integer.parseInt(p.getProperty("hintsLeft", "3"));
215+
solved = Boolean.parseBoolean(p.getProperty("solved", "false"));
216+
nextHintIndex = Integer.parseInt(p.getProperty("nextHintIndex", "0"));
217+
hintsLabel.setText(hintsLeft + " hint(s) available");
218+
refreshHearts();
219+
220+
if (solved) {
221+
btnSubmit.setDisable(true);
222+
answerField.setDisable(true);
223+
btnHint.setDisable(true);
224+
statusLabel.setText("Already solved.");
225+
}
226+
} catch (Exception e) {
227+
System.err.println("Load save failed: " + e.getMessage());
228+
}
229+
}
230+
}

0 commit comments

Comments
 (0)