/* * Written by Professor Bill Tomlinson for Winter 2004 Biomorphic Computing class at UCI. * wmt@uci.edu */ import java.applet.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; public class GameOfLife extends Applet implements Runnable { //how many blocks in x public static int xSize = 50; //how many blocks in y public static int ySize = 50; //how many pixels per block public static int cellSize = 10; public static int[][] blocks = new int[xSize][ySize]; Color backgroundColor = Color.gray; Button startStopButton; Button stepButton; Canvas gridCanvas; //initialize the grid world public void init() { //System.out.println("initting"); setGameOfLife(this); setLayout(new BorderLayout()); //Panel p = new Panel(); gridCanvas = new Canvas() { public void paint(Graphics g) { setBackground(backgroundColor); g.clearRect(1, 1, (xSize * cellSize) - 2, (ySize * cellSize) - 2); for (int thisX = 0; thisX < xSize; thisX++) { for (int thisY = 0; thisY < ySize; thisY++) { if (blocks[thisX][thisY] > 0) { g.setColor(Color.black); } else { g.setColor(Color.white); } g.fillRect(thisX * cellSize, thisY * cellSize, cellSize - 1, cellSize - 1); } } } }; Panel controlPanel = new Panel(); controlPanel.setSize(30, 10); gridCanvas.setSize(500, 500); this.setLayout(new BorderLayout()); add(BorderLayout.CENTER, gridCanvas); add(BorderLayout.SOUTH, controlPanel); gridCanvas.addMouseMotionListener(new GameOfLifeMouseMotionListener()); gridCanvas.addMouseListener(new GameOfLifeMouseMotionListener()); // start and stop buttom startStopButton = new Button("Start"); stepButton = new Button("Step"); // when start/stop button is clicked startStopButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { startStopButtonClicked(); } }); stepButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { doOneStep(); } }); controlPanel.add(stepButton); controlPanel.add(startStopButton); setVisible(true); validate(); gridCanvas.repaint(); } // init public void paint(Graphics g) { gridCanvas.repaint(); } public void run() { while (true) { doOneStep(); } } private void doOneStep() { System.out.println("doing one step"); //Please read the following short paper: //http://ddi.cs.uni-potsdam.de/HyFISCH/Produzieren/lis_projekt/proj_gamelife/ConwayScientificAmerican.htm //and implement John Conway's Game of Life. //Fields you might be interest in using: //blocks[][] is an array of ints that correspond to the blocks on the game grid //Its dimensions are xSize by ySize (both ints). //Any blocks with value > 0 when repaint is called (near the end of this method) //will be painted black. Others will be painted white. //methods you might be interested in using: //getNumberOfNeighbors(x, y) returns the number of neighboring blocks that have value > 0 //Please comment your code so that it is clear what each section is doing. //Please email this entire file to wmt@uci.edu by Monday, 1/19/04 at noon. //insert code below this line //insert code above this line. gridCanvas.repaint(); try { Thread.sleep(200); } catch (Exception e) {} } private int getNumberOfNeighbors(int x, int y) { int numNeighbors = 0; //go through each neighbor and add one to numNeighbors if it is >0 if (x > 0 && y > 0 && blocks[x - 1][y - 1] > 0) { numNeighbors++; } if (y > 0 && blocks[x][y - 1] > 0) { numNeighbors++; } if (x < GameOfLife.xSize - 1 && y > 0 && blocks[x + 1][y - 1] > 0) { numNeighbors++; } if (x > 0 && blocks[x - 1][y] > 0) { numNeighbors++; } if (x < GameOfLife.xSize - 1 && blocks[x + 1][y] > 0) { numNeighbors++; } if (x > 0 && y < GameOfLife.ySize - 1 && blocks[x - 1][y + 1] > 0) { numNeighbors++; } if (y < GameOfLife.ySize - 1 && blocks[x][y + 1] > 0) { numNeighbors++; } if (x < GameOfLife.xSize - 1 && y < GameOfLife.ySize - 1 && blocks[x + 1][y + 1] > 0) { numNeighbors++; } return numNeighbors; } public static GameOfLife thisGameOfLife; public static GameOfLife getGameOfLife() { return thisGameOfLife; } public static void setGameOfLife(GameOfLife gw) { thisGameOfLife = gw; } Thread GameOfLifeThread; public void startStopButtonClicked() { //System.out.println("Start/Stop Button clicked."); if (GameOfLifeThread != null) { GameOfLifeThread.stop(); GameOfLifeThread = null; System.out.println("STOPPED."); startStopButton.setLabel("Start"); } else { if (GameOfLifeThread == null) { GameOfLifeThread = new Thread(this); } GameOfLifeThread.start(); System.out.println("STARTED."); startStopButton.setLabel("Stop"); } } } class GameOfLifeMouseMotionListener implements MouseListener, MouseMotionListener { static int[][] blocksAtStartOfDrag; //this happens when you drag. It always starts with a mousePressed //it should be able to reverse everything exactly once, except the one where mouse was pressed. public void mouseDragged(MouseEvent e) { int xPos = e.getX() / GameOfLife.cellSize; int yPos = e.getY() / GameOfLife.cellSize; if ((xPos < GameOfLife.xSize) && (yPos < GameOfLife.ySize) && xPos >= 0 && yPos >= 0) { if (GameOfLife.blocks[xPos][yPos] == blocksAtStartOfDrag[xPos][yPos]) { if (GameOfLife.blocks[xPos][yPos] == 0) { GameOfLife.blocks[xPos][yPos] = 1; } else { GameOfLife.blocks[xPos][yPos] = 0; } } } GameOfLife.getGameOfLife().gridCanvas.repaint(); } //this happens when you click, or at the beginning of a drag //whenever this happens it should reverse the block public void mousePressed(MouseEvent e) { int xPos = e.getX() / GameOfLife.cellSize; int yPos = e.getY() / GameOfLife.cellSize; blocksAtStartOfDrag = new int[GameOfLife.xSize][GameOfLife.ySize]; for (int i = 0; i < blocksAtStartOfDrag.length; i++) { for (int j = 0; j < blocksAtStartOfDrag[i].length; j++) { blocksAtStartOfDrag[i][j] = GameOfLife.blocks[i][j]; } } if ((xPos < GameOfLife.xSize) && (yPos < GameOfLife.ySize) && xPos >= 0 && yPos >= 0) { if (GameOfLife.blocks[xPos][yPos] == 0) { GameOfLife.blocks[xPos][yPos] = 1; } else { GameOfLife.blocks[xPos][yPos] = 0; } } GameOfLife.getGameOfLife().gridCanvas.repaint(); } public void mouseMoved(MouseEvent e) { } public void mouseReleased(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mouseClicked(MouseEvent e) { } }