新手上路,能跑就行,内容不堪卒读。。。
#include <cctype>
#include <cmath>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <typeinfo>
#include "console.h"
#include "filelib.h"
#include "grid.h"
#include "gwindow.h"
#include "simpio.h"
#include "strlib.h"
#include "lifegui.h"
using namespace std;
string promptForFilename(string prompt);
void initialize_grid(ifstream &infile,Grid<char> &grid);
void print_grid(Grid<char> &grid);
void to_next_generation(Grid<char> &grid, bool wrap);
int count_neighbors(Grid<char> &grid, int r, int c);
int wrap_neighbors(Grid<char> &grid, int r, int c, int nrows, int ncols);
int unwrap_neighbors(Grid<char> &grid, int r, int c, int nrows, int ncols);
int main() {
cout<<"Welcome to the CS 106B Game of Life,\n"
<<"a simulation of the lifecycle of a bacteria colony.\n"
<<"Cells (X) live and die by the following rules:\n"
<<"- A cell with 1 or fewer neighbors dies.\n"
<<"- Locations with 2 neighbors remain stable.\n"
<<"- Locations with 3 neighbors will create life.\n"
<<"- A cell with 4 or more neighbors dies.\n"<<endl;
string filename;
filename = promptForFilename("Grid input file name? ");
ifstream infile;
infile.open(filename);
Grid<char> grid(2,2);//grid要先给一个初始大小,不能空着,会报错。
initialize_grid(infile, grid);
print_grid(grid);
bool wrap;
wrap = getYesOrNo("Should the simulation wrap around the grid (y/n)? ");
while (true){
cout<<"a)nimate, t)ick, q)uit? ";
string command, a="a", q="q", t="t";
getline(cin, command);
if (command==a) {
int frame = getInteger("How many frames? ");
for (int f=0;f<frame;f++){
to_next_generation(grid,wrap);
print_grid(grid);
pause(50);
clearConsole();
}
}else if(command == t){
to_next_generation(grid,wrap);
print_grid(grid);
}else if(command == q) break;
else cout<<"Invalid choice; please try again."<<endl;
}
cout << "Have a nice Life!" << endl;
return 0;
}
/*
* use paramerize grid initialize contents with given file.
*/
void initialize_grid(ifstream &infile,Grid<char> &grid){
string line, r, c;
getline(infile, r);
getline(infile, c);
grid.resize(stringToInteger(r), stringToInteger(c));
int row = 0;
while (getline(infile, line)){
if (line=="") break;
int col = 0;
for (char c : line){
grid[row][col]=c;
col++;
}
row++;
}
}
/*
* usage: string filename = promptForFilename(string prompt)
* ask user to input filename, ask user input again if file not exist.
* return filename.
*/
string promptForFilename(string prompt){
while (true){
string cur_dir = getCurrentDirectory();
string filename;
cout<<prompt;
getline(cin, filename);
filename = cur_dir + "\\" + filename;
if (fileExists(filename)){
return filename;
}
cout<<"Unable to open that file. Try again."<<endl;;
}
}
/*
* display char grid contents.
*/
void print_grid(Grid<char> &grid){
for (int r=0; r<grid.numRows(); r++){
for (int c=0; c<grid.numCols(); c++){
cout<<grid[r][c];
}
cout<<endl;
}
}
/* use parameter generate one round.
*/
void to_next_generation(Grid<char> &grid, bool wrap){
int nrows, ncols;
nrows = grid.numRows();
ncols = grid.numCols();
Grid<int> temp_grid(nrows,ncols);
for (int r=1;r<nrows-1;r++){
for (int c=1; c<ncols-1; c++){
temp_grid[r][c] = count_neighbors(grid, r, c);
}
}
if (wrap){
for (int c=0;c<ncols;c++){
temp_grid[0][c] = wrap_neighbors(grid, 0,c,nrows, ncols);
}
for (int c=0;c<ncols;c++){
temp_grid[nrows-1][c] = wrap_neighbors(grid, nrows-1,c,nrows, ncols);
}
for (int r=0;r<nrows;r++){
temp_grid[r][0] = wrap_neighbors(grid, r,0,nrows, ncols);
}
for (int r=0;r<nrows;r++){
temp_grid[r][ncols-1] = wrap_neighbors(grid, r,ncols-1,nrows, ncols);
}
}else{
for (int c=0;c<ncols;c++){
temp_grid[0][c] = unwrap_neighbors(grid, 0,c,nrows, ncols);
}
for (int c=0;c<ncols;c++){
temp_grid[nrows-1][c] = unwrap_neighbors(grid, nrows-1,c,nrows, ncols);
}
for (int r=0;r<nrows;r++){
temp_grid[r][0] = unwrap_neighbors(grid, r,0,nrows, ncols);
}
for (int r=0;r<nrows;r++){
temp_grid[r][ncols-1] = unwrap_neighbors(grid, r,ncols-1,nrows, ncols);
}
}
for (int r=0;r<nrows;r++){
for (int c =0;c<ncols;c++){
switch (temp_grid[r][c]){
case 0:
case 1: grid[r][c]='-';
break;
case 2: break;
case 3: grid[r][c]='X';
break;
case 4: case 5: case 6: case 7: case 8: grid[r][c]='-';
}
}
}
}
/* count neighbors for grid[r][c], uninclude edge.
*/
int count_neighbors(Grid<char> &grid, int r, int c){
int neighbor=0;
for (int i=-1;i<2;i++){
for (int j=-1;j<2;j++){
if (i==0&&j==0) continue;
if (grid[r+i][c+j]=='X') neighbor++;
}
}
return neighbor;
}
/* count edge neighbors when wrap.
*/
int wrap_neighbors(Grid<char> &grid, int r, int c, int nrows, int ncols){
int neighbor = 0;
for (int i=-1;i<2;i++){
for (int j=-1;j<2;j++){
if (i==0&&j==0) continue;
if (grid[(r+i+nrows)%nrows][(c+j+ncols)%ncols]=='X') neighbor++;
}
}
return neighbor;
}
/* count edge neighbors when unwrap.
*/
int unwrap_neighbors(Grid<char> &grid, int r, int c, int nrows, int ncols){
int neighbor = 0;
for (int i=-1;i<2;i++){
for (int j=-1;j<2;j++){
if ((r+i)<0||(c+j)<0) continue;
if ((r+i)==nrows||(c+j)==ncols) continue;
if (i==r&&j==c) continue;
if (grid[r+i][c+j]=='X') neighbor++;
}
}
return neighbor;
}