Hey.
I've seen that it has been posted about on this forum before, but little information was made available, so I'll start a new thread.
Before I start, I must note: I will be careful when posting bits of code to do with this. I know that my University and many others set this regularly, so I don't want to paste too much to give away what I have to other readers. I will paste where I feel it's necessary though.
The exercise states that we have to complete Conway's Game of Life by implementing two functions: evolve and rotate (the main function is already given, as is a 'load' function which loads a file [given as a parameter - determines how the game 'starts']). Rotate hasn't much to do with the game itself - once called, it rotates the grid 90 degrees clockwise. Evolve is the meat of the exercise, and is the one which determines when a neighbour character appears and disappears.
The exercise states that the grid used in our assessment needs to be an array of character pointers - thus, the headings for each function are as follows:
char **rotate(char **arena, int *pwidth, int *pheight)
void evolve(char **arena, int width, int height)
Another huge part of the assessment is that, when a column of the grid is in use (has one or more characters present), it must be dynamically allocated memory. When a column is not in use, that memory must be free. (So, it's a malloc()/free() exercise mainly).
I am currently struggling with rotate and do not know where to start with evolve. We are given an evolve function that works, but uses a simple 2-dimensional array of characters:
Code:
static void
evolve(char arena[WIDTH][HEIGHT])
{
int x, y;
// First shift each cell to the left so its occupied status
// is in bit 1 rather than bit 0
for (x = 0; x < WIDTH; x++)
for (y = 0; y < HEIGHT; y++)
arena[x][y] <<= 1;
// Decide whether each cell should be occupied based on the
// number of previously occupied neighbours etc.
for (x = 0; x < WIDTH; x++)
for (y = 0; y < HEIGHT; y++) {
int neighbours = 0;
neighbours += WAS_OCCUPIED_ANY(arena, x - 1, y - 1);
neighbours += WAS_OCCUPIED_ANY(arena, x - 1, y);
neighbours += WAS_OCCUPIED_ANY(arena, x - 1, y + 1);
neighbours += WAS_OCCUPIED_ANY(arena, x, y - 1);
neighbours += WAS_OCCUPIED_ANY(arena, x, y + 1);
neighbours += WAS_OCCUPIED_ANY(arena, x + 1, y - 1);
neighbours += WAS_OCCUPIED_ANY(arena, x + 1, y);
neighbours += WAS_OCCUPIED_ANY(arena, x + 1, y + 1);
if (neighbours == 3 || (neighbours == 2 && WAS_OCCUPIED_ANY(arena,x,y)))
arena[x][y] |= 1;
}
}
(A few defines to match)
Code:
#define IN_ARENA(x,y) ((x) >= 0 && (x) < WIDTH && (y) >= 0 && (y) < HEIGHT)
#define WAS_OCCUPIED(a, x, y) (a[x][y] >> 1 & 1)
#define IS_OCCUPIED(a, x, y) (a[x][y] & 1)
#define WAS_OCCUPIED_ANY(a, x, y) (IN_ARENA(x,y) ? WAS_OCCUPIED(a, x, y) : 0)
My few questions:
- I have code for 'rotate', but I get a segmentation fault upon running the program (so I've gone wrong with the memory allocation somewhere!). Is someone willing to help me via PMs? I wouldn't want to paste my code publically, as it could encourage plagiarism.
- Where would I start when tackling the 'evolve' function? Would I be able to cleverly alter the one we're already given to work with an array of pointers, rather than a 2D array?
Thanks for the help.
If it helps, here is the main file (need not be changed):
Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "life.h"
#include "load.h"
#include "rotate.h"
#include "evolve.h"
#define MAX_CYCLES 100
#define ROTATE 20
/* Display the arena in a vt100 (xterm) terminal with the given width and height.
*/
static void
show(char **arena, int width, int height)
{
int x, y;
printf("\033[2J");
for (x = 0; x < width; x++)
if (arena[x] != NULL)
for (y = 0; y < height; y++) {
if (arena[x][y] & 1)
printf("\033[%d;%dH*", y, x);
}
printf("\033[H");
fflush(stdout);
}
int main(int argc, char **argv)
{
char **arena;
int width = WIDTH, height = HEIGHT;
int cycle;
if (argc != 2 && argc != 4) {
fprintf(stderr,"usage is %s filename [ width height ]\n",argv[0]);
exit(1);
}
if (argc == 4) {
width = atoi(argv[2]);
height = atoi(argv[3]);
if (width < MINSIZE || width > MAXSIZE || height < MINSIZE || height > MAXSIZE) {
fprintf(stderr, "%s: width and height must be in the range %d to %d\n",
argv[0], MINSIZE, MAXSIZE);
exit(1);
}
}
if ((arena = load(argv[1], width, height)) == NULL) {
fprintf(stderr,"%s: Cannot open %s\n",argv[0],argv[1]);
exit(1);
}
for (cycle = 1; cycle <= MAX_CYCLES; cycle++) {
show(arena, width, height);
evolve(arena, width, height);
if (cycle % ROTATE == 0)
arena = rotate(arena, &width, &height);
/* Add a 1/10 sec delay so that we can see what is happening.
*/
usleep(100000);
}
int x;
for (x = 0; x < width; x++)
if (arena[x] != NULL)
free(arena[x]);
free(arena);
return 0;
}
(Edit: Just read that I can't actually SEND PM's until I have posted 10 times. If somebody offers to help me before that happens, I'll be more than glad to give out my email address. I'm not a spam bot, don't worry).