// TicTacToe.java, user-against-user, JavaFX GUI // From http://www.cs.armstrong.edu/liang/intro10e/html/TicTacToe.html // Mods by pmateti@wright.edu 2015 // compile and run: % javac TicTacToe.java; java TicTacToe // Has at least one bug! import javafx.application.Application; import javafx.stage.Stage; 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.Line; import javafx.scene.shape.Ellipse; public class TicTacToe extends Application { private boolean gameOver = false; private int nFilled = 0; private char whoseTurn = 'X'; // 'X' or 'O' private Cell[][] cell = new Cell[3][3]; private Label statusLabel = new Label("X's turn to play"); @Override public void start(Stage primaryStage) { GridPane pane = new GridPane(); for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) pane.add(cell[i][j] = new Cell(), j, i); BorderPane borderPane = new BorderPane(); borderPane.setCenter(pane); borderPane.setBottom(statusLabel); Scene scene = new Scene(borderPane, 300.0f, 300.0f); primaryStage.setTitle("TicTacToe"); primaryStage.setScene(scene); primaryStage.show(); } public boolean isFull() { return nFilled >= 9; // > should never happen } public boolean hasWon(char tkn) { for (int i = 0; i < 3; i++) if (cell[i][0].getToken() == tkn && cell[i][1].getToken() == tkn && cell[i][2].getToken() == tkn) return true; for (int j = 0; j < 3; j++) if (cell[0][j].getToken() == tkn && cell[1][j].getToken() == tkn && cell[2][j].getToken() == tkn) return true; if (cell[0][0].getToken() == tkn && cell[1][1].getToken() == tkn && cell[2][2].getToken() == tkn) return true; if (cell[0][2].getToken() == tkn && cell[1][1].getToken() == tkn && cell[2][0].getToken() == tkn) return true; return false; } public class Cell extends Pane { private char token = ' '; // one of blank, X, or O public Cell() { setStyle("-fx-border-color: black"); setPrefSize(100.0f, 100.0f); setOnMouseClicked(e -> handleMouseClick()); } public char getToken() { return token; } public void drawX() { double w = getWidth(), h = getHeight(); Line line1 = new Line(10.0f, 10.0f, w - 10.0f, h - 10.0f); Line line2 = new Line(10.0f, h - 10.0f, w - 10.0f, 10.0f); getChildren().addAll(line1, line2); } public void drawO() { double w = getWidth(), h = getHeight(); Ellipse ellipse = new Ellipse(w/2, h/2, w/2 - 10.0f, h/2 - 10.0f); ellipse.setStroke(Color.BLACK); ellipse.setFill(Color.WHITE); getChildren().add(ellipse); } public void setToken(char c) { if (c == 'X') drawX(); else drawO(); token = c; nFilled ++; } private void handleMouseClick() { String s = ""; if (!gameOver) { setToken(whoseTurn); if (hasWon(whoseTurn)) { gameOver = true; s = whoseTurn + " won! The game is over"; } else if (isFull()) { gameOver = true; s = "Draw! The game is over"; } else { whoseTurn = (whoseTurn == 'X') ? 'O' : 'X'; s = whoseTurn + "'s turn"; } statusLabel.setText(s); } } } public static void main(String[] args) { launch(args); } } // -eof-