Implementing Conway's Game of Life Here is an implementation of Conway's Game of Life. My code is working fine but I want you to review and give me your suggestions of how to improve it.

These are the steps of my code:


Initialize the grid cells with zeros (all cells are dead at the start)
Then randomly change some of the grid cells to one (bring some cells to life)
Draw the grid
Update the grid, by checking which cells are going to live or die
Go to step 3


gameOfLife.h

#ifndef GAME_OF_LIFE_H
#define GAME_OF_LIFE_H

#include &lt;vector&gt;
#include &lt;random&gt;

class gameOfLife
{
public:
    typedef std::vector&lt; std::vector&lt;int&gt;&gt; gridVector;

private:
    int gridSize;
    gridVector mainGrid;
    gridVector *gridCopy;

public:
    gameOfLife();

public:     
    void run();
    void initGrid();
    void drawGrid();
    void updateGrid();
    void copyGrid ();
    int checkNeighbors(gridVector *grid, int x, int y);
    void nextGeneration(int x, int y, int lod);
    int randGenerate(int start, int end);

private:     
    std::random_device randDevice;
    std::mt19937 gen;
};



#endif


implementation.cpp

#include &lt;iostream&gt;
#include "gameOfLife.h";

gameOfLife::gameOfLife() : gridSize(15), gen(randDevice())
{
}

void gameOfLife::initGrid()
{
    for(int i = 0; i &lt; gridSize; i++)
    {
        for(int j = 0; j &lt; gridSize; j++)
        {
            mainGrid[i].push_back(0);
        }
    }

    for(int i = 1; i &lt; gridSize ; i++)
    {
        for(int j = 1; j &lt; gridSize ; j++)
        {
            int randSize     = randGenerate(2 , gridSize);
            int state       = randGenerate(0 , 2);
            int indexRow    = randGenerate(1, randSize );
            int indexColumn = randGenerate(1, randSize );

            mainGrid[indexColumn][indexRow] = state;
        }
    }
}

int gameOfLife::randGenerate(int start, int end)
{
        std::uniform_int_distribution&lt;int&gt; genenNum(start, end - 1);

        return genenNum(gen);
}

void gameOfLife::drawGrid()
{
    char ch = 254;
    for(int i = 1; i &lt; gridSize - 1; i++)
    {
        for(int j = 1; j &lt; gridSize - 1; j++)
        {

                if(mainGrid[i][j])
                {
                    std::cout &lt;&lt; " "&lt;&lt;ch;
                }
                else
                {
                    std::cout &lt;&lt; "  ";
                }

        }
        std::cout&lt;&lt;std::endl;
    }
}

void gameOfLife::copyGrid ()
{
    gridCopy = &amp;mainGrid;
    (*gridCopy).resize(gridSize);
}

void gameOfLife::updateGrid()
{
    copyGrid();

    for(int i = 1; i &lt; gridSize - 1 ; i++)
    {
        for(int j = 1; j &lt; gridSize - 1; j++)
        {
            int lod = checkNeighbors(gridCopy, i, j);    
            nextGeneration( i, j, lod);

        }

    }
}

int gameOfLife::checkNeighbors(gridVector *gridCopy, int x, int y)
{
    int lod = 0;
     for(int i = -1; i &lt; 2; i++)
     {
         for(int j = -1; j &lt; 2; j++)
         {
             if(!(i == 0 &amp;&amp; j == 0))
             {
                 if((*gridCopy)[ x + i ][ y + j ]) 
                 {
                     lod++;
                 }
             }
         }
     }

     return lod;
}

void gameOfLife::nextGeneration(int x, int y, int lod)
{
    if(lod &lt; 2) 
    {
        mainGrid[x][y] = 0;
    }
    else if(lod == 3)
    {
        mainGrid[x][y] = 1;
    }
    else if(lod &gt; 3)
    {
        mainGrid[x][y] = 0;
    }
}

void gameOfLife::run()
{
    mainGrid.resize(gridSize);

    initGrid();

    while(true)
    {       
        drawGrid();
        updateGrid();       
        system("cls");
    }
}

int main()
{
    gameOfLife gol;
    gol.run();

    std::cin.get();

    return 0;
}
#includes should not end with a semicolon:


#include "gameOfLife.h";



The reason this is incorrect is because this is a preprocessor directive, which do not follow the same syntax as compiled lines.
Instead of using a typedef:


typedef std::vector&lt; std::vector&lt;int&gt;&gt; gridVector;



you can now use C++11's type alias:

using std::vector&lt;std::vector&lt;int&gt;&gt; = gridVector;

If you don't need the default constructor, you can either leave it out or make it explicitly defaulted:

gameOfLife() = default;

There's really no need for multiple public and private sections.  If you prefer to organize or separate the members in some way, you can just add line breaks.
I'm not sure why you have a *gridCopy member.  Not only would it be more natural to use a copy constructor in such cases, but having a raw pointer as a member would "force" you to have an overloaded copy constructor.  This is because the default copy constructor performs shallow copies, which will copy the pointer instead of the value at that pointer.

After removing this member, you should also remove copyGrid().
I'm not too familiar with GoL, but I don't think that while loop in run() is supposed to run infinitely.  This type of while loop will not stop unless a break or return is encountered.  You may need to modify it in such a way that it can end.