Skip to content
Snippets Groups Projects
Commit b9a1bf40 authored by Bariatti Francesco's avatar Bariatti Francesco
Browse files

Big GUI refactoring: towards MVC and beyond!

parent 4ed657df
No related branches found
No related tags found
No related merge requests found
......@@ -5,3 +5,4 @@ gui/.classpath
gui/bin
gui/.project
gui/.settings
gui/out
import javafx.scene.shape.Polygon;
public class Case {
private int rang; //N de la case (bottom right = 0, top left = 59)
private int nbFish;//Nb de poissons sur la case (0 si vide)
private Penguins penguins;
private Polygon caseFX;
public void setNbFish(int nbFish)
{
this.nbFish = nbFish;
}
public void setPenguins(Penguins penguins)
{
this.penguins = penguins;
}
public int getRang()
{
return rang;
}
public int getNbFish()
{
return nbFish;
}
public Penguins getPenguins()
{
return penguins;
}
public Polygon getCaseFX()
{
return caseFX;
}
public Case(int rang, Penguins penguins, Polygon caseFX)
{
this.rang = rang;
this.penguins = penguins;
this.caseFX = caseFX;
this.nbFish = 0;
}
public Case(int rang, int nbFish, Penguins penguins, Polygon caseFX) {
this(rang, penguins, caseFX);
this.nbFish = nbFish;
}
public enum Penguins
{
NO_PENGUIN, RED_PENGUIN, BLUE_PENGUIN;
}
}
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("view.fxml"));
BorderPane root = (BorderPane) loader.load();
Scene scene = new Scene(root,1024,680);
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
\ No newline at end of file
import javafx.scene.shape.Polygon;
public class Plateau {
private Case[] grille;
//Constructeur de grille vide (0 fish, 0 penguins)
public Plateau(Polygon[] casesFX){
grille = new Case[60];
for (int i=0; i<casesFX.length ; i++){
grille[i]= new Case(i, Case.Penguins.NO_PENGUIN, casesFX[i]);
}
}
public Case[] getGrille()
{
return grille;
}
}
public enum Player {
RED, BLUE
//TODO
}
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Polygon;
public class Controller implements Initializable {
private GameState gameState;
private Process gameProcess;
private PrintWriter gameInput;
private Plateau plateau;
@FXML
private Polygon case0, case1, case2, case3, case4, case5, case6, case7, case8, case9, case10, case11, case12, case13, case14, case15, case16, case17, case18, case19, case20, case21, case22, case23, case24, case25, case26, case27, case28, case29, case30, case31, case32, case33, case34, case35, case36, case37, case38, case39, case40, case41, case42, case43, case44, case45, case46, case47, case48, case49, case50, case51, case52, case53, case54, case55, case56, case57, case58, case59;
@FXML
private BorderPane panneauPrincipal;
@Override
public void initialize(URL location, ResourceBundle resources) {
Polygon[] cases = {case0, case1, case2, case3, case4, case5, case6, case7, case8, case9, case10, case11, case12, case13, case14, case15, case16, case17, case18, case19, case20, case21, case22, case23, case24, case25, case26, case27, case28, case29, case30, case31, case32, case33, case34, case35, case36, case37, case38, case39, case40, case41, case42, case43, case44, case45, case46, case47, case48, case49, case50, case51, case52, case53, case54, case55, case56, case57, case58, case59};
for(Polygon c : cases)
{
//c.setOnMouseClicked(new MyClickHandler());
//c.setOnMouseEntered(new MyHexEnteredHandler());
}
this.plateau = new Plateau(cases);
this.gameState = new GameState();
try {
this.gameProcess = new ProcessBuilder("../bin/theturk").start();
gameInput = new PrintWriter(new OutputStreamWriter(gameProcess.getOutputStream()), true);
} catch (IOException e) {
Alert alert = new Alert(Alert.AlertType.ERROR,"Can't run penguin program", ButtonType.OK);
alert.showAndWait();
e.printStackTrace();
System.exit(1);
}
UpdateThread upT = new UpdateThread(gameProcess, this.gameState, this.plateau);
upT.setDaemon(true);
upT.start();
//We tell the game that we will start
gameInput.print("h");
gameInput.println();
gameInput.println("0");
}
//public Polygon getPolygonFromCoordinates(double x, double y){ }
//Action de click sur case
private class MyClickHandler implements EventHandler<MouseEvent> {
@Override
public void handle (MouseEvent event){
Polygon poly = (Polygon)event.getSource();
poly.setFill(Color.GOLD);
}
}
private class MyHexEnteredHandler implements EventHandler<MouseEvent> {
@Override
public void handle (MouseEvent event){
Polygon poly = (Polygon)event.getSource();
poly.setFill(Color.GOLD);
}
}
}
package controller;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Polygon;
import model.GameState;
import model.Tile;
import view.TileView;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.URL;
import java.util.ResourceBundle;
public class Controller implements Initializable
{
private GameState gameState;
private Process gameProcess;
private PrintWriter gameInput;
private Tile[] board;
private TileView[] boardView;
@FXML
private Polygon tile0, tile1, tile2, tile3, tile4, tile5, tile6, tile7, tile8, tile9, tile10, tile11, tile12, tile13, tile14, tile15, tile16, tile17, tile18, tile19, tile20, tile21, tile22, tile23, tile24, tile25, tile26, tile27, tile28, tile29, tile30, tile31, tile32, tile33, tile34, tile35, tile36, tile37, tile38, tile39, tile40, tile41, tile42, tile43, tile44, tile45, tile46, tile47, tile48, tile49, tile50, tile51, tile52, tile53, tile54, tile55, tile56, tile57, tile58, tile59;
@FXML
private BorderPane mainPane;
@Override
public void initialize(URL location, ResourceBundle resources)
{
Polygon[] fxTiles = {tile0, tile1, tile2, tile3, tile4, tile5, tile6, tile7, tile8, tile9, tile10, tile11, tile12, tile13, tile14, tile15, tile16, tile17, tile18, tile19, tile20, tile21, tile22, tile23, tile24, tile25, tile26, tile27, tile28, tile29, tile30, tile31, tile32, tile33, tile34, tile35, tile36, tile37, tile38, tile39, tile40, tile41, tile42, tile43, tile44, tile45, tile46, tile47, tile48, tile49, tile50, tile51, tile52, tile53, tile54, tile55, tile56, tile57, tile58, tile59};
this.board = new Tile[fxTiles.length];
this.boardView = new TileView[fxTiles.length];
for (int i = 0; i < fxTiles.length; i++)
{
board[i] = new Tile(i, Tile.PenguinPresence.NO_PENGUIN);
boardView[i] = new TileView(fxTiles[i], board[i]);
}
this.gameState = new GameState();
try
{
this.gameProcess = new ProcessBuilder("../bin/theturk").start();
gameInput = new PrintWriter(new OutputStreamWriter(gameProcess.getOutputStream()), true);
}
catch (IOException e)
{
Alert alert = new Alert(Alert.AlertType.ERROR, "Can't run penguin program", ButtonType.OK);
alert.showAndWait();
e.printStackTrace();
System.exit(1);
}
UpdateThread upT = new UpdateThread(gameProcess, this.gameState, this.board, this.boardView);
upT.setDaemon(true);
upT.start();
//We tell the game that we will start
gameInput.print("h");
gameInput.println();
gameInput.println("0");
}
private class MyClickHandler implements EventHandler<MouseEvent>
{
@Override
public void handle(MouseEvent event)
{
Polygon poly = (Polygon) event.getSource();
poly.setFill(Color.GOLD);
}
}
private class MyHexEnteredHandler implements EventHandler<MouseEvent>
{
@Override
public void handle(MouseEvent event)
{
Polygon poly = (Polygon) event.getSource();
poly.setFill(Color.GOLD);
}
}
}
package controller;
import javafx.application.Platform;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.paint.Color;
import model.GameState;
import model.Player;
import model.Tile;
import view.TileView;
import java.io.BufferedReader;
import java.io.IOException;
......@@ -11,66 +16,63 @@ public class UpdateThread extends Thread
{
BufferedReader reader;
GameState gameState;
Plateau plateau;
Tile[] board;
TileView[] boardView;
public UpdateThread(Process program, GameState gameState, Plateau plateau)
public UpdateThread(Process program, GameState gameState, Tile[] board, TileView[] boardView)
{
this.reader = new BufferedReader(new InputStreamReader(program.getInputStream()));
this.gameState = gameState;
this.plateau = plateau;
this.board = board;
this.boardView = boardView;
}
public void run()
{
boolean running = true;
while(running)
boolean gameRunning = true;
while (gameRunning)
{
try
{
String line = reader.readLine();
System.out.println(line);
if(line == null)
running = false;
else
if (line == null)
{
gameRunning = false;
}
else if (line.contains("{")) //Line contains JSON
{
if (line.contains("{"))
//UPDATE MODEL
gameState.update(line.substring(line.indexOf("{"), line.lastIndexOf("}") + 1)); //Extract JSON string
for (int i = 0; i < board.length; i++)
{
board[i].setNbFish(gameState.getNbFish(i));
board[i].setPenguinPresence(Tile.PenguinPresence.NO_PENGUIN);
}
for (int i = 0; i < 4; i++)
{
gameState.update(line.substring(line.indexOf("{"), line.lastIndexOf("}") + 1));
Platform.runLater(() ->
{
for(Case c : plateau.getGrille())
{
c.setNbFish(gameState.getNbFish(c.getRang()));
switch (c.getNbFish())
{
case 0:
c.getCaseFX().setFill(Color.BLUE);
break;
case 1:
c.getCaseFX().setFill(Color.GREEN);
break;
case 2:
c.getCaseFX().setFill(Color.YELLOW);
break;
case 3:
c.getCaseFX().setFill(Color.RED);
break;
}
}
// TODO: 4/27/16 update GUI from state
});
board[gameState.getPenguinPos(i, Player.Red)].setPenguinPresence(Tile.PenguinPresence.RED_PENGUIN);
board[gameState.getPenguinPos(i, Player.Blue)].setPenguinPresence(Tile.PenguinPresence.BLUE_PENGUIN);
}
//UPDATE VIEW
for (int i = 0; i < boardView.length; i++)
boardView[i].updateFromModel();
}
} catch (IOException e)
}
catch (IOException e)
{
running = false;
gameRunning = false;
Platform.runLater(() ->
{
Alert alert = new Alert(Alert.AlertType.ERROR, "Error during reading from penguin program!", ButtonType.FINISH);
e.printStackTrace();
alert.showAndWait();
e.printStackTrace();
System.exit(1);
});
}
}
}
}
package main;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class Main extends Application
{
public static void main(String[] args)
{
launch(args);
}
@Override
public void start(Stage primaryStage)
{
try
{
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("../view/view.fxml"));
BorderPane root = (BorderPane) loader.load();
Scene scene = new Scene(root, 1024, 680);
primaryStage.setScene(scene);
primaryStage.show();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
import org.json.*;
package model;
import org.json.JSONArray;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.Map;
public class GameState
{
long[] fish;
boolean can_play_red, can_play_blue;
long[] fish; //Array of three bitboards: one for every fish value
boolean can_play_red, can_play_blue; //If the red(blue) player can play or if it has no moves left
Player current_player;
Map<Player, int[]> penguins;
Map<Player, Integer> score;
Map<Player, int[]> penguins; //For every player, the list of his penguins
Map<Player, Integer> score; //Score of every player
public GameState()
{
......@@ -22,9 +25,9 @@ public class GameState
score.put(Player.Blue, 0);
}
public void update (String jsonString){
public void update(String jsonString)
{
//System.out.println(jsonString);
JSONObject json = new JSONObject(jsonString);
can_play_red = json.getJSONObject("can_play").getBoolean("red");
can_play_blue = json.getJSONObject("can_play").getBoolean("blue");
......@@ -35,12 +38,14 @@ public class GameState
score.put(Player.Red, json.getJSONObject("score").getInt("red"));
score.put(Player.Blue, json.getJSONObject("score").getInt("blue"));
JSONArray jsonPeng = json.getJSONObject("penguins").getJSONArray("red");
for(int i = 0; i < jsonPeng.length(); i++)
for (int i = 0; i < jsonPeng.length(); i++)
penguins.get(Player.Red)[i] = jsonPeng.getInt(i);
jsonPeng = json.getJSONObject("penguins").getJSONArray("blue");
for(int i = 0; i < jsonPeng.length(); i++)
for (int i = 0; i < jsonPeng.length(); i++)
penguins.get(Player.Blue)[i] = jsonPeng.getInt(i);
};
}
;
/**
* @param tileNb The number of the tile we want to know the value of
......@@ -48,7 +53,7 @@ public class GameState
*/
public int getNbFish(int tileNb)
{
if(((fish[0] >>> tileNb) & 1) == 1)
if (((fish[0] >>> tileNb) & 1) == 1)
return 1;
else if (((fish[1] >>> tileNb) & 1) == 1)
return 2;
......@@ -57,18 +62,18 @@ public class GameState
return 0;
}
public int getPenguinPos (int i, Player player)
public int getPenguinPos(int i, Player player)
{
//TODO
return -1;
return 0;
}
public boolean isCan_play_red()
public boolean getCan_play_red()
{
return can_play_red;
}
public boolean isCan_play_blue()
public boolean getCan_play_blue()
{
return can_play_blue;
}
......@@ -83,9 +88,4 @@ public class GameState
return score.get(player);
}
enum Player
{
Red,Blue;
}
}
package model;
public enum Player
{
Red, Blue
}
package model;
public class Tile
{
private int number; //model.Tile number (bottom right = 0, top left = 59, ascending from right to left)
private int nbFish; //Number of fish on the tile
private PenguinPresence penguinPresence; //If there is a penguin on this tile
public Tile(int number, int nbFish, PenguinPresence penguinPresence)
{
this.number = number;
this.nbFish = nbFish;
this.penguinPresence = penguinPresence;
}
public Tile(int number, PenguinPresence penguinPresence)
{
this(number, 0, penguinPresence);
}
public int getNumber() { return number; }
public int getNbFish() { return nbFish; }
public void setNbFish(int nbFish) { this.nbFish = nbFish; }
public PenguinPresence getPenguinPresence() { return penguinPresence; }
public void setPenguinPresence(PenguinPresence penguinPresence) { this.penguinPresence = penguinPresence; }
public enum PenguinPresence
{
NO_PENGUIN, RED_PENGUIN, BLUE_PENGUIN;
}
}
package view;
import javafx.scene.paint.Color;
import javafx.scene.shape.Polygon;
import model.Tile;
/**
* Class that makes the association between a tile from the model and its representation
*/
public class TileView
{
private Polygon fxTile;
private Tile modelTile;
public TileView(Polygon fxTile, Tile modelTile)
{
this.fxTile = fxTile;
this.modelTile = modelTile;
}
/**
* Tell the view to update according to the model
*/
public void updateFromModel()
{
//TODO: Better tile representation
//FISH NUMBER
switch (modelTile.getNbFish())
{
case 0:
fxTile.setFill(Color.LIGHTBLUE);
break;
case 1:
fxTile.setFill(Color.GREENYELLOW);
break;
case 2:
fxTile.setFill(Color.GREEN);
break;
case 3:
fxTile.setFill(Color.DARKGREEN);
break;
}
//PENGUIN
if (modelTile.getPenguinPresence().equals(Tile.PenguinPresence.RED_PENGUIN))
fxTile.setFill(Color.RED);
else if (modelTile.getPenguinPresence().equals(Tile.PenguinPresence.BLUE_PENGUIN))
fxTile.setFill(Color.BLUE);
}
}
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment