first commit

This commit is contained in:
2019-08-13 12:17:37 -05:00
commit d5d82eff27
107 changed files with 6112 additions and 0 deletions

View 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>

View 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>

View 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;
}
}
}

View 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);
}
}

View 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();
}
}

View 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;
}
}
}
}
}
}
}

Binary file not shown.

View 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>