forked from jcrouser/CSC120-FinalProject
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLightPyramidGUI.java
More file actions
301 lines (261 loc) · 11.6 KB
/
Copy pathLightPyramidGUI.java
File metadata and controls
301 lines (261 loc) · 11.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
/**
* The LightPyramidGUI class represents the graphical user interface for the
* Christmas Tree Light-On Challenge.
* This class provides a visual, interactive environment where two players take
* turns playing the game.
* The GUI includes:
* - A pyramid of buttons representing the lights.
* - Control buttons for confirming actions, restarting the game, and viewing
* the rules.
* - A panel for displaying game status and transitions between players.
*
* Game Rules:
* - Players take turns lighting up bulbs on a pyramid-shaped Christmas tree.
* - A player can light up one or multiple bulbs on a single floor during their
* turn.
* - The top bulb cannot be lit until all other bulbs on the tree are already
* illuminated.
* - The player who successfully lights up the top bulb wins the game.
*
* Key Features:
* - Dynamic button state management for selected, unselected, and finalized
* states.
* - Support for restarting the game and undoing invalid moves.
* - Interactive rule display for player guidance.
*/
public class LightPyramidGUI {
private final ChristmasTree ChristmasTree;
private final JFrame frame;
private int currentPlayer; // 1 for Player 1, 2 for Player 2
private List<JButton> selectedButtons; // Track selected lights for the current move
private int selectedFloor; // Track the floor of the current selection
/**
* Constructs the LightPyramidGUI and initializes the game.
* Sets up the building, frame, and GUI components.
*/
public LightPyramidGUI() {
ChristmasTree = new ChristmasTree(8); // Create an 8-floor building
frame = new JFrame("Light Pyramid Game");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
currentPlayer = 1; // Player 1 starts
selectedButtons = new ArrayList<>();
selectedFloor = -1; // No floor selected initially
setupGUI();
frame.setSize(1100, 1100);
frame.setVisible(true);
}
/**
* Sets up the GUI, including the pyramid panel, middle panel, and control
* panel.
* Configures event listeners for buttons and initializes game state.
*/
private void setupGUI() {
JPanel pyramidPanel = new JPanel();
pyramidPanel.setBackground(Color.PINK);
pyramidPanel.setLayout(new GridLayout(8, 1, 10, 10)); // 8 rows for 8 floors with spacing
// Iterate over the building in reverse order to render floor 7 at the top
for (int floorIndex = ChristmasTree.getBuilding().size() - 1; floorIndex >= 0; floorIndex--) {
JPanel floorPanel = new JPanel();
floorPanel.setBackground(Color.PINK);
floorPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 30, 5)); // Center-align buttons with spacing
List<Light> floor = ChristmasTree.getBuilding().get(floorIndex);
for (int roomIndex = 0; roomIndex < floor.size(); roomIndex++) { // Adjust number of buttons per floor
JButton lightButton = new JButton();
isOffLightButton(lightButton);
int roomIndexCopy = roomIndex;
int floorIndexCopy = floorIndex;
lightButton.addActionListener(e -> {
if (selectedButtons.contains(lightButton)) {
unselectButton(lightButton);
selectedButtons.remove(lightButton);
if (selectedButtons.isEmpty()) {
selectedFloor = -1;
}
} else {
if (selectedFloor == -1 || selectedFloor == floorIndexCopy) {
selectedButtons.add(lightButton);
isSelectedLightButton(lightButton);
selectedFloor = floorIndexCopy;
boolean success = ChristmasTree.turnOnLight(floorIndexCopy, roomIndexCopy);
if (!success) {
System.out.println("Failed to update building state for floor " + floorIndexCopy
+ ", room " + roomIndexCopy);
}
} else {
ImageIcon icon = new ImageIcon("icon.jpeg");
JOptionPane.showMessageDialog(frame, "You can only turn off lights on one floor per turn!",
"Message", JOptionPane.INFORMATION_MESSAGE, icon);
}
}
});
floorPanel.add(lightButton);
}
pyramidPanel.add(floorPanel); // Add each floor panel to the pyramid panel
}
frame.add(pyramidPanel, BorderLayout.NORTH);
JPanel middlePanel = new JPanel();
middlePanel.setPreferredSize(new Dimension(800, 50));
middlePanel.setBackground(Color.PINK);
frame.add(middlePanel, BorderLayout.CENTER);
JLabel rectangleLabel = new JLabel();
rectangleLabel.setOpaque(true);
rectangleLabel.setBackground(new Color(139, 69, 19)); // Brown color
rectangleLabel.setPreferredSize(new Dimension(150, 120)); // Rectangle size
middlePanel.add(rectangleLabel, BorderLayout.CENTER);
// Add Control Panel
JPanel controlPanel = new JPanel();
controlPanel.setPreferredSize(new Dimension(800, 50));
controlPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 20, 10));
controlPanel.setBackground(Color.BLACK);
JButton confirmButton = new JButton("Confirm");
styleButton(confirmButton);
JLabel turnLabel = new JLabel("Player 1's Turn");
turnLabel.setForeground(Color.WHITE);
turnLabel.setFont(new Font("Arial", Font.BOLD, 14));
JButton startOverButton = new JButton("Start Over");
styleButton(startOverButton);
JButton ruleButton = new JButton("Rule");
styleButton(ruleButton);
controlPanel.add(turnLabel);
controlPanel.add(confirmButton);
controlPanel.add(startOverButton);
controlPanel.add(ruleButton);
frame.add(controlPanel, BorderLayout.SOUTH);
confirmButton.addActionListener(e -> {
if (selectedButtons.isEmpty()) {
ImageIcon icon = new ImageIcon("icon.jpeg");
JOptionPane.showMessageDialog(frame, "No lights selected. Make a move!", "Message",
JOptionPane.INFORMATION_MESSAGE, icon);
return;
}
// Check if the player is attempting to turn off the top floor (floor 7)
if (selectedFloor == 7) {
if (!ChristmasTree.isAllOnExceptTop()) {
ImageIcon icon = new ImageIcon("icon.jpeg");
JOptionPane.showMessageDialog(frame,
"You cannot turn on the top floor while other lights are still on! Move undone.",
"Message", JOptionPane.INFORMATION_MESSAGE, icon);
for (JButton button : selectedButtons) {
isOffLightButton(button);
}
selectedButtons.clear();
selectedFloor = -1;
} else {
for (JButton button : selectedButtons) {
isOnLightButton(button);
}
}
}
// Finalize the selected buttons
for (JButton button : selectedButtons) {
isOnLightButton(button);
}
selectedButtons.clear();
selectedFloor = -1; // Reset selected floor after confirmation
// Check for win
if (ChristmasTree.isAllOn()) {
JOptionPane.showMessageDialog(frame,
"YIPPEEE! Player " + currentPlayer + " wins by turning off the top floor!");
}
// Switch to the next player
currentPlayer = currentPlayer == 1 ? 2 : 1;
turnLabel.setText("Player " + currentPlayer + "'s Turn");
});
startOverButton.addActionListener(e -> {
// Reset the game state
selectedButtons.clear();
selectedFloor = -1;
currentPlayer = 1;
// Recreate the building
ChristmasTree.reset();
// Clear the frame and reinitialize the GUI
frame.getContentPane().removeAll();
setupGUI();
// Refresh the frame
frame.revalidate();
frame.repaint();
});
ruleButton.addActionListener(e -> {
JOptionPane.showMessageDialog(frame,
"<html>The Christmas Tree Light-On Challenge is a strategic two-player game where<br>" +
"players take turns lighting up bulbs on a pyramid-shaped Christmas tree.<br>" +
"Each turn, a player can light up one or multiple bulbs, but only from a single floor.<br>"
+
"The top bulb cannot be lit until all other bulbs on the tree are illuminated.<br>" +
"The player who successfully lights up the top bulb wins the game!</html>",
"Game Rules",
JOptionPane.INFORMATION_MESSAGE);
});
}
/**
* Resets the button to the unselected state.
* Updates the visual appearance and clears the selected buttons list if empty.
*
* @param lightButton the JButton to unselect
*/
private void unselectButton(JButton lightButton) {
isOffLightButton(lightButton);
// Reset the selected floor if no buttons are selected
if (selectedButtons.isEmpty()) {
selectedFloor = -1;
}
}
/**
* Styles a light button to represent the "on" state.
*
* @param lightButton the JButton to style
*/
private void isOffLightButton(JButton lightButton) {
lightButton.setBackground(new Color(0, 179, 44)); // Set green background
lightButton.setForeground(Color.BLACK);
lightButton.setOpaque(true);
lightButton.setContentAreaFilled(true);
lightButton.setBorderPainted(false);
lightButton.setPreferredSize(new Dimension(60, 70));
}
/**
* Styles a light button to represent the "off" state.
*
* @param button the JButton to style
*/
private void isOnLightButton(JButton button) {
button.setBackground(Color.YELLOW);
button.setForeground(Color.GRAY);
button.setOpaque(true);
button.setContentAreaFilled(true);
button.setBorderPainted(false);
button.setEnabled(false);
}
/**
* Styles a light button to represent the "selected" state.
*
* @param lightButton the JButton to style
*/
private void isSelectedLightButton(JButton lightButton) {
lightButton.setForeground(Color.ORANGE);
lightButton.setBackground(Color.ORANGE);
lightButton.setOpaque(true);
lightButton.setContentAreaFilled(true);
lightButton.setBorderPainted(false);
lightButton.setEnabled(true);
}
/**
* Applies consistent styling to control buttons (e.g., Confirm, Start Over,
* Rule).
*
* @param button the JButton to style
*/
private void styleButton(JButton button) {
button.setOpaque(true);
button.setContentAreaFilled(true);
button.setBorderPainted(false);
button.setBackground(Color.BLACK);
button.setForeground(Color.WHITE);
button.setFont(new Font("Arial", Font.BOLD, 14));
}
}