![]() |
|
![]() |
|
|
Thread Tools | Display Modes |
|
|
#61 | |||
|
Hobbyist Programmer
Join Date: Nov 2006
Posts: 111
Rep Power: 2
![]() |
I think that
&& (m_robots[i] -> energy() < leastEnergy)) Here's what I changed: Robot* Valley::otherRobotAt(Robot* rp) const
{
Robot* robotToReturn = NULL;
int leastEnergy = FULL_ENERGY;
for (int i=0; i < m_nrobots; i++)
{
if ((m_robots[i] -> row() == rp -> row() )
&& (m_robots[i] -> col() == rp -> col())
&& (m_robots[i] != rp)
&& (m_robots[i] -> energy() < leastEnergy))
{
robotToReturn = m_robots[i];
leastEnergy = robotToReturn -> energy();
return robotToReturn;
}
}
return NULL;
}EDITS: 1. Quote:
if ((otherRobotAt(m_valley) -> energy() == 0)
&& (m_energy > SHARE_THRESHHOLD))
{
m_energy -= SHARE_AMOUNT;
otherRobotAt(m_valley)-> energy() = SHARE_AMOUNT;
return true;
}but it said that otherRobotAt is undeclared. I'm trying to say that if 'there's another robot we located, that we pointed to, that has energy of 0' but it's not working out. BTW, this is part of the Robot function as a data member. class Robot
{
...
private:
string m_name;
int m_energy;
int m_row;
int m_col;
Dir m_dir;
Valley* m_valley;
};2. for (int b = 0; b < m_nrobots; b++)
{
grid[r][c] = m_robots[b] -> name()[0];
}Quote:
Something like this: grid[m_row][m_col] = m_robots[b] -> name()[0]; Quote:
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.
bool x =!( m_robot[p] -> step());
for (int p = 0; p < m_nrobots; p++)
{
if (x)
return false;
}
return true;
}Last edited by aznballerlee; Dec 2nd, 2006 at 5:13 PM. |
|||
|
|
|
|
|
#62 |
|
Expert Programmer
Join Date: Jun 2005
Posts: 852
Rep Power: 4
![]() |
0.
int leastEnergy = FULL_ENERGY; return robotToReturn; 1. otherRobotAt(m_valley) -> energy() == 0 [code] m_valley->otherRobotAt(this) -> energy() == 0 You still need to check that there is a robot at that location before trying to access its energy. 2. grid[m_row][m_col] = m_robots[b] -> name()[0]; 4. 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.
bool x =!( m_robot[p] -> step());
for (int p = 0; p < m_nrobots; p++)
{
if (x)
return false;
}
return true;
}You need to call the function inside the loop, as you were previously doing, but somehow record whether any one of the function calls returned true. Again, the best way to see it is to right down simple steps, in english, that you would do if you were physically looking at a set of robots and pressing a button on each one. Then try converting it to C++. Anything you can't convert to a simple C++ statement probably needs to be broken down further. Also again, a lot of these coding attempts would not compile, you should at least try them in a compiler, as that would pick up a lot of the things that are wrong (e.g. trying to use a variable before it is declared). |
|
|
|
|
|
#63 | |
|
Hobbyist Programmer
Join Date: Nov 2006
Posts: 111
Rep Power: 2
![]() |
1.
Quote:
2. This is the best I could think of .. // 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.
for (int b = 0; b < m_nrobots; b++)
{
grid[r][c] = m_robots[b] -> row() -> col() -> name()[0];
}for (Each robot)
{
if (robot didn't step)
return false;
}
return true;which transate in C++ to this: for (int p = 0; p < m_nrobots; p++)
{
if ( !(m_robot[p] -> step() ) )
return false;
}
return true;
}in the loop. If we don't find any that didn't step, then return true. Last edited by aznballerlee; Dec 2nd, 2006 at 8:15 PM. |
|
|
|
|
|
|
#64 | ||||
|
Expert Programmer
Join Date: Jun 2005
Posts: 852
Rep Power: 4
![]() |
Quote:
Quote:
Quote:
Yes your C and pseudo code match your english description. The problem is that your english description doesn't match the requirement. Quote:
|
||||
|
|
|
|
|
#65 |
|
Hobbyist Programmer
Join Date: Nov 2006
Posts: 111
Rep Power: 2
![]() |
Hmm this works out for part 0.
Robot* Valley::otherRobotAt(Robot* rp) const
{
Robot* robotToReturn = NULL;
int leastEnergy = FULL_ENERGY;
for (int i=0; i < m_nrobots; i++)
{
if ((m_robots[i] -> row() == rp -> row() )
&& (m_robots[i] -> col() == rp -> col())
&& (m_robots[i] != rp)
&& (m_robots[i] -> energy() < leastEnergy))
{
robotToReturn = m_robots[i];
leastEnergy = robotToReturn -> energy();
return robotToReturn;
}
}
return robotToReturn;
}4. Oooh, I get your point. Is this the idea? for (int p = 0; p < m_nrobots; p++)
{
// tell m_robot[p] to step
if ( !(m_robot[p] -> step() ) )
return false; |
|
|
|
|
|
#66 |
|
Expert Programmer
Join Date: Jun 2005
Posts: 852
Rep Power: 4
![]() |
No, it doesn't - it returns the first robot at the given location with less than full energy.
I pointed this out in post #62. Please read it. |
|
|
|
|
|
#67 |
|
Hobbyist Programmer
Join Date: Nov 2006
Posts: 111
Rep Power: 2
![]() |
0. I made a mistake:
Robot* Valley::otherRobotAt(Robot* rp) const
{
Robot* robotToReturn = NULL;
int leastEnergy = FULL_ENERGY;
for (int i=0; i < m_nrobots; i++)
{
if ((m_robots[i] -> row() == rp -> row() )
&& (m_robots[i] -> col() == rp -> col())
&& (m_robots[i] != rp)
&& (m_robots[i] -> energy() < leastEnergy))
{
robotToReturn = m_robots[i];
leastEnergy = robotToReturn -> energy();
}
}
return robotToReturn;
}2. Anyways, I thought of a way to do this: // 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.
for (int b = 0; b < m_nrobots; b++)
{
Robot *currentRobot = m_robots[b];
char ch = currentRobot -> name()[0];
int row = currentRobot -> row();
int col = currentRobot -> col();
grid[row][col] = ch;
}4. We dont return the first robot at the given location with less than full energy, because we're in a loop. It will keep updating until it finds the one with the least energy, then return it outside the loop. 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.
for (int p = 0; p < m_nrobots; p++)
{
m_robots[p] -> step();
if (m_robots[p] -> step() == NULL)
return true;
}
return false;
}Last edited by aznballerlee; Dec 2nd, 2006 at 10:48 PM. |
|
|
|
|
|
#68 |
|
Hobbyist Programmer
Join Date: Nov 2006
Posts: 111
Rep Power: 2
![]() |
Anyways, still stuck on number 4.
EDIT: I just want to verify the correctness of this code. Actually, I think it's wrong somewhere. I think same idea, return values early. 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.
int m = 0;
bool returnValue = false;
Robot *currentRobot = m_robots[m];
for (m; m < m_nrobots; m++)
{
currentRobot -> step();
if (currentRobot -> step())
returnValue = true;
}
return returnValue;
}Last edited by aznballerlee; Dec 2nd, 2006 at 11:54 PM. |
|
|
|
|
|
#69 |
|
Hobbyist Programmer
Join Date: Nov 2006
Posts: 111
Rep Power: 2
![]() |
Okay, an update on my progress. I finished my code, but there might be errors. When I compile, it runs the game, but it always gives me the error ***** Robot created with invalid coordinates after like
one or two rounds of play. Do you know what's going on? Here's my entire code: #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[MAXSOURCES];
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
if (m_energy == 0)
return false;
// Otherwise,
else
{
// 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.
m_row--;
if (m_row < 0 || m_row >= NROWS || m_col < 0 || m_col >= NCOLS)
{
cout << "***** Robot created with invalid coordinates (" << m_row << ","
<< m_col << ")!" << endl;
exit(1);
}
break;
// TODO: Implement the other movements
case SOUTH:
m_row++;
if (m_row < 0 || m_row >= NROWS || m_col < 0 || m_col >= NCOLS)
{
cout << "***** Robot created with invalid coordinates (" << m_row << ","
<< m_col << ")!" << endl;
exit(1);
}
break;
case WEST:
m_col--;
if (m_row < 0 || m_row >= NROWS || m_col < 0 || m_col >= NCOLS)
{
cout << "***** Robot created with invalid coordinates (" << m_row << ","
<< m_col << ")!" << endl;
exit(1);
}
break;
case EAST:
m_col++;
if (m_row < 0 || m_row >= NROWS || m_col < 0 || m_col >= NCOLS)
{
cout << "***** Robot created with invalid coordinates (" << m_row << ","
<< m_col << ")!" << endl;
exit(1);
}
break;
}
}
// The attempt to move consumes one unit of energy.
m_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 (m_valley -> energySourceAt(m_row, m_col))
m_energy = FULL_ENERGY;
// 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.
Robot* otherRobot = m_valley->otherRobotAt(this);
if (otherRobot != NULL)
{
if ((m_energy > SHARE_THRESHHOLD))
{
m_energy -= SHARE_AMOUNT;
otherRobot-> m_energy = SHARE_AMOUNT;
return true;
}
}
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
///////////////////////////////////////////////////////////////////////////
// TODO: Implement the constructor
// Make the valley have no robots or energy sources.
Valley::Valley()
: m_nrobots(0), m_nsources(0)
{
}
// TODO: Implement the destructor
// Delete any dynamically allocated objects held by the Valley.
Valley::~Valley()
{
delete [] m_robots[m_nrobots];
delete [] m_sources[m_nsources];
}
// TODO: Implement the accessors
// 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.
//
Robot* Valley::otherRobotAt(Robot* rp) const
{
Robot* robotToReturn = NULL;
int leastEnergy = FULL_ENERGY;
for (int i=0; i < m_nrobots; i++)
{
if ((m_robots[i] -> row() == rp -> row() )
&& (m_robots[i] -> col() == rp -> col())
&& (m_robots[i] != rp)
&& (m_robots[i] -> energy() < leastEnergy))
{
robotToReturn = m_robots[i];
leastEnergy = robotToReturn -> energy();
}
}
return robotToReturn;
}
// If there is an energy source at coordinates (r,c), return true;
// otherwise, return false.
bool Valley::energySourceAt(int r, int c) const
{
for (int k = 0; k < m_nsources; k++)
{
if ((m_sources[k]->row()== r)
&& (m_sources[k]->col()== c))
return true;
}
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 '*'
if (energySourceAt(r,c))
grid[r][c] = '*';
}
}
// 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.
for (int b = 0; b < m_nrobots; b++)
{
Robot *currentRobot = m_robots[b];
char ch = currentRobot -> name()[0];
int row = currentRobot -> row();
int col = currentRobot -> col();
grid[row][col] = ch;
}
// 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.
for (int c = 0; c < m_nrobots; c++)
{
cout << m_robots[c] -> name() << endl;
cout << m_robots[c] -> energy() << endl;
}
}
// TODO: Implement the mutators
// 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.)
bool Valley::addRobot(string name, int r, int c, Dir dir)
{
if (m_nrobots == MAXROBOTS)
return false;
else
{
m_robots[m_nrobots] = new Robot(name, this, r, c, dir);
m_nrobots++;
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.)
if (m_nsources == MAXSOURCES)
return false;
else
{
m_sources[m_nsources] = new EnergySource(r,c);
m_nsources++;
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.
int m = 0;
bool returnValue = false;
Robot *currentRobot;
for (m; m < m_nrobots; m++)
{
currentRobot = m_robots[m];
if (currentRobot -> step())
returnValue = true;
}
return returnValue;
}
///////////////////////////////////////////////////////////////////////////
// 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;
} |
|
|
|
|
|
#70 |
|
Expert Programmer
Join Date: Jun 2005
Posts: 852
Rep Power: 4
![]() |
I see you have fixed up your valley::step loop in the final code, it look good.
In the Robot:step code, you have lots of tests like: if (m_row < 0 || m_row >= NROWS || m_col < 0 || m_col >= NCOLS)
{
cout << "***** Robot created with invalid coordinates (" << m_row << ","
<< m_col << ")!" << endl;
exit(1);
} |
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Wierd compile Error. Need help please. | Keiyentai | Java | 7 | Aug 19th, 2006 1:35 AM |
| What is: "Oriented programming (OO)?" | BrinyCode | C++ | 12 | Nov 22nd, 2005 7:40 AM |
| Java programmers, game developers, artists, be ware! RPG game team is recruiting! | atcomputers.us | Paid Job Offers | 7 | Sep 25th, 2005 7:25 PM |
| User Input for Number Format | ericelysia1 | Java | 0 | Jul 21st, 2005 3:41 PM |
| Programmers Needed! Online Game | troy_eisert | C++ | 2 | Jan 29th, 2005 12:51 PM |