Solved

hw1 code fix

Posted on 2004-09-19
16
229 Views
Last Modified: 2010-04-01
// 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











0
Comment
Question by:edelossantos
  • 8
  • 8
16 Comments
 
LVL 11

Expert Comment

by:avizit
ID: 12099218


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)


0
 
LVL 11

Expert Comment

by:avizit
ID: 12099249
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





0
 
LVL 11

Expert Comment

by:avizit
ID: 12099252
in life.cpp in void Life::update()

change num_alive = 0;  to int num_alive = 0;

0
 
LVL 11

Expert Comment

by:avizit
ID: 12099260
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




0
 

Author Comment

by:edelossantos
ID: 12099401
avizit,

how do you mean in the last post???

go to class live and void num_alive(); // as function proto in pulic? Del
0
 
LVL 11

Accepted Solution

by:
avizit earned 500 total points
ID: 12099424
No ..

I tried compiling your code
and then for a few function I got the following error


 `num_alive' undeclared (first use this function)

so I presumed that you just forgot to declare ..
so I suggested that you change that " num_alive =0 ; "  to  "int num_alive = 0;"  in   void Life::initialize(int choice)  in life.cpp

BUt since the same error occurred in a few more functions , I THINK what you intended was to change the class member
num_alive , but  looks like you forgot to add num_alive in the class members list

so I THINK that it should be added in life.h as follows

++++++++++++++++++++++++++++++++++++
class Life {

 public:
  void instructions();
  void initialize(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 ;   /*********NOTE THIS ADDITION **********/

};


but frankly speaking I think you should have known that and when i asked you to do a int num_alive = 0 , you should have corrected me .. saying that no that was supposed to be a private data member etc  .. i suggest you try to understand what and howyour program is doing things :)





0
 

Author Comment

by:edelossantos
ID: 12099435
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









0
 

Author Comment

by:edelossantos
ID: 12099440
you are right!!! I will work on that. Del
0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 11

Expert Comment

by:avizit
ID: 12099442
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

0
 

Author Comment

by:edelossantos
ID: 12099449
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

?????????
0
 

Author Comment

by:edelossantos
ID: 12099464
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
0
 
LVL 11

Assisted Solution

by:avizit
avizit earned 500 total points
ID: 12099504
okay i tried compiling and i get the following error

life.o(.text+0xc): In function `Life::initialize(int)':
: undefined reference to `x'
collect2: ld returned 1 exit status

+++++++++++++++++++++++++++
void Life::initialize(int choice)
{
  extern int x;
  x  = 5;

++++++++++++++++++++++
in the above code you define "x" as extern, but havent defined it anywhere ? and what is 'x' ?
so you should find out what is 'x' for and whether you need it or not and if you need it you need to define it somewhere

0
 

Author Comment

by:edelossantos
ID: 12099513
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  


0
 
LVL 11

Expert Comment

by:avizit
ID: 12099522
i think you can use the old Makefile . first check my previous post regarding 'x'   , you have to solve that first
0
 

Author Comment

by:edelossantos
ID: 12099544
o.k.
0
 

Author Comment

by:edelossantos
ID: 12099684
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)?











0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now