Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package connectfour;
- import javafx.application.Application;
- import javafx.scene.Scene;
- import javafx.scene.control.Label;
- import javafx.scene.layout.BorderPane;
- import javafx.scene.layout.GridPane;
- import javafx.scene.layout.Pane;
- import javafx.scene.paint.Color;
- import javafx.scene.shape.Ellipse;
- import javafx.stage.Stage;
- /**
- * A version of Connect Four for JavaFX.
- *
- * @since 2021-10-06
- * @author Cameron Bennett | CIS 161 177
- */
- public class ConnectFour extends Application {
- // Initialize a 4-by-4 array of Cells.
- private Cell[][] cells = new Cell[4][4];
- // Initialize a label for the game status.
- private Label status = new Label();
- // Initialize a boolean value for holding whose turn it is.
- private boolean turn;
- // Initialize a boolean value for the game state.
- private boolean gameOver = false;
- /**
- * Gets the {@code Cell} at a specified {@code (x,y)} coordinate.
- * @param x the x-coordinate.
- * @param y the y-coordinate.
- * @return the {@code Cell} at {@code (x,y)}.
- */
- public Cell getCellAt(int x, int y) { return this.cells[x][y]; }
- /**
- * Sets the {@code Cell} at a specified {@code (x,y)} coordinate.
- * @param cell the cell to set at {@code (x,y)}.
- * @param x the x-coordinate.
- * @param y the y-coordinate.
- * @return the {@code Cell} that was set.
- */
- public Cell setCellAt(Cell cell, int x, int y) { return this.cells[x][y] = cell; }
- public Label getStatusMessage() { return this.status; }
- public void setStatusMessage(String status) { this.getStatusMessage().setText(status); }
- /**
- * Gets the name of the specified player.
- * @return a {@code String} representing the name of the current player.
- */
- public String getPlayerName(boolean turn) { return turn ? "YELLOW" : "RED"; }
- /**
- * Gets the color of the specified player.
- * @return the {@code Color} of the specified player.
- */
- public Color getPlayerColor(boolean turn) { return turn ? Color.YELLOW : Color.RED; }
- /**
- * Gets whose turn it currently is.
- * @return the {@code boolean} value of whose turn it is.
- */
- public boolean getTurn() { return this.turn; }
- /**
- * Sets whose turn it currently is and updates the status message.
- */
- public void setTurn(boolean turn) {
- this.turn = turn;
- // Update the status message.
- this.setStatusMessage(String.format("%s's turn.", getPlayerName(turn)));
- }
- public boolean isGameOver() { return gameOver; }
- public void setGameOver(boolean gameOver) { this.gameOver = gameOver; }
- public boolean checkWin(Color check) {
- // Quick and dirty method.
- // Check columns.
- for(int x = 0; x < 4; x++) {
- if(
- this.getCellAt(x, 0).getColor() == check &&
- this.getCellAt(x, 1).getColor() == check &&
- this.getCellAt(x, 2).getColor() == check &&
- this.getCellAt(x, 3).getColor() == check
- ) {
- return true;
- }
- }
- // Check rows.
- for(int y = 0; y < 4; y++) {
- if(
- this.getCellAt(0, y).getColor() == check &&
- this.getCellAt(1, y).getColor() == check &&
- this.getCellAt(2, y).getColor() == check &&
- this.getCellAt(3, y).getColor() == check
- ) {
- return true;
- }
- }
- // Check major diagonal.
- if(
- this.getCellAt(0, 0).getColor() == check &&
- this.getCellAt(1, 1).getColor() == check &&
- this.getCellAt(2, 2).getColor() == check &&
- this.getCellAt(3, 3).getColor() == check
- ) {
- return true;
- }
- // Check minor diagonal.
- return this.getCellAt(0, 3).getColor() == check &&
- this.getCellAt(1, 2).getColor() == check &&
- this.getCellAt(2, 1).getColor() == check &&
- this.getCellAt(3, 0).getColor() == check;
- }
- public boolean checkFull() {
- // Another quick and dirty method.
- // Loop through all the Cells and check for an empty one.
- for(int x = 0; x < 4; x++) {
- for(int y = 0; y < 4; y++) {
- // Check if the Cell at the (x,y) coordinate is empty.
- if(!this.getCellAt(x, y).isFilled()) {
- return false;
- }
- }
- }
- // If the method reached this point, there are no empty Cells in the grid.
- return true;
- }
- @Override
- public void start(Stage stage) {
- // Set the starting player's turn.
- this.setTurn(false);
- // Create a grid to hold the cells.
- GridPane cellGrid = new GridPane();
- // Fill the grid with cells.
- for(int x = 0; x < 4; x++) {
- for(int y = 0; y < 4; y++) {
- cellGrid.add(this.setCellAt(new Cell(x, y), x, y), x, y);
- }
- }
- // Create a BorderPane to hold the grid.
- BorderPane container = new BorderPane(cellGrid);
- container.setBottom(this.getStatusMessage());
- // Create and show the main scene.
- Scene main = new Scene(container);
- stage.setTitle("Connect Four");
- stage.setScene(main);
- stage.show();
- }
- public static void main(String[] args) { launch(); }
- /**
- * A Cell class for Connect Four.
- */
- class Cell extends Pane {
- // Initialize a Color for holding the fill color of the Cell.
- private Color color;
- // Initialize two ints for holding the (x,y) coordinates of the Cell.
- private final int x;
- private final int y;
- /**
- * Default Cell constructor.
- */
- public Cell(int x, int y) {
- this.x = x;
- this.y = y;
- // Set the border color & size of the Cell.
- this.setStyle("-fx-border-color: black;");
- this.setPrefSize(100, 100);
- // Attach a mouse click handler to the Cell to detect when a player clicks on a Cell.
- this.setOnMouseClicked(e -> handleMouseClick());
- }
- public Color getColor() { return color; }
- public void setColor(Color color) { this.color = color; }
- public boolean isFilled() { return this.color != null; }
- public void setFilled(Color fill) {
- this.setColor(fill);
- // Create new ellipse.
- Ellipse ellipse = new Ellipse(
- this.getWidth() / 2,
- this.getHeight() / 2,
- this.getWidth() / 2 - 10,
- this.getHeight() / 2 - 10
- );
- // Bind center X and center Y properties.
- ellipse.centerXProperty().bind(
- this.widthProperty().divide(2)
- );
- ellipse.centerYProperty().bind(
- heightProperty().divide(2)
- );
- // Bind height and width properties.
- ellipse.radiusXProperty().bind(
- widthProperty().divide(2).subtract(10)
- );
- ellipse.radiusYProperty().bind(
- heightProperty().divide(2).subtract(10)
- );
- // Set color.
- ellipse.setStroke(Color.BLACK);
- ellipse.setFill(fill);
- // Attach ellipse to the cell.
- this.getChildren().add(ellipse);
- }
- /**
- * Gets this Cell's x-coordinate.
- * @return this Cell's x-coordinate.
- */
- public int getX() { return this.x; }
- /**
- * Gets this Cell's y-coordinate.
- * @return this Cell's y-coordinate.
- */
- public int getY() { return this.y; }
- /**
- * Fills a cell with the current turn color and checks for a win condition.
- */
- public void activate() {
- // Fill the Cell with the color of the current player.
- boolean currentTurn = ConnectFour.this.getTurn();
- Color currentColor = ConnectFour.this.getPlayerColor(currentTurn);
- this.setFilled(currentColor);
- if(ConnectFour.this.checkWin(currentColor)) {
- // Update the game state.
- ConnectFour.this.setGameOver(true);
- // Update the status message.
- ConnectFour.this.setStatusMessage(String.format("%s wins!", ConnectFour.this.getPlayerName(currentTurn)));
- } else if(ConnectFour.this.checkFull()) {
- // Update the game state.
- ConnectFour.this.setGameOver(true);
- // Update the status message.
- ConnectFour.this.setStatusMessage("There are no more empty spaces! Game over.");
- } else {
- // Update the turn order.
- ConnectFour.this.setTurn(!ConnectFour.this.getTurn());
- }
- }
- /**
- * Searches upwards for an empty space to fill a Cell at.
- * @param startingX the x-coordinate to start at.
- */
- public void placeAtColumn(int startingX) {
- // Loop through the Cells from the bottom up, searching for an empty Cell.
- for(int currentY = 3; currentY >= 0; currentY--) {
- // Get the Cell at the current y-value.
- Cell currentCell = ConnectFour.this.getCellAt(startingX, currentY);
- // Check if the Cell is not filled.
- if(!currentCell.isFilled()) {
- // Fill the Cell.
- currentCell.activate();
- return;
- }
- }
- // If the method reached this point, there are no empty Cells in the column.
- ConnectFour.this.setStatusMessage("You can't do that.");
- }
- /**
- * Method for handling when a player clicks on a Cell.
- */
- private void handleMouseClick() {
- // Check if the game is over before trying to fill a Cell.
- if(!ConnectFour.this.isGameOver())
- placeAtColumn(this.getX());
- }
- }
- }
Add Comment
Please, Sign In to add comment