OthelloSinglePlayerController.java (5571B) download
1package nl.isygameclient.controllers.games.othello;
2
3import com.jfoenix.controls.JFXButton;
4import javafx.event.ActionEvent;
5import javafx.fxml.FXML;
6import javafx.fxml.Initializable;
7import javafx.scene.layout.GridPane;
8import javafx.scene.paint.Color;
9import javafx.scene.shape.Circle;
10import nl.isygameclient.Window;
11import nl.isygameclient.controllers.games.GameController;
12import nl.isygameclient.models.Ai;
13import nl.isygameclient.models.Game;
14import nl.isygameclient.models.Player;
15import nl.isygameclient.models.PlayerManager;
16import nl.isygameclient.models.games.Othello;
17import nl.isygameclient.util.StageHandler;
18import nl.isygameclient.util.Vector2D;
19
20import java.net.URL;
21import java.util.*;
22import java.util.stream.Stream;
23
24public class OthelloSinglePlayerController implements GameController, Initializable {
25
26 private Game game;
27 private JFXButton[][] boardButtons;
28
29 @FXML
30 private GridPane boardGrid;
31
32 private int[][] heuristics = {
33 {4, 3, 3, 3, 3, 3, 3, 4},
34 {3, 2, 2, 2, 2, 2, 2, 3},
35 {3, 2, 1, 1, 1, 1, 2, 3},
36 {3, 2, 1, 1, 1, 1, 2, 3},
37 {3, 2, 1, 1, 1, 1, 2, 3},
38 {3, 2, 1, 1, 1, 1, 2, 3},
39 {3, 2, 2, 2, 2, 2, 2, 3},
40 {4, 3, 3, 3, 3, 3, 3, 4}
41 };
42
43 private boolean hasClicked = false;
44 private Vector2D<Integer, Integer> clickedPos;
45 private boolean againstAi = false;
46
47 @Override
48 public void initialize(URL url, ResourceBundle resourceBundle) {
49 var player = new Player("player1", "white") {
50 @Override
51 public Vector2D<Integer, Integer> onPlayerTurn() {
52 return clickedPos;
53 }
54 };
55 var players = List.of(player, new Ai("player2", "black", heuristics));
56 var manager = new PlayerManager(0, new ArrayList<>(players));
57 game = new Othello(manager);
58 initializeBoard();
59 updateButtons();
60 }
61
62 private void initializeBoard() {
63 var board = game.getBoard();
64 boardButtons = new JFXButton[board.getHeight()][board.getWidth()];
65 for (int x = 0; x < board.getHeight(); x++) {
66 for (int y = 0; y < board.getWidth(); y++) {
67 JFXButton button = new JFXButton();
68 var index = x + "," + y;
69 button.setId(index);
70 button.setMinSize(60.0, 60.0);
71 button.setMaxSize(60.0, 60.0);
72
73 var styleClass = button.getStyleClass();
74 styleClass.add("othello-button");
75 styleClass.add("headline-small");
76 button.setOnAction((ActionEvent event) -> onMoveButtonClick(button));
77 boardButtons[y][x] = button;
78 boardGrid.add(button, x, y);
79 }
80 }
81 }
82
83 private void updateButtons() {
84 clearBoardButtons();
85 var board = game.getBoard();
86 for (int x = 0; x < board.getHeight(); x++) {
87 for (int y = 0; y < board.getWidth(); y++) {
88 var index = board.get(new Vector2D<>(x, y));
89 if (index == null) continue;
90 if (Objects.equals("white", index.getPlayingAs())) {
91 addStone(boardButtons[y][x], Color.WHITE);
92 } else if (Objects.equals("black", index.getPlayingAs())) {
93 addStone(boardButtons[y][x], Color.BLACK);
94 }
95 }
96 }
97 }
98
99 private void addStone(JFXButton button, Color color) {
100 var circle = new Circle();
101 circle.setRadius(20);
102 circle.setFill(color);
103 button.setGraphic(circle);
104 }
105 private void doMove(Vector2D<Integer, Integer> move) {
106 var manager = game.getPlayerManager();
107 var currentPlayer = manager.getCurrentPlayer();
108
109 if (game.getValidMoves(currentPlayer).isEmpty()) {
110 manager.nextPlayer();
111 return;
112 }
113 if (game.isMoveValid(currentPlayer, move)) {
114 game.move(currentPlayer, move);
115 updateButtons();
116 }
117 }
118
119 private void onMoveButtonClick(JFXButton button) {
120 // Move
121 var id = button.getId().split(",");
122 var index = Stream.of(id).mapToInt(Integer::parseInt).toArray();
123
124 var playerMove = new Vector2D<>(index[0], index[1]);
125 doMove(playerMove);
126
127 if (againstAi) {
128 var manager = game.getPlayerManager();
129 var move = manager.getCurrentPlayer().onPlayerTurn();
130 doMove(move);
131 }
132
133 if (game.isGameOver()) {
134 disableBoardButtons();
135 }
136 }
137
138 private void clearBoardButtons() {
139 for (JFXButton[] row : boardButtons) {
140 for (JFXButton button : row) {
141 button.setGraphic(null);
142 }
143 }
144 }
145
146 private void disableBoardButtons() {
147 for (JFXButton[] row : boardButtons) {
148 for (JFXButton button : row) {
149 button.setDisable(true);
150 }
151 }
152 }
153
154 private void enableBoardButtons() {
155 for (JFXButton[] row : boardButtons) {
156 for (JFXButton button : row) {
157 button.setDisable(false);
158 }
159 }
160 }
161
162 @Override
163 public void onNewGameButtonClick(ActionEvent actionEvent) {
164 game.restart();
165 updateButtons();
166 enableBoardButtons();
167 }
168
169 @Override
170 public void onMainMenuButtonClick(ActionEvent actionEvent) {
171 StageHandler.get().changeSceneOfStage(Window.GAME, "/nl/isygameclient/views/games/othello/OthelloMainMenu.fxml");
172 }
173}