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