|
Hobbyist Programmer
Join Date: Nov 2006
Posts: 111
Rep Power: 2 
|
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.
|