Programming Projects in C
for students of
Engineering, Sciences and Mathematics
Rouben Rostamian
2014

Resources for Project Evolution

You will need the following files to produce graphical output out of Chapter 17's Project Evolution as explained in the book.

	world-to-eps.h    world-to-eps.c

Notes and errata

An alternative path to Project Evolution

The book's Project Evolution depends on Chapter 7's Project Fetchline. It is possible to bypass that prerequisite if you are willing to sacrifice some of the program's flexibility. Specifically, the book's version of evolution reads its input data from a World Description File (WDF) which is a plain text file. To change the input data, we edit the WDF; the program itself is not modified. The Fetchline module is needed to read the WDF.

The alternative which I outline below has no WDF file, therefore it has no need for the Fetchline module because the simulation's data is built into the C program. This reduces the program's complexity. The price we pay is that whenever we change the data we have to recompile the program.

To produce this alternative version, we remove the files read.[ch] and fetch-line.[ch] from the program's directory. The new directory looks like this:

$ cd evolution
$ ls -F
Makefile     evolution.h     linked-list.h@  world-to-eps.c  write.h
array.h@     interlude.c     world-spec.c    world-to-eps.h  xmalloc.c@
evolution.c  linked-list.c@  world-spec.h    write.c         xmalloc.h@
The files world-spec.[ch] are new. This is where the user enters the simulation's data, and compiles it along with the rest of the files. I will describe their contents here.

The file world-spec.c

Here is an outline of the file world-spec.c:

#include "array.h"
#include "linked-list.h"
#include "world-spec.h"

void free_herd(conscell *herd)
{
    ...
}

void free_world(struct world *world)
{
	...
}

struct world *make_world(void)
{
        static struct world World = {    // C99-style initialization!
                .world_h        = 100,
                .world_w        = 100,
                .eden_h         = 10,
                .eden_w         = 10,
                .plant_energy   = 80,
                .reproduction_threshold = 300,
                .plants         = NULL,
                .herd           = NULL,
        };
        struct world *world = &World;
        struct animal *animal;

        // Allocate a matrix to hold the plants and zeros all its entries.
        // Thus, we begin with no plants at all.
        make_matrix(world->plants, world->world_h, world->world_w);
        for (int i = 0; i < world->world_h; i++)
                for (int j = 0; j < world->world_w; j++)
                        world->plants[i][j] = 0;

        animal = xmalloc(sizeof *animal);
        animal->i = 50;
        animal->j = 50;
        animal->d = 0;
        animal->e = 250;
        for (int i = 0; i < 8; i++)
                animal->genes[i] = 5;
        world->herd = ll_push(world->herd, animal);

        /* repeat the stanza above any number of times
           if you wish to add more animals */

        return world;
}
The functions free_herd() is described on the book's page 182. The book's version places it in the file evolution.c. In this alternative version we move it to world-spec.c because that is where it more naturally belongs.

The function free_world() is new. It is called at the end of the program, just before it exits, to free the allocated memory resources, which are

  1. the herd;
  2. the matrix of plants.
You should be able to supply the details.

The function make_world() is shown in its entirety. I defines a structure to hold the world specification, with the plants and herd members set to NULL. Subsequently it allocates a matrix of plants according to the world's dimensions and zeros all its entries, indicating that the world starts off with no food supply.

The file world-spec.h

You will supply a header file world-spec.h which constitutes an interface to the implementation in world-spec.c.

Changes in evolution.c

The changes to evolution.c are minimal. In Listing 17.12 on page 177:

  1. Replace read.h on line 5 with world-spec.h;
  2. Delete line 15 since free_herd() has moved to the file world-spec.c (see above);
  3. Delete line 20; the role of initialize_plants() function now is subsumed in the for-loop within the body of the function make_world() show above;
In Listing 17.13 on page 178:
  1. Replace lines 5–6 with
    struct world *world = NULL;
    
  2. Delete lines 8–9.
  3. Replace lines 26–29 with
    world = make_world();
    
  4. Replace lines 42–43 with
    free_world(world);
    

Finally, the Usage message, shown in the lower half of page 167 should be adjusted appropriately since we no longer read from a WDF.



Programming Projects in C Valid HTML 5 Valid CSS