first commit
This commit is contained in:
12
Fall 2017/SE 1011/Lab5/JavaFxApplication.iml
Normal file
12
Fall 2017/SE 1011/Lab5/JavaFxApplication.iml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
11
Fall 2017/SE 1011/Lab5/Lab5.iml
Normal file
11
Fall 2017/SE 1011/Lab5/Lab5.iml
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
205
Fall 2017/SE 1011/Lab5/src/barnestr/Cell.java
Normal file
205
Fall 2017/SE 1011/Lab5/src/barnestr/Cell.java
Normal file
@@ -0,0 +1,205 @@
|
||||
package barnestr;
|
||||
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.shape.Rectangle;
|
||||
|
||||
/**
|
||||
* This Class represents a cell within John Conway's Game of Life.
|
||||
* The cell is arranged in a 2D grid and has 8 neighbors (other Cells).
|
||||
* It contains a Rectangle that is used to visually represent the cell in the JavaFX framework.
|
||||
*
|
||||
* @author Derek Riley
|
||||
* @version 2018AY
|
||||
*/
|
||||
public class Cell extends Rectangle {
|
||||
|
||||
/**
|
||||
* This constant represents the scale (size) of the grid in number of pixels
|
||||
*/
|
||||
public static final int SCALE = 10;
|
||||
|
||||
/**
|
||||
* This constant represents the color the alive cells are painted
|
||||
*/
|
||||
public static final Color ALIVE_COLOR = Color.GREEN;
|
||||
|
||||
/**
|
||||
* This constant represents the color the dead cells are painted
|
||||
*/
|
||||
public static final Color DEAD_COLOR = Color.BLACK;
|
||||
|
||||
/**
|
||||
* This variable represents whether the cell is currently alive
|
||||
*/
|
||||
private boolean alive;
|
||||
|
||||
/**
|
||||
* This variable represents whether the cell will be alive in the next time tick
|
||||
*/
|
||||
private boolean willBeAlive;
|
||||
|
||||
/**
|
||||
* These variables represent the 8 neighbors of the cell
|
||||
*/
|
||||
private Cell[][] neighbors = new Cell[3][3];
|
||||
private static final int ABOVE = 0;
|
||||
private static final int MIDDLE = 1;
|
||||
private static final int BELOW = 2;
|
||||
private static final int LEFT = 0;
|
||||
private static final int CENTER = 1;
|
||||
private static final int RIGHT = 2;
|
||||
|
||||
/**
|
||||
* This method returns whether the cell is currently alive or not
|
||||
*
|
||||
* @return true if the cell is currently alive or false if not
|
||||
*/
|
||||
public boolean isAlive() {
|
||||
return alive;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the cell to be currently alive or not
|
||||
*
|
||||
* @param alive true if the cell is alive or false if not
|
||||
*/
|
||||
public void setAlive(boolean alive) {
|
||||
this.alive = alive;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the neighbor centered above the current cell
|
||||
*
|
||||
* @param neighborAboveCenter the cell above the center.
|
||||
*/
|
||||
public void setNeighborAboveCenter(Cell neighborAboveCenter) {
|
||||
neighbors[ABOVE][CENTER] = neighborAboveCenter;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the neighbor above and to the right of the current cell
|
||||
*
|
||||
* @param neighborAboveRight the cell above and to the right.
|
||||
*/
|
||||
public void setNeighborAboveRight(Cell neighborAboveRight) {
|
||||
neighbors[ABOVE][RIGHT] = neighborAboveRight;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the neighbor above and to the left of the current cell
|
||||
*
|
||||
* @param neighborAboveLeft the cell above and to the left.
|
||||
*/
|
||||
public void setNeighborAboveLeft(Cell neighborAboveLeft) {
|
||||
neighbors[ABOVE][LEFT] = neighborAboveLeft;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the neighbor at the same vertical level but to the right of the current cell
|
||||
*
|
||||
* @param neighborMiddleRight the cell to the right/middle
|
||||
*/
|
||||
public void setNeighborMiddleRight(Cell neighborMiddleRight) {
|
||||
neighbors[MIDDLE][RIGHT] = neighborMiddleRight;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the neighbor at the same vertical level but to the left of the current cell
|
||||
*
|
||||
* @param neighborMiddleLeft the cell to the left/middle row
|
||||
*/
|
||||
public void setNeighborMiddleLeft(Cell neighborMiddleLeft) {
|
||||
neighbors[MIDDLE][LEFT] = neighborMiddleLeft;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the neighbor below and centered of the current cell
|
||||
*
|
||||
* @param neighborBelowCenter the cell below the bottom row in the middle
|
||||
*/
|
||||
public void setNeighborBelowCenter(Cell neighborBelowCenter) {
|
||||
neighbors[BELOW][CENTER] = neighborBelowCenter;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the neighbor below and to the right of the current cell
|
||||
*
|
||||
* @param neighborBelowRight the cell below the bottom row to the right
|
||||
*/
|
||||
public void setNeighborBelowRight(Cell neighborBelowRight) {
|
||||
neighbors[BELOW][RIGHT] = neighborBelowRight;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the neighbor below and to the left of the current cell
|
||||
*
|
||||
* @param neighborBelowLeft the cell below the bottom row to the left
|
||||
*/
|
||||
public void setNeighborBelowLeft(Cell neighborBelowLeft) {
|
||||
neighbors[BELOW][LEFT] = neighborBelowLeft;
|
||||
}
|
||||
|
||||
/**
|
||||
* This constructor creates the cell at the given position within the grid
|
||||
*
|
||||
* @param xPosition the x-Position within the grid
|
||||
* @param yPosition the y-Position within the grid
|
||||
*/
|
||||
public Cell(double xPosition, double yPosition) {
|
||||
this.setLayoutX(xPosition * SCALE);
|
||||
this.setLayoutY(yPosition * SCALE);
|
||||
this.setWidth(SCALE);
|
||||
this.setHeight(SCALE);
|
||||
this.alive = false;
|
||||
this.willBeAlive = false;
|
||||
updateColors();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method calculates whether the cell will be alive during the next tick.
|
||||
*/
|
||||
public void determineNextTick() {
|
||||
int neighborsAlive = 0;
|
||||
for (Cell[] row : neighbors) {
|
||||
for (Cell neighbor : row) {
|
||||
if (neighbor != null && neighbor.isAlive()) {
|
||||
++neighborsAlive;
|
||||
}
|
||||
}
|
||||
}
|
||||
runLifeRules(neighborsAlive);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method updates the cell's life status based on the predicted life status in willBeAlive.
|
||||
* The cell's Rectangle color is also updated.
|
||||
*/
|
||||
public void updateTick() {
|
||||
alive = willBeAlive;
|
||||
updateColors();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method updates the color of the cell based on the ALIVE_COLOR or DEAD_COLOR
|
||||
*/
|
||||
public void updateColors() {
|
||||
if (alive) {
|
||||
this.setFill(ALIVE_COLOR);
|
||||
} else {
|
||||
this.setFill(DEAD_COLOR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method defines the life rules based on the number of neighbors alive
|
||||
*
|
||||
* @param neighborsAlive this is the number of neighbors that are alive for the current cell
|
||||
*/
|
||||
private void runLifeRules(int neighborsAlive) {
|
||||
if (neighborsAlive == 3) {
|
||||
willBeAlive = true;
|
||||
} else {
|
||||
willBeAlive = (neighborsAlive >= 2) && (neighborsAlive <= 3) && alive;
|
||||
}
|
||||
}
|
||||
}
|
||||
69
Fall 2017/SE 1011/Lab5/src/barnestr/Controller.java
Normal file
69
Fall 2017/SE 1011/Lab5/src/barnestr/Controller.java
Normal file
@@ -0,0 +1,69 @@
|
||||
package barnestr;
|
||||
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* This class is the controller for lab5.fxml
|
||||
*/
|
||||
public class Controller implements Initializable {
|
||||
|
||||
/**
|
||||
* Declares the LifeGrid called game
|
||||
*/
|
||||
LifeGrid game;
|
||||
|
||||
@FXML
|
||||
private BorderPane gamePane;
|
||||
|
||||
@FXML
|
||||
private HBox buttons;
|
||||
|
||||
@FXML
|
||||
private Button nextButton;
|
||||
|
||||
@FXML
|
||||
private Button randomizeButton;
|
||||
|
||||
@FXML
|
||||
private Label aliveDeadCount;
|
||||
|
||||
@FXML
|
||||
void getClicked(MouseEvent event) {
|
||||
game.setState(event);
|
||||
labelUpdater();
|
||||
}
|
||||
|
||||
@FXML
|
||||
void iterate(ActionEvent event) {
|
||||
game.iterate();
|
||||
labelUpdater();
|
||||
}
|
||||
|
||||
@FXML
|
||||
void randomize(ActionEvent event) {
|
||||
game.randomize();
|
||||
labelUpdater();
|
||||
}
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
assert gamePane != null :"fx:id=\"gamePane\" was not injected: check your FXML file 'game.fxml'.";
|
||||
game = new LifeGrid(gamePane);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the label that displays amount of dead or alive cells.
|
||||
*/
|
||||
private void labelUpdater() {
|
||||
aliveDeadCount.setText("Alive: "+ game.aliveCells +" Dead: " + game.deadCells);
|
||||
}
|
||||
}
|
||||
|
||||
37
Fall 2017/SE 1011/Lab5/src/barnestr/Lab5.java
Normal file
37
Fall 2017/SE 1011/Lab5/src/barnestr/Lab5.java
Normal file
@@ -0,0 +1,37 @@
|
||||
package barnestr;
|
||||
|
||||
import javafx.application.Application;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
/**
|
||||
* This class implements the lab5.FXML into the root scene and launches the application window.
|
||||
* @author barnestr
|
||||
* @version
|
||||
*/
|
||||
public class Lab5 extends Application {
|
||||
|
||||
/**
|
||||
* Launches the application
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
launch(args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the primary stage.
|
||||
* @param primaryStage
|
||||
*/
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception{
|
||||
|
||||
Parent root = FXMLLoader.load(getClass().getResource("lab5.fxml"));
|
||||
primaryStage.setTitle("Game of Life");
|
||||
primaryStage.setScene(new Scene(root, 700,700));
|
||||
primaryStage.show();
|
||||
|
||||
}
|
||||
}
|
||||
164
Fall 2017/SE 1011/Lab5/src/barnestr/LifeGrid.java
Normal file
164
Fall 2017/SE 1011/Lab5/src/barnestr/LifeGrid.java
Normal file
@@ -0,0 +1,164 @@
|
||||
package barnestr;
|
||||
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.layout.Pane;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This class implements the grid of cells used to model Conway's Game of Life.
|
||||
*
|
||||
* @author Derek Riley
|
||||
* @version 2018AY
|
||||
*/
|
||||
public class LifeGrid {
|
||||
|
||||
private static final double ALIVE_CHANCE = 0.5;
|
||||
|
||||
/**
|
||||
* This instance variable stores the grid of Cells
|
||||
*/
|
||||
private List<List<Cell>> cells;
|
||||
|
||||
public int aliveCells = 0;
|
||||
public int deadCells = 0;
|
||||
|
||||
/**
|
||||
* This constructor builds a LifeGrid using the size of the Pane passed and the scale of the cells
|
||||
*
|
||||
* @param gamePane viewing pane
|
||||
*/
|
||||
public LifeGrid(Pane gamePane) {
|
||||
final int numberOfCellsWide = (int) gamePane.getPrefWidth() / Cell.SCALE;
|
||||
final int numberOfCellsHigh = (int) gamePane.getPrefHeight() / Cell.SCALE;
|
||||
cells = new ArrayList<>();
|
||||
|
||||
//initialize the two dimensional ArrayList
|
||||
for (int i = 0; i < numberOfCellsHigh; i++) {
|
||||
cells.add(new ArrayList<>());
|
||||
}
|
||||
|
||||
//create cells
|
||||
for (int i = 0; i < numberOfCellsHigh; i++) { // yPosition
|
||||
for (int j = 0; j < numberOfCellsWide; j++) { // xPosition
|
||||
cells.get(i).add(new Cell(j, i));
|
||||
}
|
||||
}
|
||||
|
||||
//set neighbors for all cells
|
||||
for (int i = 0; i < numberOfCellsHigh; i++) { // yPosition
|
||||
for (int j = 0; j < numberOfCellsWide; j++) { // xPosition
|
||||
if (i > 0) {
|
||||
if (j > 0) {
|
||||
cells.get(i).get(j).setNeighborAboveLeft(cells.get(i - 1).get(j - 1));
|
||||
}
|
||||
cells.get(i).get(j).setNeighborAboveCenter(cells.get(i - 1).get(j));
|
||||
if (j < numberOfCellsWide - 1) {
|
||||
cells.get(i).get(j).setNeighborAboveRight(cells.get(i - 1).get(j + 1));
|
||||
}
|
||||
}
|
||||
if (j > 0) {
|
||||
cells.get(i).get(j).setNeighborMiddleLeft(cells.get(i).get(j - 1));
|
||||
}
|
||||
if (j < numberOfCellsWide - 1) {
|
||||
cells.get(i).get(j).setNeighborMiddleRight(cells.get(i).get(j + 1));
|
||||
}
|
||||
if (i < numberOfCellsHigh - 1) { // bottom boarder elements
|
||||
if (j > 0) {
|
||||
cells.get(i).get(j).setNeighborBelowLeft(cells.get(i + 1).get(j - 1));
|
||||
}
|
||||
cells.get(i).get(j).setNeighborBelowCenter(cells.get(i + 1).get(j));
|
||||
if (j < numberOfCellsWide - 1) {
|
||||
cells.get(i).get(j).setNeighborBelowRight(cells.get(i + 1).get(j + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
initialize(gamePane);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method randomizes the life and death attributes of all cells in the cells.
|
||||
* Cells have a 50% chance of being alive or dead.
|
||||
*/
|
||||
public void randomize() {
|
||||
aliveCells = 0;
|
||||
deadCells = 0;
|
||||
for (List<Cell> row : cells) {
|
||||
for (Cell cell : row) {
|
||||
cell.setAlive(Math.random() < ALIVE_CHANCE);
|
||||
cell.updateColors();
|
||||
if (cell.isAlive()) {
|
||||
aliveCells++;
|
||||
} else {
|
||||
deadCells++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method triggers one iteration (tick) of the game of life rules for the entire grid.
|
||||
*/
|
||||
public void iterate() {
|
||||
aliveCells = 0;
|
||||
deadCells = 0;
|
||||
for (List<Cell> row : cells) {
|
||||
for (Cell cell : row) {
|
||||
cell.determineNextTick();
|
||||
if (cell.isAlive()) {
|
||||
aliveCells++;
|
||||
} else {
|
||||
deadCells++;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (List<Cell> row : cells) {
|
||||
for (Cell cell : row) {
|
||||
cell.updateTick();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method adds all the cell rectangles to the Pane
|
||||
*/
|
||||
private void initialize(Pane gamePane) {
|
||||
for (List<Cell> row : cells) {
|
||||
for (Cell cell : row) {
|
||||
gamePane.getChildren().add(cell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method takes the location of a mouse click and sets the state of that cell to dead or alive.
|
||||
* @param location
|
||||
*/
|
||||
public void setState(MouseEvent location) {
|
||||
boolean loop = true;
|
||||
for (int i=0; i<cells.get(0).size()*10 && loop; i+=10) {
|
||||
if (location.getX() < i+10) {
|
||||
for (int j=0; j<cells.size()*10 && loop; j+=10) {
|
||||
if (location.getY() < j+10) {
|
||||
if (cells.get(j/10).get(i/10).isAlive()) {
|
||||
cells.get(j/10).get(i/10).setAlive(false);
|
||||
cells.get(j/10).get(i/10).updateColors();
|
||||
deadCells++;
|
||||
aliveCells--;
|
||||
loop = false;
|
||||
} else {
|
||||
cells.get(j/10).get(i/10).setAlive(true);
|
||||
cells.get(j/10).get(i/10).updateColors();
|
||||
aliveCells++;
|
||||
if (deadCells > 0) {
|
||||
deadCells--;
|
||||
}
|
||||
loop = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
Fall 2017/SE 1011/Lab5/src/barnestr/barnestr.zip
Normal file
BIN
Fall 2017/SE 1011/Lab5/src/barnestr/barnestr.zip
Normal file
Binary file not shown.
36
Fall 2017/SE 1011/Lab5/src/barnestr/lab5.fxml
Normal file
36
Fall 2017/SE 1011/Lab5/src/barnestr/lab5.fxml
Normal file
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.layout.BorderPane?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
|
||||
<BorderPane fx:id="gamePane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" onMouseClicked="#getClicked" prefHeight="650.0" prefWidth="550.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="barnestr.Controller">
|
||||
<bottom>
|
||||
<HBox fx:id="buttons" alignment="CENTER" prefHeight="50.0" prefWidth="600.0" BorderPane.alignment="CENTER">
|
||||
<children>
|
||||
<Button fx:id="nextButton" alignment="TOP_CENTER" mnemonicParsing="false" onAction="#iterate" prefWidth="95.0" text="Next">
|
||||
<opaqueInsets>
|
||||
<Insets />
|
||||
</opaqueInsets>
|
||||
<HBox.margin>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||
</HBox.margin>
|
||||
</Button>
|
||||
<Label fx:id="aliveDeadCount" text="Alive: Dead:" />
|
||||
<Button fx:id="randomizeButton" alignment="BOTTOM_RIGHT" mnemonicParsing="false" onAction="#randomize" prefWidth="95.0" text="Randomize All">
|
||||
<opaqueInsets>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||
</opaqueInsets>
|
||||
<HBox.margin>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||
</HBox.margin>
|
||||
</Button>
|
||||
</children>
|
||||
<opaqueInsets>
|
||||
<Insets />
|
||||
</opaqueInsets>
|
||||
</HBox>
|
||||
</bottom>
|
||||
</BorderPane>
|
||||
Reference in New Issue
Block a user