Saving tree to file

So I have this game that builds on it self 20 questions and it improves as it learns from you however I want it to save the improved tree as you play and the next time you run the game it will use the improved tree however I am lost on how to do that. Here is my code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// FILE: useful.cxx

#include <cassert>    // Provides assert
#include <cctype>     // Provides toupper
#include <cstdlib>    // Provides rand, RAND_MAX
#include <iostream> // Provides cout, cin, get
#include "useful.h"
using namespace std;
void display(double x)
// Library facilities used: iostream.h, stdlib.h
{
    const char STAR = '*';
    const char BLANK = ' ';
    const char VERTICAL_BAR = '|';
    const int  LIMIT = 39;
    int i;

    if (x < -LIMIT)
        x = -LIMIT;
    else if (x > LIMIT)
        x = LIMIT;

    for (i = -LIMIT; i < 0; i++)
    {
        if (i >= x)
            cout << STAR;
        else
            cout << BLANK;
    }
    cout << VERTICAL_BAR;
    for (i = 1; i <= LIMIT; i++)
    {
        if (i <= x)
            cout << STAR;
        else
            cout << BLANK;
    }
    cout << endl;
}

double random_fraction( )
// Library facilities used: stdlib.h
{
    return rand( ) / double(RAND_MAX);
}

double random_real(double low, double high)
// Library facilities used: assert.h
{
    assert(low <= high);
    return low + random_fraction( ) * (high - low);
}

void eat_line( )
// Library facilities used: iostream.h
//
{
    char next;

    do
        cin.get(next);
    while (next != '\n');
}

bool inquire(const char query[ ])
// Library facilities used: ctype.h, iostream.h
{
    char answer;
    do
    {
        cout << query << " [Yes or No]" << endl;
        cin >> answer;
        answer = toupper(answer);
        eat_line( );
    }
    while ((answer != 'Y') && (answer != 'N'));
    return (answer == 'Y');
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// FILE: bintree.h

#ifndef BINTREE_H
#define BINTREE_H
#include <cstdlib>  // Provides NULL and size_t

namespace main_savitch_10
{

    template <class Item>
    class binary_tree_node
    {
    public:
	// TYPEDEF
	typedef Item value_type;
	// CONSTRUCTOR
	binary_tree_node(
	    const Item& init_data = Item( ),
	    binary_tree_node* init_left = NULL,
	    binary_tree_node* init_right = NULL
	)
	{
      	    data_field = init_data;
	    left_field = init_left;
	    right_field = init_right;
	}
	// MODIFICATION MEMBER FUNCTIONS
	Item& data( ) { return data_field; }
	binary_tree_node* left( ) { return left_field; }
	binary_tree_node* right( ) { return right_field; }
	void set_data(const Item& new_data) { data_field = new_data; }
	void set_left(binary_tree_node* new_left) { left_field = new_left; }
	void set_right(binary_tree_node* new_right) { right_field = new_right; }
	// CONST MEMBER FUNCTIONS
	const Item& data( ) const { return data_field; }
	const binary_tree_node* left( ) const { return left_field; }
	const binary_tree_node* right( ) const { return right_field; }
	bool is_leaf( ) const
	    { return (left_field == NULL) && (right_field == NULL); }
    private:
	Item data_field;
	binary_tree_node *left_field;
	binary_tree_node *right_field;
    };

        // NON-MEMBER FUNCTIONS for the binary_tree_node<Item>:
    template <class Process, class BTNode>
    void inorder(Process f, BTNode* node_ptr);

    template <class Process, class BTNode>
    void preorder(Process f, BTNode* node_ptr);

    template <class Process, class BTNode>
    void postorder(Process f, BTNode* node_ptr);

    template <class Item, class SizeType>
    void print(binary_tree_node<Item>* node_ptr, SizeType depth);

    template <class Item>
    void tree_clear(binary_tree_node<Item>*& root_ptr);

    template <class Item>
    binary_tree_node<Item>* tree_copy(const binary_tree_node<Item>* root_ptr);

    template <class Item>
    std::size_t tree_size(const binary_tree_node<Item>* node_ptr);
}


#endif 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// FILE: animal.cxx
// An animal-guessing program to illustrate the use of the binary tree toolkit.

#include <cstdlib>     // Provides EXIT_SUCCESS
#include <iostream>    // Provides cout
#include <string>      // Provides string class
#include "bintree.h"   // Provides the binary tree node functions
#include "useful.h"    // Provides eat_line, inquire (from Appendix I)
using namespace std;
using namespace main_savitch_10;

// PROTOTYPES for functions used by this game program:
void ask_and_move(binary_tree_node<string>*& current_ptr);
// Precondition: current_ptr points to a non-leaf node in a binary taxonomy tree.
// Postcondition: The question at the current node has been asked. The current
// pointer has been shifted left (if the user answered yes) or right
// (for a no answer).

binary_tree_node<string>* beginning_tree( );
// Postcondition: The function has created a small taxonomy tree. The return
// value is the root pointer of the new tree.

void instruct( );
// Postcondition: Instructions for playing the game have been printed to the
// screen.

void learn(binary_tree_node<string>*& leaf_ptr);
// Precondition: leaf_ptr is a pointer to a leaf in a taxonomy tree. The leaf
// contains a wrong guess that was just made.
// Postcondition: Information has been elicited from the user, and the tree has
// been improved.

void play(binary_tree_node<string>* current_ptr);
// Precondition: current_ptr points to the root of a binary taxonomy tree with
// at least two leaves.
// Postcondition: One round of the animal game has been played, and maybe the
// tree has been improved.


int main( )
{
    binary_tree_node<string> *taxonomy_root_ptr;
    
    instruct( );
    taxonomy_root_ptr = beginning_tree( );
    do
        play(taxonomy_root_ptr);
    while (inquire("Shall we play again?"));
    
    cout << "Thank you for teaching me a thing or two." << endl;
    return EXIT_SUCCESS;
}

void ask_and_move(binary_tree_node<string>*& current_ptr)
// Library facilities used: bintree.h, string, useful.h
{
    cout << current_ptr->data( );
    if (inquire(" Please answer:"))
        current_ptr = current_ptr->left( );
    else
        current_ptr = current_ptr->right( );
}

binary_tree_node<string>* beginning_tree( )
// Library facilities used: bintree.h, string
{
    binary_tree_node<string> *root_ptr;
    binary_tree_node<string> *child_ptr;

    const string root_question("Are you a mammal?");
    const string left_question("Are you bigger than a cat?");
    const string right_question("Do you live underwater?");
    const string animal1("Kangaroo");
    const string animal2("Mouse");
    const string animal3("Trout");
    const string animal4("Robin");
    
    // Create the root node with the question “Are you a mammal?”
    root_ptr = new binary_tree_node<string>(root_question);

    // Create and attach the left subtree.
    child_ptr = new binary_tree_node<string>(left_question);
    child_ptr->set_left( new binary_tree_node<string>(animal1) );
    child_ptr->set_right( new binary_tree_node<string>(animal2) );
    root_ptr->set_left(child_ptr);

    // Create and attach the right subtree.
    child_ptr = new binary_tree_node<string>(right_question);
    child_ptr->set_left( new binary_tree_node<string>(animal3) );
    child_ptr->set_right( new binary_tree_node<string>(animal4) );
    root_ptr->set_right(child_ptr);

    return root_ptr;
}

void instruct( )
// Library facilities used: iostream
{
    cout << "Let's play!" << endl;
    cout << "You pretend to be an animal, and I try to guess what you are.\n";
}

void learn(binary_tree_node<string>*& leaf_ptr)
// Library facilities used: bintree.h, iostream, string, useful.h
{
    string guess_animal;    // The animal that was just guessed
    string correct_animal;  // The animal that the user was thinking of
    string new_question;    // A question to distinguish the two animals

    // Set strings for the guessed animal, correct animal and a new question.
    guess_animal = leaf_ptr->data( );
    cout << "I give up. What are you? " << endl;
    getline(cin, correct_animal);
    cout << "Please type a yes/no question that will distinguish a" << endl;
    cout << correct_animal << " from a " << guess_animal << "." << endl;
    cout << "Your question: " << endl;
    getline(cin, new_question);

    // Put the new question in the current node, and add two new children.
    leaf_ptr->set_data(new_question);
    cout << "As a " << correct_animal << ", " << new_question << endl;
    if (inquire("Please answer"))
    {
        leaf_ptr->set_left( new binary_tree_node<string> (correct_animal) );
        leaf_ptr->set_right( new binary_tree_node<string> (guess_animal) );
    }
    else
    {
        leaf_ptr->set_left( new binary_tree_node<string> (guess_animal) );
        leaf_ptr->set_right( new binary_tree_node<string> (correct_animal) );
    }
}

void play(binary_tree_node<string>* current_ptr)
// Library facilities used: bintree.h, iostream, string, useful.h
{
    cout << "Think of an animal, then press the return key.";
    eat_line( );

    while (!current_ptr->is_leaf( ))
        ask_and_move(current_ptr);

    cout << ("My guess is " + current_ptr->data( ) + ". ");
    if (!inquire("Am I right?"))
        learn(current_ptr);
    else
        cout << "I knew it all along!" << endl;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// FILE: useful.h
// PROVIDES: A toolkit of useful functions for random numbers and displays.
// Note that these are in the global namespace.
//
// FUNCTIONS in the toolkit:
//   double random_fraction( )
//     Postcondition: The return value is a random real number in the closed
//     interval [0..1] (including the endpoints).
//
//   double random_real(double low, double high)
//     Precondition: low <= high.
//     Postcondition: The return value is a random real number in the closed
//     interval [low..high] (including the endpoints).
//
//   void display(double x)
//     Postcondition: The function has written one line of output to the
//     standard ouput, with a vertical bar in the middle. If x is positive,
//     then approximately x stars are printed to the right of the vertical
//     bar. If x is negative, then approximately -x stars are printed to the
//     left of the vertical bar. If the absolute value of x is more than
//     39, then only 39 stars are printed.
//     Examples:
//     display(8) prints:                          |********
//     display(-4) prints:                     ****|
//
//   void eat_line( )
//     Postcondition: Up to next newline has been read and discarded from cin.
//
//   bool inquire(const char query[ ])
//     Precondition: query is a null-terminated string of characters.
//     Postcondition: query has been printed, and a one-line response read 
//     from the user. The function returns true if the user's response begins 
//     with 'Y' or 'y', and returns false if the user's response begins with 
//     'N' or 'n'. (If the response begins with some other letter, then the
//     query is repeated.)

#ifndef USEFUL_H  // Prevent duplicate definition
#define USEFUL_H

    double random_fraction( );
    double random_real(double low, double high);
    void display(double x);
    void eat_line( );
    bool inquire(const char query[ ]);

#endif 
Topic archived. No new replies allowed.