ARRAYS EXAMPLE: THE GAME OF LIFE CITS1001. 2 Scope of this lecture The Game of Life Implementation Performance Issues References:

Slides:



Advertisements
Similar presentations
1 CSC 221: Computer Programming I Fall 2006 interacting objects modular design: dot races constants, static fields cascading if-else, logical operators.
Advertisements

C++ Programming: Program Design Including Data Structures, Third Edition Chapter 7: User-Defined Functions II.
Chapter 7: User-Defined Functions II
Chapter 7: User-Defined Functions II Instructor: Mohammad Mojaddam.
The Fundamental Rule for Testing Methods Every method should be tested in a program in which every other method in the testing program has already been.
Game of Life Rules and Games Linh Tran ECE 573. What is Life? Life is just one example of a cellular automaton, which is any system in which rules are.
Road Map Introduction to object oriented programming. Classes
VBA Modules, Functions, Variables, and Constants
CS 177 Recitation Week 8 – Methods. Questions? Announcements  Project 3 milestone due next Thursday 10/22 9pm  Turn in with: turnin –c cs177=xxxx –p.
© The McGraw-Hill Companies, 2006 Chapter 7 Implementing classes.
Copyright 2010 by Pearson Education 1 Assignment 11: Critters.
Options for User Input Options for getting information from the user –Write event-driven code Con: requires a significant amount of new code to set-up.
Games and Simulations O-O Programming in Java The Walker School
Java Unit 9: Arrays Declaring and Processing Arrays.
Week 4-5 Java Programming. Loops What is a loop? Loop is code that repeats itself a certain number of times There are two types of loops: For loop Used.
MrsBillinghurst. net A2 Computing A2 Computing Projects Game Animation in Pascal.
REFACTORING Lecture 4. Definition Refactoring is a process of changing the internal structure of the program, not affecting its external behavior and.
Introduction to Object Oriented Programming. Object Oriented Programming Technique used to develop programs revolving around the real world entities In.
EE4E. C++ Programming Lecture 1 From C to C++. Contents Introduction Introduction Variables Variables Pointers and references Pointers and references.
OOD Case Study (For parallel treatment, see Chapter 2 of the text)
© The McGraw-Hill Companies, 2006 Chapter 4 Implementing methods.
Programming in Java Unit 2. Class and variable declaration A class is best thought of as a template from which objects are created. You can create many.
1 CSC 221: Computer Programming I Spring 2010 interaction & design  modular design: roulette game  constants, static fields  % operator, string equals.
Method Overriding Remember inheritance: when a child class inherits methods, variables, etc from a parent class. Example: public class Dictionary extends.
C++ Programming: From Problem Analysis to Program Design, Fifth Edition, Fifth Edition Chapter 7: User-Defined Functions II.
tiled Map Case Study: Rendering with JPanel © Allan C. Milne v
Graphics Concepts CS 2302, Fall /3/20142 Drawing Paths.
Copyright © 2002, Systems and Computer Engineering, Carleton University a-JavaReview.ppt * Object-Oriented Software Development Unit.
Java Threads. What is a Thread? A thread can be loosely defined as a separate stream of execution that takes place simultaneously with and independently.
Topic 26 Two Dimensional Arrays "Computer Science is a science of abstraction -creating the right model for a problem and devising the appropriate mechanizable.
1 Data Structures CSCI 132, Spring 2014 Lecture 4 Implementing Life.
Programming Principles Chapter 1. Objectives Discuss the program design process. Introduce the Game of Life. Discuss object oriented design. – Information.
Review Recursion Call Stack. Two-dimensional Arrays Visualized as a grid int[][] grays = {{0, 20, 40}, {60, 80, 100}, {120, 140, 160}, {180, 200, 220}};
Constructors CMSC 202. Object Creation Objects are created by using the operator new in statements such as… The following expression invokes a special.
11 Adding Tomato Targets Session Session Overview  We now have a game which lets a player bounce a piece of cheese on a bread bat  Now we have.
M180: Data Structures & Algorithms in Java Arrays in Java Arab Open University 1.
Object-Oriented Programming in C++
Topic 1 Object Oriented Programming. 1-2 Objectives To review the concepts and terminology of object-oriented programming To discuss some features of.
Chapter 6 Introduction to Defining Classes. Objectives: Design and implement a simple class from user requirements. Organize a program in terms of a view.
Structure Programming Lecture 8 Chapter 5&6 - Function – part I 12 December 2015.
Programming with Java © 2002 The McGraw-Hill Companies, Inc. All rights reserved. 1 McGraw-Hill/Irwin Chapter 5 Creating Classes.
Rina System development with Java Instructors: Rina Zviel-Girshin Lecture 4.
 Constructor  Finalize() method  this keyword  Method Overloading  Constructor Overloading  Object As an Argument  Returning Objects.
More Object Concepts— Farrell, Chapter 4 Dr. Burns.
CMSC 202 Arrays 2 nd Lecture. Aug 6, Array Parameters Both array indexed variables and entire arrays can be used as arguments to methods –An indexed.
 In the java programming language, a keyword is one of 50 reserved words which have a predefined meaning in the language; because of this,
CMSC 202 Advanced Section Classes and Objects: Object Creation and Constructors.
1 Arrays of Arrays An array can represent a collection of any type of object - including other arrays! The world is filled with examples Monthly magazine:
Catie Welsh March 23,  Lab 6 due Friday by 1pm 2.
Java – An Object Oriented Language CS 307 Lecture Notes Lecture Weeks 5-6 Khalid Siddiqui.
 Variables are nothing but reserved memory locations to store values. This means that when you create a variable you reserve some space in memory. 
Arrays Chapter 7. MIS Object Oriented Systems Arrays UTD, SOM 2 Objectives Nature and purpose of an array Using arrays in Java programs Methods.
Internet Computing Module II. Syllabus Creating & Using classes in Java – Methods and Classes – Inheritance – Super Class – Method Overriding – Packages.
Coding – Week 2 Functions, Arrays, and Objects. Functions  Functions are not a new concept – you’ve been using them already.  void setup() {} and void.
MT311 Java Application Development and Programming Languages Li Tak Sing( 李德成 )
LESSON 8: INTRODUCTION TO ARRAYS. Lesson 8: Introduction To Arrays Objectives: Write programs that handle collections of similar items. Declare array.
Arrays Chapter 7.
DESIGNING CLASSES THE GAME OF LIFE
Chapter 7: User-Defined Functions II
User-Defined Functions
Basic Graphics Drawing Shapes 1.
ARRAYS example: THE GAME OF LIFE
Implementing Non-Static Features
Chap 2. Identifiers, Keywords, and Types
Classes and Objects Object Creation
CMSC 202 Constructors Version 9/10.
Presentation transcript:

ARRAYS EXAMPLE: THE GAME OF LIFE CITS1001

2 Scope of this lecture The Game of Life Implementation Performance Issues References: (and hundreds of other websites)

3 Game of Life Invented by John Conway over forty years ago An example of a “cellular automaton” The game is played on a rectangular grid of “cells”

4 A model world This grid is a “model world”, where each cell is either occupied or vacant The initial configuration can be specified by the user, or chosen randomly We colour the occupied cells, and leave the others blank; the colour scheme is irrelevant to the game, but makes the application look more attractive

5 Births and Deaths In this model world, time passes in discrete steps known as generations The beginning of time is Generation 0 At each time step, the occupants of the model world live or die according to the following rules: any individual with zero or one neighbours dies of loneliness any individual with four or more neighbours dies of overcrowding a new individual is born in any unoccupied cell with exactly three neighbours The neighbours of a cell are the occupants of the eight cells surrounding that particular cell

6 Example Initial configuration Number of neighbours of each cell Next generation

7 Interpretation The occupants of these cells died of loneliness These two are new-born “babies”

8

9 At the edges The edges of the world are assumed to “wrap around”, so the map is actually a flat map of a torus-shaped world Neighbourhoods

10 Program Design The program needs classes to perform the following operations Maintain and update the map of the world Display and update the screen view of the world We will design two classes for these two aspects, and use a SimpleCanvas to provide the display Therefore we will create two classes Life LifeViewer

11 Separate the responsibilities The Life class should Maintain the current map of the world Update to the “next generation” when requested Provide access to the map for client use The LifeViewer class should Create a SimpleCanvas to display the map Display the initial generation Animate a client-specified number of generations

12 The Life instance variables public class Life { private boolean[][] map; private int width, height; // constructors & methods } We use a 2D array of type boolean for the map of the world; the value of the [i][j] entry in the array map indicates whether the (i,j) cell is populated or not

13 The first constructor public Life(boolean[][] initial) { map = initial; width = map.length; height = map[0].length; } This constructor allows the client to create a Life object with any initial pattern of occupied and unoccupied cells that they want

14 The second constructor public Life(int width, int height, double probability) { map = new boolean[width][height]; this.width = width; this.height = height; initializeMap(probability); } This constructor allows the client to specify just the width and height and have a random starting configuration created

15 Private helper method for initializing private void initializeMap(double probability) { for (int i = 0; i < width; i++) for (int j = 0; j < height; j++) map[i][j] = Math.random() < probability); } If the user specifies 0.2 as the probability, approximately 20% of the cells will be occupied Math.random() is a quick way to get random double s between 0 and 1

16 The default constructor It is polite to also give a “default” constructor for users who just wish to get going quickly, and are willing to accept programmer-chosen values public Life() { this(128, 128, 0.1); } Calls the 3-argument constructor with 128, 128, and 0.1 as the values

17 A new generation public void nextGeneration() { boolean[][] nextMap = new boolean[width][height]; for (int i = 0; i < width; i++) for (int j = 0; j < height; j++) switch (numNeighbours(i, j)) { case 2: nextMap[i][j] = map[i][j]; break; case 3: nextMap[i][j] = true; break; default: nextMap[i][j] = false; } map = nextMap; }

18 Code Dissection boolean[][] nextMap = new boolean[width][height]; This creates the space for the “next generation” to be stored in; we use the instance variables width and height to set the size We cannot do the updating “in place” because the rules specify that the updating from generation to generation occurs over the entire grid simultaneously; we cannot change some values and then use the new values in the calculation for other cells

19 switch (numNeighbours(i, j)) { case 2: nextMap[i][j] = map[i][j]; break; case 3: nextMap[i][j] = true; break; default: nextMap[i][j] = false; } Code dissection The main loop processes each cell (i,j) in turn. The number of neighbours is calculated and the (i,j) cell of nextMap is set according to the rules of the Game of Life We haven’t defined this method yet

20 Code dissection map = nextMap; The final statement makes the instance variable map refer to the newly completed “next generation” nextMap. Now everything is correctly updated.

21 Counting the neighbours private int numNeighbours(int i, int j) { int n=0; int ip = (i + 1) % width; int im = (width + i - 1) % width; int jp = (j + 1) % height; int jm = (height + j - 1) % height; if (map[im][jm]) n++; if (map[im][j]) n++; if (map[im][jp]) n++; if (map[i][jm]) n++; if (map[i][jp]) n++; if (map[ip][jm]) n++; if (map[ip][j]) n++; if (map[ip][jp]) n++; return n; }

22 Code Dissection int ip = (i+1) % width; int im = (width+i-1) % width; int jp = (j+1) % height; int jm = (height+j-1) % height; int ip = (i+1) % width; int im = (width+i-1) % width; int jp = (j+1) % height; int jm = (height+j-1) % height; Here, ip, im, jp, and jm refer to i+1, i-1, j+1 and j-1 respectively [i-1][j-1][i][j-1][i+1][j-1] [i-1][j][i][j][i+1][j] [i-1][j+1][i][j+1][i+1][j+1]

23 Dealing with wrap-around When i is equal to width-1, then i+1 is equal to width, which is off the right- hand side of the picture. Calculating (i+1)%width has the effect of “wrapping around” back to 0, which is what is needed. Similarly when i is equal to 0, then (width+i-1)%width “wraps around” back to width-1. When i is equal to width-1, then i+1 is equal to width, which is off the right- hand side of the picture. Calculating (i+1)%width has the effect of “wrapping around” back to 0, which is what is needed. Similarly when i is equal to 0, then (width+i-1)%width “wraps around” back to width-1. (i,j)

24 More dissection if (map[im][jm]) n++; if (map[im][j]) n++; if (map[im][jp]) n++; if (map[i][jm]) n++; if (map[i][jp]) n++; if (map[ip][jm]) n++; if (map[ip][j]) n++; if (map[ip][jp]) n++; return n; This is simply eight if statements that increment the variable n if the corresponding cell is occupied. Finally n is returned. Notice that the method is private, and only to be used by the Life object itself. This is simply eight if statements that increment the variable n if the corresponding cell is occupied. Finally n is returned. Notice that the method is private, and only to be used by the Life object itself.

25 One performance issue As written, this code consumes a large amount of memory mapnextMap

26 What happens during the update? After the statement map = nextMap mapnextMap

27 When the method finishes The variable nextMap disappears map This area of memory is now “garbage”

28 Garbage Collection Java will automatically “collect” the garbage for you and recycle the space, but there is a performance penalty associated with this If the world is large and you are simulating many generations, the memory will rapidly fill up and the garbage collector will interrupt the smooth “animation” To fix this, it is better to keep two “maps of the world” as instance variables and just swap them over at each generation private boolean[][] map, nextMap;

29 In the nextGeneration() method Delete the code boolean[][] nextMap = new boolean[width][height]; because we do not want to create a new array every generation, but instead re-use the instance variable nextMap Replace map = nextMap; with boolean[][] swap = map; map = nextMap; nextMap = swap;

30 How does this work? mapnextMapswap swap = map;

31 Contd. mapnextMapswap map = nextMap;

32 Contd. mapnextMapswap nextMap = swap;

33 When the method finishes mapnextMap swap disappears

34 Program Design Recall that our program design called for three classes Life LifeViewer SimpleCanvas The internal structure of the Life class has been written Now we must decide How the LifeViewer interacts with the Life object The internal structure of the LifeViewer object

35 Interaction The LifeViewer needs the Life object to do the following: Send the data for the current generation to be displayed Update to the next generation when required This means that the Life class must have the following methods public boolean[][] getMap() When called, this will return the array representing the current map public void nextGeneration() When called, this will update the Life object to the next generation

36 The extra method for Life public boolean[][] getMap() { return map; } Very simple method; simply returns a reference to the array representing the current generation

37 Variables defined in LifeViewer public class LifeViewer { private Life life; private int width, height; private SimpleCanvas c; private final static int CELL_SIZE = 4; private final static Color BACK_COLOUR = Color.white; private final static Color CELL_COLOUR = Color.red; private final static Color GRID_COLOUR = Color.black;

38 Instance Variables for LifeViewer public class LifeViewer { private Life life; private int width, height; private SimpleCanvas c; Each LifeViewer is responsible for displaying one Life object The width and height are stored as instance variables for convenience Each LifeViewer has one SimpleCanvas on which to draw

39 Class Variables for LifeViewer private final static int CELL_SIZE = 4; private final static Color BACK_COLOUR = Color.white; private final static Color CELL_COLOUR = Color.red; private final static Color GRID_COLOUR = Color.black; Here we define useful constants for the size of the cells and the colours to be used for the drawing. They are declared final because they will not change during one run of the program.

40 The constructor for LifeViewer public LifeViewer(Life life) { this.life = life; width = life.getMap().length; height = life.getMap()[0].length; c = new SimpleCanvas("Life", width * CELL_SIZE + 1, height * CELL_SIZE + 1, BACK_COLOUR); display(); }

41 What the constructor does public LifeViewer(Life life) { this.life = life; width = life.getMap().length; height = life.getMap()[0].length; The constructor’s job is to initialize all the instance variables; the argument is an instance of the class Life, and so this must be saved in the corresponding instance variable. The width and height variables are then determined by asking the life object for a reference to its 2-d boolean array, and finding its dimensions The user must pass the LifeViewer an instance of Life to be displayed

42 The constructor for LifeViewer c = new SimpleCanvas("Life", width * CELL_SIZE + 1, height * CELL_SIZE + 1, BACK_COLOUR); CELL_SIZE We need the “+1” to give the right hand edge and the bottom edge a nice border +1

43 Displaying the Life object Now we need a method to display the Life object This is basically three steps get the current map from the Life object draw the appropriate picture on the drawing area, which will involve painting every cell of the grid the right colour call c.repaint() to have the drawing rendered to the screen (It would be better to re-draw only the cells which have changed in the latest generation – how would you do that?)

44 A method to display the Life object private void display() { drawCells(); drawGrid(); c.repaint(); } Notice how the displaying functions – drawing the cells and drawing the grid – are all migrated to separate methods; this makes for code that is easy to read and to update

45 Drawing the cells private void drawCells() { Color col; for (int i = 0; i < width; i++) for (int j = 0; j < height; j++) { if (life.getMap()[i][j]) col = CELL_COLUR; else col = BACK_COLOUR; c.setForegroundColour(col); c.drawRectangle(i * CELL_SIZE, j * CELL_SIZE, (i+1) * CELL_SIZE, (j+1) * CELL_SIZE); } For each cell in the array, set the colour and draw a rectangle of that colour at the appropriate coordinates

private void drawGrid() { c.setForegroundColour(GRID_COLOUR); for (int i = 0; i <= width; i++) c.drawLine(i * CELL_SIZE, 0, i * CELL_SIZE, height * CELL_SIZE); for (int j = 0; j <= height; j++) c.drawLine(0, j * CELL_SIZE, width * CELL_SIZE, j * CELL_SIZE); } 46 Drawing the grid Draw the vertical grid lines (constant x-values, full height) Draw the horizontal grid lines (constant y-values, full width) Why <= ? Because if there are n cells, we want n+1 lines in the grid (to include the edges)

47 Animating the display public void animate(int n) { for (int i=0; i < n; i++) { life.nextGeneration(); display(); c.wait(250); } The only public method is the one that allows the user to specify that they want to see n generations of “The Game of Life”; it is a simple loop that asks the Life object to calculate the next generation, displays it, and waits briefly to give an “animated” effect

48 Create the Life object

49 It appears on the workbench

50 Now create a LifeViewer to view it

51 The initial randomly chosen configuration is displayed on a SimpleCanvas

52 After 100 generations, the map looks a bit more “organized”

53 A new colour scheme can be obtained just by changing the three constants