康威的生命游戏C++代码检查

Conway's Game of Life C++ Code check

本文关键字:代码 检查 C++ 游戏 生命 康威      更新时间:2023-10-16

我首先要说我是一个乞丐。我两周前开始学习。今天我在YT上找到了一些关于康威生命游戏的视频。到目前为止,我学到的东西我坚持我会试一试。所以我做了这个(下面的代码)。它不像它应该的那样工作,我不知道为什么。有人可以检查下面的代码并告诉我出了什么问题吗?我不想要一个完整的解决方案,只是一个提示我应该检查什么。

#include <iostream>
#include <windows.h>
#include <conio.h>
using namespace std; 
int main()
{
bool positions[50][50], new_positions[50][50];
int neighbours=0;
for(int i=0; i<50; i++) {
for(int x=0; x<50; x++) positions[i][x]=false;
}
for(int i=0; i<50; i++) {
for(int x=0; x<50; x++) new_positions[i][x]=false;
}
//This is some patterns i've put manually into array just for testing, 
//they should "be alive" at least for 3-4 cycles    
positions[5][5]=true;
positions[5][6]=true;
positions[5][7]=true;
positions[6][5]=true;
positions[5][8]=true;
positions[5][9]=true;
positions[5][10]=true;
positions[5][11]=true;
positions[5][5]=true;
positions[6][5]=true;
positions[7][5]=true;
positions[5][6]=true;
positions[8][5]=true;
positions[5][7]=true;
positions[6][8]=true;
positions[7][9]=true;
positions[8][10]=true;
positions[9][5]=true;

positions[11][11]=true;
positions[11][12]=true;
positions[12][11]=true;
positions[12][12]=true;

while(!(kbhit())) {
for(int i=0; i<50; i++) {
for(int x=0; x<50; x++) {
for(int pozX=x-1, pozI=i-1; pozI<=i+1; pozX++) {
//if(pozX!=x && pozI!=i) {      //this "if" doesn't work, don't know why                
if(pozX>=0 && pozX<50 && pozI>=0 && pozI<50) {
if(positions[pozI][pozX]==true) neighbours++;
}
//}
if(pozX==x+1) {
pozX=x-1;
pozI++;
}
}
if(neighbours==1) neighbours=0;//had to use this instead of previously mentioned if
if(positions[i][x]==true) {
if((neighbours>3) || (neighbours<2)) new_positions[i][x]=false;
}
if(positions[i][x]==false && neighbours==3) new_positions[i][x]=true;
neighbours=0;
}
}
for(int i=0; i<50; i++) {
for(int x=0; x<50; x++) {
if(new_positions[i][x]==true) cout << "X";
else cout << " ";
}
cout << endl;
}
for(int i=0; i<50; i++) {
for(int x=0; x<50; x++) positions[i][x]=false; //clears all cells
}
for(int i=0; i<50; i++) {
for(int x=0; x<50; x++) positions[i][x]=new_positions[i][x]; //sets cell status from this cycle, I know I could do this in one loop, but it is more clear to me this way
}
for(int i=0; i<50; i++) {
for(int x=0; x<50; x++) new_positions[i][x]=false; //clears this cycle "buffor"
}   
Sleep(3000);
system("cls");
}
}

我调试代码的方式是使用 https://www.onlinegdb.com/学习使用调试器真的很有价值...

我所做的包括:

  • 我删除了 kbhit() 测试和 Sleep() 调用和 cls,因为我没有使用 Windows 编译器。 如果你使用我的代码,你将不得不把它们放回去。
  • 我更改了显示
  • 电路板的位,以为其提供行号并在空白单元格中显示某些内容,并对其进行了更改以避免调用endl来刷新每一行的缓冲区。
  • 我改变了邻居的计算方式。 我认为您正在减去 1 来处理已完成的额外添加 - 我认为最好只使用 if 语句来避免首先添加它。 这是我的版本:

    int neighbours=0;
    for(int pozI=i-1; pozI<=i+1; pozI++)
    for(int pozX=x-1; pozX<=x+1; pozX++)
    if(pozX!=x || pozI!=i) // don't check position[i][x]
    if(pozX>=0 && pozX<50 && pozI>=0 && pozI<50)
    if(positions[pozI][pozX]==true)
    neighbours++;
    
  • 我改变了新板的计算方式。 你从来没有把新位置设置为真,如果它应该保持活力。 这是我的版本:

    // set the new board
    new_positions[i][x]=false;
    if(positions[i][x]==true)
    if(neighbours==2 || neighbours==3)
    new_positions[i][x]=true; // staying alive
    if(positions[i][x]==false)
    if(neighbours==3)
    new_positions[i][x]=true; // being born
    

我没有做的包括:

  • 有很多风格问题,它们是否被改变是有争议的,这取决于你认为的最佳实践。 像变量名和将所有内容都放在main()中,有一个全局using namespace std;并使用C样式数组而不是std::array都是我们可以争论的事情,但这属于 codereview.stackexchange.com 所以我没有改变任何这些。

这是完整的程序:

#include <iostream>
#include <iomanip>
using namespace std; 
int main()
{
bool positions[50][50], new_positions[50][50];
// clear the board
for(int i=0; i<50; i++)
for(int x=0; x<50; x++)
positions[i][x]=false;
//This is some patterns i've put manually into array just for testing, 
//they should "be alive" at least for 3-4 cycles    
positions[5][5]=true;
positions[5][6]=true;
positions[5][7]=true;
positions[6][5]=true;
positions[5][8]=true;
positions[5][9]=true;
positions[5][10]=true;
positions[5][11]=true;
positions[5][5]=true;
positions[6][5]=true;
positions[7][5]=true;
positions[5][6]=true;
positions[8][5]=true;
positions[5][7]=true;
positions[6][8]=true;
positions[7][9]=true;
positions[8][10]=true;
positions[9][5]=true;
positions[11][11]=true;
positions[11][12]=true;
positions[12][11]=true;
positions[12][12]=true;
// print the initial board
for(int i=0; i<50; i++) {
cout << setw(4) << i << setw(1) << " ";
for(int x=0; x<50; x++)
cout << (positions[i][x]==true?"X":".");
cout << "n";
}
cout << endl;
for(int steps=0; steps<15; steps++) {
for(int i=0; i<50; i++) {
for(int x=0; x<50; x++) {
// count the neighbours
int neighbours=0;
for(int pozI=i-1; pozI<=i+1; pozI++)
for(int pozX=x-1; pozX<=x+1; pozX++)
if(pozX!=x || pozI!=i) // don't check position[i][x]
if(pozX>=0 && pozX<50 && pozI>=0 && pozI<50)
if(positions[pozI][pozX]==true)
neighbours++;
// set the new board
new_positions[i][x]=false;
if(positions[i][x]==true)
if(neighbours==2 || neighbours==3)
new_positions[i][x]=true; // staying alive
if(positions[i][x]==false)
if(neighbours==3)
new_positions[i][x]=true; // being born
}
}
// print the old board and the new one
for(int i=0; i<50; i++) {
cout << setw(4) << i << setw(1) << " ";
for(int x=0; x<50; x++)
cout << (positions[i][x]==true?"X":".");
cout << "    ";
for(int x=0; x<50; x++)
cout << (new_positions[i][x]==true?"X":".");
cout << "n";
}
cout << endl;
// save the generation
for(int i=0; i<50; i++)
for(int x=0; x<50; x++)
positions[i][x]=new_positions[i][x];
}
// print the final board
for(int i=0; i<50; i++) {
cout << setw(4) << i << setw(1) << " ";
for(int x=0; x<50; x++)
cout << (positions[i][x]==true?"X":".");
cout << "n";
}
cout << endl;
return 0;
}