244 lines
4.9 KiB
C++
244 lines
4.9 KiB
C++
/*
|
|
* Hw01_121044046.cpp
|
|
*
|
|
* Created on: 23 Eyl 2014
|
|
* Author: Yakup TURKAN
|
|
*
|
|
* Project Name : The Game of Life
|
|
* Purpose : Implementing game of life(Von
|
|
*/
|
|
|
|
#include <iostream>
|
|
#include <cstdlib>
|
|
#include <cstdio>
|
|
|
|
using namespace std;
|
|
|
|
#define FILLER "-"
|
|
|
|
#ifndef TRUE
|
|
#define TRUE 1
|
|
#endif
|
|
#ifndef FALSE
|
|
#define FALSE 0
|
|
#endif
|
|
|
|
//Prototypes
|
|
struct cell_s {
|
|
int isAlive; //1 = Alive 0 = Dead
|
|
};
|
|
|
|
struct board_s {
|
|
int rowc;
|
|
int colc;
|
|
struct cell_s *cells;
|
|
};
|
|
|
|
struct event_s {
|
|
struct cell_s *cell;
|
|
struct event_s *nextEvent;
|
|
};
|
|
|
|
struct board_s *initBoard(char *filename);
|
|
void nextStep(struct board_s *board);
|
|
void printBoard(struct board_s *board);
|
|
void printBoard(struct board_s *board, char *filename);
|
|
struct cell_s *getCell(struct board_s *board, int x, int y);
|
|
struct event_s *addEvent(struct event_s *eventc, struct cell_s *cell);
|
|
struct event_s *queEvents(struct board_s *board);
|
|
void pollEvents(struct event_s *eventh);
|
|
|
|
int main(int argc, char **argv) {
|
|
char filename[FILENAME_MAX];
|
|
struct board_s *board;
|
|
int stepc;
|
|
|
|
cout << "Please enter the file name : ";
|
|
cin >> filename;
|
|
|
|
cout << "Initial form of file : " << endl;
|
|
board = initBoard(filename);
|
|
printBoard(board);
|
|
|
|
cout << "How many steps you want to see ? : ";
|
|
cin >> stepc;
|
|
|
|
while (cin.get() != '\n');
|
|
|
|
for (int i = 0; i < stepc; ++i) {
|
|
cout << "Step " << i + 1 << " : " << endl;
|
|
nextStep(board);
|
|
printBoard(board);
|
|
while (cin.get() != '\n')
|
|
;
|
|
}
|
|
|
|
cout << "Please enter the output file name : ";
|
|
cin >> filename;
|
|
|
|
printBoard(board, filename);
|
|
|
|
free(board->cells);
|
|
return 0;
|
|
}
|
|
|
|
struct board_s *initBoard(char *filename) {
|
|
FILE *file;
|
|
static struct board_s board;
|
|
int rowc, colc;
|
|
char c;
|
|
|
|
file = fopen(filename, "r");
|
|
|
|
if (file != NULL) {
|
|
fscanf(file, "%d %d%c", &rowc, &colc,&c);
|
|
|
|
if (c == '\r')
|
|
fscanf(file, "%c", &c);
|
|
|
|
board.rowc = rowc;
|
|
board.colc = colc;
|
|
board.cells = (struct cell_s *) malloc(
|
|
sizeof(struct cell_s) * rowc * colc);
|
|
|
|
for (int i = 0; i < rowc; ++i) {
|
|
for (int j = 0; j < colc; ++j) {
|
|
fscanf(file, "%c", &c);
|
|
|
|
if (c == 'X' || c == 'x')
|
|
board.cells[i * colc + j].isAlive = TRUE;
|
|
else
|
|
board.cells[i * colc + j].isAlive = FALSE;
|
|
}
|
|
fscanf(file, "%c", &c);
|
|
|
|
if (c == '\r')
|
|
fscanf(file, "%c", &c);
|
|
}
|
|
} else
|
|
cout << "Error occurred : Cannot read file." << endl
|
|
<< "Please make sure file exists."
|
|
<< " If error persists contact with writer." << endl;
|
|
|
|
fclose(file);
|
|
return &board;
|
|
}
|
|
|
|
void nextStep(struct board_s *board) {
|
|
pollEvents(queEvents(board));
|
|
}
|
|
|
|
void printBoard(struct board_s *board) {
|
|
struct cell_s *cells = board->cells;
|
|
int rowc = board->rowc, colc = board->colc;
|
|
|
|
for (int i = 0; i < rowc; ++i) {
|
|
for (int j = 0; j < colc; ++j)
|
|
if (cells[i * colc + j].isAlive)
|
|
cout << 'X';
|
|
else
|
|
cout << FILLER;
|
|
cout << endl;
|
|
}
|
|
}
|
|
|
|
void printBoard(struct board_s *board, char *filename) {
|
|
struct cell_s *cells = board->cells;
|
|
int rowc = board->rowc, colc = board->colc;
|
|
FILE *outp;
|
|
|
|
outp = fopen(filename, "w");
|
|
|
|
if (outp == NULL) {
|
|
cout << "An error occurred : Cannot write to file!" << endl
|
|
<< "Please contact with writer." << endl;
|
|
} else {
|
|
for (int i = 0; i < rowc; ++i) {
|
|
for (int j = 0; j < colc; ++j)
|
|
if (cells[i * colc + j].isAlive)
|
|
fprintf(outp, "X");
|
|
else
|
|
fprintf(outp, FILLER);
|
|
fprintf(outp, "\n");
|
|
}
|
|
fclose(outp);
|
|
}
|
|
}
|
|
|
|
struct cell_s *getCell(struct board_s *board, int x, int y) {
|
|
if (x >= 0 && x < board->colc)
|
|
if (y >= 0 && y < board->rowc)
|
|
return &(board->cells[y * board->colc + x]);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
struct event_s *addEvent(struct event_s *eventc, struct cell_s *cell) {
|
|
struct event_s *eventn;
|
|
|
|
eventn = (struct event_s *) malloc(sizeof(struct event_s));
|
|
eventn->cell = cell;
|
|
eventn->nextEvent = NULL;
|
|
|
|
if (eventc != NULL)
|
|
eventc->nextEvent = eventn;
|
|
|
|
return eventn;
|
|
}
|
|
|
|
struct event_s *queEvents(struct board_s *board) {
|
|
struct cell_s *cellc, *celln;
|
|
struct event_s *eventh = NULL, *eventc = NULL;
|
|
int ans, //Alive Neighbor Count
|
|
shouldAdd;
|
|
|
|
for (int row = 0; row < board->rowc; ++row) {
|
|
for (int col = 0; col < board->colc; ++col) {
|
|
ans = 0;
|
|
shouldAdd = TRUE;
|
|
cellc = getCell(board, col, row);
|
|
|
|
for (int distx = -1; distx < 2; ++distx) {
|
|
for (int disty = -1; disty < 2; ++disty) {
|
|
celln = getCell(board, distx + col, row + disty);
|
|
if (celln != NULL && celln->isAlive)
|
|
++ans;
|
|
}
|
|
}
|
|
|
|
if (cellc->isAlive) {
|
|
if (ans == 3 || ans == 4)
|
|
shouldAdd = FALSE;
|
|
} else if (ans != 3)
|
|
shouldAdd = FALSE;
|
|
|
|
if (shouldAdd) {
|
|
if (eventh == NULL) {
|
|
eventh = addEvent(eventh, cellc);
|
|
eventc = eventh;
|
|
} else
|
|
eventc = addEvent(eventc, cellc);
|
|
}
|
|
}
|
|
}
|
|
|
|
return eventh;
|
|
}
|
|
|
|
void pollEvents(struct event_s *eventh) {
|
|
struct cell_s *cell;
|
|
|
|
if (eventh != NULL) {
|
|
cell = eventh->cell;
|
|
|
|
//Births
|
|
if (!cell->isAlive)
|
|
cell->isAlive = TRUE;
|
|
//Deaths
|
|
else if (cell->isAlive)
|
|
cell->isAlive = FALSE;
|
|
|
|
pollEvents(eventh->nextEvent);
|
|
free(eventh);
|
|
}
|
|
}
|