Solved

hw1 code fix

Posted on 2004-09-19
16
239 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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
 
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

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

636 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