康威生命游戏中的动态数组错误

问题描述 投票:0回答:1

我正在开发一个模拟康威生命游戏的程序,它与预设的尺寸完美配合。然而,一旦我尝试使用选项 e 中所示的动态尺寸,我就开始遇到问题。主要问题在于“life”函数,该函数遍历数组并决定是否应该使单元格生效。我已经调试了一段时间,如果我输入尺寸为 50*40,它会迭代直到 61, 1。这在技术上应该可行,但每次都会中断。请记住,我为每个维度添加了 12,以说明我在边缘周围放置的缓冲区。从技术上讲,它应该可以工作,对吗?如果您有任何建议,我将非常感激!

#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <new> // i havent used this one yet
#include <cmath>

using namespace std;

// REMEMBER: The outside of the array is 6 more than what we show so that nothing interferes
//also that it goes y,x and that x is going to be bigger so that we get a rectange


//we use the copy function to copy an array from eachother, either the current one to the temp one or
//vise versa. This is so that we can alter the cells one step at a time without affecting everything else.

void copy(int **array1, int **array2, int o, int p)
{
    for(int j = 0; j < o; j++)
    {
        for(int i = 0; i < p; i++)
            array2[j][i] = array1[j][i];
    }
} // the second array sent is assigned the first array sent!


//this array will initialize our arrays so that we can use them later
int** init(int n, int m)
{
    int **array;
    array = new int*[m]; // x
    array = new int*[n]; // y
    
    for (int q=0; q < n; q++)
        
    {
        array[q] = new int[n];
        
        for (int w=0; w < m; w++)
        {
            array[w] = new int[m];
        }
    }
    return  array;
}


void populate(int o, int p, int** board){           // THIS FUNCTION HASN'T BEEN USED YET

    for(int i=0; i < p; i++)
    {
        for(int j=0; j < o; j++)                    // It was in a in-class demo but i dont think i need it
        {
            board[i][j] = pow(i, j);
        }
    }
}


//The life function looks at the pieces around the cell and figures out what happens next.
// Probably the most important in the entire program, feast your eyes!

void life(int **array, int o, int p)
{
    //Copies the main array to a temp array so changes can be made without affecting anyone else
    int **temp;
    temp = init(o, p);
    
    copy(array, temp, o, p);
    
    for(int j = 1; j < o; j++)
    {
        for(int i = 1; i < p; i++)
        {
            // checks all 8 cells surrounding it
            int count = 0;
            cout << " j is " << j << " and i is " << i << endl;
           // cout << array[j][i]; //             DEBUGGING
            count =
            array[j-1][i] + array[j-1][i-1] +
            array[j][i-1] + array[j+1][i-1] +
            array[j+1][i] + array[j+1][i+1] +
            array[j][i+1] + array[j-1][i+1];
            
            //cell dies.
            
            if(count < 2 || count > 3)
            {
                temp[j][i] = 0;
            }
            
            //nothing happens.
            
            if(count == 2)
            {
                
                temp[j][i] = array[j][i];
            }
            
            //now the cell will be born, or if it already is alive then it stays that way.
            
            if(count == 3)
            {
                temp[j][i] = 1;
            }
        }
    }
    
    //Copies the  temp array back to the main array.
    copy(temp, array, o, p);
}


//This function prints the 40 x 50 part of the array, a 1 means that there will be a cell there,
//otherwise it will just be an empty space.

void print(int **array, int o, int p)
{
    // WE ONLY CHECK WHAT WE SEE, WHICH IS 6 LESS THAN THE ARRAY!!!
    for(int j = 6; (j < (o-6)); j++)
    {
        for(int i = 6; (i < (p-6)); i++)
        {
            if(array[j][i] == 1 )
                cout << '*';
            else
                cout << '.';
        }
        cout << endl;
    }
}


//I read somewhere it would be a good idea to make sure to end the program early if it somehow
//became stable by itself early. so this compares the old array with the new one to check if they
//are the same. This commonly occurs if a glider runs off the screen for example.

bool compare(int **array1, int **array2,int o,int p)
{
    int counter = 0;
    for(int j = 0; j < o; j++)
    {
        for(int i = 0; i < p; i++)
        {
            if(array1[j][i]==array2[j][i])
                counter++;
        }
    }
    
    if(counter == o*p)
        return true;
    else
        return false;
}


int main()
{
    int o= 52, p=62;
    int **firstgen;
    int **next;
    int **backup;
    
    
   // 40 + 12, 50 + 12
    
    int x, y;
    char starty;
    char again;
    char cont;
    bool comparison;
    
    //Here is where we initialize our arrays
    
    firstgen = init(o,p);
    next = init(o,p);
    backup = init(o,p);
    
    cout << endl << "Welcome to John Conway's Game of Life." << endl;
    
    //This loop is for if we are still simulating, don't get confused!
    do
    {
        //this loop checks for inputs.
        do
        {
            menu:       //this is a goto we use for if we change dimensions
            
            x = 0, y = 0;
        
            //now we get the menu
            cout << endl <<  "--- Choose an option Below ---" << endl;
            cout << "(a) Glider" << endl;
            cout << "(b) Gosper Gilder gun" << endl;
            cout << "(c) R Pentomino Pattern" << endl;
            cout << "(d) Oscillator" << endl;
            cout << "(e) Change the dimensions (it defaults to (50*40)" << endl;
            cin >> starty;
            
        }while(starty != 'a' && starty != 'b' && starty != 'c' && starty != 'd' && starty != 'e');
       
        int i = 0;
        
        //we need to assign firstgen in this area
        
        //choose a glider position
        if (starty == 'a'){
            
            x= 0, y= 0;
            
            cout << " X dimension: ";
            cin >> x;
            cout << " Y dimension: ";
            cin >> y;
            
            if (x < 0 || x > p || y < 0 || y > o){
                cout << endl << "you entered invalid dimensions" << endl;
                goto menu;
            }
            
            x = x+6; //we add 6 because there are six spots to the left that aren't shown we need to account for
            y = y+6;
            
            //creates the glider
            firstgen[y][x] = 1;
            firstgen[y][x+1] = 1;
            firstgen[y][x+2] = 1;
            firstgen[y-1][x] = 1;
            firstgen[y-2][x+1] = 1;
            
        }
        else if (starty == 'b'){
            x= 0, y= 0;
            cout << "Your dimensions are based on the farthest left point" << endl;
            cout << " X dimension: ";
            cin >> x;
            cout << " Y dimension: ";
            cin >> y;
            
            if (x < 0 || x > p || y < 0 || y > o){
                cout << endl << "you entered invalid dimensions" << endl;
                goto menu;
            }
            
            //this is because we have the buffer zone of 6
             x = x+6;
             y = y+6;
            
            //Gosper gun
            
            //box on left
            firstgen[y][x] = 1;
            firstgen[y][x+1] = 1;
            firstgen[y+1][x] = 1;
            firstgen[y+1][x+1] = 1;
            
            //left circle starting in top of the left curve (flat part)
            firstgen[y][x+10] = 1;
            firstgen[y-1][x+11] = 1;
            firstgen[y-2][x+12] = 1;
            firstgen[y-2][x+13] = 1;
            firstgen[y+1][x+10] = 1;
            firstgen[y+2][x+10] = 1;
            firstgen[y+3][x+11] = 1;
            firstgen[y+4][x+12] = 1;
            firstgen[y+4][x+13] = 1;
            //dot in middle
            firstgen[y+1][x+14] = 1;
            //arrow thing on the right
            firstgen[y-1][x+15] = 1;
            firstgen[y][x+16] = 1;
            firstgen[y+1][x+16] = 1;
            firstgen[y+1][x+17] = 1;
            firstgen[y+2][x+16] = 1;
            firstgen[y+3][x+15] = 1;
            
            //boomerang bit on the far right section
            firstgen[y][x+20] = 1;
            firstgen[y][x+21] = 1;
            firstgen[y-1][x+20] = 1;
            firstgen[y-1][x+21] = 1;
            firstgen[y-2][x+20] = 1;
            firstgen[y-2][x+21] = 1;
            firstgen[y-3][x+22] = 1;
            firstgen[y-3][x+24] = 1;
            firstgen[y-4][x+24] = 1;
            firstgen[y+1][x+22] = 1;
            firstgen[y+1][x+24] = 1;
            firstgen[y+2][x+24] = 1;
            
            //tiny box on farthest right, almost done!
            firstgen[y-1][x+34] = 1;
            firstgen[y-1][x+35] = 1;
            firstgen[y-2][x+34] = 1;
            firstgen[y-2][x+35] = 1;
        }
    
        else if (starty == 'c')
        {
            x= 0, y= 0;
            cout << "Your dimensions are based on the farthest left point" << endl;
            cout << " X dimension: ";
            cin >> x;
            cout << " Y dimension: ";
            cin >> y;
            
            if (x < 0 || x > p || y < 0 || y > o){
                cout << endl << "you entered invalid dimensions" << endl;
                goto menu;
            }
            
            x = x+6;
            y = y+6;
        
        //creates R Pentamino pattern
            
             firstgen[y][x] = 1;
             firstgen[y][x+1] = 1;
             firstgen[y+1][x+1] = 1;
             firstgen[y-1][x+1] = 1;
             firstgen[y-1][x+2] = 1;
            
        
        }
    // creates the simple oscillator
        else if (starty == 'd')
        {
            x= 0, y= 0;
            cout << "Your dimensions are based on the top of the oscillator" << endl;
            cout << " X dimension: ";
            cin >> x;
            cout << " Y dimension: ";
            cin >> y;
            
            if (x < 0 || x > p || y < 0 || y > o){
                cout << endl << "you entered invalid dimensions" << endl;
                goto menu;
            }
            
            x = x+6;
            y = y+6;
            
            firstgen[y][x] = 1;
            firstgen[y+1][x] = 1;
            firstgen[y+2][x] = 1;
        }
        
        // allows you to choose your dimensions
        else if (starty == 'e')
        {
            o= 0, p= 0;
            x= 0, y= 0;
            cout << "choose the height and width of your field, between 0 and 100" << endl;
            cout << " X dimension: ";
            cin >> x;
            cout << " Y dimension: ";
            cin >> y;
            
            if (x < 0 || x > 100 || y < 0 || y > 100){
                cout <<  endl << "Please keep dimensions between 0 and 100" << endl;
                goto menu;
            }
            
            
            // the problem is that it is adding my x dimension and my placement choice together and then
            // starts to run the program, which threadbreaks. I need to find out why these two values are
            // adding together and fix it
            
            x = x+12;
            y = y+12;       // plus twelve so that we have 6 around all sides
            
            p = x;
            o = y;
            
            firstgen = init(o,p);
            next = init(o,p);
            backup = init(o,p);
            
            // is this part below necessary?
            //firstgen[o][p];
           //  next[o][p];
            // backup[o][p];
            // idk
            
           // cout << "y value is: " << o << " and the x value is " << p << endl; // debugging
            
            goto menu;
        }
    
        //Loop that does the simulation.
        
        do
        {
            //Prints the generation.  If i == 0, the firstgen array is copied to the
            //next array, and is printed before any functions act upon it.
            
            cout << endl << "Generation " << i << ":" << endl << endl;
            
            //Initializes the arrays by copying the firstgen array to the next array.
            
            if(i == 0)
                copy(firstgen, next, o, p);
            
            //this stuff below happens in every cycle
            cout << "the x/p value is" << p << "and the y/o value is " << o << endl;
            copy(next, backup, o, p);
            print(next, o, p);
            life(next, o, p);
            i++;
            
            //Pauses the system .2 seconds so that it doesn't flash past you super fast and you
            // can't appreciate its beauty
            
            system("sleep .2");
            
            //Checks whether the generation is a multiple of 100 to ask
            //the user if they want to continue
            
            if(i % 100 == 1 && i != 1)
                {
                cout << endl;
                
                //Loop to check for proper inputs.
                do
                    {
                    cout << "Continue? (y or n): ";
                    cin >> cont;
                        
                    }while(cont != 'y' && cont != 'n');
                    
                if(cont == 'n')
                    break;
                }
            
            //Compares the current generation with a backup generation.
            //The idea is that if it is the same with the backup generation then
            //something boring is going on or smething went wrong. It will end if that
            //is the case.
            
            comparison = compare(next, backup, o, p);
            if(comparison == false)
               // system("clear");
                //cout << string( 10, '\n' );
            if(comparison == true)
                cout << endl;
        }while(comparison == false);
        
        //Loop to check if we want to keep going.
        do
        {
            cout << "Run another Simulation? (y or n): ";
            cin >> again;
            
        }
        while(again != 'y' && again != 'n');
      
        
        //this is where we clean out all our firstgen values
        //i used to have this at the top but didn't really need it
        for(int y = 0; y < o; y++)
        {
            for(int x = 0; x < p; x++)
            {
                firstgen[y][x] = 0;
            }
        }
    }
    while(again == 'y');
    
    return 0;
}
c++ arrays dynamic
1个回答
0
投票

我明白了!

需要注意的是,确保您的启动函数创建的数组与您将要访问的数组的大小相同。我试图从 array[52][1] 中获取不存在的值,因为在我的 init 函数中,我只运行了 for 循环 while n < o, which means it didn't create the 52nd row. what a relief!

© www.soinside.com 2019 - 2024. All rights reserved.