Project to simulate rails

 

Corrected Mistakes:

 

  1. Documented the project as multiple inheritance.
  2. Failed to pass commuter thru helper functions.
  3. is_end_of_line() function also set end_of_line.
  4. No polymorphic behavior with vector<Track> which
    is needed for passing and showing a Signal.
  5. No need to use typeid(), use polymorphic behavior
    on tr->show();
  6. Lacked random behavior, load a random seed from time.
  7. Only one signal was created on the track.

 

Needs:

 

  1. Signals that gradually increase and decrease.
  2. End of line UNLOADING and the simple return.
  3. Return should move in the opposite direction.
  4. Return routes and connections and conflicts of
    multiple trains.
  5. Schedule Queues of Trains which set routes
    which go and return.
  6. Power association for locomotive strength with
    number of passengers / freight / terrain.

File: rail_sim.cpp

 

// rail_sim.cpp : Defines the entry point for the console application.

#include <iostream>

// #include <fstream>

// #include <string>

// #include <cstdlib>

#include <ctime>

// #include <exception>

// #include <stdexcept>

#include <vector>

// #include <algorithm>

#include "track.h"

#include "train.h"

 

using namespace std;

 

void render_display( Train & commuter, vector<Track *> & track );

void render_track( Train & commuter, vector<Track *> & track );

void show_track( Train & commuter, const Track & tr );

int main( /* int argc, char* argv[] */ ) {

      // Create random behaviour with current time as a random seed

      srand(time(0));

 

      vector<Track *> tracks;

      Train commuter;

 

      try {

        // lay down the rails ...

        for (int rail = 0; rail < Train::NUM_RAILS; rail++) {

                  if ( !(rail % Signal::DEFAULT_DENSITY) ) {

                Signal * signal = new Signal(rail, 90);

                tracks.push_back( signal );

            } else {

                Track * track = new Track(rail);

                tracks.push_back( track );

            }

        }

 

        // initialize the train ...

        tracks[0]->set_end_of_line(true);

        tracks[ Train::NUM_RAILS - 1 ]->set_end_of_line(true);

 

        render_display(commuter, tracks);

 

        while ( tolower( cin.get() ) != 'x' ) {

            cin.ignore(255, '\n');

            commuter.updateStatus();

            render_display(commuter, tracks);

        }

 

    } catch (...) {

        cout << "main.catch(...): An error was thrown..." << endl;

    }

 

      cout << "Exiting." << endl;

      return 0;

}

void render_display( Train & commuter, vector<Track *> & track ) {

    system("cls");

      static int count = 1;

 

    cout << "\n\n  TRACK " << count << ": ";

    commuter.showStatus();

    render_track( commuter, track );

      ++count;

    cout << "\n\nPress ANY KEY + [ENTER] for next iteration ,'X' to exit:";

}

 

void render_track( Train & commuter, vector<Track *> & track ) {

 

    cout << "\n  [";

     

      const vector<Track*>::iterator END = track.end();

      for ( vector<Track*>::iterator it = track.begin();

              it != END; ++it) {

                  show_track(commuter, **it);

    }

    cout << "]" << endl;

}

 

void show_track( Train & commuter, const Track & tr ) {

 

    if ( tr.get_mile_marker() == commuter.get_track_location() )

        commuter.show();

      else

        tr.show();

}

 

Files:  train.h and train.cpp

 

#ifndef TRAIN_H_

#define TRAIN_H_

 

// #include <string>

#include <iostream>

 

using std::cout;

using std::cin;

using std::endl;

 

class Train {

  public:

      static const int MAX_PASSENGERS = 350;

      static const int NUM_RAILS = 25;

      enum { LOADING, INTRANSIT, UNLOADING };

 

    Train() {

            state = LOADING;

            velocity = 0;

            westbound = true;

            track_location = 0;

      }

        virtual ~Train();

        void show() const;

        void showStatus() const;

        void updateStatus();

            int get_track_location() const { return track_location; }

 

  private:

            int track_location;

        int passengers;

        int velocity;

        int speed_limit;

        int state;

        bool westbound;

};

 

#endif

 

// workermi.cpp -- working class methods with MI

#include "train.h"

#include <iostream>

#include <string>

 

using namespace std;

 

 

//      Train methods

 

Train::~Train() {}

 

void Train::show() const {

    if ( velocity > 0 ) {

        if ( westbound )

            cout << "<";

        else

            cout << ">";

    } else

        cout << "#";

}

 

void Train::showStatus() const {

    switch( state ) {

        case LOADING    :   cout << "Train is loading..."; break;

        case INTRANSIT  :   cout << "Train is intransit..."; break;

        case UNLOADING  :   cout << "Train is unloading..."; break;

    }

 

    cout << "\n  SPEED: " << velocity << "  PASSENGERS: " << passengers;

 

    string dir = ( westbound ) ? "West-bound" : "East-bound";

 

    cout << " DIRECTION: " << dir << endl;

}

 

void Train::updateStatus() {

    try {

        switch( state ) {

                case LOADING    :

                        passengers =  rand() % ( MAX_PASSENGERS );

                        westbound = ! westbound;

                        velocity = 60;

                        state = INTRANSIT;

                        break;

 

                case INTRANSIT  :

                        ( westbound ) ? track_location-- : track_location++;

                        break;

 

                case UNLOADING  :

                        passengers =  0;

                        westbound = ! westbound;

                        velocity = 0;

                        state = INTRANSIT;

                        break;

        }

            // this should be track UNLOADING

        if ( track_location > ( NUM_RAILS - 1 ) )

            throw "You went off the rails!";

    } catch (char * str) {

        cout << "\nERROR: " << str << endl;

            throw;

    }

}

 

Files: track.h and track.cpp

 

#ifndef TRACK_H_

#define TRACK_H_

 

// #include <string>

#include <iostream>

#include "train.h"

 

using std::cout;

using std::cin;

using std::endl;

 

class Track {

    public:

        Track( int mile_marker ) : mile_marker(mile_marker),

                           end_of_line(false) {

          }

        virtual ~Track();

        virtual void show() const { cout << "="; }

            bool set_end_of_line( bool yesNo ) {

                  bool value = end_of_line;

                  end_of_line = yesNo;

                  return value;

            }

            bool is_end_of_line() const {

                  return end_of_line;

 

            }

 

            int get_mile_marker() const { return mile_marker; }

    private:

        bool end_of_line;

        int mile_marker;

        int type;

        bool occupied;

};

 

 

class Signal : virtual public Track {

public:

      enum { DENSITY_MIN = 3, DEFAULT_DENSITY = 5,

               DENSITY_MAX = 9 };

    Signal( int mile_marker, int signal_speed )

                : Track(mile_marker),

                    signal_speed(signal_speed) {

    }

 

    void show() const { cout << "%"; }

 

private:

    int signal_speed;

};

 

#endif

 

// workermi.cpp -- working class methods with MI

#include "track.h"

#include "train.h"

 

#include <iostream>

using std::cout;

using std::cin;

using std::endl;

 

//      TrackObject methods

 

Track::~Track() {

    //cout << "deleting track\n";

}

 

 

1