Introduction To MATLAB Programming

Conway Game of Life

This unit challenges you to employ the skills that you have acquired in more complex tasks, as well as in a larger coding project. The project is an implementation of the Conway Game of Life, in which cells in a 2D grid are labeled as either “alive” or “dead.” The game runs according to a defined set of rules, and you will be responsible for calculating each state of the cells, updating the grid, and plotting the grid. Other avenues of exploration and variations to the game are also proposed for your implementation.

Warm-up

In all the following questions you are expected to have an “elegant” solution, not a brute force one. No if statements or loops. Unless where specifically noted, no MATLAB® functions are to be used.

  1. Find out what the command diag does. (We already learned about oneszeros, and sum, but if you are unsure, look them up as well.) Using sum and diag, find the sum of the diagonal of a matrix. (For example, A in the next question.)
  2. Let A=magic(6). What expression will give you the 2×2 submatrix of elements in the upper left corner? How about lower right? Can you write an expression that will also work for any other matrix A, for example A=magic(10)?
  3. Find the sub-matrix of elements of A whose both coordinates are odd.
  4. With no MATLAB functions, write the matrix A “flipped” right to left. Up to down.
  5. Get the sum of the “anti diagonal” of the magic square by a simple expression using sumdiag and the colon (:) notation.
  6. Let x = [2 5 1 6]. Add 3 to just the odd-positioned elements (resulting in a 2-vector). Now write the expression that adds 3 to the odd-positioned elements and puts the result in the even positions of the original x vector.
  7. Let y = [4 2 1 3]. Think of y as a specific reordering (permutation) of the numbers {1,2,3,4}. “4 goes to 1, 2 remains, 1 goes to 3 and 3 goes to 4.” Use y to reorder the elements of x in the same manner. (The result should be [6 5 2 1].)
  8. What is the vector that corresponds to the permutation of n elements that takes every element one position to the left, except for the first element, which goes to the end?
  9. (Bonus) The inverse of a permutation y is a permutation z that, when combined with y (in either order) gives the original (non-permuted) elements. Given a permutation vector (as y is in the previous question), find the vector z which corresponds to the inverse of y.
  10. Experiment with assignments such as b(1:3,1:2:4)=1. Make a “checkerboard” matrix: an 8-by-8 matrix whose cell a(i,j) equals 1 if i+j is odd and 0 if it is even. (Of course, do not use loops or if statements!) If you like, use the function spy or pcolor to “see” the checkerboard that you created. (Tricky. Do it in two commands, not one. If you want to do this with one command you may use ones. Also possible using mod and reshape.)
  11. Recall that a matrix (such as A) can also be referenced using a single coordinate: A(3). Remind yourself how this coordinate is related to the original matrix.
  12. Use the single index reference to a matrix in order to extract the diagonal of a 5-by-5 matrix. (Do not use the function diag.) Do the same to extract the “anti-diagonal”.

Conway Game of Life Implementation

This project implements the Conway Game of Life. Idea: The world consists of a 2D grid. Each cell in the grid can be “alive” or “dead”. At each step the cells are updated according to the following rules:

  • A dead cell will become alive if it has exactly 3 live neighbors (each non-boundary cell has 8 neighbors in this grid).
  • A live cell will die unless it has 2 or 3 live neighbors.

We use a matrix to hold the grid. A cell is “alive” if the relevant matrix element is 1 and “dead” if 0. Several steps are needed:

  1. Figure out how many live neighbors each cell has.
  2. Update the grid.
  3. Plot the grid.

Homework 9. Implement the Conway Game of Life by iterating over all the grid cells and for each one counting the neighbors. You can either be careful not to access elements that are beyond the limits of the matrix, or make the matrix slightly larger and only iterate over the “middle” part of the matrix. Start with a small grid, as this is a very inefficient method upon which we will improve. To plot the grid use pcolor. Make sure you first calculate the number of neighbors and then update the grid, otherwise your update of early cells will interfere with the calculation of the later cells.

As you can easily see when trying to increase the size of the grid, this is a very inefficient method. We want to do all the tasks on a matrix-at-a-time basis, with no unneeded for loops.

The hardest part of the calculation is the neighbor-counting part. Here’s one way to do this:

Noff_r= [-1, -1, 0, 1, 1,  1,  0, -1]; %the row offset of the 8 neighbors 
Noff_c=[ 0,  1, 1, 1, 0, -1, -1, -1]; %the column offset of the 8 neighbors
n N=numel(Noff_r); % the number of neighbors each element has
count = zeros(size(A)-[2 2]); %A is the grid with a border of zeros
for j j=1:n N
      count=count + A(Noff_r(jj)+(2:end-1),Noff_c(jj)+(2:end-1)); %this is the heart
end %now count will have the correct number of alive neighbors.

Exercise 20. It takes time and practice to understand code. Explain to a friend, or a classmate how this code works.

Exercise 21. Here are various parts of the next step:

  • Given the matrix count find the logical expression that informs which elements of A(2:end-1,2:end-1) have 2 or 3 neighbors.
  • Find the truth matrix specifiying the elements that need to “die” according to the count.
  • Find the truth matrix specifiying the elements that need to be “born” according to the count.
  • Find the elements that are alive and need to remain so.
  • Update A according to the rules.
  • Show the grid using pcolor.

Homework 10. (Bonus) Counting neighbors can be done as a single linear algebra multiplication of A(:) by a large, mostly empty matrix. Figure out how this is possible, and implement it. Since the matrix is so large, use a sparse matrix.

Project 3. Now that we have all the parts (refer to Homework 9, Exercise 20, Exercise 21, and Homework 10), here’s the project: Initialize the board using rand. Put the counting, updating, plotting parts of the game into a loop. When busy calculating MATLAB® avoids updating the plots. To force MATLAB to update the plots, place a pause(0.1) after pcolor.

Once you have the basic dynamics working, there are various directions for further study:

  • You will find that a large grid still requires too much memory and computation time. Since the matrices A and count are mostly zeros, it can be beneficial to use a sparse matrix for them. Figure out how to do it. To get a random sparse matrix use sprand.
  • What happens if you change the rules? You can change the birth/life/death rules, or you can change the definition of neighborhood, or both. Find an alternative dynamic with nice results.
  • A square grid is only one possibility. You could also consider a triangular or hexagonal grid. How would you implement them? Can you find nice game rules for them? How would you plot them? You cannot use pcolor any more.