package org.fhnw.aigs.RockPaperScissors.client; import javafx.application.Platform; import javafx.event.EventHandler; import javafx.geometry.Insets; import javafx.geometry.Orientation; import javafx.geometry.Pos; import javafx.scene.control.Label; import javafx.scene.control.Separator; import javafx.scene.input.MouseEvent; import javafx.scene.layout.GridPane; import javax.swing.JOptionPane; import org.fhnw.aigs.RockPaperScissors.commons.GameState; import org.fhnw.aigs.RockPaperScissors.commons.RockPaperScissorsSelectionMessage; import org.fhnw.aigs.RockPaperScissors.commons.RockPaperScissorsSymbol; /** * Class defining the game board */ public class RockPaperScissorsBoard extends GridPane { private RockPaperScissorsClientGame clientGame; // ClientGame object private GridPane fieldsPane; // GridPane for selection fields private GridPane opponentPane; // GridPane to display opponent's move private Label opponentLabel; // Label for opponent name and points private Label myLabel; // Label for our name and points private Separator separator; // Horizontal line as separator private RockPaperScissorsBoardPane opponentField; // Pane to display opponent's move private RockPaperScissorsBoardPane rockField; // Pane to select rock private RockPaperScissorsBoardPane paperField; // Pane to select paper private RockPaperScissorsBoardPane scissorsField; // Pane to select scissors /** * Constructor to build main GUI * @param clientGame The ClientGame object for this game */ public RockPaperScissorsBoard(RockPaperScissorsClientGame clientGame) { this.clientGame = clientGame; opponentField = new RockPaperScissorsBoardPane(); rockField = new RockPaperScissorsBoardPane(); paperField = new RockPaperScissorsBoardPane(); scissorsField = new RockPaperScissorsBoardPane(); opponentLabel = new Label("Gegner: 0"); myLabel = new Label("Ich: 0"); separator = new Separator(Orientation.HORIZONTAL); fieldsPane = new GridPane(); opponentPane = new GridPane(); opponentField.setSymbol(RockPaperScissorsSymbol.None, GameState.None); rockField.setSymbol(RockPaperScissorsSymbol.Rock, GameState.None); paperField.setSymbol(RockPaperScissorsSymbol.Paper, GameState.None); scissorsField.setSymbol(RockPaperScissorsSymbol.Scissors, GameState.None); opponentLabel.getStyleClass().add("playerLabel"); myLabel.getStyleClass().add("playerLabel"); separator.getStyleClass().add("separator"); opponentPane.add(opponentField, 0, 0); opponentPane.setAlignment(Pos.CENTER); fieldsPane.add(rockField, 0, 0); fieldsPane.add(paperField, 1, 0); fieldsPane.add(scissorsField, 2, 0); fieldsPane.vgapProperty().set(10); fieldsPane.hgapProperty().set(10); fieldsPane.setPadding(new Insets(10,10,10,10)); this.add(opponentLabel, 0, 0); this.add(opponentPane, 0, 1); this.add(separator, 0, 2); this.add(fieldsPane, 0, 3); this.add(myLabel, 0, 4); this.vgapProperty().set(20); this.setAlignment(Pos.CENTER); // Event handlers for the three selection fields rockField.setOnMouseClicked(new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent event) { setSelectedPane(RockPaperScissorsSymbol.Rock); RockPaperScissorsSelectionMessage msg = new RockPaperScissorsSelectionMessage(RockPaperScissorsSymbol.Rock); clientGame.sendMessageToServer(msg); } }); paperField.setOnMouseClicked(new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent event) { setSelectedPane(RockPaperScissorsSymbol.Paper); RockPaperScissorsSelectionMessage msg = new RockPaperScissorsSelectionMessage(RockPaperScissorsSymbol.Paper); clientGame.sendMessageToServer(msg); } }); scissorsField.setOnMouseClicked(new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent event) { setSelectedPane(RockPaperScissorsSymbol.Scissors); RockPaperScissorsSelectionMessage msg = new RockPaperScissorsSelectionMessage(RockPaperScissorsSymbol.Scissors); clientGame.sendMessageToServer(msg); } }); } /** * Reset the formatting for all selection fields, then mark the selected one. * If nothing is selected, then this just resets the styles; for example, at * the beginning of a new move. * This makes use of classes defined in the CSS * @param symbol Selected symbol */ private void setSelectedPane(RockPaperScissorsSymbol symbol) { Platform.runLater(new Runnable() { @Override public void run() { // remove any applied styles rockField.getStyleClass().remove("rockPaperScissorsField"); rockField.getStyleClass().remove("rockPaperScissorsFieldSelected"); paperField.getStyleClass().remove("rockPaperScissorsField"); paperField.getStyleClass().remove("rockPaperScissorsFieldSelected"); scissorsField.getStyleClass().remove("rockPaperScissorsField"); scissorsField.getStyleClass().remove("rockPaperScissorsFieldSelected"); // set style as required if (symbol == RockPaperScissorsSymbol.Paper) { paperField.getStyleClass().add("rockPaperScissorsFieldSelected"); } else if (symbol == RockPaperScissorsSymbol.Rock) { rockField.getStyleClass().add("rockPaperScissorsFieldSelected"); } else if (symbol == RockPaperScissorsSymbol.Scissors) { scissorsField.getStyleClass().add("rockPaperScissorsFieldSelected"); } }}); } /** * Update the GUI: symbols and descriptive texts * @param opponentSymbol Opponents symbol * @param myState Mein Status (won, lost, etc.) * @param mySymbol Our symbol * @param opponentName Opponent's name * @param opponentPoints Opponent's points * @param myPoints Our points */ public void updateGUI(RockPaperScissorsSymbol opponentSymbol, GameState myState, RockPaperScissorsSymbol mySymbol, String opponentName, int opponentPoints, int myPoints){ setSymbols(opponentSymbol, myState, mySymbol); setNamesAndPoints(opponentName, opponentPoints, myPoints); } /** * set the symbol images (ours and opponent's), including overlays to show results * @param opponentSymbol Opponent's symbol * @param myState Our status (won, lost, etc.) * @param mySymbol Our symbol */ public void setSymbols(RockPaperScissorsSymbol opponentSymbol, GameState myState, RockPaperScissorsSymbol mySymbol) { if (myState == GameState.Win) { opponentField.setSymbol(opponentSymbol, GameState.Lose); if (mySymbol == RockPaperScissorsSymbol.Rock) { rockField.setSymbol(RockPaperScissorsSymbol.Rock, GameState.Win); } else if (mySymbol == RockPaperScissorsSymbol.Paper) { paperField.setSymbol(RockPaperScissorsSymbol.Paper, GameState.Win); } else { scissorsField.setSymbol(RockPaperScissorsSymbol.Scissors, GameState.Win); } } else if (myState == GameState.Lose) { opponentField.setSymbol(opponentSymbol, GameState.Win); if (mySymbol == RockPaperScissorsSymbol.Rock) { rockField.setSymbol(RockPaperScissorsSymbol.Rock, GameState.Lose); } else if (mySymbol == RockPaperScissorsSymbol.Paper) { paperField.setSymbol(RockPaperScissorsSymbol.Paper, GameState.Lose); } else { scissorsField.setSymbol(RockPaperScissorsSymbol.Scissors, GameState.Lose); } } else { // The move is a draw, no one wins opponentField.setSymbol(opponentSymbol, GameState.Draw); rockField.setSymbol(RockPaperScissorsSymbol.Rock, GameState.Draw); paperField.setSymbol(RockPaperScissorsSymbol.Paper, GameState.Draw); scissorsField.setSymbol(RockPaperScissorsSymbol.Scissors, GameState.Draw); } } /** * Set the labels containing names and points. * @param opponentName Opponent's name * @param opponentPoints Opponent's points * @param myPoints Our points */ public void setNamesAndPoints(String opponentName, int opponentPoints, int myPoints) { Platform.runLater(new Runnable() { @Override public void run() { opponentLabel.setText(opponentName + ": " + Integer.toString(opponentPoints) + " Points"); myLabel.setText("Ich: " + Integer.toString(myPoints) + " Points"); } }); } /** * Change text in the window header, to the right of the game name. * We access the main window via the ClientGame object * @param text Text to display */ public void setHeader(String text) { clientGame.getGameWindow().getHeader().setStatusLabelText(text); } /** * Prepare the client for the next move * @param message Message to display, from previous move * @param lastTurn True if this was the last move of the game */ public void nextTurn(String message, boolean lastTurn) { if (!lastTurn) { JOptionPane.showMessageDialog(null, message + "\nClick OK for the next move.", "Move finished", JOptionPane.INFORMATION_MESSAGE); } else { // last move JOptionPane.showMessageDialog(null, message + "\nClick OK to see the winner.", "Move finished", JOptionPane.INFORMATION_MESSAGE); } // Reset the displayed selections, to prepare for the next move setSymbols(RockPaperScissorsSymbol.None, GameState.None, RockPaperScissorsSymbol.None); setSelectedPane(RockPaperScissorsSymbol.None); setHeader("Waiting for opponent's move..."); } }