OthelloMultiPlayerController.java (9146B) download
1package nl.isygameclient.controllers.games.othello;
2
3import com.jfoenix.controls.JFXButton;
4import javafx.application.Platform;
5import javafx.event.ActionEvent;
6import javafx.fxml.FXML;
7import javafx.fxml.Initializable;
8import javafx.scene.control.TextField;
9import javafx.scene.layout.GridPane;
10import javafx.scene.paint.Color;
11import javafx.scene.shape.Circle;
12import nl.isygameclient.Window;
13import nl.isygameclient.controllers.games.GameController;
14import nl.isygameclient.models.Ai;
15import nl.isygameclient.models.Game;
16import nl.isygameclient.models.Player;
17import nl.isygameclient.models.PlayerManager;
18import nl.isygameclient.models.games.Othello;
19import nl.isygameclient.network.GameClient;
20import nl.isygameclient.network.GameType;
21import nl.isygameclient.network.Match;
22import nl.isygameclient.util.StageHandler;
23import nl.isygameclient.util.Vector2D;
24
25import java.io.IOException;
26import java.net.URL;
27import java.util.ArrayList;
28import java.util.List;
29import java.util.Objects;
30import java.util.ResourceBundle;
31import java.util.stream.Stream;
32
33public class OthelloMultiPlayerController implements GameController, Initializable, Runnable {
34
35 private Game game;
36 private Thread gameThread;
37 private boolean running;
38
39 private GameClient client;
40 private Match match;
41 private String playerSelf = "X", playerOther = "O";
42
43 private JFXButton[][] boardButtons;
44
45 @FXML
46 private TextField hostField;
47 @FXML
48 private TextField portField;
49 @FXML
50 private TextField nameField;
51
52 @FXML
53 private TextField opponentField;
54 @FXML
55 private GridPane boardGrid;
56
57 private int[][] heuristics = {
58 {4, 3, 3, 3, 3, 3, 3, 4},
59 {3, 2, 2, 2, 2, 2, 2, 3},
60 {3, 2, 1, 1, 1, 1, 2, 3},
61 {3, 2, 1, 1, 1, 1, 2, 3},
62 {3, 2, 1, 1, 1, 1, 2, 3},
63 {3, 2, 1, 1, 1, 1, 2, 3},
64 {3, 2, 2, 2, 2, 2, 2, 3},
65 {4, 3, 3, 3, 3, 3, 3, 4}
66 };
67
68 private boolean hasClicked = false;
69 private Vector2D<Integer, Integer> clickedPos;
70
71 @Override
72 public void initialize(URL url, ResourceBundle resourceBundle) {
73 var player = new Player("player1", "white") {
74 @Override
75 public Vector2D<Integer, Integer> onPlayerTurn() {
76 return clickedPos;
77 }
78 };
79 var players = List.of(player, new Ai("player2", "black", heuristics));
80 var manager = new PlayerManager(0, new ArrayList<>(players));
81 game = new Othello(manager);
82 initializeBoard();
83 updateButtons();
84 }
85
86 private void initializeBoard() {
87 var board = game.getBoard();
88 boardButtons = new JFXButton[board.getHeight()][board.getWidth()];
89 for (int i = 0; i < board.getHeight(); i++) {
90 for (int j = 0; j < board.getWidth(); j++) {
91 JFXButton button = new JFXButton();
92 var index = i + "," + j;
93 button.setId(index);
94 button.setMinSize(60.0, 60.0);
95 button.setMaxSize(60.0, 60.0);
96
97 var styleClass = button.getStyleClass();
98 styleClass.add("othello-button");
99 styleClass.add("headline-small");
100 button.setOnAction((ActionEvent event) -> onMoveButtonClick(button));
101 boardButtons[i][j] = button;
102 boardGrid.add(button, i, j);
103 }
104 }
105 }
106
107 private void updateButtons() {
108 clearBoardButtons();
109 var board = game.getBoard();
110 for (int i = 0; i < board.getHeight(); i++) {
111 for (int j = 0; j < board.getWidth(); j++) {
112 var index = board.get(new Vector2D<>(i, j));
113 if (index == null) continue;
114 if (Objects.equals("white", index.getPlayingAs())) {
115 addStone(boardButtons[i][j], Color.WHITE);
116 } else if (Objects.equals("black", index.getPlayingAs())) {
117 addStone(boardButtons[i][j], Color.BLACK);
118 }
119 }
120 }
121 }
122
123 private void addStone(JFXButton button, Color color) {
124 var circle = new Circle();
125 circle.setRadius(20);
126 circle.setFill(color);
127 button.setGraphic(circle);
128 }
129
130 private void onMoveButtonClick(JFXButton button) {
131 // Move
132 var id = button.getId().split(",");
133 var index = Stream.of(id).mapToInt(Integer::parseInt).toArray();
134 var manager = game.getPlayerManager();
135 var currentPlayer = manager.getCurrentPlayer();
136 if (game.getValidMoves(currentPlayer).isEmpty()) {
137 manager.nextPlayer();
138 return;
139 }
140 if (game.isMoveValid(currentPlayer, new Vector2D<>(index[0], index[1]))) {
141 game.move(currentPlayer, new Vector2D<>(index[0], index[1]));
142 updateButtons();
143 }
144
145 if (game.isGameOver()) {
146 disableBoardButtons();
147 }
148 }
149
150 public void run() {
151 running = true;
152// try {
153// client = new GameClient(hostField.getText(), Integer.parseInt(portField.getText()));
154// client.login(nameField.getText());
155//
156// if (opponentField.getText().length() == 0)
157// match = client.match(GameType.TICTACTOE);
158// else
159// match = client.match(GameType.TICTACTOE, opponentField.getText());
160//
161// while (running) {
162// match.update();
163//
164// if (!match.isStarted())
165// continue;
166//
167// // game.setCurrentPlayer(match.isYourTurn() ? playerSelf : playerOther);
168// // game.move(Integer.parseInt(moveMap.get("move")));
169// Platform.runLater(() -> {
170// playingAgainstLabel.setText(match.getOpponent());
171//
172// if (match.isYourTurn()) {
173// currentPlayer.setText(playerSelf);
174// enableBoardButtons();
175// } else {
176// currentPlayer.setText(playerOther);
177// disableBoardButtons();
178// }
179// for (int i = 0; i < 3 * 3; i++) {
180// switch (match.getMove(i)) {
181// case -1 -> boardButtons.get(i).setText(playerOther);
182// case 0 -> boardButtons.get(i).setText("");
183// case 1 -> boardButtons.get(i).setText(playerSelf);
184// }
185// }
186// });
187//
188// if (match.getOutcome() == null)
189// continue;
190//
191// running = false;
192//
193// Platform.runLater(() -> {
194// switch (match.getOutcome().type) {
195// case DRAW:
196// System.out.println("Draw!");
197// gameOverText.setText("Draw!");
198// gameOverText.setVisible(true);
199// break;
200// case LOSS:
201// System.out.printf("%s, Is the Winner!\n\n", playerOther);
202// gameOverText.setText(String.format("%s, is the Winner!\n\n", playerOther));
203// gameOverText.setVisible(true);
204// break;
205// case WIN:
206// System.out.printf("%s, Is the Winner!\n\n", playerSelf);
207// gameOverText.setText(String.format("%s, is the Winner!\n\n", playerSelf));
208// gameOverText.setVisible(true);
209// default:
210// }
211// });
212// }
213// match.abort();
214// client.close();
215// } catch (IOException e) {
216// e.printStackTrace();
217// }
218 }
219
220
221 private void clearBoardButtons() {
222 for (JFXButton[] row : boardButtons) {
223 for (JFXButton button : row) {
224 button.setGraphic(null);
225 }
226 }
227 }
228
229 private void disableBoardButtons() {
230 for (JFXButton[] row : boardButtons) {
231 for (JFXButton button : row) {
232 button.setDisable(true);
233 }
234 }
235 }
236
237 private void enableBoardButtons() {
238 for (JFXButton[] row : boardButtons) {
239 for (JFXButton button : row) {
240 button.setDisable(false);
241 }
242 }
243 }
244
245 @FXML
246 public void onNewGameButtonClick(ActionEvent e) throws NumberFormatException, InterruptedException {
247 game.restart();
248// gameOverText.setVisible(false);
249
250 if (gameThread != null && running) {
251 running = false;
252 gameThread.join();
253 }
254 gameThread = new Thread(this);
255 gameThread.start();
256
257 updateButtons();
258 enableBoardButtons();
259 }
260
261 @Override
262 public void onMainMenuButtonClick(ActionEvent e) {
263 StageHandler.get().changeSceneOfStage(Window.GAME, "/nl/isygameclient/views/games/othello/OthelloMainMenu.fxml");
264
265 }
266}