2014-12-13 215 views
0

康威的生活游戏的工作,我觉得我很接近完成它,但我的逻辑有一些缺陷。我已经为此倾注了好几个小时,我只是觉得第二双眼睛能够比我更快地发现我的错误。我的程序编译得很好,但输出结果并不遵循特定位置的游戏准则(第0行,第1行在第二代时有生命,但不应该,但第10行似乎按预期工作)。对于任何不熟悉的人: http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life#Rules生命游戏的逻辑错误(C++)

我几乎可以肯定逻辑错误发生在函数advGen中。以下链接保存了readGrid使用的细菌内容:http://pastebin.com/6vurFRSB

感谢您花时间阅读并帮助您选择这样做。

//sample setup to start the game of life - startlife.cpp 

#include <iostream> 
#include <fstream> 
#include <iomanip> 
using namespace std; 

const int SIZE = 20; 

//initial function prototypes 
void initGrid(bool life[][SIZE], bool nextGen[][SIZE]); 
void readGrid(bool life[][SIZE], bool nextGen[][SIZE]); 
void printGrid(bool life[][SIZE], bool nextGen[][SIZE]); 
void advGen(bool life[][SIZE], bool nextGen[][SIZE]); 

int main() 
{ 
    bool life[SIZE][SIZE]; 
    bool nextGen[SIZE][SIZE]; 

    readGrid(life, nextGen); 
    /* for (int count = 0; count < 5; count++){ 
     determineNextGen(life); 
    }*/ 

    printGrid(life, nextGen); 
    advGen(life, nextGen); 
    printGrid(life, nextGen); 

    return 0; 
} 


/*------------------------------------------------------- 

      readGrid (and related functions) 

---------------------------------------------------------*/ 

void readGrid(bool life[][SIZE], bool nextGen[][SIZE]) 
{ 
    ifstream infile("bacteria.txt"); //see class site project#5 for data file 

    int numBacteria, row, col; 

    initGrid(life, nextGen); 

    infile >> row >> col; 
    while (infile){ 
     life[row][col] = true; 
     infile >> row >> col; 
    } 
    infile.close(); 
} 


void initGrid(bool life[][SIZE], bool nextGen[][SIZE]) 
{ 
    for (int row = 0; row < SIZE; row++) 
    { 
     for (int col = 0; col < SIZE; col++){ 
      life[row][col] = false; 
     } 
    } 
    for (int row = 0; row < SIZE; row++) 
    { 
     for (int col = 0; col < SIZE; col++){ 
      nextGen[row][col] = false; 
     } 
    } 
} 

void printGrid(bool life[][SIZE], bool nextGen[][SIZE]) 
{ 
    cout << "" << endl; 
    for (int row = 0; row < SIZE; row++) 
    { 
     cout << setw(2) << row; 
     for (int col = 0; col < SIZE; col++) 
     { 
      if (life[row][col]) 
      { 
       cout << "*"; 
      } 
      else 
      { 
       cout << " "; 
      } 
     } 
     cout << endl; 
    } 
} 

void advGen(bool life[][SIZE], bool nextGen[][SIZE]) 
{ 
    int neighbor = 0; 

    for (int row = 0; row < SIZE; row++) 
    { 
     for (int col = 0; col < SIZE; col++) 
     { 
      if (row == 0) 
      { 
       if (col == 0) 
       { 
        if (life[row + 1][col] == true) 
         ++neighbor; 
        if (life[row][col + 1] == true) 
         ++neighbor; 
        if (life[row + 1][col + 1] == true) 
         ++neighbor; 
        if ((life[row][col] == true) && (neighbor < 2 || neighbor > 3)) 
        { 
         nextGen[row][col] = false; 
        } 
        else if ((life[row][col] == false) && (neighbor == 3)) 
        { 
         nextGen[row][col] = true; 
        } 
       } 
       else if (col == 19) 
       { 
        if (life[row + 1][col] == true) 
         ++neighbor; 
        if (life[row][col - 1] == true) 
         ++neighbor; 
        if (life[row + 1][col - 1] == true) 
         ++neighbor; 
        if ((life[row][col] == true) && (neighbor < 2 || neighbor > 3)) 
        { 
         nextGen[row][col] = false; 
        } 
        else if ((life[row][col] == false) && (neighbor == 3)) 
        { 
         nextGen[row][col] = true; 
        } 
       } 
       else 
       { 
        if (life[row + 1][col] == true) 
         ++neighbor; 
        if (life[row][col + 1] == true) 
         ++neighbor; 
        if (life[row][col - 1] == true) 
         ++neighbor; 
        if (life[row + 1][col + 1] == true) 
         ++neighbor; 
        if (life[row + 1][col - 1] == true) 
         ++neighbor; 
        if ((life[row][col] == true) && (neighbor < 2 || neighbor > 3)) 
        { 
         nextGen[row][col] = false; 
        } 
        else if ((life[row][col] == false) && (neighbor == 3)) 
        { 
         nextGen[row][col] = true; 
        } 
       } 
      } 
      if (row == 19) 
      { 
       if (col == 0) 
       { 
        if (life[row - 1][col] == true) 
         ++neighbor; 
        if (life[row][col + 1] == true) 
         ++neighbor; 
        if (life[row - 1][col + 1] == true) 
         ++neighbor; 
        if ((life[row][col] == true) && (neighbor < 2 || neighbor > 3)) 
        { 
         nextGen[row][col] = false; 
        } 
        else if ((life[row][col] == false) && (neighbor == 3)) 
        { 
         nextGen[row][col] = true; 
        } 
       } 
       else if (col == 19) 
       { 
        if (life[row - 1][col] == true) 
         ++neighbor; 
        if (life[row][col - 1] == true) 
         ++neighbor; 
        if (life[row - 1][col - 1] == true) 
         ++neighbor; 
        if ((life[row][col] == true) && (neighbor < 2 || neighbor > 3)) 
        { 
         nextGen[row][col] = false; 
        } 
        else if ((life[row][col] == false) && (neighbor == 3)) 
        { 
         nextGen[row][col] = true; 
        } 
       } 
       else 
       { 
        if (life[row - 1][col] == true) 
         ++neighbor; 
        if (life[row][col - 1] == true) 
         ++neighbor; 
        if (life[row][col + 1] == true) 
         ++neighbor; 
        if (life[row - 1][col - 1] == true) 
         ++neighbor; 
        if (life[row - 1][col + 1] == true) 
         ++neighbor; 
        if ((life[row][col] == true) && (neighbor < 2 || neighbor > 3)) 
        { 
         nextGen[row][col] = false; 
        } 
        else if ((life[row][col] == false) && (neighbor == 3)) 
        { 
         nextGen[row][col] = true; 
        } 
       } 
      } 
      if (col == 0) 
      { 
       if (row == 0) 
       { 
        if (life[row + 1][col] == true) 
         ++neighbor; 
        if (life[row][col + 1] == true) 
         ++neighbor; 
        if (life[row + 1][col + 1] == true) 
         ++neighbor; 
        if ((life[row][col] == true) && (neighbor < 2 || neighbor > 3)) 
        { 
         //nothing 
        } 
        else if ((life[row][col] == false) && (neighbor == 3)) 
        { 
         //nothing 
        } 
       } 
       else if (row == 19) 
       { 
        if (life[row - 1][col] == true) 
         ++neighbor; 
        if (life[row][col + 1] == true) 
         ++neighbor; 
        if (life[row - 1][col + 1] == true) 
         ++neighbor; 
        if ((life[row][col] == true) && (neighbor < 2 || neighbor > 3)) 
        { 
         //nothing 
        } 
        else if ((life[row][col] == false) && (neighbor == 3)) 
        { 
         //nothing 
        } 
       } 
       else 
       { 
        if (life[row - 1][col] == true) 
         ++neighbor; 
        if (life[row + 1][col] == true) 
         ++neighbor; 
        if (life[row][col + 1] == true) 
         ++neighbor; 
        if (life[row - 1][col + 1] == true) 
         ++neighbor; 
        if (life[row + 1][col + 1] == true) 
         ++neighbor; 
        if ((life[row][col] == true) && (neighbor < 2 || neighbor > 3)) 
        { 
         nextGen[row][col] = false; 
        } 
        else if ((life[row][col] == false) && (neighbor == 3)) 
        { 
         nextGen[row][col] = true; 
        } 
       } 
      } 
      if (col == 19) 
      { 
       if (row == 0) 
       { 
        if (life[row - 1][col] == true) 
         ++neighbor; 
        if (life[row][col - 1] == true) 
         ++neighbor; 
        if (life[row + 1][col - 1] == true) 
         ++neighbor; 
        if ((life[row][col] == true) && (neighbor < 2 || neighbor > 3)) 
        { 
         //nothing 
        } 
        else if ((life[row][col] == false) && (neighbor == 3)) 
        { 
         //nothing 
        } 
       } 
       else if (row == 19) 
       { 
        if (life[row - 1][col] == true) 
         ++neighbor; 
        if (life[row][col - 1] == true) 
         ++neighbor; 
        if (life[row - 1][col - 1] == true) 
         ++neighbor; 
        if ((life[row][col] == true) && (neighbor < 2 || neighbor > 3)) 
        { 
         //nothing 
        } 
        else if ((life[row][col] == false) && (neighbor == 3)) 
        { 
         //nothing 
        } 
       } 
       else 
       { 
        if (life[row][col - 1] == true) 
         ++neighbor; 
        if (life[row - 1][col] == true) 
         ++neighbor; 
        if (life[row + 1][col] == true) 
         ++neighbor; 
        if (life[row + 1][col - 1] == true) 
         ++neighbor; 
        if (life[row - 1][col - 1] == true) 
         ++neighbor; 
        if ((life[row][col] == true) && (neighbor < 2 || neighbor > 3)) 
        { 
         nextGen[row][col] = false; 
        } 
        else if ((life[row][col] == false) && (neighbor == 3)) 
        { 
         nextGen[row][col] = true; 
        } 
       } 
      } 
      else 
       { 
        if (life[row - 1][col] == true) 
         ++neighbor; 
        if (life[row + 1][col] == true) 
         ++neighbor; 
        if (life[row][col - 1] == true) 
         ++neighbor; 
        if (life[row][col + 1] == true) 
         ++neighbor; 
        if (life[row - 1][col - 1] == true) 
         ++neighbor; 
        if (life[row + 1][col + 1] == true) 
         ++neighbor; 
        if (life[row - 1][col + 1] == true) 
         ++neighbor; 
        if (life[row + 1][col - 1] == true) 
         ++neighbor; 
        if ((life[row][col] == true) && (neighbor < 2 || neighbor > 3)) 
        { 
         nextGen[row][col] = false; 
        } 
        else if ((life[row][col] == false) && (neighbor == 3)) 
        { 
         nextGen[row][col] = true; 
        } 
       }neighbor = 0; 
     } 
    } 
    for (int row = 0; row < SIZE; row++) 
     { 
     for (int col = 0; col < SIZE; col++) 
      { 
       life[row][col] = nextGen[row][col]; 
      } 
     } 

} 
+1

你有很多重复的代码在那里会受益于被移入单独的功能。它会让你的代码更容易阅读。 – David 2014-12-13 03:26:28

+0

_你拥有的'== true'的每一次使用都是100%冗余的,而不是视觉噪声。如果你只是将这些'bool'转换为'int'并添加它们,那么'if(life [...])++ neighbour'的_huge_栈可以简化为几行一起。为了避免边界逻辑以更多内存为代价,你可以用左边,右边,上边和下边填充板,并且不要写在它们上面。 – 2014-12-13 03:42:57

回答

1

您的代码重复计算邻居的数量。这是因为,例如,如果row是0并且col是0,则它在顶部执行row == 0事件,并且如果大约100行进一步向下执行,则执行col == 0内部的row == 0事件。

解决此问题的一种方法是使用正确的else子句。即做类似的事情:

if (row == 0) 
{ 
    ... 
} 
else if (row == 19) 
{ 
    ... 
} 
else 
{ 
    ... 
} 

你也需要这样做的列案例。

更好的解决方案是查看所有这些特殊情况,并尝试将它们合理化为代码重复性较低的内容。

你试图实现的是防止读取数组边界之外。

一个简单的方法来做到这一点是有一个函数在row, col,检查rowcol并返回false如果rowcol是出界,以获得阵列的价值。然后,您可以为每个位置的8个周围块中的每个块调用该函数,而无需针对行0和19以及列0和19的特殊情况。

我建议尝试编写上面的函数,而不是我只是在这里为你粘贴它。

编辑:另外请注意 - 你并不总是将值设置到nextGen,所以你杀死的是有生命有2个或3相邻的小区,你可能需要重新考虑你的if/else语句分配到nextGen

+0

我会投这个票,但我太新了。我非常感谢你的解释,我想知道是否有更简单的方法来做到这一点。非常感谢! – 2014-12-13 03:51:38

+0

我试着写了你所建议的功能,但在我用更多的代码让自己感到难堪之前,你是否可以试着解释函数做了什么不同的方法? – 2014-12-13 05:32:52

+0

该函数需要将'life'数组作为参数和'row'和'col'的参数。然后需要检查'row'和'col'是否在数组内(即> = 0和 2014-12-13 09:25:25