hanze/game-client

src/main/java/nl/isygameclient/controllers/games/othello/OthelloSinglePlayerController.java in modern-design
Repositories | Summary | Log | Files

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}