Untitled

 avatar
unknown
plain_text
13 days ago
10 kB
6
Indexable
#include <string>
#include <iostream>
#define MAX_ARR 200

using namespace std;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*           MOVIE CLASS DEFINITIONS                   */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * */

class Movie{	
	friend ostream& operator<<(ostream&, const Movie&);
	public:
		Movie(const string& title, const string& category);
		bool operator==(const string& t) const {return title == t;}	
        string getCategory()const{return category;}
	protected:
		virtual void play(ostream& ost) const = 0;
		string title;
		string category;
};

Movie::Movie(const string& title, const string& category): 
    title(title), category(category){}


//**added to overload stream insertion operator using polymorphism??
ostream& operator<<(ostream& ost, const Movie& movie) {
    movie.play(ost);
    return ost;
}


// high definition
class HDMovie: public Movie{
	public:
		HDMovie (const string& title, const string& cat, const string& hd);
	protected:
		virtual void play(ostream& ost) const;
		string hdContent;
};

HDMovie::HDMovie(const string& title, const string& cat, const string& hd):
    Movie(title, cat), hdContent(hd){}

void HDMovie::play(ostream& ost) const{    
    ost << "HD Movie: " << title << " " << category << " " << hdContent << endl;
}


// standard definition
class SDMovie: public Movie{
	public:
		SDMovie (const string& title, const string& cat, const string& sd);
	protected:
		virtual void play(ostream& ost) const;
		string sdContent;
};

SDMovie::SDMovie(const string& title, const string& cat, const string& sd):
    Movie(title, cat), sdContent(sd){}

void SDMovie::play(ostream& ost) const{
    ost << "SD Movie: " << title << " " << category << " " << sdContent << endl;
}

class Criteria {
    public :
        virtual bool matches ( const Movie &) const = 0;
};

class CatCriteria: public Criteria{
    public:
        CatCriteria(const string& cat){
            this->category = cat;
        }

        virtual bool matches (const Movie& m) const{
            return category == m.getCategory();
        }

    private:
        string category;
};


/* * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*           MOVIELIST CLASS DEFINITIONS               */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * */

class MovieList{
	
	class Node{
		public:
			Node (Movie* m): data(m), next(nullptr){}
			Movie* data;
			Node* next;
	};
	
	public:
		MovieList();   
		~MovieList();
		// add to the front of the MovieList
		bool add(Movie*, int index);
		void addBack(Movie*);
		
		// remove and return the Movie at the front
		Movie* remove(int index);
        bool isEmpty() const {return head == nullptr;}

		
	private:
		Node* head;
		int size; 

};

/* * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*           MOVIELIST CLASS IMPLEMENTATIONS           */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * */

MovieList::MovieList() : head(nullptr), size(0) {}

//deconstructor:
MovieList::~MovieList() {
    while (head) {
        Node* temp = head;
        head = head->next;
        delete temp->data;
        delete temp;
    }
}

//**adding to the front**
bool MovieList::add(Movie* m, int index) {
    if (index < 0 || index > size) return false; 
		Node* newNode = new Node(m);
		if (index==0){
			newNode -> next = head; 
			head = newNode;
			++size;
			return true;
		}

	Node* current = head;
	for (int i = 0; i < index -1; i++){
		current = current -> next;
	}
 
	newNode -> next = newNode;
	current -> next = newNode;
	++size;
	return true;

}

//**adding to the back of the list
void MovieList::addBack(Movie* m) {
    add(m, size);
}

//removing from from list based on index provided
Movie* MovieList::remove(int index) {
    if (index < 0 || index >= size || head == nullptr)
        return nullptr;

    Node* temp;
    Movie* removed;
    if (index == 0) {
        temp = head;
        head = head->next;
    } else {
        Node* prev = head;
        for (int i = 1; i < index; ++i)
            prev = prev->next;
        temp = prev->next;
        prev->next = temp->next;
    }
    removed = temp->data;
    delete temp;
    --size;
    return removed;
}


/* * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*           ARRAY CLASS DEFINITION                    */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * */

template <class T>
class Array {
	public:
		Array();	
		~Array();
		// add T to the back of the array if there is room
		Array<T>& operator+=(const T&);
		// remove T if it exists
		Array<T>& operator-=(const T&);
		// return element at index, or call exit(1) on bad index
		T& operator[](int index);
		const T& operator[](int index) const;
		// inline functions
		int getSize() const { return numElements; }
		bool isFull() const { return numElements >= MAX_ARR;}
	
	private:
		int numElements;
		T* elements;
};

/* * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*           ARRAY CLASS IMPLEMENTATION                */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * */


// **THIS IS IMPORTANT
template <class T>
Array <T>::Array(){
	numElements=0;
	elements = new T[MAX_ARR];
}


template <class T>
Array<T>::~Array() {
    delete[] elements;
}


template <class T>
T& Array<T>::operator[](int index){
	if (index < 0 || index >= numElements) exit(1);
	return elements[index];
}


template <class T>
Array<T>& Array<T>::operator+=(const T& val) {
    if (isFull()) return *this;
    elements[numElements++] = val;
    return *this;
}

template <class T>
Array<T>& Array<T>::operator-=(const T& val) {
    for (int i = 0; i < numElements; ++i) {
        if (elements[i] == val) {
            for (int j = i; j < numElements - 1; ++j) {
                elements[j] = elements[j + 1];
            }
            --numElements;
            break;
        }
    }
    return *this;
}





class Factory{
    public:
        Movie* makeMovie(const string& title, const string& cat, const string& content);
};


/* * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*      PROFILE AND FACTORY CLASS IMPLEMENTATIONS      */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * */



/* * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*           MOVIEFLIX CLASS DEFINITIONS               */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * */


class MovieFlix{
	public:
        MovieFlix();
		~MovieFlix();
		
		// make a new Movie and add it to the array 
		bool addMovie(const string& title, const string& cat, 
			const string& content);
	
		Movie*  getMovie(const string& title) const;
        Movie*  removeMovie(const string& title);

        // Find the profile with the given name and add all the movies
        // in the current searchList to their watchList. The searchList
        // should be empty after this operation.
        void addToPlaylist(const Criteria& crit);
        void playPlaylist() const;
        void printMovies() const;
	
	private:
				
		// master list of all movies
		Array<Movie*> movies;
        // master list of all profiles
        // current search results
        MovieList playList;
        Factory factory;
};	

/* * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*           MOVIEFLIX CLASS IMPLEMENTATIONS           */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * */
MovieFlix::MovieFlix() {}

MovieFlix::~MovieFlix() {
    for (int i = 0; i < movies.getSize(); i++) {
        delete movies[i];
    }
}

bool MovieFlix::addMovie(const string& title, const string& cat, const string& content) {
    // Prevent duplicates
    for (int i = 0; i < movies.getSize(); i++) {
        if (*movies[i] == title) {
            return false;
        }
    }
    if (movies.isFull()) return false;

    Movie* m = factory.makeMovie(title, cat, content); //createMovie isn't actually implemented but we pretend
    movies += m;
    return true;
}

Movie* MovieFlix::getMovie(const string& title) const {
    for (int i = 0; i < movies.getSize(); i++) {
        if (*movies[i] == title) {
            return movies[i];
        }
    }
    return nullptr;
}

Movie* MovieFlix::removeMovie(const string& title) {
    for (int i = 0; i < movies.getSize(); ++i) {
    	if (*movies[i] == title) {
     		Movie* m = movies[i];
        	movies -= m;  // Pass a Movie* to match T
        	return m;
    }
}
    return nullptr;
}

void MovieFlix::addToPlaylist(const Criteria& crit) {
    for (int i = 0; i < movies.getSize(); i++) {
        if (crit.matches(*movies[i])) {
            playList.addBack(movies[i]); //don't need to dereference here
        }
    }
}

void MovieFlix::playPlaylist() const {
    if (playList.isEmpty()) {
        cout << "Playlist is empty." << endl;
        return;
    }

    // We'll need to remove and play each movie from the list
    MovieList temp = playList; // copy to avoid mutating original
    Movie* m;
    int index = 0;
    while ((m = temp.remove(0)) != nullptr) {
        cout << *m;
    }
}

void MovieFlix::printMovies() const {
    if (movies.getSize() == 0) {
        cout << "No movies in the catalog." << endl;
        return;
    }

    for (int i = 0; i < movies.getSize(); i++) {
        cout << *movies[i];
    }
}



/* * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*           MAIN FUNCTION WITH TESTS                  */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * */

int main(){

    MovieFlix mf;

    string titles[] = {"D", "B","E", "A", "C"};
    string cats[] = {"X", "Y","X", "Y", "Z"};
    string content[] = {"X", "Y","X", "Y", "Z"};



    cout<<"Adding movies"<<endl;
    for(int i = 0 ; i < 5; ++i){
        mf.addMovie(titles[i], cats[i], content[i]);   
    }

    mf.printMovies();

    Criteria* crit;

    cout<<endl<<"Adding to play list"<<endl<<endl;

    mf.addToPlaylist(*crit);

    mf.playPlaylist();

    return 0;

}
Editor is loading...
Leave a Comment