Reputation: 25
I'm trying to program Conway's Game of Life in C but I am stumped as to how to store an ALIVE or DEAD cell.
The board is stored in an array of 32 unsigned longs (32x32 board) with each bit representing a cell (1 = alive, 0 = dead). I can't change this design.
So far, I have the code determining how many neighbors a particular cell has but I need to change its state based on the game's rules (a 1 may need to become either 0 or 1, a 0 may need to be either 1 or 0).
I assume I can use bitwise operations for this (|, &, ^) but I don't know how to isolate a particular bit in a row and store it as I iterate through the rest of the row and then store the new, re-calculate row as one unsigned long.
i.e. if 10011...0 needs to be 01101...1. How can I do this?
I realize the code will need additional for loops but I am just trying to wrap my head around this particular problem before proceeding.
Any help is appreciated.
#include <stdio.h>
#include <stdlib.h>
unsigned long columnMask;
int compass = 0;
int totAliveNeighbors = 0;
int iterator = 0;
int iterator2 = 0;
#define ARRAY_SIZE 32
#define NEIGHBORS 8
unsigned long grid[ARRAY_SIZE];
unsigned long copyGrid[ARRAY_SIZE];
unsigned long neighbors[NEIGHBORS];
unsigned long init32;
unsigned long holder = 0;
int main(void){
srand(time(NULL));
printf("\n");
/** Seeds the grid with random numbers **/
for(iterator = 0; iterator < 32; iterator++){
init32 = ((double)rand()/RAND_MAX)*0xFFFFFFFF;
grid[iterator] = init32;
}
/** Displays the binary representation of the grid elements **/
for(iterator = 0; iterator < 32; iterator++){
displayBinary(grid[iterator]);
printf("\n");
}
printf("\n");
/** Calculate and sum neighbors for 'x' cell **/
/** Will need to iterate through each column by shifting the mask **/
/** Will need to iterate through each row **/
iterator= 0; //example use
neighbors[0] = north(iterator);
neighbors[1] = south(iterator);
neighbors[2] = east(iterator);
neighbors[3] = west(iterator);
neighbors[4] = northWest(iterator);
neighbors[5] = northEast(iterator);
neighbors[6] = southWest(iterator);
neighbors[7] = SouthEast(iterator);
columnMask = 0x80000000//need to shift by iterator value later on
for(compass =0; compass < 8; compass++){
totAliveNeighbors += ((columnMask & neighbors[compass])?1:0);
}
}//end main
void displayBinary(unsigned long x){
unsigned long MASK = 0x80000000;
do {
//printf("%c",(x & MASK)?'X':0x20);
printf("%s", (x & MASK)?"1":"0");
} while ((MASK >>=1)!=0);
}
unsigned long north(int rowNum){
if(rowNum == 0){
return 0;
}
else
return grid[rowNum-1];
}
unsigned long west(int rowNum){
holder = grid[rowNum] >>1;
return holder;
}
unsigned long east(int rowNum){
holder = grid[rowNum] <<1;
return holder;
}
unsigned long south(int rowNum){
if(rowNum == 31)
return 0;
else
return grid[rowNum+1];
}
unsigned long northWest(int rowNum){
if(rowNum == 0)
return 0;
else{
holder = grid[rowNum-1] >>1;
return holder;
}
}
unsigned long northEast(int rowNum){
if(rowNum == 0)
return 0;
else{
holder = grid[rowNum-1] <<1;
return holder;
}
}
unsigned long southWest(int rowNum){
if(rowNum == 31)
return 0;
else{
holder = grid[rowNum+1] >>1;
return holder;
}
}
unsigned long SouthEast(int rowNum){
if(rowNum == 31)
return 0;
else{
holder = grid[rowNum+1] <<1;
return holder;
}
}
Upvotes: 2
Views: 2714
Reputation: 240591
You can set a bit by ORing (|
) with a value that has that bit set.
You can unset a bit by ANDing (&
) with a value that has every bit set except that one.
You can turn a value that has one bit set into a value that has every bit except that one set with the NOT (~
) operator.
You can tell if a bit is set by ANDing (&
) with a value that only has that bit set, and seeing whether the result is true or false.
You can make a value with the nth bit (counting from the right, with the rightmost bit named the 0th bit) set by left-shifting (<<
) the value 1
by n places.
Upvotes: 6