View Single Post
Old Nov 29th, 2006, 6:33 PM   #2
aznballerlee
Hobbyist Programmer
 
Join Date: Nov 2006
Posts: 111
Rep Power: 2 aznballerlee is on a distinguished road
This is the skeleton code, added some of the accessor and constructor stuff I finished easily. My problem is where to go next ..

// Portions you are to complete are marked with a TODO: comment.
// The first thing you probably want to do is implement the trivial
// functions.  Then get Valley::addEnergySource and Valley::display going.
// That gives you more flexibility in the order you tackle the rest
// of the functionality.

#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
using namespace std;

///////////////////////////////////////////////////////////////////////////
// Manifest constants
///////////////////////////////////////////////////////////////////////////

const int NROWS = 10;               // number of rows in the valley
const int NCOLS = 10;               // number of columns in the valley
const int MAXROBOTS = 10;           // max number of robots allowed
const int MAXSOURCES = NROWS*NCOLS; // max number of energy sources
const int FULL_ENERGY = 60;         // number of units when fully charged
const int SHARE_THRESHHOLD = 30;    // will share energy if have at least this
const int SHARE_AMOUNT = 10;        // amount of energy to share

///////////////////////////////////////////////////////////////////////////
// Type definitions
///////////////////////////////////////////////////////////////////////////

enum Dir {
	NORTH, EAST, SOUTH, WEST
};

class Valley;  // This is needed to let compiler know that Valley is a type
//   name, since it's mentioned in the Robot declaration.

class Robot
{
public:
	// Constructor
	Robot(string nm, Valley* vp, int r, int c, Dir d);

	// Accessors
	string name() const;
	int    energy() const;
	int    row() const;
	int    col() const;
	Dir    dir() const;

	// Mutators
	bool   step();

private:
	string  m_name;
	int     m_energy;
	int     m_row;
	int     m_col;
	Dir     m_dir;
	Valley* m_valley;
};

class EnergySource
{
public:
	// Constructor
	EnergySource(int r, int c);

	// Accessors
	int row() const;
	int col() const;

private:
	int m_row;
	int m_col;
};

class Valley
{
public:
	// Constructor
	Valley();
	~Valley();

	// Accessors
	Robot* otherRobotAt(Robot* rp) const;
	bool   energySourceAt(int r, int c) const;
	void   display() const;

	// Mutators
	bool   addRobot(string name, int r, int c, Dir dir);
	bool   addEnergySource(int r, int c);
	bool   step();

private:
	Robot*        m_robots[MAXROBOTS];
	int           m_nrobots;
	EnergySource* m_sources[MAXROBOTS];
	int           m_nsources;
};

///////////////////////////////////////////////////////////////////////////
//  Robot implementation
///////////////////////////////////////////////////////////////////////////

Robot::Robot(string nm, Valley* vp, int r, int c, Dir d)
: m_name(nm), m_energy(FULL_ENERGY), m_row(r), m_col(c), m_dir(d), m_valley(vp)
{
	// Since the first character of the Robot's name shows up in the
	// display, there had better be a first character.
	if (nm.size() == 0)
	{
		cout << "***** A robot must have a non-empty name!" << endl;
		exit(1);
	}
	if (r < 0  ||  r >= NROWS  ||  c < 0  ||  c >= NCOLS)
	{
		cout << "***** Robot created with invalid coordinates (" << r << ","
			<< c << ")!" << endl;
		exit(1);
	}
}

// TODO:  Implement the other four accessor functions.  These should be trivial. 
string Robot::name() const
{
	return m_name;
}

int Robot::energy() const
{
	return m_energy;
}

int Robot::row() const
{
	return m_row;
}

int Robot::col() const
{
	return m_col;
}

Dir Robot::dir() const
{
	return m_dir;
}

// TODO:  Implement the step function.  Here's an outline:

bool Robot::step()
{
	// If the robot has no energy left, return false
	// Otherwise,
	//    Randomly change direction with probability 1/3
	if (rand() % 3 == 0)    // 1/3 probability to pick a direction
		m_dir = Dir(rand() % 4);    // pick a random direction
	//    Attempt to move one step in the direction we're currently facing.
	//      (E.g., to move north, decrement the row coordinate.)  If we can't
	//      move in that direction, don't move.
	switch (m_dir)
	{
	case NORTH:
		// TODO: Move one step north, if possible.
		break;
	case SOUTH:
	case WEST:
	case EAST:
		// TODO: Implement the other movements
		break;
	}
	//    The attempt to move consumes one unit of energy.
	//    If as a result of the attempt to move, the robot is at an energy
	//       source, it's recharged to the FULL_ENERGY level.
	//    If at this spot there's another robot whose energy level is 0,
	//       then if we have at least SHARE_THRESHHOLD units of energy,
	//       transfer SHARE_AMOUNT units to that other robot.  (If there
	//       are two or more dead robots here, we donate to only one.)
	//    Return true, indicating the robot attempted to move.
	return true;
}

///////////////////////////////////////////////////////////////////////////
//  EnergySource implementations
///////////////////////////////////////////////////////////////////////////

// TODO:  Implement the constructor
//    EnergySource(int r, int c)
//        The constructed EnergySource's location will be at coordinates (r,c).

EnergySource::EnergySource(int r, int c)
: m_row(r), m_col(c)
{
	if (r < 0  ||  r >= NROWS  ||  c < 0  ||  c >= NCOLS)
	{
		cout << "***** EnergySource created with invalid coordinates (" << r << ","
			<< c << ")!" << endl;
		exit(1);
	}
}

// TODO:  Implement the two accessor functions.  These should be trivial.
int EnergySource::row() const
{
	return m_row;
}

int EnergySource::col() const
{
	return m_col;
}

///////////////////////////////////////////////////////////////////////////
//  Valley implementations
///////////////////////////////////////////////////////////////////////////

Valley::Valley()
: m_nrobots(0), m_nsources(0)
{
	//      TODO:  Implement the constructor
	//      Make the valley have no robots or energy sources.
}

Valley::~Valley()
{
	// delete []   ;
	//      TODO:  Implement the destructor
	//      Delete any dynamically allocated objects held by the Valley.
}

// TODO:  Implement the accessors
//
//    Robot* otherRobotAt(Robot* rp) const
//      If there is at least one robot (other than the one rp points to)
//      at the same (r,c) coordinates as the one rp points to, return a
//      pointer to the one of those other robots with the least amount
//      of energy remaining (if there's a tie, any one of the tied robots
//      will do); otherwise, return NULL.
//
//    bool energySourceAt(int r, int c) const
//      If there is an energy source at coordinates (r,c), return true;
//      otherwise, return false.
//
//    Fill in the rest of the display function

void Valley::display() const
{
	char grid[NROWS][NCOLS];
	int r, c;

	// fill the grid with dots
	for (r = 0; r < NROWS; r++)
		for (c = 0; c < NCOLS; c++)
			grid[r][c] = '.';

	// TODO:  mark each energy source with a star
	// for each energy source in the valley,
	//   set the appropriate element of the grid to '*'

	// TODO:  indicate each robot's position
	// for each robot in the valley,
	//   set the appropriate element of the grid to the first character
	//          of the robot's name.

	// Clear the screen
	system("cls");  // Under LINUX, try  system("clear");

	// Draw the grid
	for (r = 0; r < NROWS; r++)
	{
		for (c = 0; c < NCOLS; c++)
			cout << grid[r][c];
		cout << endl;
	}
	cout << endl;

	// TODO:  Write robot energy info
	// for each robot in the valley,
	//   write the robot's name and remaining energy level.
}

// TODO:  Implement the mutators

bool Valley::addRobot(string name, int r, int c, Dir dir)
{
	//      TODO: implement addRobot
	//      If MAXROBOTS have already been added, return false.  Otherwise,
	//      dynamically allocate a new robot whose name is name, at coordinates
	//      (r,c) facing in direction dir.  Save the pointer to the newly
	//      allocated robot and return true.  (Hint:  The Valley class could
	//      contain a private array with MAXROBOTS elements.)
	return true;
}

bool Valley::addEnergySource(int r, int c)
{
	//      TODO: implement addEnergySource
	//      If MAXSOURCES have already been added, return false.  Otherwise,
	//      dynamically allocate a new energy source at coordinates (r,c).
	//      Save the pointer to the newly allocated energy source and return true.
	//      (Hint:  The Valley class could contain a private array with MAXSOURCES
	//      elements.)
	return true;
}

bool Valley::step()
{
	//      TODO: implement step
	//      Have each robot in the valley step.  If any of them attempted to move,
	//      return true.  If none of them did, they're all dead, so return false.
	return true; // This is here for now just so this will compile.
}


///////////////////////////////////////////////////////////////////////////
//  main()
///////////////////////////////////////////////////////////////////////////

// You can use whatever main routine you want.  In fact, try different
// things that will thoroughly test your classes.  This main routine is
// the one that the sample executable uses.

int main()
{
	// Initialize the random number generator
	srand(time(0));

	// Create a valley
	Valley v;

	// Populate it with three robots
	v.addRobot("Abner", 0, 0, SOUTH);
	v.addRobot("Betty", 9, 9, NORTH);
	v.addRobot("Chris", 0, 9, SOUTH);

	// Add energy sources at (2,2), (2,5), (2,8), (5,2), ..., (8,8)
	for (int r = 2; r <= 8; r += 3)
		for (int c = 2; c <= 8; c += 3)
			v.addEnergySource(r, c);

	// Step until all robots are dead, displaying the valley each time
	do
	{
		v.display();
		cout << "Press Enter to continue ";
		cin.ignore(100000, '\n');
	} while(v.step());

	cout << "All robots are dead" << endl;
}

Last edited by aznballerlee; Nov 29th, 2006 at 6:53 PM.
aznballerlee is offline   Reply With Quote