My professor asks me to program the Game Of Life with some required and I find unnecessary classes. But anyhow as I am coding and running the program midway I run into this problem

void Life::setup_grid()
{
    cout << "Size of Grid: " << grid.size() << endl;
    cout << "rows: " << rows << endl;
    cout << "cols: " << cols << endl;
    for(int i = 0; i < rows; i++)
    {
        for(int j = 0; j < cols; j++)
        {
            if(cell == 'A')
                grid[i][j] = new ACell();  //I get "Expression: vector subscript out of range." here.  
            else
                grid[i][j] = new BCell();  //I will assume I would get the same expression here.
        }
    }
}

I've already resized the vector in the constructor. Yet it still gives me that expression. Can anyone help? All my source code is below so please refer to it if necessary.

AbstractCell.h

#ifndef ABSTRACTCELL_H
#define ABSTRACTCELL_H
#include <iostream>
using namespace std;

class AbstractCell
{
    public:
        AbstractCell();
        void set_life_status(bool life_status);
        bool isAlive();
    private:
        bool alive;
};

#endif

AbstractCell.cpp

#include <iostream>
#include "AbstractCell.h"
using namespace std;


AbstractCell::AbstractCell()
{   alive = false;  }

void AbstractCell::set_life_status(bool life_status)
{   alive = life_status;    }

bool AbstractCell::isAlive()
{ return alive; }

ACell.h

#ifndef ACELL_H
#define ACELL_H
#include <iostream>
#include "AbstractCell.h"
using namespace std;

class ACell : public AbstractCell
{
    public:
        ACell();
};

#endif 

ACell.cpp

#include <iostream>
#include "ACell.h"
using namespace std;

ACell::ACell()
{   set_life_status(false); }

BCell.h

#ifndef BCELL_H
#define BCELL_H
#include <iostream>
#include "AbstractCell.h"
using namespace std;

class BCell : public AbstractCell
{
    public:
        BCell();
        int get_age();
        void set_age(int new_age);
    private:
        int age_of_cell;
};

#endif BCELL_H

BCell.cpp

#include <iostream>
#include "BCell.h"
using namespace std;

BCell::BCell()
{
    set_life_status(false);
    age_of_cell = 0;
}

int BCell::get_age()
{ return age_of_cell;   }

void BCell::set_age(int new_age)
{    age_of_cell = new_age; }

Life.h

#ifndef LIFE_H
#define LIFE_H
#include <iostream>
#include <iomanip>
#include <vector>
#include <fstream>
#include <cstdlib>
#include <string>
#include "ACell.h"
#include "BCell.h"

class Life : public ACell, public BCell
{
    public:
        //Basic Game will start with Cell Type A and default size board of 20x20
        Life(); 
        //Game with user inputted cell type with default board size of 20x20
        Life(char cell_type);
        //User inputted cell type and board size
        Life(char cell_type, int num_of_rows, int num_of_cols);
        void setup_grid();
        char get_cell_type();
        int get_alive_cells();
        int get_rows();
        int get_cols();
        int get_generation();
        void set_alive_cell_count(int num_alive);
        void set_cell_type(char type);
        void set_rows(int new_row_size);
        void set_cols(int new_col_size);
        void set_generation(int new_generation_num);
        void to_next_gen();
        void print_grid();
        void set_alive_cells();
        bool toFile(int gen, int pop);

    private:
        char cell;
        int rows;
        int cols;
        int generation;
        int cells_alive;    
        vector < vector<AbstractCell*> > grid;
};

#endif

Life.cpp

#include <iostream>
#include <vector>
#include <fstream>
#include <iomanip>
#include <cstdlib>
#include <string>
#include "Life.h"
#define default_rows 20
#define default_cols 20
#define begin_generation 0
using namespace std;



Life::Life()
{
    cell = 'A';
    rows = default_rows;
    cols = default_cols;
    generation = begin_generation;
    grid.resize(rows * cols);
}


Life::Life(char cell_type)
{
    cell = cell_type;
    rows = default_rows;
    cols = default_cols;
    generation = begin_generation;
    grid.resize(rows * cols);
}


Life::Life(char cell_type, int num_of_rows, int num_of_cols)
{
    cell = cell_type;
    rows = num_of_rows;
    cols = num_of_cols;
    generation = begin_generation;
    grid.resize(rows * cols);
}


void Life::setup_grid()
{
    cout << "Size of Grid: " << grid.size() << endl;
    cout << "rows: " << rows << endl;
    cout << "cols: " << cols << endl;
    for(int i = 0; i < rows; i++)
    {
        for(int j = 0; j < cols; j++)
        {
            if(cell == 'A')
                grid[i][j] = new ACell();
            else
                grid[i][j] = new BCell();
        }
    }
}


char Life::get_cell_type()
{   return cell;    }


int Life::get_alive_cells()
{   return cells_alive; }


int Life::get_rows()
{   return rows;    }


int Life::get_cols()
{   return cols;    }


int Life::get_generation()
{   return generation;  }


void Life::set_alive_cell_count(int num_alive)
{   cells_alive = num_alive;    }


void Life::set_cell_type(char type)
{   cell = type;    }


void Life::set_rows(int new_row_size)
{   rows = new_row_size;    }


void Life::set_cols(int new_col_size)
{   cols = new_col_size;    }


void Life::set_generation(int new_generation_num)
{   generation = new_generation_num;    }


void Life::to_next_gen()
{

}


void Life::print_grid()
{
    cout << "Generation = " << generation << "    Population = " << cells_alive <<  endl;
    toFile(generation, cells_alive);
    if(cell == 'A')
    {
        for(int i = 0; i < rows; i++)
        {
            for(int j = 0; j < cols; j++)
            {
                if(!(grid[i][j]->isAlive()))
                    cout << '.';
                else
                    cout << '*';
            }
            cout << "\n";
        }
    }
    //If not cell A then it has to be B
    else if(cell == 'B')
    {
        for(int i = 0; i < rows; i++)
        {
            for(int j = 0; j < cols; j++)
            {
                if(!(grid[i][j]->isAlive()))
                    cout << '-';
                else
                    cout << '+';
            }
            cout << "\n";
        }
    }

}


bool Life::toFile(int gen, int pop)
{
    ofstream exported_file;
    if(cell == 'A')
    {
        exported_file.open("ACellLife.out");
        exported_file << "Generation = " << gen << "  Population = " << pop << "\n";
        exported_file.close();
    }
    else if(cell == 'B')
    {
        exported_file.open("BCellLife.out");
        exported_file << "Generation = " << gen << "  Population = " << pop << "\n";
        exported_file.close();
    }
    else
    {
        cout << "No File will be created.";
        return false;
    }
    return true;
}

Recommended Answers

All 6 Replies

Consider using the "at" function instead of the [] operator and catching the error. You have a 2 dimensional vector. You need to find out which one gives the error. For some debugging...

cout << i << '\t' << j << '\t';
cin.get();
cout << grid.size() << '\t';
cin.get();
cout << grid[i].size() << endl;
cin.get();

The cin.get() lines are important. We can't have the program crashing and worrying about not knowing whether some output was in the buffer, but not printed. We need to know which line the program crashed at and we need to be able to slow things down stepwise. An alternative would also be to use a debugger with breakpoints, etc. again, consider using at() instead of [] when debugging. I did not do that above.

Wait so VernonDozier where do you want me to put that debugging code?

I think the issue is comming from how you are sizing the vector. I think you should use this to define the size of the vector in your constructors.

grid.resize(rows);
for (int i = 0; i < rows; i++)
{
    grid[i].resize(cols);
}

Nathan that doesn't work. Lol. I've tried that already. But thanks for the reply though.

Actually Nathan it does work thank you very much. :D

Glad to help.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.