Looping input function
Consider following the Single Responsibility Principal and break the function up into smaller functions that do less.

Note: This answer makes use of the loopEvos() that is provided in the updated version of the source files on GitHub.

void loopEvos (Grid* grid, size_t speed) {
    nodelay(stdscr, TRUE); // Getting of the input is asyncronous
    // Infinitely loops until any key is pressed
    while (true) {
        grid-&gt;evolve();
        displayGrid(grid);

        printw("Press any key to end execution...\n");

        // If there has been something inputted, then break out of this sub-loop
        if (getch() != ERR) {
            break;
        }

        usleep((__useconds_t)speed * 1000); // Sleep the desired amount of time (in micro seconds converted to milliseconds)
    }
}


Whenever code is written future expansion of the program/function must be considered. In the function above there is the code :

        if (c == ' ') {
            grid-&gt;evolve();
        } else if (c == 'q') {
            return;
        } else if (c == '\n') {
            loopEvos(grid, speed);
            nodelay(stdscr, FALSE);
        }


It would be is easier to expand the code if another type of control statement was used instead. If the code was

        switch (c) {
            case ' ':
                grid-&gt;evolve();
                continue;
            case 'q':
                return;
            case '\n':
                loopEvos(grid, speed);
                nodelay(stdscr, FALSE);
                continue:
            default :
                printw("Invalid character input\n");
                return;
        }


It would be easier to handle any additional input characters such as 
KEY_UP, KEY_LEFT, KEY_DOWN and KEY_UP.

        switch (c) {
            case ' ':
                grid-&gt;evolve();
                continue;
            case 'q':
                return;
            case '\n':
                loopEvos(grid, speed);
                nodelay(stdscr, FALSE);
                continue;
        // The following code is modified from procs/procs.hpp in the GitHub account.
            case 's':
                askFileSave(grid);
                continue;
            case 'c':
                changeSettings(&amp;speed);
                continue;
            case KEY_UP:
                if (cursorPosY &gt;= 1) {
                    cursorPosY -= 1;
                }
                continue;
            case KEY_LEFT:
                if (cursorPosX &gt;= 2) {
                    cursorPosX -= 2;
                }
                continue;
            case KEY_DOWN:
                if (cursorPosY &lt; (grid-&gt;y - 1)) {
                    cursorPosY += 1;
                }
                continue;
            case KEY_RIGHT:
                if ((cursorPosX / 2) &lt; grid-&gt;x - 1) {
                    cursorPosX += 2;
                }
                continue;
            default :
                printw("Invalid character input\n");
                return;
        }


It might be easier to read, understand and modify the outer loop if it was a do
while loop rather than a while true loop

void startEvolutionLoop (Grid* grid, size_t speed) {
    clear();

     int userInput;
     do {
         // First of all displays the grid with supporting information
         displayGrid(grid);
         printw("[Space] Evolve once        [Enter] Run evolutions        [q] Exit\n");

         // Gets the most recently touched character
         userInput = getch();

         if (userInput == ' ') {
             grid-&gt;evolve();
         } else if (userInput == 'q') {
             continue;
         } else if (userInput == '\n') {
             loopEvos(grid, speed);  // from procs/procs.hpp in the GitHub account.
             nodelay(stdscr, FALSE);
         }
     } while (userInput != `q`);
}