Question: Card game code Alice proceeds FORWARD starting with lowest card and proceeding to the highest card, while Bob proceeds BACKWARDS through his cards in sorted
Card game code
Alice proceeds FORWARD starting with lowest card and proceeding to the highest card, while Bob proceeds BACKWARDS through his cards in sorted order.
Once the cards are in order, the game begins. Alice iterates forward through her binary tree (in increasing order of the cards), checking whether Bob has that card. Then check if Bob has each card using the search function of the BST. Once a matching card is found, you should print the line Alice picked matching card ". The card should then be removed from both players hands by calling delete on the binary search tree. Make sure to delete any dynamically allocated memory when removing the cards from your trees!
The process then repeats, except this time, Bob looks through his cards starting with the largest card and working towards the smallest card. This means that while the first card Alice finds should be the first shared card (in order), the first card Bob finds should be the last shared card (in order). Once there are no matching cards, you should print out the final hands of both players with the matching cards removed.
What should the code in main.cpp look like to allow the game to be played as described above? Given the templated functions which can take any arguement below. The txt files will be read in through ifstream separately compare the value and suit, so storing the cards as strings is probably not the best approach.
CARDS.H header file
| #ifndef BST_h | |
| #define BST_h | |
| #include | |
| using namespace std; | |
| template | |
| class BST { | |
| public: | |
| BST(); // constructor | |
| ~BST(); // destructor | |
| bool insert(T value); // insert value; return false if duplicate | |
| void printPreOrder() const; // prints tree data pre-order to cout | |
| void printInOrder() const; // print tree data in-order to cout | |
| void printPostOrder() const; // print tree data post-order to cout | |
| int count() const; // count of values | |
| bool contains(T value) const; // true if value is in tree | |
| T getPredecessor(T value) const; // returns the predecessor value of the given value or 0 if there is none | |
| T getSuccessor(T value) const; // returns the successor value of the given value or 0 if there is none | |
| bool remove(T value); // deletes the Node containing the given value from the tree | |
| private: | |
| struct Node { | |
| T info; | |
| Node *left, *right, * parent; | |
| // useful constructor: | |
| Node(T v) : info(v), left(0), right(0), parent(0) { } | |
| }; | |
| // just one instance variable (pointer to root node): | |
| Node *root; | |
| // recursive utility functions for use by public methods above | |
| Node* getNodeFor(T value, Node* n) const; //returns the node for a given value or NULL if none exists | |
| void clear(Node *n); // for destructor | |
| bool insert(T value, Node *n); // note overloading names for simplicity | |
| void printPreOrder(Node *n) const; | |
| void printInOrder(Node *n) const; | |
| void printPostOrder(Node *n) const; | |
| int count(Node *n) const; | |
| // these are used by getPredecessor and getSuccessor, and one of them used by remove | |
| Node* getSuccessorNode(T value) const; // returns the Node containing the successor of the given value | |
| Node* getPredecessorNode(T value) const; // returns the Node containing the predecessor of the given value | |
| }; | |
| #endif | |
| CARDS.CPP function definitions
// constructor sets up empty tree | |||||||
| template | |||||||
| BST::BST() : root(0) { } | |||||||
| // destructor deletes all nodes | |||||||
| template | |||||||
| BST::~BST() { | |||||||
| clear(root); | |||||||
| } | |||||||
| // recursive helper for destructor | |||||||
| template | |||||||
| void BST::clear(Node *n) { | |||||||
| if (n) { | |||||||
| clear(n->left); | |||||||
| clear(n->right); | |||||||
| delete n; | |||||||
| } | |||||||
| } | |||||||
| // insert value in tree; return false if duplicate | |||||||
| template | |||||||
| bool BST::insert(T value) { | |||||||
| // handle special case of empty tree first | |||||||
| if (!root) { | |||||||
| root = new Node(value); | |||||||
| return true; | |||||||
| } | |||||||
| // otherwise use recursive helper | |||||||
| return insert(value, root); | |||||||
| } | |||||||
| // recursive helper for insert (assumes n is never 0) | |||||||
| template | |||||||
| bool BST::insert(T value, Node *n) { | |||||||
| if (value == n->info) | |||||||
| return false; | |||||||
| if (value < n->info) { | |||||||
| if (n->left) | |||||||
| return insert(value, n->left); | |||||||
| else { | |||||||
| n->left = new Node(value); | |||||||
| n->left->parent = n; | |||||||
| return true; | |||||||
| } | |||||||
| } | |||||||
| else { | |||||||
| if (n->right) | |||||||
| return insert(value, n->right); | |||||||
| else { | |||||||
| n->right = new Node(value); | |||||||
| n->right->parent = n; | |||||||
| return true; | |||||||
| } | |||||||
| } | |||||||
| } | |||||||
| // print tree data pre-order | |||||||
| template | |||||||
| void BST::printPreOrder() const { | |||||||
| printPreOrder(root); | |||||||
| } | |||||||
| // recursive helper for printPreOrder() | |||||||
| template | |||||||
| void BST::printPreOrder(Node *n) const { | |||||||
| if (n) { | |||||||
| cout << n->info << " "; | |||||||
| printPreOrder(n->left); | |||||||
| printPreOrder(n->right); | |||||||
| } | |||||||
| } | |||||||
| // print tree data in-order, with helper | |||||||
| template | |||||||
| void BST::printInOrder() const { | |||||||
| printInOrder(root); | |||||||
| } | |||||||
| template | |||||||
| void BST::printInOrder(Node *n) const { | |||||||
| if (n) { | |||||||
| printInOrder(n->left); | |||||||
| cout | |||||||
| printInOrder(n->right); | |||||||
| } | |||||||
| } | |||||||
| // prints tree data post-order, with helper | |||||||
| template | |||||||
| void BST::printPostOrder() const { | |||||||
| printPostOrder(root); | |||||||
| } | |||||||
| template | |||||||
| void BST::printPostOrder(Node *n) const { | |||||||
| if (n) { | |||||||
| printPostOrder(n->left); | |||||||
| printPostOrder(n->right); | |||||||
| cout << n->info << " "; | |||||||
| } | |||||||
| } | |||||||
| // return count of values | |||||||
| template | |||||||
| int BST::count() const { | |||||||
| return count(root); | |||||||
| } | |||||||
| // recursive helper for count | |||||||
| template | |||||||
| int BST::count(Node *n) const { | |||||||
| if(n==NULL) | |||||||
| return 0; | |||||||
| else{ | |||||||
| int c=1; | |||||||
| c+=count(n->left); | |||||||
| c+=count(n->right); | |||||||
| return c; | |||||||
| } | |||||||
| } | |||||||
| // Parameters: | |||||||
| // int value: the value to be found | |||||||
| template | |||||||
| typename BST::Node* BST::getNodeFor(T value, Node* n) const{ | |||||||
| /*while(n){ | |||||||
| if (n -> info == value) | |||||||
| return n; | |||||||
| if (n -> info > value) | |||||||
| n = n -> left; | |||||||
| if (n -> info < value) | |||||||
| n = n -> right; | |||||||
| //cout | |||||||
| } | |||||||
| return NULL;*/ | |||||||
| if(n==NULL) return NULL; | |||||||
| else if(n->info == value) return n; | |||||||
| else if(n->info>value) return getNodeFor(value, n->left); | |||||||
| else if(n->inforight); | |||||||
| } | |||||||
| // returns true if value is in the tree; false if not | |||||||
| template | |||||||
| bool BST::contains(T value) const { | |||||||
| return(getNodeFor(value, root)!=NULL); | |||||||
| } | |||||||
| // returns the Node containing the predecessor of the given value | |||||||
| template | |||||||
| typename BST::Node* BST::getPredecessorNode(T value) const{ | |||||||
| Node* n = getNodeFor(value, root); | |||||||
| if (n==NULL) | |||||||
| return n; | |||||||
| Node* temp = NULL; | |||||||
| if(n->left){ | |||||||
| n=n->left; | |||||||
| while(n->right){ | |||||||
| n = n->right; | |||||||
| } | |||||||
| temp = n; | |||||||
| } | |||||||
| else { | |||||||
| while(n->parent){ | |||||||
| // Node* tempParent = n->parent; | |||||||
| if(n->parent->info < value){ | |||||||
| temp=n->parent; | |||||||
| break; | |||||||
| } | |||||||
| else{ | |||||||
| n = n->parent; | |||||||
| } | |||||||
| } | |||||||
| } | |||||||
| return temp; | |||||||
| } | |||||||
| // returns the predecessor value of the given value or 0 if there is none | |||||||
| template | |||||||
| T BST::getPredecessor(T value) const{ | |||||||
| T pred; | |||||||
| Node* val = getPredecessorNode(value); | |||||||
| if (val == NULL){ | |||||||
| return pred; | |||||||
| } | |||||||
| else | |||||||
| return val->info; | |||||||
| } | |||||||
| // returns the Node containing the successor of the given value | |||||||
| template | |||||||
| typename BST::Node* BST::getSuccessorNode(T value) const{ | |||||||
| Node* n = getNodeFor(value, root); | |||||||
| if (n==NULL){ | |||||||
| Node* n=NULL; | |||||||
| return n; | |||||||
| } | |||||||
| Node* temp = NULL; | |||||||
| if(n->right){ | |||||||
| n=n->right; | |||||||
| while(n->left){ | |||||||
| n = n->left; | |||||||
| } | |||||||
| temp = n; | |||||||
| } | |||||||
| else { | |||||||
| while(n->parent){ | |||||||
| // Node* tempParent = n->parent; | |||||||
| if(n->parent->info > value){ | |||||||
| temp=n->parent; | |||||||
| break; | |||||||
| } | |||||||
| else{ | |||||||
| n = n->parent; | |||||||
| } | |||||||
| } | |||||||
| } | |||||||
| return temp; | |||||||
| } | |||||||
| // returns the successor value of the given value or 0 if there is none | |||||||
| template | |||||||
| T BST::getSuccessor(T value) const{ | |||||||
| Node* tmp = getSuccessorNode(value); | |||||||
| T succ; | |||||||
| if (tmp == NULL) | |||||||
| return succ; | |||||||
| else | |||||||
| return (tmp->info); | |||||||
| } | |||||||
| // deletes the Node containing the given value from the tree | |||||||
| // returns true if the node exist and was deleted or false if the node does not exist | |||||||
| template | |||||||
| bool BST::remove(T value){ | |||||||
| if (!getNodeFor(value,root)) | |||||||
| return false; | |||||||
| Node* n = getNodeFor(value, root); | |||||||
| if (n->right==NULL && n->left==NULL){ //leaf | |||||||
| if(n == root){ | |||||||
| root = NULL; | |||||||
| delete n; | |||||||
| } | |||||||
| else if (n==(n->parent->left)) | |||||||
| n->parent->left = NULL; | |||||||
| else | |||||||
| n->parent->right = NULL; | |||||||
| delete n; | |||||||
| } | |||||||
| else if(n->left == NULL || n->right == NULL){ //only one child | |||||||
| if(n==root){ //and is root | |||||||
| if(n->right) root = n->right; | |||||||
| else root = n->left; | |||||||
| } | |||||||
| else{ //and is not root | |||||||
| Node* next; | |||||||
| if(n->right) next= n->right; | |||||||
| else next = n->left; | |||||||
| if(n->parent->right == n){ //if n is right of parent | |||||||
| n->parent->right = next; | |||||||
| n->parent->right->parent = n->parent; | |||||||
| } | |||||||
| else{ //else n is left of parent | |||||||
| n->parent->left = next; | |||||||
| n->parent->left->parent = n->parent; | |||||||
| } | |||||||
| } | |||||||
| delete n; | |||||||
| } | |||||||
| else{ //two children | |||||||
| Node* swap; | |||||||
| T temp; | |||||||
| swap = getPredecessorNode(n->info); | |||||||
| temp = n->info; | |||||||
| n->info = swap->info; | |||||||
| swap->info = temp; | |||||||
| remove(swap->info); | |||||||
| } | |||||||
| return true; | |||||||
| }
|
this is what my main.cpp looks like now
| #include | |
| #include | |
| #include | |
| using namespace std; | |
| int main(int argv, char** argc){ | |
| if(argv < 3){ | |
| cout << "Please provide 2 file names" << endl; | |
| return 1; | |
| } | |
| ifstream cardFile1 (argc[1]); | |
| ifstream cardFile2 (argc[2]); | |
| string line; | |
| if (cardFile1.fail() || cardFile2.fail() ){ | |
| cout << "Could not open file " << argc[2]; | |
| return 1; | |
| } | |
| BST | |
| //Read each file | |
| while (getline (cardFile1, line) && (line.length() > 0)){ | |
| alice.insert(line); | |
| } | |
| cardFile1.close(); | |
| while (getline (cardFile2, line) && (line.length() > 0)){ | |
| bob.insert(line); | |
| } | |
| cardFile2.close(); | |
| //start the game | |
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
