Link to home
Start Free TrialLog in
Avatar of edelossantos
edelossantos

asked on

hw1 code fix

// makefile

# Makefile:
#        It uses the C++ Compiler with all warnings and
#        full debugging; will create a single executable called 'main'
# ---------------------------------------------------------------
# the compiler
CPP = cxx
# compiler flags
CFLAGS = -L/usr/lib/cmplrs/cxx -DPOSIX_4D9 -w0 -gall
# linker flags to link in the libraries libm.a and libtask.a
LFLAGS = -lm -ltask
#
RM = rm -f
# ----------------------------------------------------------------
# Explanation of macros:
#     $< is any dependent file which is out of file1
#     $* is the target's basename (without extension)
#     $@ is the target's fullname
#
# add suffix .cpp since it is not a default with make util
.SUFFIXES:      .cpp .o
#
# implicit rule for compilation only:
.cpp.o:
      ${CPP} -c ${CFLAGS} $<

OFILES=            main.o life.o util.o

HFILES=            life.h  util.h

# dependencies
#
default:      main      
#
main:            $(OFILES)
            ${CPP} ${CFLAGS} ${LFLAGS} $(OFILES) -o $@

main.o:            main.cpp life.h util.h
life.o:            life.cpp life.h util.h
util.o:            util.cpp util.h

#
clean:
      ${RM} *.o
      ${RM} core
#
veryclean:      clean
      ${RM}  main  

/* filename: util.h
   programer: Enrique De Los Santos
   project: Conways Game of Life, hw1
   purpose: header file for VT 100 screen functions and usefule I/O utils
   Note: a VT 100 screen is 24 rows and 80 columns in standard mode*/

#ifndef UTIL_H  
#define UTIL_H

/* type bool and false & true are already defined in dUNIX C++
typedef int bool;
const bool false = 0;
const bool true = 1; */

// this is also in /usr/unclude/stdef.h which is used in >stdlib.h>

#define NULL 0L

// useful definitions for flag and screen operations

#define STDSCREEN 80        
#define DOWN 0                        
#define UP   1
#define END   0
#define START 1
#define FAIL    0
#define SUCCESS 1
#define MISS -1
#define HIT   1

// usefule error codes

enum Error_code { success, fail, range_error, underflow, overflow, fatal,
                  not_present, duplicate_error, entry_inserted, entry_found,
                  internal_error };

// screen functions

void clearScreen ();                        // clears all rows of screen                  
void clearTop();                        // clears top row 0 only                        
void clearBelowTop();                         // clears row 1 down on a VT 100 screen                
void goTop();                           // moves cursor to top row 0                          
void topLine(const char * text = " "  );      // display text at row 0           
void bottomLine (char * text = " ");              // displays text at row 23, column 10

// I/O functions
 
void hitAnyKey ();                        // "Hit any key to continue..." prompt                    
void flushInput ();                        // reads 80 chars from stdin                    
void Warning(char *);                        // writes message to stderr                  
void Error(char *);                         // writes message to stderr and exits                    
bool promptYesNo(char * prompt="");             // prompts user to enter yes, no    
void EatWhiteSpace(void);                  // discards white space input              
bool user_says_yes();                        // function prototype

#endif

// end of util.h

/* filename: util.cpp
   programer: Enrique De Los Santos
   project: Conways Game of Life, hw1
   purpose: I/O and VT 100 screen manipulation utility functions*/
   
#include <iostream>
#include <ctype.h>
#include <stdlib.h>
#include "util.h"

/* SCREEN HANDLING FUNCTIONS -
   vertrical position goes from 0-23
   horizontal position goes from 0-79*/

// clear everything on screen
void clearScreen (void)
{
  cout << "\033[2J";          
  cout << "\033[;f";        
}

// goto top-left corner; clear to end of line
void clearTop()

  {cout << "\033[0;0f" << "\033[0K";}

// clear everything except top row
void clearBelowTop()

  {cout << "\033[1;0f" << "\033[1B" << "\033[J";}

// to the top-left corner
void goTop ()

  {cout << "\033[0;0f";}

// goto top-left corner; clear to end of line; print string
void topLine(const char str[])
 
  {cout << "\033[0;0f" << "\033[0K" << str;}

// goto line 23; clear line 23; write text
void bottomLine (char * str)
 
  {cout << "\033[23;0Hf" << "\033[2K" << str;}

// I/O functions

// precondition: the input buffer is empty
void hitAnyKey ()
{
   char ch;
   bottomLine ("Hit any key to continue...");
   cin.get(ch);
   clearScreen();
}

// flush input buffer
void flushInput ()
{
   char buff[81];
   if (cin)
      cin.getline(buff,80);      // flush the input buffer of 80 characters    
}

void Warning(char *message)
{
   cerr << message;
}

void Error(char *message)
{
   cerr << message;
   exit(1);
}

// discard leading white space
void EatWhiteSpace()
{
    char ch;
    do {
      cin.get(ch);
    }
    while(isspace(ch));

    if(ch != EOF)
      cin.putback(ch);
}

bool promptYesNo(char * c)
{
   char ch;
   cout << c << " [y|n]?";
   do {
      cin.get(ch);  
      tolower(ch);
      } while (ch != 'y' && ch != 'n');
   return (ch == 'y');
}

bool user_says_yes()
{
   int c;
   bool initial_response = true;

   do {  
      if (initial_response)
         cout << " (y,n)? " << flush;

      else
         cout << "Respond with either y or n: " << flush;

      do { //  Ignore white space.
         c = cin.get();
      } while (c == '\n' || c ==' ' || c == '\t');
      initial_response = false;
   } while (c != 'y' && c != 'Y' && c != 'n' && c != 'N');
   return (c == 'y' || c == 'Y');
}

// end of util.cpp

/* filename: life.h
   prgrammer: Enrique De Los Santos
   project: Conways Game of Life, hw1*/

#ifndef LIFE_H
#define LIFE_H

const int maxrow = 20, maxcol = 60;    //  grid dimensions

class Life {

public:
   void instructions();
   void initialize();
   void print();
   void update();
   

private:
   int grid[maxrow + 2][maxcol + 2];  //  allows for two extra rows and columns
   int neighbor_count(int row, int col);

};

#endif

// end of life.h

/* Filename: life.cpp
   Programmer: Enrique De Los Santos (Del)
   Project: Conways Game of Life, hw1*/

//purpose: definitions for Life class

#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>

#include <time.h>

using namespace std;

#include "util.h"
#include "life.h"

// 1 = random (default)  2 = file 3 = manual  
void Life::initialize(int choice)
{
   extern int x;
   x  = 5;
   int make_alive;  
   int row, col;
   char filename[50];
   num_alive = 0;
   for (row = 0; row <= maxrow+1; row++)
       for (col = 0; col <= maxcol+1; col++)
           grid[row][col] = 0;


   // initialize randomly
   if ( choice == 1 )
   {
      // seed the random number generator
      srand((time(NULL)));
   
      // randomly make cells alive  
      for (row = 0; row <= maxrow+1; row++)
          for (col = 0; col <= maxcol+1; col++) {
              make_alive = rand() % 6;
              if ( make_alive == 1 ) {
                 grid[row][col] = make_alive;
                 num_alive ++;
            }
         }
 
   }
   else

   // initialize from file
   if ( choice == 2 )
   {

      cout << "Enter Filename: ";
      cin >> filename;
 
       // open input file
       ifstream infile( filename, ios::in );
       if( !infile ) {
          cerr << "File could not be opened\n";
          exit( 1 );
       }
       /* error checking for EOF and out of bounds  
           you could also use !infile.eof()      */

       while (infile) {
             infile >> row;

           // check to see if you are at eof
           if (!infile.fail())      
              infile >> col;

           // this will prevent you from processing EOF  
           if (!infile.fail() && row_ok(row) && col_ok(col)){
              grid[row][col] = 1;
              num_alive ++;
           }
        }
        infile.close();
     }  
    else
 

    // initialize  manually  
    if ( choice == 3 )
    {
       cout << "\nList coordinate pair for living cells (e.g. 4 5)"
            << " or -1 -1 to end:" << endl;
       cin >> row >> col;

       while (row != -1 || col != -1) {
          if (row >= 1 && row <= maxrow)
             if (col >= 1 && col <= maxcol)
                grid[row][col] = 1;
             else
                cout << "Column " << col << " is out of range." << endl;
          else
             cout << "Row " << row << " is out of range." << endl;
           cin >> row >> col;
           num_alive++;
       }  // user has entered -1 -1
     }    // end code to get input from user

}

int Life::neighbor_count(int row, int col)
/*
Pre:  The Life object contains a configuration, and the coordinates
      row and col define a cell inside its hedge.

Post: The number of living neighbors of the specified cell is returned.*/
{
   int i, j;
   int count = 0;
   for (i = row - 1; i <= row + 1; i++)
       for (j = col - 1; j <= col + 1; j++)
           count += grid[i][j];  //  Increase the count if neighbor is alive.
   count -= grid[row][col];      //  Reduce count, since cell is not its own neighbor.
   return count;
}

void Life::update()
/*
Pre:  The Life object contains a configuration.

Post: The Life object contains the next generation of configuration.*/
{
   int row, col;
   int new_grid[maxrow + 2][maxcol + 2];

   for (row = 1; row <= maxrow; row++)
      for (col = 1; col <= maxcol; col++)
         switch (neighbor_count(row, col)) {
         case 2:
            new_grid[row][col] = grid[row][col];    //  Status stays the same.
            break;
         case 3:
            new_grid[row][col] = 1;                 //  Cell is now alive.
            break;
         default:
            new_grid[row][col] = 0;                 //  Cell is now dead.
         }

   num_alive = 0;
   for (row = 1; row <= maxrow; row++)
      for (col = 1; col <= maxcol; col++) {
         grid[row][col] = new_grid[row][col];
         // count the number of living cells
         if ( grid[row][col] == 1 )
            num_alive++;
      }
}

void Life::print()
/*
Pre:  The Life object contains a configuration.

Post: The configuration is written for the user.*/
{
   int row, col;
   clearScreen();
   cout << "The current " << maxrow << "x" << maxcol << 
            " grid contains " << num_alive << " cells: "
        << endl;

   for (row = 1; row <= maxrow; row++) {
       for (col = 1; col <= maxcol; col++)
           if (grid[row][col] == 1) cout << '*';
           else cout << ' ';
       cout << endl;
   }
   cout << endl;
}

void Life::instructions()
/*
Pre:  None.

Post: Instructions for using the Life program have been printed.*/
{
   clearScreen();
   cout << "Welcome to Conway's Game of Life." << endl;
   cout << "The grid contains "
        << maxrow << " by " << maxcol;
   cout << " cells." << endl;
   cout << "The occupied cells change from generation to generation" << endl;
   cout << "according to the number of neighboring cells which are alive."
        << endl << endl;
}

bool Life::row_ok(int r)
// performs row range checking on r
{
  return r >= 1 && r <= maxrow;
}

bool Life::col_ok(int c)
// performs column range checking on c
{
  return c >= 1 && c <= maxcol;
}

// end of life.cpp

// main.cpp
/* filename: main.cpp
   programmer: Enrique De Los Santos
   project: Conways Game of Life, hw1
   purpose: driver*/

#include<iostream>

//using namespace std;

#include "util.h"
#include "life.h"

int main()  //  Program to play Conway's game of Life.
/*
Pre:  The user supplies an initial configuration of living cells.

Post: The program prints a sequence of pictures showing the changes in
      the configuration of living cells according to the rules for
      the game of Life.
Uses: The class Life and its methods initialize(), print(), and update().
      The functions  instructions(),  user_says_yes().*/

{
   Life configuration;
   configuration.instructions();
   configuration.initialize();
   configuration.print();
   cout << "Continue viewing new generations? " << endl;
   while (user_says_yes()) {
      configuration.update();
      configuration.print();
      cout << "Continue viewing new generations? " << endl;
   }
}

// end of main.cpp

output:

[edeloss2@pegasus hw1]$ make
cxx -c -L/usr/lib/cmplrs/cxx -DPOSIX_4D9 -w0 -gall life.cpp
cxx: Error: life.cpp, line 20: declaration is incompatible with
          "void Life::initialize()" (declared at line 14 of "life.h")
void Life::initialize(int choice)
-----------^
cxx: Error: life.cpp, line 27: identifier "num_alive" is undefined
   num_alive = 0;
---^
cxx: Error: life.cpp, line 76: identifier "row_ok" is undefined
           if (!infile.fail() && row_ok(row) && col_ok(col)){
---------------------------------^
cxx: Error: life.cpp, line 76: identifier "col_ok" is undefined
           if (!infile.fail() && row_ok(row) && col_ok(col)){
------------------------------------------------^
cxx: Error: life.cpp, line 146: identifier "num_alive" is undefined
   num_alive = 0;
---^
cxx: Error: life.cpp, line 165: identifier "num_alive" is undefined
            " grid contains " << num_alive << " cells: "
---------------------------------^
cxx: Error: life.cpp, line 193: class "Life" has no member "row_ok"
bool Life::row_ok(int r)
-----------^
cxx: Error: life.cpp, line 199: class "Life" has no member "col_ok"
bool Life::col_ok(int c)
-----------^
cxx: Info: 8 errors detected in the compilation of "life.cpp".
make: *** [life.o] Error 1











Avatar of avizit
avizit



1) in life.cpp
change
           num_alive = 0;
to
          int    num_alive = 0;

2) in life.h

void initialize();  should be void initialize(int );

since in life.cpp you define it as void Life::initialize(int choice)


1) in life.h

you have to add the following two functions in the class ..
so maybe you can add the following two to the public members list

bool row_ok(int r);
  bool col_ok(int c);


2) in my previous post i have asked to change

void initialize();  should be void initialize(int );

but seems you need two functions now

one with
void initialize()  // for call in main.cpp configuration.initialize();
and one with
void initialize(int )
 
******OR *********

 you can change the call in main to
configuration.initialize(1 );     //**** ie initialize randomly





in life.cpp in void Life::update()

change num_alive = 0;  to int num_alive = 0;

I think i got you wrong

you have to put

num_alive as a member data of class "Life"

not to change the declaration in the functions




Avatar of edelossantos

ASKER

avizit,

how do you mean in the last post???

go to class live and void num_alive(); // as function proto in pulic? Del
ASKER CERTIFIED SOLUTION
Avatar of avizit
avizit

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
with new changes:

# Makefile:
#        It uses the C++ Compiler with all warnings and
#        full debugging; will create a single executable called 'main'
# ---------------------------------------------------------------
# the compiler
CPP = cxx
# compiler flags
CFLAGS = -L/usr/lib/cmplrs/cxx -DPOSIX_4D9 -w0 -gall
# linker flags to link in the libraries libm.a and libtask.a
LFLAGS = -lm -ltask
#
RM = rm -f
# ----------------------------------------------------------------
# Explanation of macros:
#     $< is any dependent file which is out of file1
#     $* is the target's basename (without extension)
#     $@ is the target's fullname
#
# add suffix .cpp since it is not a default with make util
.SUFFIXES:      .cpp .o
#
# implicit rule for compilation only:
.cpp.o:
      ${CPP} -c ${CFLAGS} $<

OFILES=            main.o life.o util.o

HFILES=            life.h  util.h

# dependencies
#
default:      main      
#
main:            $(OFILES)
            ${CPP} ${CFLAGS} ${LFLAGS} $(OFILES) -o $@

main.o:            main.cpp life.h util.h
life.o:            life.cpp life.h util.h
util.o:            util.cpp util.h

#
clean:
      ${RM} *.o
      ${RM} core
#
veryclean:      clean
      ${RM}  main  

/* filename: util.h
   programer: Enrique De Los Santos
   project: Conways Game of Life
   purpose: header file for VT 100 screen functions and usefule I/O utils
   Note: a VT 100 screen is 24 rows and 80 columns in standard mode*/

#ifndef UTIL_H  
#define UTIL_H

/* type bool and false & true are already defined in dUNIX C++
typedef int bool;
const bool false = 0;
const bool true = 1; */

// this is also in /usr/unclude/stdef.h which is used in >stdlib.h>

#define NULL 0L

// useful definitions for flag and screen operations

#define STDSCREEN 80        
#define DOWN 0                        
#define UP   1
#define END   0
#define START 1
#define FAIL    0
#define SUCCESS 1
#define MISS -1
#define HIT   1

// usefule error codes

enum Error_code { success, fail, range_error, underflow, overflow, fatal,
                  not_present, duplicate_error, entry_inserted, entry_found,
                  internal_error };

// screen functions

void clearScreen ();                        // clears all rows of screen                  
void clearTop();                        // clears top row 0 only                        
void clearBelowTop();                         // clears row 1 down on a VT 100 screen                
void goTop();                           // moves cursor to top row 0                          
void topLine(const char * text = " "  );      // display text at row 0           
void bottomLine (char * text = " ");              // displays text at row 23, column 10

// I/O functions
 
void hitAnyKey ();                        // "Hit any key to continue..." prompt                    
void flushInput ();                        // reads 80 chars from stdin                    
void Warning(char *);                        // writes message to stderr                  
void Error(char *);                         // writes message to stderr and exits                    
bool promptYesNo(char * prompt="");             // prompts user to enter yes, no    
void EatWhiteSpace(void);                  // discards white space input              
bool user_says_yes();                        // function prototype

#endif

// end of util.h

/* filename: util.cpp
   programer: Enrique De Los Santos
   project: Conways Game of Life, hw1
   purpose: I/O and VT 100 screen manipulation utility functions*/
   
#include <iostream>
#include <ctype.h>
#include <stdlib.h>
#include "util.h"

/* SCREEN HANDLING FUNCTIONS -
   vertrical position goes from 0-23
   horizontal position goes from 0-79*/

// clear everything on screen
void clearScreen (void)
{
  cout << "\033[2J";          
  cout << "\033[;f";        
}

// goto top-left corner; clear to end of line
void clearTop()

  {cout << "\033[0;0f" << "\033[0K";}

// clear everything except top row
void clearBelowTop()

  {cout << "\033[1;0f" << "\033[1B" << "\033[J";}

// to the top-left corner
void goTop ()

  {cout << "\033[0;0f";}

// goto top-left corner; clear to end of line; print string
void topLine(const char str[])
 
  {cout << "\033[0;0f" << "\033[0K" << str;}

// goto line 23; clear line 23; write text
void bottomLine (char * str)
 
  {cout << "\033[23;0Hf" << "\033[2K" << str;}

// I/O functions

// precondition: the input buffer is empty
void hitAnyKey ()
{
   char ch;
   bottomLine ("Hit any key to continue...");
   cin.get(ch);
   clearScreen();
}

// flush input buffer
void flushInput ()
{
   char buff[81];
   if (cin)
      cin.getline(buff,80);      // flush the input buffer of 80 characters    
}

void Warning(char *message)
{
   cerr << message;
}

void Error(char *message)
{
   cerr << message;
   exit(1);
}

// discard leading white space
void EatWhiteSpace()
{
    char ch;
    do {
      cin.get(ch);
    }
    while(isspace(ch));

    if(ch != EOF)
      cin.putback(ch);
}

bool promptYesNo(char * c)
{
   char ch;
   cout << c << " [y|n]?";
   do {
      cin.get(ch);  
      tolower(ch);
      } while (ch != 'y' && ch != 'n');
   return (ch == 'y');
}

bool user_says_yes()
{
   int c;
   bool initial_response = true;

   do {  
      if (initial_response)
         cout << " (y,n)? " << flush;

      else
         cout << "Respond with either y or n: " << flush;

      do { //  Ignore white space.
         c = cin.get();
      } while (c == '\n' || c ==' ' || c == '\t');
      initial_response = false;
   } while (c != 'y' && c != 'Y' && c != 'n' && c != 'N');
   return (c == 'y' || c == 'Y');
}

// end of util.cpp

/* filename: life.h
   prgrammer: Enrique De Los Santos
   project: Conways Game of Life, hw1*/

#ifndef LIFE_H
#define LIFE_H

const int maxrow = 20, maxcol = 60;    //  grid dimensions

class Life {

public:
   void instructions();
   void initialize(int);
   void num_alive(int);
   void print();
   void update();
   bool row_ok(int r);
   bool col_ok(int c);

private:

   int grid[maxrow + 2][maxcol + 2];  //  allows for two extra rows and columns
   int neighbor_count(int row, int col);

};

#endif

// end of life.h

/* Filename: life.cpp
   Programmer: Enrique De Los Santos (Del)
   Project: Conways Game of Life, hw1*/

//purpose: definitions for Life class

#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>

#include <time.h>

using namespace std;

#include "util.h"
#include "life.h"

// 1 = random (default)  2 = file 3 = manual  
void Life::initialize(int choice)
{
   extern int x;
   x  = 5;
   int make_alive;  
   int row, col;
   char filename[50];
   int num_alive = 0;

   for (row = 0; row <= maxrow+1; row++)
       for (col = 0; col <= maxcol+1; col++)
           grid[row][col] = 0;


   // initialize randomly
   if ( choice == 1 )
   {
      // seed the random number generator
      srand((time(NULL)));
   
      // randomly make cells alive  
      for (row = 0; row <= maxrow+1; row++)
          for (col = 0; col <= maxcol+1; col++) {
              make_alive = rand() % 6;
              if ( make_alive == 1 ) {
                 grid[row][col] = make_alive;
                 num_alive ++;
            }
         }
 
   }
   else

   // initialize from file
   if ( choice == 2 )
   {

      cout << "Enter Filename: ";
      cin >> filename;
 
       // open input file
       ifstream infile( filename, ios::in );
       if( !infile ) {
          cerr << "File could not be opened\n";
          exit( 1 );
       }
       /* error checking for EOF and out of bounds  
           you could also use !infile.eof()      */

       while (infile) {
             infile >> row;

           // check to see if you are at eof
           if (!infile.fail())      
              infile >> col;

           // this will prevent you from processing EOF  
           if (!infile.fail() && row_ok(row) && col_ok(col)){
              grid[row][col] = 1;
              num_alive ++;
           }
        }
        infile.close();
     }  
    else
 

    // initialize  manually  
    if ( choice == 3 )
    {
       cout << "\nList coordinate pair for living cells (e.g. 4 5)"
            << " or -1 -1 to end:" << endl;
       cin >> row >> col;

       while (row != -1 || col != -1) {
          if (row >= 1 && row <= maxrow)
             if (col >= 1 && col <= maxcol)
                grid[row][col] = 1;
             else
                cout << "Column " << col << " is out of range." << endl;
          else
             cout << "Row " << row << " is out of range." << endl;
           cin >> row >> col;
           num_alive++;
       }  // user has entered -1 -1
     }    // end code to get input from user

}

int Life::neighbor_count(int row, int col)
/*
Pre:  The Life object contains a configuration, and the coordinates
      row and col define a cell inside its hedge.

Post: The number of living neighbors of the specified cell is returned.*/
{
   int i, j;
   int count = 0;
   for (i = row - 1; i <= row + 1; i++)
       for (j = col - 1; j <= col + 1; j++)
           count += grid[i][j];  //  Increase the count if neighbor is alive.
   count -= grid[row][col];      //  Reduce count, since cell is not its own neighbor.
   return count;
}

void Life::update()
/*
Pre:  The Life object contains a configuration.

Post: The Life object contains the next generation of configuration.*/
{
   int row, col;
   int new_grid[maxrow + 2][maxcol + 2];

   for (row = 1; row <= maxrow; row++)
      for (col = 1; col <= maxcol; col++)
         switch (neighbor_count(row, col)) {
         case 2:
            new_grid[row][col] = grid[row][col];    //  Status stays the same.
            break;
         case 3:
            new_grid[row][col] = 1;                 //  Cell is now alive.
            break;
         default:
            new_grid[row][col] = 0;                 //  Cell is now dead.
         }

   int num_alive = 0;

   for (row = 1; row <= maxrow; row++)
      for (col = 1; col <= maxcol; col++) {
         grid[row][col] = new_grid[row][col];
         // count the number of living cells
         if ( grid[row][col] == 1 )
            num_alive++;
      }
}

void Life::print()
/*
Pre:  The Life object contains a configuration.

Post: The configuration is written for the user.*/
{
   int row, col;
   clearScreen();
   cout << "The current " << maxrow << "x" << maxcol << 
            " grid contains " << num_alive << " cells: "
        << endl;

   for (row = 1; row <= maxrow; row++) {
       for (col = 1; col <= maxcol; col++)
           if (grid[row][col] == 1) cout << '*';
           else cout << ' ';
       cout << endl;
   }
   cout << endl;
}

void Life::instructions()
/*
Pre:  None.

Post: Instructions for using the Life program have been printed.*/
{
   clearScreen();
   cout << "Welcome to Conway's Game of Life." << endl;
   cout << "The grid contains "
        << maxrow << " by " << maxcol;
   cout << " cells." << endl;
   cout << "The occupied cells change from generation to generation" << endl;
   cout << "according to the number of neighboring cells which are alive."
        << endl << endl;
}

bool Life::row_ok(int r)
// performs row range checking on r
{
  return r >= 1 && r <= maxrow;
}

bool Life::col_ok(int c)
// performs column range checking on c
{
  return c >= 1 && c <= maxcol;
}

// end of life.cpp

// main.cpp
/* filename: main.cpp
   programmer: Enrique De Los Santos
   project: Conways Game of Life, hw1
   purpose: driver*/

#include<iostream>

//using namespace std;

#include "util.h"
#include "life.h"

int main()  //  Program to play Conway's game of Life.
/*
Pre:  The user supplies an initial configuration of living cells.

Post: The program prints a sequence of pictures showing the changes in
      the configuration of living cells according to the rules for
      the game of Life.
Uses: The class Life and its methods initialize(), print(), and update().
      The functions  instructions(),  user_says_yes().*/

{
   Life configuration;
   configuration.instructions();
   configuration.initialize(1); // initialize randomly
   configuration.print();
   cout << "Continue viewing new generations? " << endl;
   while (user_says_yes()) {
      configuration.update();
      configuration.print();
      cout << "Continue viewing new generations? " << endl;
   }
}

// end of main.cpp

output:

[edeloss2@pegasus hw1]$ make veryclean
rm -f *.o
rm -f core
rm -f  main
[edeloss2@pegasus hw1]$ make
cxx -c -L/usr/lib/cmplrs/cxx -DPOSIX_4D9 -w0 -gall main.cpp
cxx -c -L/usr/lib/cmplrs/cxx -DPOSIX_4D9 -w0 -gall life.cpp
cxx -c -L/usr/lib/cmplrs/cxx -DPOSIX_4D9 -w0 -gall util.cpp
cxx -L/usr/lib/cmplrs/cxx -DPOSIX_4D9 -w0 -gall -lm -ltask main.o life.o ut
-o main
ld:
Unresolved:
x
make: *** [main] Error 1









you are right!!! I will work on that. Del
umm looks like all the files get compiled correctly now , only the linker is giving error ,

sorry I dont have a DIGITAL UNIX machine to test exactly

but can you just try once by removing that -ltask from your Makefile

i.e change

LFLAGS = -lm -ltask

to

LFLAGS= -lm

just try and see

avizit, after making the correct correction...I get this error.

output:

[edeloss2@pegasus hw1]$ make veryclean
rm -f *.o
rm -f core
rm -f  main
[edeloss2@pegasus hw1]$ make
cxx -c -L/usr/lib/cmplrs/cxx -DPOSIX_4D9 -w0 -gall main.cpp
cxx -c -L/usr/lib/cmplrs/cxx -DPOSIX_4D9 -w0 -gall life.cpp
cxx -c -L/usr/lib/cmplrs/cxx -DPOSIX_4D9 -w0 -gall util.cpp
cxx -L/usr/lib/cmplrs/cxx -DPOSIX_4D9 -w0 -gall -lm -ltask main.o life.o util
-o main
ld:
Unresolved:
x
make: *** [main] Error 1

?????????
but can you just try once by removing that -ltask from your Makefile

i.e change

LFLAGS = -lm -ltask

to

LFLAGS= -lm

still getting same error.  Del
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I put a different makefile and got this:

[edeloss2@pegasus hw1]$ make
cxx -c -w0 -gall -L/usr/lib/cmplrs/cxx -DPOSIX_4D9 main.cpp
cxx -L/usr/lib/cmplrs/cxx -DPOSIX_4D9 -lm -ltask main.o  -o main
ld:
Unresolved:
Life::instructions(void)
Life::print(void)
user_says_yes(void)
Life::update(void)
make: *** [main] Error 1

new makefile below:

# Makefile:
#           It uses the C++ Compiler with all warnings and
#           debugging enabled. A single executable will
#           be produced.
# ---------------------------------------------------------------
CPP = cxx
CFLAGS = -L/usr/lib/cmplrs/cxx -DPOSIX_4D9
DFLAGS = -w0 -gall
LD = cxx
LLIBS = -lm -ltask
#
# Linker Flags:
# set "-lm" if we need to use the "math" functions
CLIBS= -lm
RM = rm -f
# ----------------------------------------------------------------
# Explanation of macros:
#     $< is any dependent file which is out of date
#     $* is the target's basename (without extension)
#     $@ is the target's fullname
#
# In general ".cpp" (unlike ".c") is not automatically recognized as a
# reserved suffix, so we should inform "make" in case we use this later:
.SUFFIXES:      .cpp .o
#
# implicit rule for compilation only:
.cpp.o:
      ${CPP} -c ${DFLAGS} ${CFLAGS} $<

OFILES=            main.o

HFILES=
# dependencies
#
default:      all
all:              main      
#
main:           $(OFILES)
            ${LD} ${CFLAGS} ${LLIBS} $(OFILES) -o $@

main.o:            main.cpp

#
clean:
      ${RM} *.o
      ${RM} core
#
veryclean:      clean
      ${RM}  main  
      ${RM}  *.tar  


i think you can use the old Makefile . first check my previous post regarding 'x'   , you have to solve that first
o.k.
avizit,

I got the program to run,...I am going to be signing off but will be back online tomorrow between 0930 and 1000 PDT.

Here is the new program...would you please check for the correct program behavior.  Thank you.  Del

# Makefile:
#        It uses the C++ Compiler with all warnings and
#        full debugging; will create a single executable called 'main'
# ---------------------------------------------------------------
# Note: If you want to use the g++ compiler on pegasus or helios
# uncomment the g++ lines and comment the Digital Unix lines

# the Digital Unix C++ compiler needs these lines:
CPP = cxx
CFLAGS = -L/usr/lib/cmplrs/cxx -DPOSIX_4D9 -w0 -gall

# the g++ compiler on pegasus and helios needs these lines:
# CPP = g++
# CFLAGS = -DPOSIX_4D9 -w -g

# link in the math library
LFLAGS = -lm

RM = rm -f
# ----------------------------------------------------------------
# Explanation of macros:
#     $< is any dependent file which is out of file1
#     $* is the target's basename (without extension)
#     $@ is the target's fullname
#
# add suffix .cpp since it is not a default with make util
.SUFFIXES:      .cpp .o
#
# implicit rule for compilation only:
.cpp.o:
      ${CPP} -c ${CFLAGS} $<

OFILES=            main.o life.o util.o

HFILES=            life.h  util.h

# dependencies
#
default:      main      
#
main:           $(OFILES)
            ${CPP} ${CFLAGS} ${LFLAGS} $(OFILES) -o $@

main.o:            main.cpp life.h util.h
life.o:            life.cpp life.h util.h
util.o:            util.cpp util.h

#
clean:
      ${RM} *.o
      ${RM} core
#
veryclean:      clean
      ${RM}  main  
      
/* filename: util.h
   programer: Enrique De Los Santos
   project: Conways Game of Life
   purpose: header file for VT 100 screen functions and usefule I/O utils
   Note: a VT 100 screen is 24 rows and 80 columns in standard mode*/

#ifndef UTIL_H  
#define UTIL_H

/* type bool and false & true are already defined in dUNIX C++
typedef int bool;
const bool false = 0;
const bool true = 1; */

// this is also in /usr/unclude/stdef.h which is used in >stdlib.h>

#define NULL 0L

// useful definitions for flag and screen operations

#define STDSCREEN 80        
#define DOWN 0                        
#define UP   1
#define END   0
#define START 1
#define FAIL    0
#define SUCCESS 1
#define MISS -1
#define HIT   1

// usefule error codes

enum Error_code { success, fail, range_error, underflow, overflow, fatal,
                  not_present, duplicate_error, entry_inserted, entry_found,
                  internal_error };

// screen functions

void clearScreen ();                        // clears all rows of screen                  
void clearTop();                        // clears top row 0 only                        
void clearBelowTop();                         // clears row 1 down on a VT 100 screen                
void goTop();                           // moves cursor to top row 0                          
void topLine(const char * text = " "  );      // display text at row 0           
void bottomLine (char * text = " ");              // displays text at row 23, column 10

// I/O functions
 
void hitAnyKey ();                        // "Hit any key to continue..." prompt                    
void flushInput ();                        // reads 80 chars from stdin                    
void Warning(char *);                        // writes message to stderr                  
void Error(char *);                         // writes message to stderr and exits                    
bool promptYesNo(char * prompt="");             // prompts user to enter yes, no    
void EatWhiteSpace(void);                  // discards white space input              
bool user_says_yes();                        // function prototype

#endif

// end of util.h

/* filename: util.cpp
   programer: Enrique De Los Santos
   project: Conways Game of Life, hw1
   purpose: I/O and VT 100 screen manipulation utility functions*/
   
#include <iostream>
#include <ctype.h>
#include <stdlib.h>
#include "util.h"

/* SCREEN HANDLING FUNCTIONS -
   vertrical position goes from 0-23
   horizontal position goes from 0-79*/

// clear everything on screen
void clearScreen (void)
{
  cout << "\033[2J";          
  cout << "\033[;f";        
}

// goto top-left corner; clear to end of line
void clearTop()

  {cout << "\033[0;0f" << "\033[0K";}

// clear everything except top row
void clearBelowTop()

  {cout << "\033[1;0f" << "\033[1B" << "\033[J";}

// to the top-left corner
void goTop ()

  {cout << "\033[0;0f";}

// goto top-left corner; clear to end of line; print string
void topLine(const char str[])
 
  {cout << "\033[0;0f" << "\033[0K" << str;}

// goto line 23; clear line 23; write text
void bottomLine (char * str)
 
  {cout << "\033[23;0Hf" << "\033[2K" << str;}

// I/O functions

// precondition: the input buffer is empty
void hitAnyKey ()
{
   char ch;
   bottomLine ("Hit any key to continue...");
   cin.get(ch);
   clearScreen();
}

// flush input buffer
void flushInput ()
{
   char buff[81];
   if (cin)
      cin.getline(buff,80);      // flush the input buffer of 80 characters    
}

void Warning(char *message)
{
   cerr << message;
}

void Error(char *message)
{
   cerr << message;
   exit(1);
}

// discard leading white space
void EatWhiteSpace()
{
    char ch;
    do {
      cin.get(ch);
    }
    while(isspace(ch));

    if(ch != EOF)
      cin.putback(ch);
}

bool promptYesNo(char * c)
{
   char ch;
   cout << c << " [y|n]?";
   do {
      cin.get(ch);  
      tolower(ch);
      } while (ch != 'y' && ch != 'n');
   return (ch == 'y');
}

bool user_says_yes()
{
   int c;
   bool initial_response = true;

   do {  
      if (initial_response)
         cout << " (y,n)? " << flush;

      else
         cout << "Respond with either y or n: " << flush;

      do { //  Ignore white space.
         c = cin.get();
      } while (c == '\n' || c ==' ' || c == '\t');
      initial_response = false;
   } while (c != 'y' && c != 'Y' && c != 'n' && c != 'N');
   return (c == 'y' || c == 'Y');
}

// end of util.cpp

/* filename: life.h
   prgrammer: Enrique De Los Santos
   project: Conways Game of Life, hw1*/

#ifndef LIFE_H
#define LIFE_H

const int maxrow = 20, maxcol = 60;    //  grid dimensions

class Life {

public:
   void instructions();
   void initialize(int);
   void func1 (int &);
   //void num_alive(int);
   void print();
   void update();
   bool row_ok(int r);
   bool col_ok(int c);

private:

   int grid[maxrow + 2][maxcol + 2];  //  allows for two extra rows and columns
   int neighbor_count(int row, int col);
   int num_alive ;
   //int x;

};

#endif

// end of life.h

/* Filename: life.cpp
   Programmer: Enrique De Los Santos (Del)
   Project: Conways Game of Life, hw1*/

//purpose: definitions for Life class

#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>

#include <time.h>

using namespace std;

#include "util.h"
#include "life.h"

// 1 = random (default)  2 = file 3 = manual  
void Life::initialize(int choice)
{
   extern int x;
   x  = 5;
   int make_alive;  
   int row, col;
   char filename[50];
   int num_alive = 0;

   for (row = 0; row <= maxrow+1; row++)
       for (col = 0; col <= maxcol+1; col++)
           grid[row][col] = 0;


   // initialize randomly
   if ( choice == 1 )
   {
      // seed the random number generator
      srand((time(NULL)));
   
      // randomly make cells alive  
      for (row = 0; row <= maxrow+1; row++)
          for (col = 0; col <= maxcol+1; col++) {
              make_alive = rand() % 6;
              if ( make_alive == 1 ) {
                 grid[row][col] = make_alive;
                 num_alive ++;
            }
         }
 
   }
   else

   // initialize from file
   if ( choice == 2 )
   {

      cout << "Enter Filename: ";
      cin >> filename;
 
       // open input file
       ifstream infile( filename, ios::in );
       if( !infile ) {
          cerr << "File could not be opened\n";
          exit( 1 );
       }
       /* error checking for EOF and out of bounds  
           you could also use !infile.eof()      */

       while (infile) {
             infile >> row;

           // check to see if you are at eof
           if (!infile.fail())      
              infile >> col;

           // this will prevent you from processing EOF  
           if (!infile.fail() && row_ok(row) && col_ok(col)){
              grid[row][col] = 1;
              num_alive ++;
           }
        }
        infile.close();
     }  
    else
 

    // initialize  manually  
    if ( choice == 3 )
    {
       cout << "\nList coordinate pair for living cells (e.g. 4 5)"
            << " or -1 -1 to end:" << endl;
       cin >> row >> col;

       while (row != -1 || col != -1) {
          if (row >= 1 && row <= maxrow)
             if (col >= 1 && col <= maxcol)
                grid[row][col] = 1;
             else
                cout << "Column " << col << " is out of range." << endl;
          else
             cout << "Row " << row << " is out of range." << endl;
           cin >> row >> col;
           num_alive++;
       }  // user has entered -1 -1
     }    // end code to get input from user

}

int Life::neighbor_count(int row, int col)
/*
Pre:  The Life object contains a configuration, and the coordinates
      row and col define a cell inside its hedge.

Post: The number of living neighbors of the specified cell is returned.*/
{
   int i, j;
   int count = 0;
   for (i = row - 1; i <= row + 1; i++)
       for (j = col - 1; j <= col + 1; j++)
           count += grid[i][j];  //  Increase the count if neighbor is alive.
   count -= grid[row][col];      //  Reduce count, since cell is not its own neighbor.
   return count;
}

void Life::update()
/*
Pre:  The Life object contains a configuration.

Post: The Life object contains the next generation of configuration.*/
{
   int row, col;
   int new_grid[maxrow + 2][maxcol + 2];

   for (row = 1; row <= maxrow; row++)
      for (col = 1; col <= maxcol; col++)
         switch (neighbor_count(row, col)) {
         case 2:
            new_grid[row][col] = grid[row][col];    //  Status stays the same.
            break;
         case 3:
            new_grid[row][col] = 1;                 //  Cell is now alive.
            break;
         default:
            new_grid[row][col] = 0;                 //  Cell is now dead.
         }

   int num_alive = 0;

   for (row = 1; row <= maxrow; row++)
      for (col = 1; col <= maxcol; col++) {
         grid[row][col] = new_grid[row][col];
         // count the number of living cells
         if ( grid[row][col] == 1 )
            num_alive++;
      }
}

void Life::print()
/*
Pre:  The Life object contains a configuration.

Post: The configuration is written for the user.*/
{
   int row, col;
   clearScreen();
   cout << "The current " << maxrow << "x" << maxcol << 
            " grid contains " << num_alive << " cells: "
        << endl;

   for (row = 1; row <= maxrow; row++) {
       for (col = 1; col <= maxcol; col++)
           if (grid[row][col] == 1) cout << '*';
           else cout << ' ';
       cout << endl;
   }
   cout << endl;
}

void Life::instructions()
/*
Pre:  None.

Post: Instructions for using the Life program have been printed.*/
{
   clearScreen();
   cout << "Welcome to Conway's Game of Life." << endl;
   cout << "The grid contains "
        << maxrow << " by " << maxcol;
   cout << " cells." << endl;
   cout << "The occupied cells change from generation to generation" << endl;
   cout << "according to the number of neighboring cells which are alive."
        << endl << endl;
}

bool Life::row_ok(int r)
// performs row range checking on r
{
  return r >= 1 && r <= maxrow;
}

bool Life::col_ok(int c)
// performs column range checking on c
{
  return c >= 1 && c <= maxcol;
}

extern int x = 222;     /* initializes the variable referred to in file1*/

void func1 (int & arg1)  /*  func1 has external linkage, arg1 has no linkage
                             but points back to the variable in main */
{

  arg1 = 200;
  x = 333;
  cout << "\nFUNC1:\n";
  cout << "x: " << x << endl;
  //cout << "y: " << y << endl;
  cout << "arg1: " << arg1 << endl;
}


// end of life.cpp

// main.cpp
/* filename: main.cpp
   programmer: Enrique De Los Santos
   project: Conways Game of Life, hw1
   purpose: driver*/

#include<iostream>

//using namespace std;

#include "util.h"
#include "life.h"

extern int x;     /* identifiers outside any function default to external */
void func1 (int &);   /* prototypes have no linkage  */

int main()  //  Program to play Conway's game of Life.
/*
Pre:  The user supplies an initial configuration of living cells.

Post: The program prints a sequence of pictures showing the changes in
      the configuration of living cells according to the rules for
      the game of Life.
Uses: The class Life and its methods initialize(), print(), and update().
      The functions  instructions(),  user_says_yes().*/

{
   Life configuration;
   void initialize();
   void initialize(int);
   configuration.instructions();
   //configuration.initialize(1); // initialize randomly
   configuration.print();
   cout << "Continue viewing new generations? " << endl;
   while (user_says_yes()) {
      configuration.update();
      configuration.print();
      cout << "Continue viewing new generations? " << endl;
      cout << "x: " << x << endl;

      func1(x);
      cout << "x: " << x << endl;


   }
}

// end of main.cpp

output:

The current 20x60 grid contains 0 cells:







                        * *





                                           *

       *

                            *   *   *          ** *
*             *         *
                                         *  *             *

Continue viewing new generations?
 (y,n)?