Question: main.cpp // zion.cpp // Portions you are to complete are marked with a TODO: comment. // We've provided some incorrect return statements (so indicated) just




main.cpp
// zion.cpp
// Portions you are to complete are marked with a TODO: comment.
// We've provided some incorrect return statements (so indicated) just
// to allow this skeleton program to compile and run, albeit incorrectly.
// The first thing you probably want to do is implement the trivial
// functions (marked TRIVIAL). Then get Arena::display going. That gives
// you more flexibility in the order you tackle the rest of the functionality.
// As you finish implementing each TODO: item, remove its TODO: comment.
#include
#include
#include
#include
using namespace std;
///////////////////////////////////////////////////////////////////////////
// Manifest constants
///////////////////////////////////////////////////////////////////////////
const int MAXROWS = 20; // max number of rows in the arena
const int MAXCOLS = 40; // max number of columns in the arena
const int MAXROBOTS = 130; // max number of robots allowed
const int MAXSHOTLEN = 5; // max number of steps you can shoot
const int UP = 0;
const int DOWN = 1;
const int LEFT = 2;
const int RIGHT = 3;
///////////////////////////////////////////////////////////////////////////
// Auxiliary function declarations
///////////////////////////////////////////////////////////////////////////
int decodeDirection(char dir);
void clearScreen();
///////////////////////////////////////////////////////////////////////////
// Type definitions
///////////////////////////////////////////////////////////////////////////
class Arena; // This is needed to let the compiler know that Arena is a
// type name, since it's mentioned in the Robot declaration.
class Robot
{
public:
// Constructor
Robot(Arena* ap, int r, int c);
// Accessors
int row() const;
int col() const;
// Mutators
void move();
bool takeDamageAndLive();
private:
Arena* m_arena;
int m_row;
int m_col;
// TODO: You'll probably find that a robot object needs an additional
// data member to support your implementation of the behavior affected
// by being hit and taking damage.
};
class Player
{
public:
// Constructor
Player(Arena *ap, int r, int c);
// Accessors
int row() const;
int col() const;
int age() const;
bool isDead() const;
// Mutators
string takeComputerChosenTurn();
void stand();
void move(int dir);
bool shoot(int dir);
void setDead();
private:
Arena* m_arena;
int m_row;
int m_col;
int m_age;
bool m_dead;
};
class Arena
{
public:
// Constructor/destructor
Arena(int nRows, int nCols);
~Arena();
// Accessors
int rows() const;
int cols() const;
Player* player() const;
int robotCount() const;
int nRobotsAt(int r, int c) const;
void display(string msg) const;
// Mutators
bool addRobot(int r, int c);
bool addPlayer(int r, int c);
void damageRobotAt(int r, int c);
bool moveRobots();
private:
int m_rows;
int m_cols;
Player* m_player;
Robot* m_robots[MAXROBOTS];
int m_nRobots;
};
class Game
{
public:
// Constructor/destructor
Game(int rows, int cols, int nRobots);
~Game();
// Mutators
void play();
private:
Arena* m_arena;
};
///////////////////////////////////////////////////////////////////////////
// Robot implementation
///////////////////////////////////////////////////////////////////////////
Robot::Robot(Arena* ap, int r, int c)
{
if (ap == nullptr)
{
cout
exit(1);
}
if (r ap->rows() || c ap->cols())
{
cout
exit(1);
}
m_arena = ap;
m_row = r;
m_col = c;
}
int Robot::row() const
{
return m_row;
}
int Robot::col() const
{
// TODO: TRIVIAL: Return what column the robot is at.
// Delete the following line and replace it with the correct code.
return 1; // This implementation compiles, but is incorrect.
}
void Robot::move()
{
// Attempt to move in a random direction; if we can't move, don't move
switch (rand() % 4)
{
case UP:
// TODO: Move the robot up one row if possible.
break;
case DOWN:
case LEFT:
case RIGHT:
// TODO: Implement the other movements.
break;
}
}
bool Robot::takeDamageAndLive()
{
// TODO: If the robot has been hit once before, return false (since a
// second hit kills a robot). Otherwise, return true (since the robot
// survived the damage).
}
///////////////////////////////////////////////////////////////////////////
// Player implementations
///////////////////////////////////////////////////////////////////////////
Player::Player(Arena* ap, int r, int c)
{
if (ap == nullptr)
{
cout
exit(1);
}
if (r ap->rows() || c ap->cols())
{
cout
exit(1);
}
m_arena = ap;
m_row = r;
m_col = c;
m_age = 0;
m_dead = false;
}
int Player::row() const
{
// TODO: TRIVIAL: Return what row the player is at.
// Delete the following line and replace it with the correct code.
return 1; // This implementation compiles, but is incorrect.
}
int Player::col() const
{
// TODO: TRIVIAL: Return what column the player is at.
// Delete the following line and replace it with the correct code.
return 1; // This implementation compiles, but is incorrect.
}
int Player::age() const
{
// TODO: TRIVIAL: Return the player's age.
// Delete the following line and replace it with the correct code.
return 0; // This implementation compiles, but is incorrect.
}
string Player::takeComputerChosenTurn()
{
// TODO: Replace this implementation:
stand();
return "Stood";
// Your replacement implementation should do something intelligent
// and return a string that describes what happened. When you've
// decided what action to take, take it by calling move, shoot, or stand.
// This function must return one of the following four strings:
// "Moved."
// "Shot and hit!"
// "Shot and missed!"
// "Stood."
// Here's one possible strategy:
// If moving in some direction would put me in less immediate danger
// than standing, then move in that direction.
// else shoot in the direction of the nearest robot I can hit.
// A more aggressive strategy is possible, where you hunt down robots.
}
void Player::stand()
{
m_age++;
}
void Player::move(int dir)
{
m_age++;
switch (dir)
{
case UP:
// TODO: Move the player up one row if possible.
break;
case DOWN:
case LEFT:
case RIGHT:
// TODO: Implement the other movements.
break;
}
}
bool Player::shoot(int dir)
{
m_age++;
if (rand() % 3 == 0) // miss with 1/3 probability
return false;
// TODO: Damage the nearest robot in direction dir, returning
// true if a robot is hit and damaged, false if not hit.
return false; // This implementation compiles, but is incorrect.
}
bool Player::isDead() const
{
// TODO: TRIVIAL: Return whether the player is dead.
return false; // This implementation compiles, but is incorrect.
}
void Player::setDead()
{
m_dead = true;
}
///////////////////////////////////////////////////////////////////////////
// Arena implementations
///////////////////////////////////////////////////////////////////////////
Arena::Arena(int nRows, int nCols)
{
if (nRows MAXROWS || nCols > MAXCOLS)
{
cout
exit(1);
}
m_rows = nRows;
m_cols = nCols;
m_player = nullptr;
m_nRobots = 0;
}
Arena::~Arena()
{
// TODO: Delete the player and all remaining dynamically allocated robots.
}
int Arena::rows() const
{
// TODO: TRIVIAL: Return the number of rows in the arena.
// Delete the following line and replace it with the correct code.
return 1; // This implementation compiles, but is incorrect.
}
int Arena::cols() const
{
// TODO: TRIVIAL: Return the number of columns in the arena.
// Delete the following line and replace it with the correct code.
return 1; // This implementation compiles, but is incorrect.
}
Player* Arena::player() const
{
return m_player;
}
int Arena::robotCount() const
{
return m_nRobots;
}
int Arena::nRobotsAt(int r, int c) const
{
// TODO: Return the number of robots at row r, column c.
return 0; // This implementation compiles, but is incorrect.
}
void Arena::display(string msg) const
{
// Position (row,col) in the arena coordinate system is represented in
// the array element grid[row-1][col-1]
char grid[MAXROWS][MAXCOLS];
int r, c;
// Fill the grid with dots
for (r = 0; r
for (c = 0; c
grid[r][c] = '.';
// Indicate each robot's position
// TODO: If one robot is at some grid point, set the char to 'R'.
// If it's 2 though 8, set it to '2' through '8'.
// For 9 or more, set it to '9'.
// Indicate player's position
if (m_player != nullptr)
{
// Set the char to '@', unless there's also a robot there,
// in which case set it to '*'.
char& gridChar = grid[m_player->row()-1][m_player->col()-1];
if (gridChar == '.')
gridChar = '@';
else
gridChar = '*';
}
// Draw the grid
clearScreen();
for (r = 0; r
{
for (c = 0; c
cout
cout
}
cout
// Write message, robot, and player info
cout
if (msg != "")
cout
cout
if (m_player == nullptr)
cout
else
{
if (m_player->age() > 0)
cout age()
if (m_player->isDead())
cout
}
}
bool Arena::addRobot(int r, int c)
{
// If MAXROBOTS have already been added, return false. Otherwise,
// dynamically allocate a new robot at coordinates (r,c). Save the
// pointer to the newly allocated robot and return true.
// TODO: Implement this.
return false; // This implementation compiles, but is incorrect.
}
bool Arena::addPlayer(int r, int c)
{
// Don't add a player if one already exists
if (m_player != nullptr)
return false;
// Dynamically allocate a new Player and add it to the arena
m_player = new Player(this, r, c);
return true;
}
void Arena::damageRobotAt(int r, int c)
{
// TODO: Damage one robot at row r, column c if at least one is there.
// If the robot does not survive the damage, destroy it.
}
bool Arena::moveRobots()
{
for (int k = 0; k
{
// TODO: Have the k-th robot in the arena make one move.
// If that move results in that robot being in the same
// position as the player, the player dies.
}
// return true if the player is still alive, false otherwise
return ! m_player->isDead();
}
///////////////////////////////////////////////////////////////////////////
// Game implementations
///////////////////////////////////////////////////////////////////////////
Game::Game(int rows, int cols, int nRobots)
{
if (nRobots > MAXROBOTS)
{
cout
exit(1);
}
// Create arena
m_arena = new Arena(rows, cols);
// Add player
int rPlayer = 1 + rand() % rows;
int cPlayer = 1 + rand() % cols;
m_arena->addPlayer(rPlayer, cPlayer);
// Populate with robots
while (nRobots > 0)
{
int r = 1 + rand() % rows;
int c = 1 + rand() % cols;
// Don't put a robot where the player is
if (r == rPlayer && c == cPlayer)
continue;
m_arena->addRobot(r, c);
nRobots--;
}
}
Game::~Game()
{
delete m_arena;
}
void Game::play()
{
Player* p = m_arena->player();
if (p == nullptr)
{
m_arena->display("");
return;
}
string msg = "";
do
{
m_arena->display(msg);
msg = "";
cout
cout
string action;
getline(cin,action);
if (action.size() == 0)
p->stand();
else
{
switch (action[0])
{
default: // if bad move, nobody moves
cout
continue;
case 'q':
return;
case 'c': // computer moves player
msg = p->takeComputerChosenTurn();
break;
case 'u':
case 'd':
case 'l':
case 'r':
p->move(decodeDirection(action[0]));
break;
case 's':
if (action.size()
{
cout
continue;
}
switch (action[1])
{
default: // if bad direction, nobody moves
cout
continue;
case 'u':
case 'd':
case 'l':
case 'r':
if (p->shoot(decodeDirection(action[1])))
msg = "Hit!";
else
msg = "Missed!";
break;
}
break;
}
}
m_arena->moveRobots();
} while ( ! m_arena->player()->isDead() && m_arena->robotCount() > 0);
m_arena->display(msg);
}
///////////////////////////////////////////////////////////////////////////
// Auxiliary function implementations
///////////////////////////////////////////////////////////////////////////
int decodeDirection(char dir)
{
switch (dir)
{
case 'u': return UP;
case 'd': return DOWN;
case 'l': return LEFT;
case 'r': return RIGHT;
}
return -1; // bad argument passed in!
}
///////////////////////////////////////////////////////////////////////////
// main()
///////////////////////////////////////////////////////////////////////////
int main()
{
// Initialize the random number generator. (You don't need to
// understand how this works.)
srand(static_cast
// Create a game
// Use this instead to create a mini-game: Game g(3, 3, 2);
Game g(15, 18, 80);
// Play the game
g.play();
}
///////////////////////////////////////////////////////////////////////////
// clearScreen implementations
///////////////////////////////////////////////////////////////////////////
// DO NOT MODIFY OR REMOVE ANY CODE BETWEEN HERE AND THE END OF THE FILE!!!
// THE CODE IS SUITABLE FOR VISUAL C++, XCODE, AND g++ UNDER LINUX.
// Note to Xcode users: clearScreen() will just write a newline instead
// of clearing the window if you launch your program from within Xcode.
// That's acceptable.
#ifdef _MSC_VER // Microsoft Visual C++
#include
void clearScreen()
{
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(hConsole, &csbi);
DWORD dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
COORD upperLeft = { 0, 0 };
DWORD dwCharsWritten;
FillConsoleOutputCharacter(hConsole, TCHAR(' '), dwConSize, upperLeft,
&dwCharsWritten);
SetConsoleCursorPosition(hConsole, upperLeft);
}
#else // not Microsoft Visual C++, so assume UNIX interface
#include
void clearScreen() // will just write a newline in an Xcode output window
{
static const char* term = getenv("TERM");
if (term == nullptr || strcmp(term, "dumb") == 0)
cout
else
{
static const char* ESC_SEQ = "\x1B["; // ANSI Terminal esc seq: ESC [
cout
}
}
#endif
The Machines that created The Matrix are attacking Zion and Neo is nowhere to be found! Before they reach Zion you've been tasked with holding them off. Well, that's the scenario for a new video game under development. Your assignment is to complete the prototype that uses character-based graphics. If you execute the sample Windows, Mac, or Linux program provided on the website, you will see the player (indicated by @) in a rectangular arena filled with killer robots (usually indicated by R). At each turn, the user will select an action for the player to take. The player will take the action, and then each robot will move one step in a random direction. If a robot lands on the position occupied by the player, the player dies This smaller version of the game may help you see the operation of the game more clearly At each turn the player may take one of these actions: . Stand. In this case, the player does not move or shoot. Move one step up, down, left, or right. If the player attempts to move out of the arena (e.g., down, when on the bottom row), the result is the same as standing.t is allowable for the player to move to a position currently occupied by a robot. If no robot occupies that position after the robots have moved, the player survived the turn. Shoot in one of the four directions up, down, left, or right. If there is at least one robot within 5 steps in that direction (this only matters with anything larger than a 6x6 arena), the nearest one in that direction is the candidate victim. If more than one robot is nearest i.e., they occupy the same position), only one robot at that position is the candidate victim. With 2/3 probability, the candidate victim is damaged; with 1/3 probability, the shot is ineffective and no robot is damaged. A robot that has been damaged for the second time is destroyed (i.e.to destroy a robot takes two shots that hit). The game allows the user to select the player's action: u/dVr for movement, su/sd/sl/sr for shooting, and just hitting enter for standing. The user may also type q to prematurely quit the game, or c to have the computer select the player's move. When it's the robots' turn, each robot picks a random direction (up, down, left, or right) with equal probability. The robot moves one step in that direction if it can; if the robot attempts to move out of the arena, however, (e.g., down, when on the bottom row), it does not move. More than one robot may occupy the same position; in that case, instead of R, the display will show a digit character indicating the number of robots at that position (where 9 indicates 9 or more). If after the robots move, a robot occupies the same position as the player, the player dies
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
