BU CAS CS 113
Introduction to Computer Science II with Intensive C
Fall 1997


Assignment 4


Last Modified: Tue Oct 28 13:29:11 1997

Deadline

October 16, 1996

What to Submit

You should submit three files. Be sure the files you submit have exactly the following names: hw4-koch.c hw4-madlib.c hw4-life.c .

These programs are to be electronically submitted by using the submit program on csa. The code you submit should conform with the program assignment guidelines.

Assignment

  1. Koch's Snowflake (see PAC, 217--220)

    Write a program to display Koch's snowflake using the turtle graphics routines to do the drawing. Since Roberts does not assume a turtle graphics library, some of what he says should be ignored, since you can do things more easily now that you have turtle graphics to work with. (Ignore Robert's comments about DrawPolarLine(), for example, since having the turtle "remember" its direction and able to draw forward makes this problem even easier.) For the turtle graphics, you may link your program against my turtle.o as in the Makefile. In any case, you only need to submit the main program. I will test it by linking it with my turtle package.

    The function(s) which you write for drawing the snowflake must be recursive. In particular, there should be NO LOOPING CONSTRUCTS in your program. (No for, while, do, etc.)

    You should write your program by filling the missing comments and code in the following shell:

    
    /* program shell for hw4, fall 1997 */
    
    /* edit this file, adding CODE and COMMENTS as necessary. */
    
    #include <stdlib.h>
    #include "turtle.h"	/* a version of turtle.h has been placed where 
    			 * it can be read */
    #include "simpio.h"
    #include "genlib.h"
    
    const int MAX_DEGREE = 5;
    
    void GetParameters(double *lengthPtr, int *degreePtr);
    void DrawKochSnowflake(double length, int degree);
    
    int main(void)
    {
      double length = 1;
      int degree = 1;
    
      InitTurtle();
    
      GetParameters(&length, & degree);
    
      /* 
       * position and orient turtle to keep it roughly centered
       * move up 2/3 of length, then turn right 150 degrees so turtle is
       * ready to move down the right side of the "triangle" which forms basis
       * for the snowflake. 
       *
       *                  /\  <- start here and go down right side first
       *                 /  \
       *                /    \
       *               /______\
       */
    
      MoveTurtle(length * 2.0 / 3.0);  
      TurnRight(150);
    
      DrawKochSnowflake(length,degree);
    
      return(0);
    
    }
    
    void GetParameters(double *lengthPtr, int *degreePtr)
    {
      printf("Enter the length of one side: ");
      *lengthPtr = GetReal();
      printf("Enter degree of snowflake (max = %i): ",MAX_DEGREE);
      *degreePtr = GetInteger();
      
     
      if (*degreePtr > MAX_DEGREE) {
        *degreePtr = MAX_DEGREE;
        printf("Your degree is too large. Using %d instead.",*degreePtr);
      }
      if (*degreePtr < 0) {
        *degreePtr = 0;
        printf("Your degree is too small. Using %d instead.",*degreePtr);
      }
    }
    
    
    Given the shell above, there are actually very few lines of code required for this program. The difficult part is figuring out how to solve the problem recursively. One hint: you will probably want to think about a Koch snowflake as a triangle made of three Koch lines.

  2. Madlibs (see PAC, 157, problem 10) This one can be done just as explained in the text.

  3. Conway's Game of Life

    Life and Death in Conway's world.

    Life is a game played on a "checkerboard". Each square of the checkerboard is a cell. At any time some of the cells will be alive and others dead. Which cells are alive at time 0 can be arbitrarily determined. Thereafter, the state of the cells at any later time follows from the previous one by the rules of the game:

    Representation.

    The sequences of pictures below represent a typical life history. A line of 5 live cells is chosen for generation 0. Living cells are represented by o, dead cells by a period. All cells not pictured are assumed to be dead.

    One cell of the board may be designated as the "home base". To make the home base visible, it is marked with O when alive and : when dead. Note that the home base, may not be at the center of the displayed portion of the board. Some notes on the transitions from one time to the next are given below the example. Note that I have only displayed as much of the board as necessary to see the live cells.

    
    
    t=0		t=1		t=2		t=3		t=4
    
    .......		....... 	.......		.......		.......
    .ooOoo.		..ooo..		...o...		...o...		..ooo..
    .......		..oOo..		..o.o..		..ooo..		.o...o.
           		..ooo..		.o.:.o.		.oo:oo.		.o.:.o.
           		.......		..o.o..		..ooo..		.o...o.
           		       		...o...		...o...		..ooo..
           		       		.......		.......		.......
    
    
    t=5		t=6		t=7		t=8
    
    .........	.........	...........	same as t=6
    ....o....	...ooo...	.....o.....	
    ...ooo...	.........	.....o.....
    ..o.o.o..	.o.....o.	.....o.....	
    .ooo:ooo.	.o..:..o.	...........	
    ..o.o.o..	.o.....o.	.ooo.:.ooo.	
    ...ooo...	.........	...........	
    ....o....	...ooo...	.....o.....	
    .........	.........	.....o.....	
    				.....o.....
    				...........
    
    

    In this sequence:

    Time 0->1:
    The three inner cells each have two neighbors and will survive. The three cells just above these, and the three cells just below, are born, because they each have three neighbors.

    Time 1->2:
    The corners will survive because they each have exactly three neighbors. All the other cells will die of overcrowding. Four cells will be born by the middle of each side.

    Time 2->3:
    Every living cell has exactly two neighbors, so none die. A birth "in each corner."

    Time 3->4:
    Overcrowding kills all except the 4 outer cells.

    Time 4->5:
    Every living cell has exactly 2 neighbors, so none die. Birth along each row of three.

    Time 5->6:
    Overcrowding kills all but 4 cells. Birth on either side of each of these 4.

    Time 6->7->8->9.....:
    At each generation the tips of the Blinkers die of exposure. The births on each side reform the line in a perpendicular direction. Thus these two situations will alternate forever.

    Other Examples.

    Although I cannot guarantee that its rules are identical to the ones here (especially with respect to the edges of the board) you might want to check out a version of Conway's Game of Life which you can play on the WWW at http://www.research.digital.com/nsl/projects/life/life.html. You may find this a handy thing to use to test and debug your program.

    Programming Assignment.

    Write a program which simulates Conway's Game of Life. Your program should take a file name as an argument, read from that file the initial configuration and simulation information and then simulate the game as specified in the file. Here is a shell which gets the file name from the argument list for you and also demonstrates a possible structure for the program. (Other structures are possible, some are actually better.)

    #include <stdio.h>
    #include "genlib.h"
    #include "simpio.h"
    #indlude "strlib.h"
    
    int main(int argc, string argv[])
    {
      string fileName;
      int  roundsToSimulate, roundsToDisplay;
      lifeBoardT board;
    
      /* if syntax is wrong, exit with error message */
      if (argc != 2) {Error("Syntax: $s ", argv[0]);}
      
      fileName = CopyString(argv[1]);
    
      ReadGameFile(fileName, &board, &roundsToSimulate, &roundsToDisplay);
    
      SimulateGame(board, roundsToSimulate, roundsToDisplay);
     
      return(0); 
    }
    

    1. Input. The format of the input file should be:
      • on the first line: two integers separated by a space, giving the number of rows and columns (in that order) in the board.
      • on the second line: two integers separated by a space, giving the number of rounds to simulate (= last value of t) and the number of rounds to display. (Display half at the beginning, half at end).
      • on subsequent lines: each line represents one row of the board.
      You may assume that the format of the redirected file is correct. Here is an example input file which should generate the example above.
      12 11
      9 9
      ...........
      ...........
      ...........
      ...........
      ...........
      ...........
      ...ooOoo...
      ...........
      ...........
      ...........
      ...........
      ...........
      

    2. Output. Your program should output the number of boards specified in the input file (half at the beginning of the simulation, half at the end, you may round either way). Each board should be identified by number and use the format explained above. Unlike the example, you do not have to display boards next to each other. They may appear one after the other with a couple of blank lines between successive rounds. Also, unlike the example, your boards may all be the same size. (I omitted unnecessary stuff to save space.)

    Implementation Notes.

Extra Credit. As we have defined the game, the board is finite. One could consider a version of the game where the board is infinite, but the amount of "life" is always finite. Any squares "off the edges" of the displayed portion of the board are considered dead. In this version, life can spread beyond the original edges of the board. To implement this, you need to dynamically allocate new space for the board when this happens. (This is somewhat like GetDynamicIntegerArray.) The output would then look just like the example above, the board growing as the life spreads beyond the edges.

You may program a version which allows for a "growing board" for extra credit. You might want to get the required version running first, though, just to be safe. If you do it wisely, it should not cost you any time to do the required version first and then extend it. Your boards do not have to shrink if the live cells near the edges start dying off.

Makefile

To check that your assignment compiles correctly, use the Makefile for this assignment:
  1. Copy this Makefile into the directory where your programs are.
  2. Name it Makefile.
  3. type: make -k. (The -k means "keep going", which instructs make to build as much as it can, rather than quit after the first error.)

Academic Honesty and Collaboration

It is reasonable to discuss with others possible general approaches to problems. It is unreasonable to work together on a detailed solution, to copy a solution, or to give away a solution. If your common discussion can be detected by looking at the solutions, then there is too much collaboration. Such instances of academic dishonesty may result in a course grade of F or expulsion from Boston University.

Do not allow your work to be used by others:

Warning: If someone cheats by using your work, you will also be penalized.