Please write the program that does the following: Sim_object Exxon constructed I
ID: 3697483 • Letter: P
Question
Please write the program that does the following:
Sim_object Exxon constructed
Island Exxon constructed
Sim_object Shell constructed
Island Shell constructed
Sim_object Bermuda constructed
Island Bermuda constructed
Sim_object Ajax constructed
Track_base constructed
Ship Ajax constructed
Cruiser Ajax constructed
Sim_object Xerxes constructed
Track_base constructed
Ship Xerxes constructed
Cruiser Xerxes constructed
Sim_object Valdez constructed
Track_base constructed
Ship Valdez constructed
Tanker Valdez constructed
Model constructed
Controller constructed
View constructed
Time 0: Enter command: throttle up to full speed
Unrecognized command!
Time 0: Enter command: create X Tanker -5 20
Name is too short!
Time 0: Enter command: create Oil_City Torpedo_boat -5 20
Trying to create ship of unknown type!
Time 0: Enter command: create Valdez Tanker -5 20
Name is invalid!
Time 0: Enter command: create Valiant Tanker -5 20
Name is invalid!
Time 0: Enter command: Ajax attack Oil_City
Ship not found!
Time 0: Enter command: Oil_City destination Cuba
Unrecognized command!
Time 0: Enter command: Valdez destination Cuba 10
Island not found!
Time 0: Enter command:Valdez destination Bermuda 1z 0
Valdez will sail on course 225.00 deg, speed 1.00 nm/hr to Bermuda
Time 0: Enter command: Unrecognized command!
Time 0: Enter command: Valdez load_at Bermuda
Valdez will load at Bermuda
Time 0: Enter command: Valdez unload_at Bermuda
Load and unload cargo destinations are the same!
Time 0: Enter command: Valdez unload_at Exxon
Valdez will unload at Exxon
Valdez will sail on course 225.00 deg, speed 10.00 nm/hr to Bermuda
Time 0: Enter command: Ajax attack Ajax
Cannot attack itself!
Time 0: Enter command: Ajax course 369 10 Ajax course XXX 10
Invalid heading entered!
Time 0: Enter command: Ajax course 359 -10
Negative speed entered!
Time 0: Enter command: size x1
Expected an integer!
Time 0: Enter command: Ajax course xyz 10
Expected a double!
Time 0: Enter command: zoom xyz
Expected a double!
Time 0: Enter command: Ajax stop_attacking
Unrecognized command!
Time 0: Enter command: Ajax stop_attack
Was not attacking!
Time 0: Enter command: Ajax dock_at Bermuda
Can't dock!
Time 0: Enter command: Ajax refuel
Must be docked!
Time 0: Enter command: Ajax load_at Bermuda
Cannot load at a destination!
Time 0: Enter command: Ajax unload_at Bermuda
Cannot unload at a destination!
Time 0: Enter command: Valdez attack Ajax
Cannot attack!
Time 0: Enter command: Valdex stop_attack Valdez stop_attack
Unrecognized command!
Time 0: Enter command: Valdez stop_attack
Cannot attack!
Time 0: Enter command: Ajax attack Valdez
Ajax will attack Valdez
Time 0: Enter command: Ajax attack Valdez
Already attacking this target!
Time 0: Enter command: Valdez destination Bermuda 15
Tanker has cargo destinations!
Time 0: Enter command: Valdez stop
Valdez stopping at (30.00, 30.00)
Valdez now has no cargo destinations
Time 0: Enter command: Valdez destination Bermuda 15
Ship cannot go that fast!
Time 0: Enter command: quit
View destructed
Done
Cruiser Ajax destructed
Ship Ajax destructed
Track_base destructed
Sim_object Ajax destructed
Island Bermuda destructed
Sim_object Bermuda destructed
Island Exxon destructed
Sim_object Exxon destructed
Island Shell destructed
Sim_object Shell destructed
Tanker Valdez destructed
Ship Valdez destructed
Track_base destructed
Sim_object Valdez destructed
Cruiser Xerxes destructed
Ship Xerxes destructed
Track_base destructed
Sim_object Xerxes destructed
Model destructed
Controller destructed
Explanation / Answer
main.cpp
#include "Controller.h"
#include <iostream>
using namespace std;
// The main function creates the Controller object, then tells it to run.
int main ()
{
cout.setf(ios::fixed, ios::floatfield);
cout.precision(2);
Controller controller;
controller.run();
}
Controller.cpp
#include "Controller.h"
#include "Views.h"
#include "Ship_factory.h"
#include "Ship.h"
#include "Utility.h"
#include "Model.h"
#include <memory>
#include <algorithm>
#include <iostream>
#include <functional>
#include <string>
#include <map>
using namespace std;
void Controller::error_handler(const Error& error) const{
cout << error.msg << endl;
cin.clear();
while ((char)cin.get() != ' ');
return;
}
void Controller::run(){
map<string, void (Controller::*)()> func_map; // map of member func pointer
map<string, void (Controller::*)(shared_ptr<Ship>)> func_ship_map; //map of member func pointer
func_map["default"] = &Controller::command_view_default;
func_map["size"] = &Controller::command_view_size;
func_map["zoom"] = &Controller::command_view_zoom;
func_map["pan"] = &Controller::command_view_pan;
func_map["show"] = &Controller::command_view_show;
func_map["status"] = &Controller::command_model_status;
func_map["go"] = &Controller::command_model_go;
func_map["create"] = &Controller::command_model_create;
func_map["open_map_view"] = &Controller::command_open_map_view;
func_map["close_map_view"] = &Controller::command_close_map_view;
func_map["open_sailing_view"] = &Controller::command_open_sailing_view;
func_map["close_sailing_view"] = &Controller::command_close_sailing_view;
func_map["open_bridge_view"] = &Controller::command_open_bridge_view;
func_map["close_bridge_view"] = &Controller::command_close_bridge_view;
func_ship_map["course"] = &Controller::command_ship_course;
func_ship_map["position"] = &Controller::command_ship_position;
func_ship_map["destination"] = &Controller::command_ship_destination;
func_ship_map["load_at"] = &Controller::command_ship_load_at;
func_ship_map["unload_at"] = &Controller::command_ship_unload_at;
func_ship_map["dock_at"] = &Controller::command_ship_dock_at;
func_ship_map["attack"] = &Controller::command_ship_attack;
func_ship_map["refuel"] = &Controller::command_ship_refuel;
func_ship_map["stop"] = &Controller::command_ship_stop;
func_ship_map["stop_attack"] = &Controller::command_ship_stop_attack;
while(true){
cout << " Time " << Model::get_instance().get_time() << ": Enter command: ";
string command;
cin>>command;
try {
if(command.compare("quit")==0){
Model::get_instance().detach(map_view_ptr);
Model::get_instance().detach(sailing_view_ptr);
for_each(bridge_view_ptrs.begin(), bridge_view_ptrs.end(), [](pair<string,shared_ptr<Bridge_view>> const& bridge_pair){Model::get_instance().detach(bridge_pair.second);});
cout << "Done" << endl;
return;
}
if(Model::get_instance().is_ship_present(command)){
string second_command;
cin>>second_command;
shared_ptr<Ship> ship_ptr = Model::get_instance().get_ship_ptr(command);
if(func_ship_map.find(second_command)==func_ship_map.end()){
throw Error("Unrecognized command!");
}
(this->*(func_ship_map[second_command]))(ship_ptr);
continue;
}
//Is it a valid command
if(func_map.find(command)!=func_map.end()){
(this->*(func_map[command]))();
continue;
}else{
throw Error("Unrecognized command!");
}
}catch(Error& error){
error_handler(error);
}
}
}
void Controller::command_ship_course(shared_ptr<Ship> ship_ptr){
double heading, speed;
heading = read_double();
speed = read_double();
if(heading<0.0||heading>=360.0){
throw Error("Invalid heading entered!");
}
if(speed<0.0){
throw Error("Negative speed entered!");
}
ship_ptr->set_course_and_speed(heading, speed);
return;
}
void Controller::command_ship_position(shared_ptr<Ship> ship_ptr){
double x,y, speed;
x = read_double();
y = read_double();
speed = read_double();
if(speed<0.0){
throw Error("Negative speed entered!");
}
ship_ptr->set_destination_position_and_speed(Point(x,y), speed);
return;
}
void Controller::command_ship_destination(shared_ptr<Ship> ship_ptr){
string island_name;
double speed;
island_name = read_string();
speed = read_double();
shared_ptr<Island> island_ptr = Model::get_instance().get_island_ptr(island_name);
ship_ptr->set_destination_position_and_speed(island_ptr->get_location(), speed);
return;
}
void Controller::command_ship_load_at(shared_ptr<Ship> ship_ptr){
string island_name = read_string();
shared_ptr<Island> island_ptr = Model::get_instance().get_island_ptr(island_name);
ship_ptr->set_load_destination(island_ptr);
return;
}
void Controller::command_ship_unload_at(shared_ptr<Ship> ship_ptr){
string island_name = read_string();
shared_ptr<Island> island_ptr = Model::get_instance().get_island_ptr(island_name);
ship_ptr->set_unload_destination(island_ptr);
return;
}
void Controller::command_ship_dock_at(shared_ptr<Ship> ship_ptr){
string island_name = read_string();
shared_ptr<Island> island_ptr = Model::get_instance().get_island_ptr(island_name);
ship_ptr->dock(island_ptr);
return;
}
void Controller::command_ship_attack(shared_ptr<Ship> ship_ptr){
string ship_name = read_string();
shared_ptr<Ship> ship_ptr_target = Model::get_instance().get_ship_ptr(ship_name);
ship_ptr->attack(ship_ptr_target);
return;
}
void Controller::command_ship_refuel(shared_ptr<Ship> ship_ptr){
ship_ptr->refuel();
}
void Controller::command_ship_stop(shared_ptr<Ship> ship_ptr){
ship_ptr->stop();
}
void Controller::command_ship_stop_attack(shared_ptr<Ship> ship_ptr){
ship_ptr->stop_attack();
}
void Controller::command_view_default(){
if(!map_view_ptr){
throw Error("Map view is not open!");
}
map_view_ptr->set_defaults();
}
void Controller::command_view_size(){
if(!map_view_ptr){
throw Error("Map view is not open!");
}
int size = read_int();
map_view_ptr->set_size(size);
}
void Controller::command_view_zoom(){
if(!map_view_ptr){
throw Error("Map view is not open!");
}
double scale;
scale = read_double();
map_view_ptr->set_scale(scale);
}
void Controller::command_view_pan(){
if(!map_view_ptr){
throw Error("Map view is not open!");
}
double x,y;
x =read_double();
y = read_double();
map_view_ptr->set_origin(Point(x,y));
}
void Controller::command_view_show(){
for_each(views_set.begin(), views_set.end(), [](shared_ptr<View> view_ptr){view_ptr->draw();});
}
void Controller::command_model_status(){
Model::get_instance().describe();
}
void Controller::command_model_go(){
Model::get_instance().update();
}
void Controller::command_model_create(){
string ship_name, type_name;
double x,y;
ship_name = read_string();
if(ship_name.size()<2){
throw Error("Name is too short!");
}
type_name = read_string();
if(Model::get_instance().is_name_in_use(ship_name)){
throw Error("Name is already in use!");
}
x = read_double();
y = read_double();
shared_ptr<Ship> ship_ptr = create_ship(ship_name, type_name, Point(x,y));
Model::get_instance().add_ship(ship_ptr);
return;
}
int Controller::read_int(){
int result;
if(!(cin>>result)){
throw Error("Expected an integer!");
}
return result;
}
double Controller::read_double(){
double result;
if(!(cin>>result)){
throw Error("Expected a double!");
}
return result;
}
string Controller::read_string(){
string result;
if(!(cin>>result)){
throw Error("Unrecognized command!");
}
return result;
}
void Controller::command_open_map_view(){
if(map_view_ptr){
throw Error("Map view is already open!");
}
map_view_ptr = make_shared<Map_view>();
Model::get_instance().attach(map_view_ptr);
add_view(map_view_ptr);
}
void Controller::command_close_map_view(){
if(!map_view_ptr){
throw Error("Map view is not open!");
}
Model::get_instance().detach(map_view_ptr);
remove_view(map_view_ptr);
map_view_ptr.reset();
}
void Controller::command_open_sailing_view(){
if(sailing_view_ptr){
throw Error("Sailing data view is already open!");
}
sailing_view_ptr = make_shared<Sailing_data_view>();
Model::get_instance().attach(sailing_view_ptr);
add_view(sailing_view_ptr);
}
void Controller::command_close_sailing_view(){
if(!sailing_view_ptr){
throw Error("Sailing data view is not open!");
}
Model::get_instance().detach(sailing_view_ptr);
remove_view(sailing_view_ptr);
sailing_view_ptr.reset();
}
void Controller::command_open_bridge_view(){
string ship_name = read_string();
if(!Model::get_instance().is_ship_present(ship_name)){
throw Error("Ship not found!");
}
if(bridge_view_ptrs.find(ship_name)!=bridge_view_ptrs.end()){
throw Error("Bridge view is already open for that ship!");
}
shared_ptr<Bridge_view> bridge_view_ptr = make_shared<Bridge_view>(ship_name);
bridge_view_ptrs[ship_name] = bridge_view_ptr;
Model::get_instance().attach(bridge_view_ptr);
add_view(bridge_view_ptr);
}
void Controller::command_close_bridge_view(){
string ship_name = read_string();
if(bridge_view_ptrs.find(ship_name)==bridge_view_ptrs.end()){
throw Error("Bridge view for that ship is not open!");
}else{
Model::get_instance().detach(bridge_view_ptrs[ship_name]);
remove_view(bridge_view_ptrs[ship_name]);
bridge_view_ptrs.erase(ship_name);
}
}
void Controller::add_view(shared_ptr<View> view_ptr){
views_set.push_back(view_ptr);
}
void Controller::remove_view(shared_ptr<View> view_ptr){
auto it = find(views_set.begin(), views_set.end(), view_ptr);
views_set.erase(it);
}
Cruise_ship.cpp
#include "Cruise_ship.h"
#include "Model.h"
#include "Ship.h"
#include "Island.h"
#include <string>
#include <map>
#include <set>
#include <memory>
#include <iostream>
#include <algorithm>
using namespace std;
Cruise_ship::Cruise_ship(const std::string& name_, Point position_)
:Ship(name_,position_,500,15,2,0),
cruise_ship_state(NO_CRUISE),
all_visited(false){}
void Cruise_ship::set_destination_position_and_speed(Point destination, double speed){
if(cruise_ship_state!=NO_CRUISE){
cancel_cruise();
}
Ship::set_destination_position_and_speed(destination,speed);
find_next_destination(destination);
cur_speed = speed;
start_island = cur_destination;
cout<<get_name()<<" will visit "<<cur_destination<<endl;
cout << get_name() << " cruise will start and end at " << cur_destination<< endl;
cruise_ship_state = IN_CRUISE;
}
void Cruise_ship::find_next_destination(Point& destination){
vector<shared_ptr<Island>> islands = Model::get_instance().get_island_set();
sort(islands.begin(), islands.end(), Island_Compare(destination));
for(shared_ptr<Island> island_ptr:islands){
if(!island_visited[island_ptr->get_name()]){
island_visited[island_ptr->get_name()]=true;;
cruise_ship_state = IN_CRUISE;
cur_destination = island_ptr->get_name();
return;
}
}
if(!islands.empty()){
cur_destination = start_island;
all_visited = true;
}
}
void Cruise_ship::set_course_and_speed(double course, double speed){
if(cruise_ship_state!=NO_CRUISE){
cancel_cruise();
}
Ship::set_course_and_speed(course, speed);
}
bool Cruise_ship::in_cruise() const{
return cruise_ship_state!=NO_CRUISE&&cruise_ship_state!=OVER;
}
void Cruise_ship::update(){
Ship::update();
if(!can_move()&&in_cruise()){
cancel_cruise();
return;
}
switch(cruise_ship_state) {
case NO_CRUISE:
break;
case IN_CRUISE:{
shared_ptr<Island> cur_dest_ptr = Model::get_instance().get_island_ptr(cur_destination);
if(can_dock(cur_dest_ptr)){
dock(cur_dest_ptr);
}
if(is_docked()){
if(all_visited){
cruise_ship_state = OVER;
cout<<get_name()<<" cruise is over at "<<start_island<<endl;
}else{
cruise_ship_state = REFUEL;
}
}
}
break;
case REFUEL:
refuel();
cruise_ship_state = VISITING;
break;
case VISITING:
cruise_ship_state = NAVIGATING;
break;
case NAVIGATING:{
shared_ptr<Island> cur_dest_ptr = Model::get_instance().get_island_ptr(cur_destination);
Point cur_dest_point = cur_dest_ptr->get_location();
find_next_destination(cur_dest_point);
cur_dest_ptr = Model::get_instance().get_island_ptr(cur_destination);
Ship::set_destination_position_and_speed(cur_dest_ptr->get_location(), cur_speed);
cout<<get_name()<<" will visit "<<cur_destination<<endl;
cruise_ship_state = IN_CRUISE;
}
break;
default:
break;
}
}
void Cruise_ship::describe() const{
cout << " Cruise_ship ";
Ship::describe();
switch (cruise_ship_state) {
case NO_CRUISE:
break;
case IN_CRUISE:
cout << "On cruise to " << cur_destination<< endl;
break;
case REFUEL:
case NAVIGATING:
cout << "Waiting during cruise at " << cur_destination<< endl;
break;
default:
break;
}
}
void Cruise_ship::cancel_cruise(){
cruise_ship_state = NO_CRUISE;
cout << get_name() << " canceling current cruise" << endl;
island_visited.clear();
return;
}
Cruise_ship.h
#ifndef CRUISE_SHIP_H
#define CRUISE_SHIP_H
#include "Ship.h"
#include <map>
#include <string>
#include <memory>
using namespace std;
typedef enum{
REFUEL,
VISITING,
NAVIGATING,
IN_CRUISE,
NO_CRUISE,
OVER
} Cruise_ship_state;
class Cruise_ship:public Ship{
public:
Cruise_ship(const std::string& name_, Point position_);
void set_destination_position_and_speed(Point destination, double speed);
void set_course_and_speed(double course, double speed);
// Update the state of the Ship
void update() override;
void describe() const override;
private:
Cruise_ship_state cruise_ship_state;
map<string, bool> island_visited;
string cur_destination;
string start_island;
bool all_visited;
double cur_speed;
void cancel_cruise();
void find_next_destination(Point& destination);
bool in_cruise() const;
Cruise_ship(const Cruise_ship&) = delete;
Cruise_ship(Cruise_ship&&) = delete;
Cruise_ship& operator=(const Cruise_ship&) = delete;
Cruise_ship& operator=(Cruise_ship&&) = delete;
};
#endif
Cruiser.cpp
#include "Cruiser.h"
#include "Warship.h"
#include <iostream>
using std::cout;
using std::endl;
Cruiser::Cruiser(const std::string& name_, Point position_)
:Warship(name_, position_, 1000, 20., 10., 6, 3, 15)
{}
void Cruiser::update(){
Warship::update();
if(!is_attacking()){
return;
}
if(target_in_range()){
fire_at_target();
}else{
cout << get_name() << " target is out of range" << endl;
stop_attack();
}
}
void Cruiser::describe() const{
cout << " Cruiser ";
Warship::describe();
}
void Cruiser::receive_hit(int hit_force, std::shared_ptr<Ship> attacker_ptr){
Ship::receive_hit(hit_force, attacker_ptr);
//If not attacking then start attack
if(warship_state==NOT_ATTACKING){
Warship::attack(attacker_ptr);
}
}
Cruiser.h
#ifndef CRUISER_H
#define CRUISER_H
#include "Warship.h"
class Cruiser : public Warship{
public:
Cruiser(const std::string& name_, Point position_);
void update() override;
void describe() const override;
void receive_hit(int hit_force, std::shared_ptr<Ship> attacker_ptr) override;
};
#endif
Ship.h
#ifndef SHIP_H
#define SHIP_H
#include "Sim_object.h"
#include "Track_base.h"
#include "Island.h"
#include <memory>
typedef enum{
DOCKED,
STOPPED,
MOVING_TO_POSITION,
MOVING_ON_COURSE,
DEAD_IN_THE_WATER,
SUNK
} Ship_state;
class Ship : public Sim_object{
public:
Ship(const std::string& name_, Point position_, double fuel_capacity_,
double maximum_speed_, double fuel_consumption_, int resistance_);
Point get_location() const override {return track.get_position();}
bool can_move() const;
bool is_moving() const;
bool is_docked() const;
bool is_afloat() const;
bool can_dock(std::shared_ptr<Island> island_ptr) const;
void update() override;
void describe() const override;
void broadcast_current_state() override;
virtual void set_destination_position_and_speed(Point destination_position, double speed);
virtual void set_course_and_speed(double course, double speed);
virtual void stop();
virtual void dock(std::shared_ptr<Island> island_ptr);
virtual void refuel();
virtual void set_load_destination(std::shared_ptr<Island>);
virtual void set_unload_destination(std::shared_ptr<Island>);
virtual void attack(std::shared_ptr<Ship> in_target_ptr);
virtual void stop_attack();
virtual void receive_hit(int hit_force, std::shared_ptr<Ship> attacker_ptr);
protected:
int resistance; // Current resistance
double fuel_capacity; //fuel capacity
Ship_state get_ship_state() const {return ship_state;}
void set_ship_state(Ship_state ship_state_){ship_state = ship_state_;}
double get_maximum_speed() const;
std::shared_ptr<Island> get_docked_Island() const;
private:
double fuel; // Current amount of fuel
double maximum_speed; // Maximum speed
double fuel_consumption; // tons/nm required
Point destination; // Current destination if any
std::shared_ptr<Island> island_docked; //island ship dock
Ship_state ship_state; // shop state
Track_base track; // track_bask object
void calculate_movement();
Ship(const Ship&) = delete;
Ship(Ship&&) = delete;
Ship& operator=(const Ship&) = delete;
Ship& operator=(Ship&&) = delete;
};
#endif
Ship.cpp
#include "Geometry.h"
#include "Ship.h"
#include "Track_base.h"
#include "Utility.h"
#include "Island.h"
#include "Navigation.h"
#include "Model.h"
#include <iostream>
using namespace std;
void Ship:: calculate_movement()
{
double time = 1.0; // "full step" time
double destination_distance = cartesian_distance(get_location(), destination);
double full_distance = track.get_speed() * time;
double full_fuel_required = full_distance * fuel_consumption; // tons = nm * tons/nm
double distance_possible, time_possible;
if(full_fuel_required <= fuel) {
distance_possible = full_distance;
time_possible = time;
}
else {
distance_possible = fuel / fuel_consumption; // nm = tons / tons/nm
time_possible = (distance_possible / full_distance) * time;
}
if(ship_state == MOVING_TO_POSITION && destination_distance <= distance_possible) {
track.set_position(destination);
double fuel_required = destination_distance * fuel_consumption;
fuel -= fuel_required;
track.set_speed(0.);
ship_state = STOPPED;
}
else {
track.update_position(time_possible);
if(full_fuel_required >= fuel) {
fuel = 0.0;
ship_state = DEAD_IN_THE_WATER;
}
else {
fuel -= full_fuel_required;
}
}
}
Ship::Ship(const std::string& name_, Point position_, double fuel_capacity_,
double maximum_speed_, double fuel_consumption_, int resistance_)
:Sim_object(name_),
resistance(resistance_),
fuel_capacity(fuel_capacity_),
fuel(fuel_capacity_),
maximum_speed(maximum_speed_),
fuel_consumption(fuel_consumption_),
ship_state(STOPPED)
{
track.set_position(position_);
}
bool Ship::can_move() const{
return is_afloat()&&(ship_state!=DEAD_IN_THE_WATER);
}
bool Ship::is_moving() const{
return ship_state==MOVING_TO_POSITION||ship_state==MOVING_ON_COURSE;
}
bool Ship::is_docked() const{
return ship_state==DOCKED;
}
bool Ship::is_afloat() const{
return ship_state!=SUNK;
}
bool Ship::can_dock(std::shared_ptr<Island> island_ptr) const{
Point cur_point = track.get_position();
Point island_point = island_ptr->get_location();
double dist = cartesian_distance(cur_point, island_point);
return dist<0.1;
}
void Ship::update(){
if(is_afloat()){
if(resistance>=0){
switch(ship_state){
case MOVING_ON_COURSE:
case MOVING_TO_POSITION:
calculate_movement();
cout << get_name()<< " now at " << track.get_position()<< endl;
Model::get_instance().notify_location(get_name(), get_location());
Model::get_instance().notify_state(get_name(), fuel, track.get_course(), track.get_speed());
break;
case STOPPED:
cout << get_name()<< " stopped at " << track.get_position()<< endl;
break;
case DOCKED:
cout << get_name() << " docked at " << island_docked->get_name() << endl;
break;
case DEAD_IN_THE_WATER:
cout << get_name() << " dead in the water at " << track.get_position()<< endl;
break;
default:
break;
}
return;
}else{
ship_state = SUNK;
cout<<get_name()<<" sunk"<<endl;
Model::get_instance().notify_gone(get_name());
return;
}
}else{
cout<<get_name()<<" sunk"<<endl;
return;
}
}
void Ship::describe() const{
cout << get_name() << " at " << track.get_position();
if(is_afloat()){
cout << ", fuel: " << fuel << " tons" << ", resistance: " << resistance << endl;
switch(ship_state){
case MOVING_TO_POSITION:
cout << "Moving to " << destination << " on " << track.get_course_speed() << endl;
break;
case MOVING_ON_COURSE:
cout << "Moving on " << track.get_course_speed() << endl;
break;
case STOPPED:
cout << "Stopped" << endl;
break;
case DOCKED:
cout << "Docked at " << island_docked->get_name()<< endl;
break;
case DEAD_IN_THE_WATER:
cout << "Dead in the water" << endl;
break;
default:
break;
}
}else{
if(ship_state==SUNK){
cout << " sunk" << endl;
}
}
return;
}
void Ship::broadcast_current_state(){
Model::get_instance().notify_location(get_name(), get_location());
Model::get_instance().notify_state(get_name(), fuel, track.get_course(), track.get_speed());
}
void Ship::set_destination_position_and_speed(Point destination_position, double speed){
if(!can_move()){
throw Error("Ship cannot move!");
}
if(speed>maximum_speed){
throw Error("Ship cannot go that fast!");
}
destination = destination_position;
Point cur = track.get_position();
Compass_vector cv(cur, destination);
Course_speed cs(cv.direction, speed);
track.set_course_speed(cs);
ship_state = MOVING_TO_POSITION;
Model::get_instance().notify_state(get_name(), fuel, track.get_course(), track.get_speed());
cout << get_name() << " will sail on " << track.get_course_speed() << " to " << destination<< endl;
return;
}
void Ship::set_course_and_speed(double course, double speed){
if(!can_move()){
throw Error("Ship cannot move!");
}
if(speed>maximum_speed){
throw Error("Ship cannot go that fast!");
}
Course_speed cs(course, speed);
track.set_course_speed(cs);
Model::get_instance().notify_state(get_name(), fuel, track.get_course(), track.get_speed());
ship_state = MOVING_ON_COURSE;
cout << get_name() << " will sail on " << track.get_course_speed() << endl;
return;
}
void Ship::stop(){
if(!can_move()){
throw Error("Ship cannot move!");
}
track.set_speed(0);
Model::get_instance().notify_state(get_name(), fuel, track.get_course(), track.get_speed());
cout << get_name() << " stopping at " << track.get_position()<< endl;
ship_state = STOPPED;
return;
}
void Ship::dock(std::shared_ptr<Island> island_ptr){
if(ship_state!=STOPPED){
throw Error("Can't dock!");
}
if(!can_dock(island_ptr)){
throw Error("Can't dock!");
}
ship_state = DOCKED;
track.set_position(island_ptr->get_location());
island_docked = island_ptr;
Model::get_instance().notify_location(get_name(), island_docked->get_location());
cout<<get_name()<< " docked at " << island_ptr->get_name()<< endl;
return;
}
void Ship::refuel(){
if(!is_docked()){
throw Error("Must be docked!");
}
double required_fuel = fuel_capacity - fuel;
if(required_fuel<0.005){
fuel = fuel_capacity;
Model::get_instance().notify_state(get_name(), fuel, track.get_course(), track.get_speed());
return;
}else{
//get refuel
double fuel_get = island_docked->provide_fuel(required_fuel);
fuel+=fuel_get;
Model::get_instance().notify_state(get_name(), fuel, track.get_course(), track.get_speed());
cout << get_name() << " now has " << fuel << " tons of fuel" << endl;
}
return;
}
void Ship::set_load_destination(std::shared_ptr<Island>){
throw Error("Cannot load at a destination!");
}
void Ship::set_unload_destination(std::shared_ptr<Island>){
throw Error("Cannot unload at a destination!");
}
void Ship::attack(std::shared_ptr<Ship> in_target_ptr){
throw Error("Cannot attack!");
}
void Ship::stop_attack(){
throw Error("Cannot attack!");
}
void Ship::receive_hit(int hit_force, std::shared_ptr<Ship> attacker_ptr){
resistance-=hit_force;
cout << get_name() << " hit with " << hit_force << ", resistance now " << resistance<< endl;
return;
}
std::shared_ptr<Island> Ship::get_docked_Island() const{
return island_docked;
}
double Ship::get_maximum_speed() const{
return maximum_speed;
}
Warship.cpp
#include "Warship.h"
#include "Ship.h"
#include "Utility.h"
#include <iostream>
#include <memory>
using std::cout;
using std::endl;
using namespace std;
Warship::Warship(const std::string& name_, Point position_, double fuel_capacity_,
double maximum_speed_, double fuel_consumption_factor_, int resistance_,
int firepower_, double maximum_range_)
:Ship(name_, position_, fuel_capacity_, maximum_speed_, fuel_consumption_factor_, resistance_),
firepower(firepower_),
maximum_range(maximum_range_),
warship_state(NOT_ATTACKING)
{
}
void Warship::update(){
Ship::update();
if(warship_state==NOT_ATTACKING){
return;
}
shared_ptr<Ship> target_sptr = target_ptr.lock();
if(!is_afloat()){
stop_attack();
return;
}
if(!target_sptr||!target_sptr->is_afloat()){
stop_attack();
return;
}
cout << get_name() << " is attacking " << endl;
}
void Warship::attack(std::shared_ptr<Ship> target_ptr_){
if(!is_afloat()){
throw Error("Cannot attack!");
}
if(target_ptr_.get()==this){
throw Error("Warship may not attack itself!");
}
target_ptr = target_ptr_;
warship_state = ATTACKING;
cout << get_name() << " will attack " << target_ptr_->get_name() << endl;
return;
}
void Warship::stop_attack(){
if(warship_state==NOT_ATTACKING){
throw Error("Was not attacking!");
}
warship_state = NOT_ATTACKING;
target_ptr.reset();
cout << get_name() << " stopping attack" << endl;
}
void Warship::describe() const{
Ship::describe();
shared_ptr<Ship> target_sptr = target_ptr.lock();
if(warship_state==ATTACKING){
if(target_sptr&&target_sptr->is_afloat()){
cout << "Attacking " << target_sptr->get_name() << endl;
}else{
cout << "Attacking absent ship" << endl;
}
}
}
bool Warship::is_attacking() const{
return warship_state==ATTACKING;
}
void Warship::fire_at_target(){
cout << get_name() << " fires" << endl;
shared_ptr<Ship> target_sptr = target_ptr.lock();
target_sptr->receive_hit(firepower,shared_from_this());
}
bool Warship::target_in_range() const{
Point cur_point = get_location();
shared_ptr<Ship> target_sptr = target_ptr.lock();
Point target_point = target_sptr->get_location();
double distance = cartesian_distance(cur_point, target_point);
return distance<=maximum_range;
}
Warship.h
#ifndef WARSHIP_H
#define WARSHIP_H
#include "Ship.h"
typedef enum{
ATTACKING,
NOT_ATTACKING
} Warship_state;
class Warship :public Ship, public std::enable_shared_from_this<Warship>{
public:
Warship(const std::string& name_, Point position_, double fuel_capacity_,
double maximum_speed_, double fuel_consumption_factor_, int resistance_,
int firepower_, double maximum_range_);
void update() override;
void attack(std::shared_ptr<Ship> target_ptr_) override;
void stop_attack() override;
void describe() const override;
protected:
Warship_state warship_state; //warship state
int firepower; //Current firepower
double maximum_range; //maximum range
std::weak_ptr<Ship> target_ptr; //pointer of attacking target
bool is_attacking() const;
void fire_at_target();
bool target_in_range() const;
};
#endif
Sim_object.h
#ifndef SIM_OBJECT_H
#define SIM_OBJECT_H
#include <string>
#include <iostream> // demonstration only
#include "Geometry.h"
class Sim_object {
public:
Sim_object(const std::string& name_) :
name(name_){}
virtual ~Sim_object()
{}
const std::string& get_name() const
{return name;}
// ask model to notify views of current state
virtual void broadcast_current_state() {}
virtual Point get_location() const = 0;
virtual void describe() const = 0;
virtual void update() = 0;
private:
std::string name;
};
#endif
Geometry.h
#ifndef GEOMETRY_H
#define GEOMETRY_H
#include <iosfwd>
double to_radians(double theta_d);
double to_degrees(double theta_r);
struct Cartesian_vector;
struct Polar_vector;
struct Point
{
double x;
double y;
Point (double in_x = 0., double in_y = 0.) :
x(in_x), y(in_y)
{}
// compare two Points
bool operator== (const Point& rhs) const;
bool operator!= (const Point& rhs) const;
};
double cartesian_distance (const Point& p1, const Point& p2);
struct Cartesian_vector
{
double delta_x;
double delta_y;
Cartesian_vector (double in_delta_x = 0., double in_delta_y = 0.) :
delta_x(in_delta_x), delta_y(in_delta_y)
{}
Cartesian_vector(const Point& p1, const Point& p2);
Cartesian_vector(const Polar_vector& pv);
};
struct Polar_vector
{
double r;
double theta;
Polar_vector (double in_r = 0., double in_theta = 0.) :
r(in_r), theta(in_theta)
{}
Polar_vector(const Point& p1, const Point& p2);
Polar_vector(const Cartesian_vector& cv);
};
Cartesian_vector operator- (const Point& p1, const Point& p2);
Point operator+ (const Point& p, const Cartesian_vector& cv);
Point operator+ (const Cartesian_vector& cv, const Point& p);
Point operator+ (const Point& p, const Polar_vector& pv);
Point operator+ (const Polar_vector& pv, const Point& p);
Cartesian_vector operator+ (const Cartesian_vector& cv1, const Cartesian_vector& cv2);
Cartesian_vector operator- (const Cartesian_vector& cv1, const Cartesian_vector& cv2);
Cartesian_vector operator/ (const Cartesian_vector& cv, double d);
Cartesian_vector operator/ (double d, const Cartesian_vector& cv);
Polar_vector operator/ (const Polar_vector& pv, double d);
Polar_vector operator/ (double d, const Polar_vector& pv);
Cartesian_vector operator* (const Cartesian_vector& cv, double d);
Cartesian_vector operator* (double d, const Cartesian_vector& cv);
Polar_vector operator* (const Polar_vector& pv, double d);
Polar_vector operator* (double d, const Polar_vector& pv);
std::ostream& operator<< (std::ostream& os, const Point& p);
std::ostream& operator<< (std::ostream& os, const Cartesian_vector& cv);
std::ostream& operator<< (std::ostream& os, const Polar_vector& pv);
#endif
i cant able to upload all files