-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMemoryGameController
More file actions
181 lines (159 loc) · 5.66 KB
/
Copy pathMemoryGameController
File metadata and controls
181 lines (159 loc) · 5.66 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
import javafx.animation.PauseTransition;
import javafx.util.Duration;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class MemoryGameController {
private MemoryGameModel model;
private MemoryGameView gameView;
private Stage stage;
private boolean waiting = false;
/*
* purpose: constructor that begins the program by showing the difficulty menu
* input: Stage stage - the main application window
* output: none
* assumptions: stage is already created and passed in from the Application class
*/
public MemoryGameController(Stage stage) {
this.stage = stage;
showDifficultySelection();
}
/*
* purpose: display the difficulty selection screen and attach button actions
* input: none
* output: none
* assumptions: DifficultyView exists and provides Easy/Medium/Hard buttons
*/
private void showDifficultySelection() {
DifficultyView diffView = new DifficultyView();
Scene scene = new Scene(diffView.getRoot(), 400, 400);
stage.setScene(scene);
stage.show();
diffView.getEasyButton().setOnAction(e -> startGame(4, 4));
diffView.getMediumButton().setOnAction(e -> startGame(6, 6));
diffView.getHardButton().setOnAction(e -> startGame(8, 8));
}
/*
* purpose: create a new game with the chosen board size and show the game screen
* input: rows - number of rows on the board
* cols - number of columns on the board
* output: none
* assumptions: rows * cols is even
*/
private void startGame(int rows, int cols) {
model = new MemoryGameModel(rows, cols);
gameView = new MemoryGameView(rows, cols);
Scene scene = new Scene(gameView.getRoot(), 450, 450);
stage.setScene(scene);
attachButtonHandlers(rows, cols);
}
/*
* purpose: attach event handlers to every button in the board grid
* input: rows - an int variable that represents the number of rows
* cols - an int variable that represents the number of columns
* output: none
* assumptions: gameView and model are both initialized
*/
private void attachButtonHandlers(int rows, int cols) {
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
int row = r;
int col = c;
gameView.getButton(row, col).setOnAction(e -> handleFlip(row, col));
}
}
}
/*
* purpose: handle what happens when a tile is clicked (flip, check match, etc.)
* input: r - an int variable that represents the number of rows
* c - an int variable that represents the number of columns
* output: none
* assumptions: r and c lead to a tile on the board
*/
private void handleFlip(int r, int c) {
if (waiting) return;
boolean twoFlipped = flipTileAndUpdateButton(r, c);
if (twoFlipped) {
waiting = true;
PauseTransition pause = new PauseTransition(Duration.seconds(1));
pause.setOnFinished(e -> checkAndProcessMatch());
pause.play();
}
}
/*
* purpose: flip the selected tile and update its button state
* input: r - an int variable that represents the number of rows
* c - an int variable that represents the number of columns
* output: boolean - true if two tiles have been flipped, false otherwise
* assumptions: r and c lead to a tile on the board
*/
private boolean flipTileAndUpdateButton(int r, int c) {
boolean twoFlipped = model.flipTile(r, c);
updateButton(r, c);
return twoFlipped;
}
/*
* purpose: check if the two flipped tiles match and update the game state accordingly
* input: none
* output: none
* assumptions: two tiles have been flipped and `waiting` is set to true
*/
private void checkAndProcessMatch() {
if (model.checkMatch()) {
model.markMatched();
} else {
model.flipBack();
}
refreshBoard();
waiting = false;
if (model.allMatched()) {
showWinScreen();
}
}
/*
* purpose: show a "play again?" win screen when the game ends
* input: none
* output: none
* assumptions: stage exists
*/
private void showWinScreen() {
PlayAgainView winView = new PlayAgainView();
Scene winScene = new Scene(winView.getRoot(), 400, 300);
stage.setScene(winScene);
winView.getPlayAgainButton().setOnAction(e -> showDifficultySelection());
winView.getQuitButton().setOnAction(e -> stage.close());
}
/*
* purpose: update the text displayed on a single button
* input: r - row index
* c - column index
* output: none
* assumptions: r and c reference a valid tile
*/
private void updateButton(int r, int c) {
MemoryGameModel.Tile t = model.getTile(r, c);
switch (t.getState()) {
case FACE_DOWN:
gameView.updateButton(r, c, "???");
break;
case FACE_UP:
gameView.updateButton(r, c, t.getValue());
break;
case MATCHED:
gameView.updateButton(r, c, "");
break;
}
}
/*
* purpose: refresh all buttons to match the model
* input: none
* output: none
* assumptions: model and view match in dimensions
*/
private void refreshBoard() {
for (int r = 0; r < model.getRows(); r++) {
for (int c = 0; c < model.getCols(); c++) {
updateButton(r, c);
}
}
}
}