From ed6b5d533198e503b5d118b9dfe6fef732c6ac23 Mon Sep 17 00:00:00 2001 From: MSAYIF Bassem <bassem.msayif@etu.univ-amu.fr> Date: Mon, 28 Sep 2020 17:44:12 +0200 Subject: [PATCH] Ajout du TP3 --- tp3/Cell.java | 78 +++++++++++++++++++++++ tp3/GameOfLife.java | 87 ++++++++++++++++++++++++++ tp3/GameOfLifeGUI.java | 48 +++++++++++++++ tp3/Grid.java | 136 +++++++++++++++++++++++++++++++++++++++++ tp3/GridIterator.java | 31 ++++++++++ tp3/Main.java | 25 ++++++++ 6 files changed, 405 insertions(+) create mode 100644 tp3/Cell.java create mode 100644 tp3/GameOfLife.java create mode 100644 tp3/GameOfLifeGUI.java create mode 100644 tp3/Grid.java create mode 100644 tp3/GridIterator.java create mode 100644 tp3/Main.java diff --git a/tp3/Cell.java b/tp3/Cell.java new file mode 100644 index 0000000..9a0b4bd --- /dev/null +++ b/tp3/Cell.java @@ -0,0 +1,78 @@ +/** + * {@link Cell} instances represent the cells of <i>The Game of Life</i>. + */ + +public class Cell { + private boolean isAlive; + + public Cell(){ + this.isAlive = false; + } + + /** + * Determines whether this {@link Cell} is alive or not. + * + * @return {@code true} if this {@link Cell} is alive and {@code false} otherwise + */ + + public boolean isAlive() { + return this.isAlive; + } + + /** + * Determines whether this {@link Cell} is dead or not. + * + * @return {@code true} if this {@link Cell} is dead and {@code false} otherwise + */ + + public boolean isDead() { + return !this.isAlive; + } + + /** + * Sets the state of this {@link Cell} to alive. + * + * @param cellState the new state of this {@link Cell} + */ + + public void setAlive() { + this.isAlive = true; + } + + /** + * Sets the state of this {@link Cell} to dead. + * + * @param cellState the new state of this {@link Cell} + */ + + public void setDead() { + this.isAlive = false; + } + + + /** + * Change the state of this {@link Cell} from ALIVE to DEAD or from DEAD to ALIVE. + */ + + public void toggleState() { + if(this.isAlive) + this.isAlive = false; + else + this.isAlive = true; + } + + public boolean isAliveInNextState(int numberOfAliveNeighbours) { + if(isAlive()){ + if (numberOfAliveNeighbours == 2 || numberOfAliveNeighbours == 3) + return true; + else + return false; + } + else{ + if (numberOfAliveNeighbours == 3) + return true; + else + return false; + } + } +} diff --git a/tp3/GameOfLife.java b/tp3/GameOfLife.java new file mode 100644 index 0000000..1d5bb85 --- /dev/null +++ b/tp3/GameOfLife.java @@ -0,0 +1,87 @@ +import java.util.Random; + +/** + * {@link GameOfLife} instances run <i>The Game of Life</i>. + */ +public class GameOfLife { + + private final Random random = new Random(); + private final Grid grid; + private int generationNumber; + + /** + * Creates a new {@code GameOfLife} instance given the underlying {@link Grid}. + * + * @param grid the underlying {@link Grid} + * @throws NullPointerException if {@code grid} is {@code null} + */ + public GameOfLife(Grid grid) { + // this.grid = requireNonNull(grid, "grid is null"); + this.grid = grid; + grid.randomGeneration(random); + } + + /** + * Transitions into the next generationNumber. + */ + public void next() { + grid.nextGeneration(); + generationNumber++; + } + + + /** + * Returns the current generationNumber. + * + * @return the current generationNumber + */ + private int getGenerationNumber() { + return generationNumber; + } + + /** + * Returns the {@link Grid}. + * + * @return the {@link Grid} + */ + public Grid getGrid() { + return grid; + } + + /** + * Plays the game. + */ + public void play(int maxGenerations) { + for(int generation =0; generation < maxGenerations; generation++){ + this.next(); + System.out.println("generation : " + generation); + } + + + } + + /** + * Pauses the game. + */ + public void pause() { + // timeline.pause(); + } + + /** + * Clears the current game. + */ + public void clear() { + pause(); + grid.clear(); + generationNumber = 0; + } + + /** + * Clears the current game and randomly generates a new one. + */ + public void reset() { + clear(); + grid.randomGeneration(random); + } + +} diff --git a/tp3/GameOfLifeGUI.java b/tp3/GameOfLifeGUI.java new file mode 100644 index 0000000..c162ce0 --- /dev/null +++ b/tp3/GameOfLifeGUI.java @@ -0,0 +1,48 @@ +import java.awt.*; +import java.awt.Graphics; +import javax.swing.*; + +public class GameOfLifeGUI extends JFrame { + private int squareSize = 7; + private int numberOfRows; + private int numberOfColumns; + private JLabel[][] labelGrid; + private GridLayout gridLayout; + private JPanel gridPanel; + private JFrame frame; + + public GameOfLifeGUI(Grid g) { + this.numberOfRows = g.getNumberOfRows(); + this.numberOfColumns = g.getNumberOfColumns(); + gridLayout = new GridLayout(numberOfRows, numberOfColumns); + gridPanel = new JPanel(gridLayout); + labelGrid = new JLabel[numberOfRows][numberOfColumns]; + for (int x = 0; x < numberOfColumns; x++) + for (int y = 0; y < numberOfRows; y++){ + labelGrid[x][y] = new JLabel("*"); + JLabel label; + if(g.getCell(x,y).isAlive()) + labelGrid[x][y].setForeground(Color.red); + else + labelGrid[x][y].setForeground(Color.white); + gridPanel.add(labelGrid[x][y]); + } + frame = new JFrame("Game of Life"); + frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + frame.setContentPane(gridPanel); + frame.setSize(squareSize * numberOfRows, squareSize * numberOfColumns); + frame.setLocationByPlatform(true); + frame.setVisible(true); + } + + public void update(Grid g){ + for (int x = 0; x < numberOfColumns; x++) + for (int y = 0; y < numberOfRows; y++){ + JLabel label = labelGrid[x][y]; + if(g.getCell(x,y).isAlive()) + label.setForeground(Color.red); + else + label.setForeground(Color.white); + } + } +} diff --git a/tp3/Grid.java b/tp3/Grid.java new file mode 100644 index 0000000..939e05f --- /dev/null +++ b/tp3/Grid.java @@ -0,0 +1,136 @@ +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.Random; + +/** + * {@code Grid} instances represent the grid in <i>The Game of Life</i>. + */ +public class Grid implements Iterable<Cell> { + + private final int numberOfRows; + private final int numberOfColumns; + private final Cell[][] cells; + + /** + * Creates a new {@code Grid} instance given the number of rows and columns. + * + * @param numberOfRows the number of rows + * @param numberOfColumns the number of columns + * @throws IllegalArgumentException if {@code numberOfRows} or {@code numberOfColumns} are + * less than or equal to 0 + */ + public Grid(int numberOfRows, int numberOfColumns) { + this.numberOfRows = numberOfRows; + this.numberOfColumns = numberOfColumns; + this.cells = createCells(); + } + + @Override + public Iterator<Cell> iterator() { + return new GridIterator(this); + } + + private Cell[][] createCells() { + Cell[][] cells = new Cell[getNumberOfRows()][getNumberOfColumns()]; + for (int rowIndex = 0; rowIndex < getNumberOfRows(); rowIndex++) { + for (int columnIndex = 0; columnIndex < getNumberOfColumns(); columnIndex++) { + cells[rowIndex][columnIndex] = new Cell(); + } + } + return cells; + } + + /** + * Returns the {@link Cell} at the given index. + * + * <p>Note that the index is wrapped around so that a {@link Cell} is always returned. + * + * @param rowIndex the row index of the {@link Cell} + * @param columnIndex the column index of the {@link Cell} + * @return the {@link Cell} at the given row and column index + */ + public Cell getCell(int rowIndex, int columnIndex) { + return cells[getWrappedRowIndex(rowIndex)][getWrappedColumnIndex(columnIndex)]; + } + + private int getWrappedRowIndex(int rowIndex) { + return (rowIndex + getNumberOfRows()) % getNumberOfRows(); + } + + private int getWrappedColumnIndex(int columnIndex) { + return (columnIndex + getNumberOfColumns()) % getNumberOfColumns(); + } + + /** + * Returns the number of rows in this {@code Grid}. + * + * @return the number of rows in this {@code Grid} + */ + public int getNumberOfRows() { + return numberOfRows; + } + + /** + * Returns the number of columns in this {@code Grid}. + * + * @return the number of columns in this {@code Grid} + */ + public int getNumberOfColumns() { + return numberOfColumns; + } + + /** + * Transitions all {@link Cell}s in this {@code Grid} to the next generation. + * + * <p>The following rules are applied: + * <ul> + * <li>Any live {@link Cell} with fewer than two live neighbours dies, i.e. underpopulation.</li> + * <li>Any live {@link Cell} with two or three live neighbours lives on to the next + * generation.</li> + * <li>Any live {@link Cell} with more than three live neighbours dies, i.e. overpopulation.</li> + * <li>Any dead {@link Cell} with exactly three live neighbours becomes a live cell, i.e. + * reproduction.</li> + * </ul> + */ + void nextGeneration() { + goToNextState(calculateNextStates()); + } + + private boolean[][] calculateNextStates() { + return null; + } + + private boolean calculateNextState(int rowIndex, int columnIndex, Cell cell) { + return false; + } + + private int countAliveNeighbours(int rowIndex, int columnIndex) { + return 0; + } + + + private List<Cell> getNeighbours(int rowIndex, int columnIndex) { + return null; + } + + private void goToNextState(boolean[][] nextState) { + } + + /** + * Sets all {@link Cell}s in this {@code Grid} as dead. + */ + void clear() { + } + + /** + * Goes through each {@link Cell} in this {@code Grid} and randomly sets it as alive or dead. + * + * @param random {@link Random} instance used to decide if each {@link Cell} is alive or dead + * @throws NullPointerException if {@code random} is {@code null} + */ + + void randomGeneration(Random random) { + } + +} diff --git a/tp3/GridIterator.java b/tp3/GridIterator.java new file mode 100644 index 0000000..19fc9e0 --- /dev/null +++ b/tp3/GridIterator.java @@ -0,0 +1,31 @@ +import java.util.Iterator; + +/** + * {@link GridIterator} instances are used to iterate over the cells of a grid. + */ +public class GridIterator implements Iterator<Cell> { + private int rowIndex; + private int columnIndex; + private Grid grid; + + GridIterator(Grid grid) { + this.rowIndex = 0; + this.columnIndex = 0; + this.grid = grid; + } + + @Override + public boolean hasNext() { + return columnIndex < grid.getNumberOfColumns() && rowIndex < grid.getNumberOfRows(); + } + + @Override + public Cell next() { + final Cell result = grid.getCell(rowIndex, columnIndex); + columnIndex = (columnIndex +1) % grid.getNumberOfColumns(); + if(columnIndex == 0){ + rowIndex++; + } + return result; + } +} diff --git a/tp3/Main.java b/tp3/Main.java new file mode 100644 index 0000000..bf344ee --- /dev/null +++ b/tp3/Main.java @@ -0,0 +1,25 @@ +import java.io.*; +import java.awt.*; +import javax.swing.*; + +public class Main{ + public static void main(String args[]) throws IOException { + int NUMBER_OF_ROWS = 64; + int NUMBER_OF_COLUMNS = 64; + + GameOfLife gameOfLife = new GameOfLife(new Grid(NUMBER_OF_ROWS, NUMBER_OF_COLUMNS)); + + GameOfLifeGUI gui = new GameOfLifeGUI(gameOfLife.getGrid()); + + for(int generation =0; generation < 1000; generation++){ + try { + Thread.sleep(100); + } catch (InterruptedException ie) { + + } + gameOfLife.next(); + gui.update(gameOfLife.getGrid()); + } + + } +} -- GitLab