Commit 1d18aace authored by HaskellElephant's avatar HaskellElephant

Initial Commit

parents
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
<classpathentry kind="output" path="bin"/>
</classpath>
eclipse.preferences.version=1
encoding/<project>=UTF-8
[Se Laboppgave 2](https://inf101.ii.uib.no/inf101/inf101v16/wikis/lab-2)
package inf101.v16.cell;
/**
*
* The State of a cell
*/
public enum CellState {
ALIVE,
DYING,
DEAD
}
package inf101.v16.cell;
import inf101.v16.datastructures.MyGrid;
import inf101.v16.datastructures.IGrid;
import java.awt.Color;
import java.util.Random;
/**
*
* An ICellAutomata that implements Conways game of life.
*
* @see ICellAutomata
*
* Every cell has two states: Alive or Dead. Each step the state of each
* cell is decided from its neighbors (diagonal, horizontal and lateral).
* If the cell has less than two alive Neighbors or more than three
* neighbors the cell dies. If a dead cell has exactly three neighbors it
* will become alive.
*
* @author eivind
*/
public class GameOfLife implements ICellAutomaton {
/**
* The grid the game is played in.
*/
IGrid<CellState> currentGeneration;
/**
*
* Construct a GameOfLife ICellAutomaton using a grid with the given height
* and width.
*
* @param height
* @param width
*/
public GameOfLife(int width, int height) {
currentGeneration = new MyGrid<CellState>(width, height,
CellState.DEAD);
}
@Override
public void initializeGeneration() {
Random random = new Random();
for (int x = 0; x < currentGeneration.getWidth(); x++) {
for (int y = 0; y < currentGeneration.getHeight(); y++) {
if (random.nextBoolean()) {
currentGeneration.set(x, y, CellState.ALIVE);
} else {
currentGeneration.set(x, y, CellState.DEAD);
}
}
}
}
@Override
public int getHeight() {
return currentGeneration.getHeight();
}
@Override
public int getWidth() {
return currentGeneration.getWidth();
}
@Override
public Color getColorInCurrentGeneration(int x, int y) {
if (currentGeneration.get(x, y) == CellState.ALIVE) {
return Color.black;
} else {
return Color.white;
}
}
@Override
public void stepAutomaton() {
IGrid<CellState> nextGeneration = new MyGrid<CellState>(
currentGeneration.getWidth(), currentGeneration.getHeight(),
CellState.ALIVE);
for (int x = 0; x < currentGeneration.getWidth(); x++) {
for (int y = 0; y < currentGeneration.getHeight(); y++) {
int numNeighbours = 0;
for (int dx = -1; dx <= 1; dx++) {
for (int dy = -1; dy <= 1; dy++) {
if (dx == 0 && dy == 0)
continue; // samme celle, hopp over
if (y + dy < 0)
continue; // utenfor brettet
if (y + dy >= currentGeneration.getHeight())
continue; // utenfor brettet
if (x + dx < 0)
continue; // utenfor brettet
if (x + dx >= currentGeneration.getWidth())
continue; // utenfor brettet
// tell levende naboer
if (currentGeneration.get(x + dx, y + dy) == CellState.ALIVE) {
numNeighbours++;
}
}
}
if (numNeighbours < 2) {
nextGeneration.set(x, y, CellState.DEAD);
} else if (numNeighbours == 3) {
nextGeneration.set(x, y, CellState.ALIVE);
} else if (numNeighbours > 3) {
nextGeneration.set(x, y, CellState.DEAD);
} else {
nextGeneration.set(x, y, currentGeneration.get(x, y));
}
}
}
currentGeneration = nextGeneration;
}
}
package inf101.v16.cell;
import java.awt.Color;
/**
*
* An ICellAutomaton represents a Cellular Automaton. The
* automaton contains a cell generation organized in rows
* and columns. Height and width refers to how many
* rows and columns there are in the Cellular Automaton
* respectively.
* @author eivind
*/
public interface ICellAutomaton {
/**
*
* Get the color of the cell in a given x,y location.
* @param x
* @param y
* @return The color of the cell in the given row and column.
*/
Color getColorInCurrentGeneration(int x, int y);
/**
* The ICellAutomaton gives the cells their initial value.
* For instance the cellular automaton might give the cells
* a random state.
*/
void initializeGeneration();
/**
* Progresses the state of the cell to the next generation.
*/
void stepAutomaton();
/**
* @return The number of rows.
*/
int getHeight();
/**
* @return The number of columns.
*/
int getWidth();
}
package inf101.v16.cell;
import inf101.v16.cell.gui.CellAutomataGUI;
public class Main {
public static void main(String[] args) {
ICellAutomaton ca = new GameOfLife(100,100);
//Når du er klar til å teste ut BriansBrain
//kan du bytte linjen over med det følgende:
//ICellAutomaton ca = new BriansBrain(100,100);
CellAutomataGUI.run(ca);
}
}
package inf101.v16.cell;
import inf101.v16.datastructures.MyGrid;
import inf101.v16.datastructures.IGrid;
import java.awt.Color;
import java.util.Random;
/**
*
* An ICellAutomata that implements the Seeds Cellular Automaton.
*
* @see ICellAutomata
*
* Every cell has two states: Alive or Dead. Each step the state of each
* cell is decided from its neighbors (diagonal, horizontal and lateral).
* If a dead cell has exactly two alive neighbors then it becomes alive,
* otherwise it dies.
*
* @author eivind
*/
public class SeedsAutomaton implements ICellAutomaton {
/**
* The grid containing the current generation.
*/
IGrid<CellState> currentGeneration;
/**
*
* Construct a Seeds ICellAutomaton using a grid with the given height and
* width.
*
* @param height
* @param width
*/
public SeedsAutomaton(int width, int height) {
currentGeneration = new MyGrid<CellState>(width, height,
CellState.DEAD);
}
@Override
public void initializeGeneration() {
Random random = new Random();
for (int x = 0; x < currentGeneration.getWidth(); x++) {
for (int y = 0; y < currentGeneration.getHeight(); y++) {
if (random.nextBoolean()) {
currentGeneration.set(x, y, CellState.ALIVE);
} else {
currentGeneration.set(x, y, CellState.DEAD);
}
}
}
}
@Override
public int getHeight() {
return currentGeneration.getHeight();
}
@Override
public int getWidth() {
return currentGeneration.getWidth();
}
@Override
public Color getColorInCurrentGeneration(int x, int y) {
if (currentGeneration.get(x, y) == CellState.ALIVE) {
return Color.black;
} else {
return Color.white;
}
}
@Override
public void stepAutomaton() {
IGrid<CellState> nextGeneration = new MyGrid<CellState>(
currentGeneration.getHeight(), currentGeneration.getWidth(),
CellState.ALIVE);
for (int x = 0; x < currentGeneration.getWidth(); x++) {
for (int y = 0; y < currentGeneration.getHeight(); y++) {
int numNeighbours = 0;
for (int dx = -1; dx <= 1; dx++) {
for (int dy = -1; dy <= 1; dy++) {
if (dx == 0 && dy == 0)
continue; // samme celle, hopp over
if (y + dy < 0)
continue; // utenfor brettet
if (y + dy >= currentGeneration.getHeight())
continue; // utenfor brettet
if (x + dx < 0)
continue; // utenfor brettet
if (x + dx >= currentGeneration.getWidth())
continue; // utenfor brettet
if (currentGeneration.get(x + dx, y + dy) == CellState.ALIVE) {
numNeighbours++;
}
}
}
if (numNeighbours == 2) {
nextGeneration.set(x, y, CellState.ALIVE);
} else {
nextGeneration.set(x, y, CellState.DEAD);
}
}
}
currentGeneration = nextGeneration;
}
}
\ No newline at end of file
package inf101.v16.cell.gui;
import inf101.v16.cell.ICellAutomaton;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
/**
*
* A Component that draws the cells in a ICellAutomaton.
*
* @author eivind
*/
class AutomatonComponent extends Component {
/**
* The dimension of the grid containing the cells.
*/
private Dimension gridDim;
/**
* The automaton to paint the cells of.
*/
private ICellAutomaton automaton;
/**
* The height of each cell in pixels.
*/
private final int cellHeight = 5;
/**
* The width of each cell in pixels.
*/
private final int cellWidth = 5;
/**
* The size of the space between each cell and between the cell and the edge
* of the window.
*/
private final int padding = 1;
private static final long serialVersionUID = 4548104480314044678L;
/**
* Construct a AutomatonComponent that will paint the given automaton.
*
* @param grid
*/
public AutomatonComponent(ICellAutomaton automaton) {
this.automaton = automaton;
gridDim = new Dimension((cellWidth + padding) * automaton.getWidth()
+ padding, (cellHeight + padding) * automaton.getHeight() + padding);
}
/*
* (non-Javadoc)
*
* @see java.awt.Component#getPreferredSize() Returns the dimensions of the
* grid.
*/
@Override
public Dimension getPreferredSize() {
return gridDim;
}
/*
* (non-Javadoc)
*
* @see java.awt.Component#paint(java.awt.Graphics) Paints the automaton.
*/
public void paint(Graphics g) {
for (int x = 0; x < automaton.getWidth(); x++) {
for (int y = 0; y < automaton.getHeight(); y++) {
g.setColor(automaton.getColorInCurrentGeneration(x, y));
g.fillRect(x * (cellHeight + padding) + padding, y
* (cellHeight + padding) + padding, cellHeight,
cellWidth);
}
}
}
}
package inf101.v16.cell.gui;
import inf101.v16.cell.ICellAutomaton;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
*
* The application in which AutomatonComponent is displayed.
*
* @author eivind
*/
public class CellAutomataGUI extends JPanel implements ActionListener {
private static final long serialVersionUID = 8755882090377973497L;
AutomatonComponent automatonComponent;
ICellAutomaton automaton;
private javax.swing.Timer timer;
private JButton startButton;
private JButton stopButton;
private JButton stepButton;
private JButton setBoardButton;
public CellAutomataGUI(ICellAutomaton automata) {
this.automaton = automata;
}
/**
* Sets up the GUI.
*/
public void initialize() {
setLayout(new BorderLayout());
automaton.initializeGeneration();
automatonComponent = new AutomatonComponent(automaton);
JPanel p = new JPanel();
startButton = new JButton();
startButton.addActionListener(this);
startButton.setText("Start Automaton");
setBoardButton = new JButton();
setBoardButton.addActionListener(this);
setBoardButton.setText("Reset Board");
stopButton = new JButton();
stopButton.addActionListener(this);
stopButton.setText("Stop Automaton");
stepButton = new JButton();
stepButton.addActionListener(this);
stepButton.setText("Next Step");
p.add(startButton);
p.add(stopButton);
p.add(stepButton);
p.add(setBoardButton);
add(p, BorderLayout.NORTH);
add(automatonComponent, BorderLayout.CENTER);
timer = new javax.swing.Timer(1000/20, this);
}
/**
*
* Initializes a JFrame in which we place the a CellAutomataGUI containing
* the given ICellAutomaton.
*
* @param ca
*/
public static void run(ICellAutomaton ca) {
JFrame f = new JFrame("Inf101 Cell Automaton");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
CellAutomataGUI ap = new CellAutomataGUI(ca);
ap.initialize();
f.add("Center", (Component) ap);
f.pack();
f.setVisible(true);
}
/*
* (non-Javadoc)
*
* @see
* java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*
* Called whenever a button is pressed or the timer tells us its time to
* make a step.
*/
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == timer) {
timer.restart();
automaton.stepAutomaton();
automatonComponent.repaint();
} else if (e.getSource() == startButton) {
timer.start();
} else if (e.getSource() == stopButton) {
timer.stop();
} else if (e.getSource() == stepButton) {
timer.stop();
automaton.stepAutomaton();
automatonComponent.repaint();
} else if (e.getSource() == setBoardButton) {
automaton.initializeGeneration();
automatonComponent.repaint();
}
}
}
\ No newline at end of file
package inf101.v16.datastructures;
import static org.junit.Assert.*;
import java.util.Random;
import org.junit.Test;
public class GridTest {
Random random = new Random();
/**
* Tests that trying to access outside of the dimensions of the grid throws
* an IndexOutOfBoundsException.
*/
@Test
public void outOfBoundsTest() {
IGrid<Integer> grid = new MyGrid<Integer>(10, 10, 0);
try {
grid.set(11, 0, 4);
fail("Should throw exception");
} catch (IndexOutOfBoundsException e) {
;
}
try {
grid.set(0, 11, 4);
fail("Should throw exception");
} catch (IndexOutOfBoundsException e) {
;
}
}
@Test
public void setGetTest1() {
IGrid<Integer> grid = new MyGrid<>(100, 100, 0);
for (int x = 0; x < 100; x++)
for (int y = 0; y < 100; y++) {
Integer i = random.nextInt();
grid.set(x, y, i);
assertEquals(i, grid.get(x, y));
}
}
@Test
public void setGetTest2() {
IGrid<Integer> grid = new MyGrid<>(100, 100, 0);
for (int x = 0; x < 100; x++)
for (int y = 0; y < 100; y++) {
grid.set(x, y, x * y);
}
for (int x = 0; x < 100; x++)
for (int y = 0; y < 100; y++) {
grid.set(x, y, x * y);
assertEquals(x * y, (int) grid.get(x, y));
}
}
@Test
public void copyTest() {
IGrid<Integer> grid = new MyGrid<>(100, 100, 0);
for (int x = 0; x < 100; x++)
for (int y = 0; y < 100; y++) {
Integer i = random.nextInt();
grid.set(x, y, i);
}
IGrid<Integer> newGrid = grid.copy();
for (int x = 0; x < 100; x++)
for (int y = 0; y < 100; y++) {
assertEquals(grid.get(x, y), newGrid.get(x,y));
}
}
}
package inf101.v16.datastructures;
public interface IGrid<T> {
/**
* @return The height of the grid.
*/
int getHeight();
/**
* @return The width of the grid.
*/
int getWidth();
/**
*
* Set the contents of the cell in the given x,y location.
*
* y must be greater than or equal to 0 and less than getHeight().
* x must be greater than or equal to 0 and less than getWidth().
*
* @param x The column of the cell to change the contents of.
* @param y The row of the cell to change the contents of.
* @param element The contents the cell is to have.
*/