Skip to content
Snippets Groups Projects
Commit 624828aa authored by TRAVERS Corentin's avatar TRAVERS Corentin
Browse files

Initial commit

parents
No related branches found
No related tags found
No related merge requests found
Showing
with 933 additions and 0 deletions
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store
/*
* This file was generated by the Gradle 'init' task.
*
* This generated file contains a sample Java application project to get you started.
* For more details take a look at the 'Building Java & JVM projects' chapter in the Gradle
* User Manual available at https://docs.gradle.org/7.2/userguide/building_java_projects.html
*/
plugins {
// Apply the application plugin to add support for building a CLI application in Java.
id 'application'
id "org.openjfx.javafxplugin" version "0.0.13"
}
javafx {
version = "17"
modules = [ 'javafx.controls', 'javafx.fxml' ]
}
repositories {
// Use Maven Central for resolving dependencies.
mavenCentral()
}
dependencies {
// Use JUnit Jupiter for testing.
testImplementation 'org.junit.jupiter:junit-jupiter:5.7.2',
'org.assertj:assertj-core:3.23.1'
}
application {
// Define the main class for the application.
mainClass = 'main.App'
}
tasks.named('test') {
// Use JUnit Platform for unit tests.
useJUnitPlatform()
}
/*
* This file was generated by the Gradle 'init' task.
*
* This generated file contains a sample Java application project to get you started.
* For more details take a look at the 'Building Java & JVM projects' chapter in the Gradle
* User Manual available at https://docs.gradle.org/7.2/userguide/building_java_projects.html
*/
plugins {
// Apply the application plugin to add support for building a CLI application in Java.
id 'application'
id "org.openjfx.javafxplugin" version "0.0.10"
}
javafx {
version = "17"
modules = [ 'javafx.controls', 'javafx.fxml' ]
}
repositories {
// Use Maven Central for resolving dependencies.
mavenCentral()
}
dependencies {
// Use JUnit Jupiter for testing.
testImplementation 'org.junit.jupiter:junit-jupiter:5.7.2',
'org.assertj:assertj-core:3.23.1'
// This dependency is used by the application.
implementation 'com.google.guava:guava:30.1.1-jre'
}
application {
// Define the main class for the application.
mainClass = 'main.App'
}
tasks.named('test') {
// Use JUnit Platform for unit tests.
useJUnitPlatform()
}
package controller;
import javafx.animation.PauseTransition;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.paint.Color;
import javafx.util.Duration;
import model.*;
import view.MatrixPane;
import java.util.List;
import java.util.Random;
public class GameController {
public static final Color COLOR_ONE = Color.RED;
public static final Color COLOR_TWO = Color.BLUE;
public static final Color COLOR_THREE = Color.YELLOW;
public static final Color COLOR_FOUR = Color.GREEN;
private static final List<Color> availableColors = List.of(COLOR_ONE, COLOR_TWO, COLOR_THREE, COLOR_FOUR);
public static final double PAUSE_MILLISECONDS = 400;
private final PauseTransition pause = new PauseTransition(Duration.millis(PAUSE_MILLISECONDS));
private final Random random = new Random();
@FXML
MatrixPane matrixPane;
@FXML
private Label scoreLabel;
@FXML
private Label tourLabel;
private FloodGame game;
public void initialize(){
this.game = new FloodGame(
matrixPane.getGrid().getNumberOfColumns() * matrixPane.getGrid().getNumberOfRows());
setPlayerHuman();
matrixPane.setGameController(this);
setScoreLabelTextProperty();
setTourLabelTextProperty();
addTurnListener();
setPauseAnimation();
}
private void addTurnListener(){
game.getTurnProperty().addListener((observable, oldValue, newValue) -> playComputerTurn());
}
private void colorGrid(ColorGenerator colorGenerator){
// TODO
// matrixPane.getGrid().color(colorGenerator);
}
@FXML
public void fillGridUniform() {
// TODO uncomment:
// colorGrid(new UniformColorGenerator(COLOR_ONE));
}
@FXML
public void fillGridRandom() {
// TODO uncomment
// colorGrid(new RandomColorGenerator(availableColors,random));
}
@FXML
public void fillGridDistinct() {
// TODO uncomment
// fillGridUniform();
// colorGrid(new DistinctColorGenerator(COLOR_ONE,List.of(COLOR_THREE, COLOR_FOUR)));
}
@FXML
public void fillGridCycle() {
// TODO uncomment
// colorGrid(new CyclingColorGenerator(availableColors));
}
@FXML
public void fillGridUniformExceptOne() {
// TODO uncomment
// colorGrid(new UniformExceptOneColorGenerator(COLOR_ONE,COLOR_TWO));
}
private void playComputerTurn(){
// TODO
// uncomment
// if (!game.hasEnded() && !game.isHumanTurn()){
// ComputerPlayer player = ((ComputerPlayer) game.getPlayer());
// Flooder.flood(player.getStartCell(), player.play());
// setScoreLabelTextProperty();
// pause.play();
// }
}
public void playHumanTurn(Color color){
// TODO
// uncomment
// if(!game.hasEnded() && game.isHumanTurn()){
// Flooder.flood(game.getPlayer().getStartCell(), color);
// setScoreLabelTextProperty();
// game.incrementTurn();
//}
}
private void setPauseAnimation(){
pause.setOnFinished(e -> game.incrementTurn());
}
private void setTourLabelTextProperty() {
tourLabel.textProperty().bind(game.getTurnProperty().asString());
}
private void setScoreLabelTextProperty() {
// TODO
// uncomment
// Player player = game.getPlayer();
// scoreLabel.textProperty().setValue(Integer.toString(game.getPlayerScore(player)));
}
@FXML
public void startGame(){
if(game.getTurn() != 0) game.resetTurn();
setScoreLabelTextProperty();
playComputerTurn();
}
private Cell getGridStartCell(){
return matrixPane.getGrid().getCell(0,0);
}
@FXML
public void setPlayerHuman(){
// TODO
// game.setPlayer(new HumanPlayer("human", getGridStartCell()));
}
@FXML
public void setPlayerRandom() {
// TODO
// Player player = ... instantiate a ComputerPlayer named "random" that follows the random strategy
// game.setPlayer(player);
}
@FXML
public void setPlayerRobin() {
// TODO
// Player player = ... instantiate a ComputerPlayer named "cyclic" that follows the cyclic strategy
// game.setPlayer(player);
}
@FXML
public void setPlayerRandomWalk() {
// TODO
// Player player = ... instantiate a ComputerPlayer named "walker" that follows the random walk strategy
// game.setPlayer(player);
}
@FXML
public void setPlayerGreedy() {
// TODO
// Player player = ... instantiate a ComputerPlayer named "greedy" that follows the greedy strategy
// game.setPlayer(player);
}
}
/*
* This Java source file was generated by the Gradle 'init' task.
*/
package main;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
import java.io.IOException;
public class App extends Application {
private Stage primaryStage;
private AnchorPane rootLayout;
public void start(Stage primaryStage){
this.primaryStage = primaryStage;
this.primaryStage.setTitle("Flooding");
initRootLayout();
}
public void initRootLayout() {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/view/MatrixPane.fxml"));
try {
rootLayout = loader.load();
} catch (IOException e) {
e.printStackTrace();
}
Scene scene = new Scene(rootLayout);
primaryStage.setScene(scene);
loader.getController();
primaryStage.show();
}
}
package model;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.paint.Color;
/**
* This class provides a partial implementation of the {@code Cell} interface.
*
*/
public abstract class AbstractCell implements Cell{
static final Color DEFAULT_CELL_COLOR = Color.LIGHTGRAY;
private final ObjectProperty<Color> colorProperty = new SimpleObjectProperty<>(DEFAULT_CELL_COLOR);
public AbstractCell(){}
/**
* The constructor of {@code AbstractCell}
* @param color the color of the cell
*/
public AbstractCell(Color color){
setColor(color);
}
@Override
public void setColor(Color color){
colorProperty.setValue(color);
}
@Override
public Color getColor(){
return colorProperty.getValue();
}
@Override
public ObjectProperty<Color> getColorProperty(){
return colorProperty;
}
}
package model;
public abstract class AbstractPlayer implements Player{
private String name;
private final Cell startCell;
public AbstractPlayer(String name, Cell startCell){
setName(name);
this.startCell = startCell;
}
public AbstractPlayer(Cell startCell){
this("player", startCell);
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public Cell getStartCell(){
return this.startCell;
}
}
package model;
import javafx.beans.property.Property;
import javafx.scene.paint.Color;
import java.util.Iterator;
import java.util.List;
public interface Cell {
/**
* Change the color of this {@code Cell} to {@code color}.
* @param color the color this {@code Cell} is changed to.
*/
void setColor(Color color);
/**
* Return the color of this {@code Cell}.
* @return the current color of this {@code cell}.
*/
Color getColor();
/**
* A cell is placed somewhere on a grid. Its neighbours thus depend on the underlying grid.
*
* @return the list of cell that are neighbours of this{@code Cell}.
*/
List<Cell> getNeighbours();
/**
* Update the list of neighbours of this {@code Cell}.
* @param cells a list of cells that are the neighbours of this {@code cell}
* int the underlying grid.
*/
void setNeighbours(List<Cell> cells);
/**
* Returns this {@link Cell}'s property.
*
* @return this {@link Cell}'s property
*/
Property<Color> getColorProperty();
}
package model;
import javafx.scene.paint.Color;
public interface ColorGenerator {
Color nextColor(Cell cell);
}
package model;
import javafx.beans.property.SimpleIntegerProperty;
import java.util.Arrays;
import java.util.List;
public class FloodGame {
private Player player;
private final int totalFloodingArea;
private final SimpleIntegerProperty turn = new SimpleIntegerProperty(0);
public FloodGame(int totalFloodingArea){
this.totalFloodingArea = totalFloodingArea;
}
public void setPlayer(Player player){
this.player = player;
}
public Player getPlayer(){
return player;
}
public void setTurn(int value){
turn.setValue(value);
}
public int getTurn(){
return turn.getValue();
}
public void resetTurn() {
setTurn(0);
}
public SimpleIntegerProperty getTurnProperty(){
return turn;
}
public void incrementTurn(){
setTurn(getTurn()+1);
}
public boolean isHumanTurn(){
return getPlayer().isHuman();
}
public int getPlayerScore(Player player) {
// TODO
return 0;
}
public boolean hasWon(Player player){
// TODO
return false;
}
public boolean hasEnded(){
// TODO
return false;
}
}
package model;
import javafx.beans.property.Property;
import javafx.scene.paint.Color;
import java.util.List;
public class GrayCell extends AbstractCell{
public static final Cell GRAY_CELL = new GrayCell();
/**
* A cell is placed somewhere on a grid. Its neighbours thus depend on the underlying grid.
*
* @return the list of cell that are neighbours of this{@code Cell}.
*/
@Override
public List<Cell> getNeighbours() {
return null;
}
/**
* Update the list of neighbours of this {@code Cell}.
*
* @param cells a list of cells that are the neighbours of this {@code cell}
* int the underlying grid.
*/
@Override
public void setNeighbours(List<Cell> cells) {
}
@Override
public void setColor(Color color){
}
}
package model;
public class GrayGrid implements Grid{
private final int numberOfRows;
private final int numnberOfColumns;
public GrayGrid(int numberOfRows, int numberOfColumns){
this.numberOfRows = numberOfRows;
this.numnberOfColumns = numberOfColumns;
}
/**
* Return the cell located at the given coordinates in the grid.
*
* @param row the row of the returned the cell
* @param column the column of the returned cell
* @return the cell located in row {@code row} and in column {@code column}
*/
@Override
public Cell getCell(int row, int column) {
return GrayCell.GRAY_CELL;
}
/**
* Return the number of rows of this {@code Grid}
*
* @return the number of rows of this {@code Grid}
*/
@Override
public int getNumberOfRows() {
return numberOfRows;
}
/**
* Return the number of columns of this {@code Grid}
*
* @return the number of columns of this {@code Grid}
*/
@Override
public int getNumberOfColumns() {
return numnberOfColumns;
}
}
package model;
public interface Grid {
/**
* Return the cell located at the given coordinates in the grid.
* @param row the row of the returned the cell
* @param column the column of the returned cell
* @return the cell located in row {@code row} and in column {@code column}
*/
Cell getCell(int row, int column);
/**
* Return the number of rows of this {@code Grid}
* @return the number of rows of this {@code Grid}
*/
int getNumberOfRows();
/**
* Return the number of columns of this {@code Grid}
* @return the number of columns of this {@code Grid}
*/
int getNumberOfColumns();
/**
* Color every cell of this {@code Grid} using the provided {@code ColorGenerator}
* @param colorGenerator the generator used to determine the color of each cell.
* The new color of {@code cell} is obtained by calling the method {@code nextColor}
*/
}
package model;
import javafx.scene.paint.Color;
public interface PlayStrategy {
Color play(Cell startCell);
}
package model;
public interface Player {
boolean isHuman();
}
package model;
import javafx.scene.paint.Color;
import java.util.List;
public class RobinStrategy implements PlayStrategy {
private final List<Color> availableColors;
private int index = 0;
public RobinStrategy(List<Color> availableColors) {
this.availableColors = availableColors;
}
@Override
public Color play(Cell startCell) {
index = (index + 1) % availableColors.size();
return availableColors.get(index);
}
}
package model;
import javafx.scene.paint.Color;
import java.util.Iterator;
import java.util.List;
public class SquareCell extends AbstractCell{
List<Cell> neighbours;
/**
* A cell is placed somewhere on a grid. Its neighbours thus depend on the underlying grid.
*
* @return the list of cell that are neighbours of this{@code Cell}.
*/
@Override
public List<Cell> getNeighbours() {
return null;
}
/**
* Update the list of neighbours of this {@code Cell}.
*
* @param cells a list of cells that are the neighbours of this {@code cell}
* int the underlying grid.
*/
@Override
public void setNeighbours(List<Cell> cells) {
}
}
package util;
import java.util.NoSuchElementException;
import java.util.Set;
public class SetUtil {
public static <T> T anyElement(Set<T> elements){
return elements.stream().findAny().orElseThrow(NoSuchElementException::new);
}
}
package view;
import controller.GameController;
import javafx.animation.FillTransition;
import javafx.beans.NamedArg;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.util.Duration;
import model.Cell;
import model.GrayGrid;
import model.Grid;
public class MatrixPane extends GridPane {
public final double tileWidth;
public final double tileHeight;
private final Integer numberOfColumns;
private final Integer numberOfRows;
private final Grid cellGrid;
private GameController controller;
public MatrixPane(@NamedArg("tileWidth") Double tileWidth,
@NamedArg("tileHeight") Double tileHeight,
@NamedArg("numberOfColumns") Integer numberOfColumns,
@NamedArg("numberOfRows") Integer numberOfRows) {
this.tileWidth = tileWidth;
this.tileHeight = tileHeight;
this.numberOfColumns = numberOfColumns;
this.numberOfRows = numberOfRows;
// TODO replace by new ArrayGrid(numberOfRows, numberOfColumns)
cellGrid = new GrayGrid(numberOfRows, numberOfColumns);
initMatrix();
}
public void setGameController(GameController controller){
this.controller = controller;
}
private void initMatrix() {
for (int rowIndex= 0; rowIndex < numberOfRows ; rowIndex++) {
for (int columnIndex = 0; columnIndex < numberOfColumns; columnIndex++) {
addCellRectangle(cellGrid.getCell(rowIndex,columnIndex),rowIndex,columnIndex);
}
}
}
public Grid getGrid(){
return cellGrid;
}
private void addCellRectangle(Cell cell, int rowIndex, int columnIndex) {
Rectangle rectangleCell = new Rectangle(tileWidth,tileHeight);
rectangleCell.setStyle("-fx-stroke: black; -fx-stroke-width: 1");
addStatePropertyListener(cell, rectangleCell);
rectangleCell.setFill(cell.getColor());
addClickEventHandler(cell, rectangleCell);
add(rectangleCell, columnIndex, rowIndex);
}
private void addStatePropertyListener(Cell cell, Rectangle cellRectangle) {
cell.getColorProperty().addListener((observable, oldValue, newValue) ->
updateFill(cellRectangle, oldValue, newValue));
}
private void updateFill(Rectangle cellRectangle,Color cellColor, Color newCellColor) {
new FillTransition(Duration.millis(35),cellRectangle,cellColor,newCellColor).play();
}
private void addClickEventHandler(Cell cell, Rectangle cellRectangle) {
cellRectangle.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> controller.playHumanTurn(cell.getColor()));
}
}
.background {
-fx-background-color: #1d1d1d;
}
.label {
-fx-font-size: 11pt;
-fx-font-family: "Segoe UI Semibold";
-fx-text-fill: white;
-fx-opacity: 0.6;
}
.label-bright {
-fx-font-size: 11pt;
-fx-font-family: "Segoe UI Semibold";
-fx-text-fill: white;
-fx-opacity: 1;
}
.label-header {
-fx-font-size: 32pt;
-fx-font-family: "Segoe UI Light";
-fx-text-fill: white;
-fx-opacity: 1;
}
.table-view {
-fx-base: #1d1d1d;
-fx-control-inner-background: #1d1d1d;
-fx-background-color: #1d1d1d;
-fx-table-cell-border-color: transparent;
-fx-table-header-border-color: transparent;
-fx-padding: 5;
}
.table-view .column-header-background {
-fx-background-color: transparent;
}
.table-view .column-header, .table-view .filler {
-fx-border-width: 0 0 1 0;
-fx-background-color: transparent;
-fx-border-color:
transparent
transparent
derive(-fx-base, 80%)
transparent;
-fx-border-insets: 0 10 1 0;
}
.table-view .column-header .label {
-fx-font-size: 20pt;
-fx-font-family: "Segoe UI Light";
-fx-text-fill: white;
-fx-alignment: center-left;
-fx-opacity: 1;
}
.table-view:focused .table-row-cell:filled:focused:selected {
-fx-background-color: -fx-focus-color;
}
.split-pane:horizontal > .split-pane-divider {
-fx-border-color: transparent #1d1d1d transparent #1d1d1d;
-fx-background-color: transparent, derive(#1d1d1d,20%);
}
.split-pane {
-fx-padding: 1 0 0 0;
}
.menu-bar {
-fx-background-color: derive(#1d1d1d,20%);
}
.context-menu {
-fx-background-color: derive(#1d1d1d,50%);
}
.menu-bar .label {
-fx-font-size: 14pt;
-fx-font-family: "Segoe UI Light";
-fx-text-fill: white;
-fx-opacity: 0.9;
}
.menu .left-container {
-fx-background-color: black;
}
.text-field {
-fx-font-size: 12pt;
-fx-font-family: "Segoe UI Semibold";
}
/*
* Metro style Push Button
* Author: Pedro Duque Vieira
* http://pixelduke.wordpress.com/2012/10/23/jmetro-windows-8-controls-on-java/
*/
.button {
-fx-padding: 5 22 5 22;
-fx-border-color: #e2e2e2;
-fx-border-width: 2;
-fx-background-radius: 0;
-fx-background-color: #1d1d1d;
-fx-font-family: "Segoe UI", Helvetica, Arial, sans-serif;
-fx-font-size: 11pt;
-fx-text-fill: #d8d8d8;
-fx-background-insets: 0 0 0 0, 0, 1, 2;
}
.button:hover {
-fx-background-color: #3a3a3a;
}
.button:pressed, .button:default:hover:pressed {
-fx-background-color: white;
-fx-text-fill: #1d1d1d;
}
.button:focused {
-fx-border-color: white, white;
-fx-border-width: 1, 1;
-fx-border-style: solid;
-fx-border-radius: 0, 0;
-fx-border-insets: 1 1 1 1, 0;
}
.button:disabled, .button:default:disabled {
-fx-opacity: 0.4;
-fx-background-color: #1d1d1d;
-fx-text-fill: white;
}
.button:default {
-fx-background-color: -fx-focus-color;
-fx-text-fill: #ffffff;
}
.button:default:hover {
-fx-background-color: derive(-fx-focus-color,30%);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment