C+中的细胞自动机+; 我试图写一个C++著名游戏的代码。这是我到目前为止得到的。当我运行它时,它给出了一个初始的随机细胞群,但下一代似乎不起作用。我的代码有什么问题 #include <iostream> #include <cstdlib> #include <time.h> using namespace std; int main(){ //Number of rows and columns const char live = '*'; const char dead = ' '; const int rows = 10; const int cols = 10; char life[rows][cols]; char life1[rows][cols]; int ans=0; //create initial generation randomly srand (time(NULL)); int cell; for(int r=0; r<rows; r++){ for(int c=0; c<cols; c++){ cell= rand()%10; if(cell >= 5){ life[r][c] = live; } else { life[r][c] = dead; } } } for(int r=0; r < rows; r++){ for(int c = 0; c<cols;c++){ cout << life[r][c] << " "; } cout << endl; } for(int k=0; k <10;k++){ for(int r=0; r < rows; r++){ for(int c=0;c<cols;c++){ if(life[r][c] == live){ if((c-1) >=1 && (life[r][c-1] == live)) ans++; if(c<cols && (life[r][c+1] == live)) ans++; if(c<cols && r<rows && (life[r+1][c+1] == live)) ans++; if(r<rows && (life[r+1][c] == live)) ans++; if(c<cols && c >=0 && (life[r+1][c-1] == live)) ans++; if(r>=0 && c >=0 && (life[r-1][c-1] == live)) ans++; if(r>=0 && (life[r-1][c]==live)) ans++; if(r>=0 && c<cols && (life[r-1][c+1] == live)) ans++; if(ans==2 || ans==3) life[r][c]= live; if(ans>3) life[r][c]= dead; if(ans<2) life[r][c]=live; } else { if( life[r][c]==dead){ if(c>=0 && (life[r][c-1]==dead)) ans++; if(c<cols && (life[r][c+1]==dead)) ans++; if(r<rows && c<cols && (life[r+1][c+1]==dead)) ans++; if(r<rows && (life[r][c]==life[r+1][c])) ans++; if(r<rows && c>0 && (life[r][c]==life[r+1][c-1])) ans++; if(r>=0 && c>=0 && (life[r][c]==life[r-1][c-1])) ans++; if(r>=0 &&(life[r][c]==life[r-1][c])) ans++; if(r>=0 && c<cols && (life[r][c] == life[r-1][c+1])) ans++; if(ans==3) life[r][c]=live; } } } } for(int r=0; r<rows; r++){ for(int c=0; c< cols; c++){ life[r][c]=life1[r][c]; } } for(int r=0; r<rows;r++){ for(int c =0; c<cols;c++){ cout << life[r][c] << " "; } cout<<endl; } } return 0; } #包括 #包括 #包括 使用名称空间std; int main(){ //行数和列数 const char live='*'; const char dead=''; const int rows=10; 常数int cols=10; 字符寿命[行][列]; 字符life1[行][cols]; int ans=0; //随机创建初始生成 srand(时间(空)); int细胞; 对于(int r=0;r
),让我们从使代码工作所需的最小更改开始C+中的细胞自动机+; 我试图写一个C++著名游戏的代码。这是我到目前为止得到的。当我运行它时,它给出了一个初始的随机细胞群,但下一代似乎不起作用。我的代码有什么问题 #include <iostream> #include <cstdlib> #include <time.h> using namespace std; int main(){ //Number of rows and columns const char live = '*'; const char dead = ' '; const int rows = 10; const int cols = 10; char life[rows][cols]; char life1[rows][cols]; int ans=0; //create initial generation randomly srand (time(NULL)); int cell; for(int r=0; r<rows; r++){ for(int c=0; c<cols; c++){ cell= rand()%10; if(cell >= 5){ life[r][c] = live; } else { life[r][c] = dead; } } } for(int r=0; r < rows; r++){ for(int c = 0; c<cols;c++){ cout << life[r][c] << " "; } cout << endl; } for(int k=0; k <10;k++){ for(int r=0; r < rows; r++){ for(int c=0;c<cols;c++){ if(life[r][c] == live){ if((c-1) >=1 && (life[r][c-1] == live)) ans++; if(c<cols && (life[r][c+1] == live)) ans++; if(c<cols && r<rows && (life[r+1][c+1] == live)) ans++; if(r<rows && (life[r+1][c] == live)) ans++; if(c<cols && c >=0 && (life[r+1][c-1] == live)) ans++; if(r>=0 && c >=0 && (life[r-1][c-1] == live)) ans++; if(r>=0 && (life[r-1][c]==live)) ans++; if(r>=0 && c<cols && (life[r-1][c+1] == live)) ans++; if(ans==2 || ans==3) life[r][c]= live; if(ans>3) life[r][c]= dead; if(ans<2) life[r][c]=live; } else { if( life[r][c]==dead){ if(c>=0 && (life[r][c-1]==dead)) ans++; if(c<cols && (life[r][c+1]==dead)) ans++; if(r<rows && c<cols && (life[r+1][c+1]==dead)) ans++; if(r<rows && (life[r][c]==life[r+1][c])) ans++; if(r<rows && c>0 && (life[r][c]==life[r+1][c-1])) ans++; if(r>=0 && c>=0 && (life[r][c]==life[r-1][c-1])) ans++; if(r>=0 &&(life[r][c]==life[r-1][c])) ans++; if(r>=0 && c<cols && (life[r][c] == life[r-1][c+1])) ans++; if(ans==3) life[r][c]=live; } } } } for(int r=0; r<rows; r++){ for(int c=0; c< cols; c++){ life[r][c]=life1[r][c]; } } for(int r=0; r<rows;r++){ for(int c =0; c<cols;c++){ cout << life[r][c] << " "; } cout<<endl; } } return 0; } #包括 #包括 #包括 使用名称空间std; int main(){ //行数和列数 const char live='*'; const char dead=''; const int rows=10; 常数int cols=10; 字符寿命[行][列]; 字符life1[行][cols]; int ans=0; //随机创建初始生成 srand(时间(空)); int细胞; 对于(int r=0;r,c++,C++,),让我们从使代码工作所需的最小更改开始 重置ans每次迭代:在内部循环开始时(在cols上),设置ans=0;否则你在3上计数,永远不会返回,所有东西都保持死状态 保留您的一代:下一代是从life数组计算的,因此在计算一代时不要更改此数组。而是将结果写入life1。在每次外部(k)迭代结束时,结果将复制回life 正确应用规则:在if(life[r][c]==live)案例结束时,如果邻居少于2个,则单元应根据规则死亡。因此,将if(ans=1&&(life[r][c-1]==live))
- 重置
每次迭代:在内部循环开始时(在ans
上),设置cols
否则你在ans=0;
上计数,永远不会返回,所有东西都保持死状态3
- 保留您的一代:下一代是从
数组计算的,因此在计算一代时不要更改此数组。而是将结果写入life
。在每次外部(life1
)迭代结束时,结果将复制回k
life
- 正确应用规则:在
案例结束时,如果邻居少于2个,则单元应根据规则死亡。因此,将if(life[r][c]==live)
指定为if(ans<2)life1[r][c]=死亡;
而不是if(ans<2)life1[r][c]=死亡;
live
- 使用
,完成作业:对于另一种情况(life1
)添加if(life[r][c]==dead)
以确保完成初始化:else
if(ans==3)life1[r][c]=live;else life1[r][c]=dead
- 使用整个数组大小(从索引
0开始):
ommits第一个索引。替换为if((c-1)>=1&&(life[r][c-1]==live))
if(c>=1&&(life[r][c-1]==live))
- 保持在数组边界内(以
结尾)。size-1
超出边界,则替换为如果(c
保持在边界内如果((c+1)
- 注意所有其他
语句的数组边界,方法与两个示例相同if
int count\u living\u neights(char-life[10][10],int-rowPos,int-colPos)
,在该函数中,您可以放置所有逻辑来计算living neighter cells。然后,如果在主节点中级联,则替换巨大的:
for(int k = 0; k < 10; k++)
{
for(int r = 0; r < rows; r++)
{
for(int c = 0; c < cols; c++)
{
int count = count_living_neighbors(life, r, c);
if(life[r][c] == live)
{
if(count == 2 || count == 3)
life1[r][c] = live;
else
life1[r][c] = dead;
}
else
{
if(count == 3)
life1[r][c]=live;
else
life1[r][c]= dead;
}
}
}
for(int r = 0; r < rows; r++)
{
for(int c = 0; c < cols; c++)
{
life[r][c] = life1[r][c];
}
}
for(int r = 0; r < rows; r++)
{
for(int c = 0; c < cols; c++)
{
cout << life[r][c] << " ";
}
cout << endl;
}
}
让我们从使代码工作所需的最小更改开始
- 重置
ans
每次迭代:在内部循环开始时(在cols
上),设置ans=0;
否则你在3
上计数,永远不会返回,所有东西都保持死状态
保留您的一代:下一代是从life
数组计算的,因此在计算一代时不要更改此数组。而是将结果写入life1
。在每次外部(k
)迭代结束时,结果将复制回life
正确应用规则:在if(life[r][c]==live)
案例结束时,如果邻居少于2个,则单元应根据规则死亡。因此,将if(ans<2)life1[r][c]=死亡;
指定为if(ans<2)life1[r][c]=死亡;
而不是live
使用life1
,完成作业:对于另一种情况(if(life[r][c]==dead)
)添加else
以确保完成初始化:if(ans==3)life1[r][c]=live;else life1[r][c]=dead
使用整个数组大小(从索引0开始):if((c-1)>=1&&(life[r][c-1]==live))
ommits第一个索引。替换为if(c>=1&&(life[r][c-1]==live))
保持在数组边界内(以size-1
结尾)。如果(c
超出边界,则替换为如果((c+1)
保持在边界内
注意所有其他if
语句的数组边界,方法与两个示例相同
现在转到代码设计:我建议您创建一个函数int count\u living\u neights(char-life[10][10],int-rowPos,int-colPos)
,在该函数中,您可以放置所有逻辑来计算living neighter cells。然后,如果在主节点中级联,则替换巨大的:
for(int k = 0; k < 10; k++)
{
for(int r = 0; r < rows; r++)
{
for(int c = 0; c < cols; c++)
{
int count = count_living_neighbors(life, r, c);
if(life[r][c] == live)
{
if(count == 2 || count == 3)
life1[r][c] = live;
else
life1[r][c] = dead;
}
else
{
if(count == 3)
life1[r][c]=live;
else
life1[r][c]= dead;
}
}
}
for(int r = 0; r < rows; r++)
{
for(int c = 0; c < cols; c++)
{
life[r][c] = life1[r][c];
}
}
for(int r = 0; r < rows; r++)
{
for(int c = 0; c < cols; c++)
{
cout << life[r][c] << " ";
}
cout << endl;
}
}
grek40已经给出了实际的答案,但我认为给你一些关于编码风格的建议可能没有什么坏处。这个答案基于grek40的代码
首先,如果你处理一些数据结构,这是你想要一个类的明显标志。我还将去掉数组(你想避免在C++中使用数组),并使用enum使单元格的状态更具可读性
让我们从一个位于头文件中的接口开始
#include <vector>
using std::vector;
enum CellState{ //replacing your char* with CellState
dead, alive
};
class GameOfLife{
public:
GameOfLife(const unsigned int rows, const unsigned int cols);
virtual ~GameOfLife(){}; //can omit the virtual if no subclasses are guaranteed
void iterate(const unsigned int iterations = 1); //can do several steps at once, one step at a time is the assumed default
void print() const;
private:
vector<vector<CellState> > state;
void initialize(const unsigned int rows, const unsigned int cols); //does the randomization
unsigned int neighbors(const unsigned int row, const unsigned int col) const;
}
让我们继续讨论位于GameOfLife.cpp中的类的实现。现在我将省略必要的include,比如iostream
让我们从简单的一个开始,打印:
inline char state_to_char(const CellState state){
if(state == dead){
return ' ';
}
return '*';
}
void GameOfLife::print() const{
for(unsigned int r = 0; r < state.size(); r++){
for(unsigned int c = 0; c < state[r].size(); c++){
cout << state_to_char(state[r][c]) << " ";
}
cout << endl;
}
}
(创建initialize是为了方便以后在需要时引入新构造函数)
未签名的int型邻居与grek40设计的count\u living\u邻居相似
对于核心部分,迭代:
//function to resize any vector^2
template<class T>
void resize(vector<vector<T> >& target, const unsigned int dx, const unsigned int dy){
target.resize(dx);
for(unsigned int i=0; i<dx; i++){
target[i].resize(dy);
}
}
GameOfLife::iterate(const unsigned int iterations){
unsigned int rows = state.size();
unsigned int cells = 0;
if(rows != 0){
cells = state[0].size();
}
vector<vector<CellState> > new_state;
resize(new_state, rows, cells);
for(unsigned int iteration = 0; iteration < iterations; iteration++){
for(unsigned int r = 0; r < rows; r++){
for(unsigned int c = 0; c < cells; c++){
unsigned int count = neighbors(r, c);
if(state[r][c] == alive){
if(count == 2 || count == 3){
new_state[r][c] = alive;
}else{
new_state[r][c] = dead;
}else{
if(count == 3){
new_state[r][c] = alive;
}else{
new_state[r][c] = dead;
}
}
}//end for c
}//end for r
state = new_state;
}//end for iteration
}
//用于调整任何向量^2大小的函数
模板
无效调整大小(向量和目标、常量无符号整数dx、常量无符号整数dy){
调整目标大小(dx);
对于(unsigned int i=0;i来说,grek40已经给出了实际答案,但我认为给您一些关于编码风格的建议可能不会有什么坏处。这个答案基于grek40的代码
首先,如果您对某些数据结构进行研究,这是一个明确的迹象,表明您
void GameOfLife::initialize(const unsigned int rows, const unsigned int cols){
state.resize(rows);
for(unsigned int r = 0, r < rows, r++){
state[r].resize(cols);
}
insert your code of randomly assigning dead or alive with changed names
}
GameOfLife::GameOfLife(const unsigned int rows, const unsigned int cols){
initialize(rows, cols);
}
//function to resize any vector^2
template<class T>
void resize(vector<vector<T> >& target, const unsigned int dx, const unsigned int dy){
target.resize(dx);
for(unsigned int i=0; i<dx; i++){
target[i].resize(dy);
}
}
GameOfLife::iterate(const unsigned int iterations){
unsigned int rows = state.size();
unsigned int cells = 0;
if(rows != 0){
cells = state[0].size();
}
vector<vector<CellState> > new_state;
resize(new_state, rows, cells);
for(unsigned int iteration = 0; iteration < iterations; iteration++){
for(unsigned int r = 0; r < rows; r++){
for(unsigned int c = 0; c < cells; c++){
unsigned int count = neighbors(r, c);
if(state[r][c] == alive){
if(count == 2 || count == 3){
new_state[r][c] = alive;
}else{
new_state[r][c] = dead;
}else{
if(count == 3){
new_state[r][c] = alive;
}else{
new_state[r][c] = dead;
}
}
}//end for c
}//end for r
state = new_state;
}//end for iteration
}