Create a function that makes a copy of a private map

So I'm doing this project: http://www.gamedev.net/topic/409907-c-workshop---project-1/

For now I've done a function that creates menus and prints them, and a function that creates the character as an object.

Now I want to be able to show the stats of the player on the main menu, the problem is that I don't know how to make a copy of the map as it's private...
The code is probably a mess, I hope you guys understand it... thanks!

Main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <string>
#include <time.h>
#include <stdlib.h>
#include <map>
#include <algorithm>
#include <stdlib.h>
#include "Create_Character.h"
#include "Menu.h"

using namespace std;

int main()
{
   Menu_main();
}


Menu.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iterator>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
#include <map>

using namespace std;

class Menu
{
public:
    void create_menu(std::string line);
    void show_menu();

private:
        std::string get_values();
        std::vector<std::string> menu_table;
};

int Menu_main();
void Restart_Copied_Stats();


Menu.cpp
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
#include <iterator>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
#include "Menu.h"
#include "Create_Character.h"

using namespace std;

std::map <string, unsigned int> saved_stats;
void Restart_Copied_Stats()
{
    saved_stats ["Strength"] = 8;
    saved_stats ["Armor"] = 8;
    saved_stats ["Health"] = 50;
    saved_stats ["Crit Chance"] = 1;
    saved_stats ["Dodge"] = 5;
    saved_stats ["Level"] = 1;
    saved_stats ["Experience"] = 0;
    saved_stats ["Gold"] = 6;
}



void Menu::show_menu()
{
    for (int i = 0; i < menu_table.size(); i++)
    {
        if (i == 0)
        {
            cout<< "================ "<< menu_table[0]<< " ================";
        }
        else

        cout<< "\n"<<i<<". "<<menu_table[i];
    }
    cout<< "\n================ "<< menu_table[0]<< " ================";
}
void Menu::create_menu(std::string line)
{

	std::stringstream  lineStream(line);

	std::string cell("");

	// collect all the strings
	while (std::getline(lineStream, cell, ','))
	{
		menu_table.push_back(cell);
	}
}


Menu_Main.cpp
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
#include <iterator>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
#include <algorithm>
#include <map>
#include "Create_Character.h"
#include "Menu.h"

using namespace std;



bool character_created = false;



int Menu_main()
{
    int decision;
    std::string main_menu_list ("MAIN MENU,Create Character,Buy Equipment,See Stats,Fight!,Quit");
    Menu Main_Menu;
    Main_Menu.create_menu(main_menu_list);

    system("CLS");
    Main_Menu.show_menu();
    cout<<"\n";
    cin>> decision;

    switch(decision)
    {
        case 1:
            if (character_created == true)
            {
                std::string continue_char;
                system("CLS");
                cout<< "You have already created a character, if you continue all your data will be lost! Do you wish to continue?";
                cin>> continue_char;
                std::transform(continue_char.begin(), continue_char.end(),continue_char.begin(), ::toupper);
                if (continue_char == "Y"|| continue_char == "YES")
            {
                Char_main();
            }
            else
                Menu_main();

            }

            character_created = true;
            Char_main();
            break;

    }

}


Create_Character.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <string>
#include <time.h>
#include <stdlib.h>
#include <map>
#include <stdlib.h>

using namespace std;

class new_player
{
public:
    void set_name();
    void create_character();
    void set_random_stats();
    void reset_values();
    void show_stats();
    map <string, unsigned int> return_map();

private:
    std::map <string, unsigned int> stats;
    std::string name_player = "Villaop the Fighter";
};
int Char_main();


Create_Character.cpp
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
#include <iostream>
#include <string>
#include <time.h>
#include <stdlib.h>
#include <map>
#include <stdlib.h>
#include "Create_Character.h"
#include "Menu.h"

using namespace std;

map <string, unsigned int>new_player::return_map()
{
    return (this->stats);
}

void new_player::set_name()
{
    cin.ignore();
    system("CLS");
    cout<< "Please set the character's name: ";
    getline(cin, name_player, '\n');
}

void new_player::show_stats()
{
    system("CLS");
    cout<<"Name: "<<name_player<<"\nStrength: "<< new_player::stats ["Strength"]
    <<"\nArmor: "<<stats ["Armor"]<<"\nHealth: "
    <<stats ["Health"]<<"\nCritical Chance: "<<stats ["Crit Chance"]
    <<"\nDodge: "<<stats ["Dodge"]<<"\nLevel: "<<stats ["Level"]
    <<"\nExperience: "
    <<stats ["Experience"]<<"\nGold: "
    <<stats ["Gold"];
}

void new_player::reset_values()
{
    stats ["Strength"] = 8;
    stats ["Armor"] = 8;
    stats ["Health"] = 50;
    stats ["Crit Chance"] = 1;
    stats ["Dodge"] = 5;
    stats ["Level"] = 1;
    stats ["Experience"] = 0;
    stats ["Gold"] = 6;
}

void new_player::set_random_stats()
{
    stats ["Strength"] += rand() % 13;
    stats ["Armor"] += rand() % (13-(stats ["Strength"] - 8));
    stats ["Crit Chance"] += rand() % (13-((stats ["Strength"] - 8) + stats ["Armor"] - 8));
    stats ["Dodge"] += 29 - (stats ["Strength"]+stats ["Armor"]+stats ["Crit Chance"]);
    this->show_stats();
}

void new_player::create_character()
{
    this->reset_values();
    this->set_random_stats();
}


Character_Main.cpp
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
#include <iostream>
#include <string>
#include <time.h>
#include <stdlib.h>
#include <map>
#include <algorithm>
#include <stdlib.h>
#include "Create_Character.h"
#include "Menu.h"

using namespace std;

int Char_main()
{
    srand(time(NULL));
    bool quit = false;
    new_player Villaop;
    Villaop.reset_values();
    int decision = 0;
    while (quit == false)
    {
    std::string char_menu_list ("CREATE CHARACTER,Set Name,Roll Stats,See Stats,Back");
    Menu Char_Menu;
    Char_Menu.create_menu(char_menu_list);

    system("CLS");
    Char_Menu.show_menu();
    cin>> decision;
    if (decision == 1)
    {
        Villaop.set_name();
    }
    else if (decision == 4)
    {
        quit = true;
    }
    else if (decision == 3)
    {
        Villaop.show_stats();
        cout<<"\n";
        system("pause");

    }
    else if (decision == 2)
    {
        bool satisfied = false;
        while (satisfied == false)
        {
            std::string satisfaction;
            Villaop.create_character();
            cout<< "\n\nAre you satisfied with your stats?";
            cin>> satisfaction;
            std::transform(satisfaction.begin(), satisfaction.end(),satisfaction.begin(), ::toupper);
            if (satisfaction == "Y"|| satisfaction == "YES")
            {
                satisfied = true;
            }
        }
    }
    }
    Menu_main();

}


So I'm pretty new with coding, you'll see that once you read the code... I really hope you guys can help me!

THANKS!!!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <string>
#include <map>

struct A
{
    // return (copy) by value
    std::map<std::string,int> stats() const { return saved_stats ; }

    // return reference to const
    const std::map<std::string,int>& stats_by_ref() const { return saved_stats ; }

    private: std::map<std::string,int> saved_stats {  {"zero",0},  {"one",1}, {"two",2} };
};

int main()
{
    A a ;

    auto cpy = a.stats() ; // copy

    const auto& ref = a.stats_by_ref() ; // reference to const
}
Where am I supposed to put this code? And I don't really understand it... could you explain it a bit please? I just don't understand the "zero" 0 "one" 1, etc.
> I just don't understand the "zero" 0 "one" 1, etc.

The non-static member saved_stats is iniotialised with the expression { {"zero",0}, {"one",1}, {"two",2} }

In-class member initialiser: http://www.stroustrup.com/C++11FAQ.html#member-init

Initialiser lists: http://www.stroustrup.com/C++11FAQ.html#init-list

List initialisation: http://en.cppreference.com/w/cpp/language/list_initialization

std::map<> constructor (5) : http://en.cppreference.com/w/cpp/container/map/map

The map saved_stats is initialised to contain the following three entries:
1. key (string): "zero" mapped value (int): 0
2. key (string): "one" mapped value (int): 1
3. key (string): "two" mapped value (int): 2
And isn't there any way of creating a global object? Let's say I create new_player::player and then access that object in any function.
Because later on I will need to be accessing the info in that object and I will be changing the values of the player as he get's more exp and levels up...

If it's not possible, then how could I do that? Create the object and then access it with pointers? Sounds tedious
> And isn't there any way of creating a global object?

Yes. Declare and define it at namespace scope, a la std::cout


> Let's say I create new_player::player and then access that object in any function.

I do not understand what you are trying to do.

What does an object of type new_player represent? Or is new_player a namespace?

Is player a class? Or is it a (member) function?
new_player is a class, it represents a character inside the game. It has a map wich has the stats (strength, armor, etc.) it has a name and some functions to access the name and map as they are private.

The game represents a fighting simulator 1v1; if the player wins the fight, he gains experience and gold wich has to be saved on the map (player.stats) so what I need to do is create this player object and be able to access it whenever I want; meaning that I want to be able to access its information (stats and name) and change them if I need to.
If there is to be only one player, do you need an object of type player?

Make it a namespace, perhaps:

1
2
3
4
5
6
7
8
9
/////////  player.h ////////////

// ...

namespace player
{
    extern std::string name ;
    extern std::map<std::string,int> stats ;
}



1
2
3
4
5
6
7
8
9
/////////  player.cpp ////////////

#include "player.h"

namespace player
{
    std::string name ;
    std::map<std::string,int> stats ;
}


And then:
1
2
3
4
5
6
7
8
#include "player.h"

int main()
{
    player::name = "erik341" ;
    player::stats[ "gold" ] += 6 ;
    // etc... 
}


If the program is big, you can reduce coupling by:
defining name and stats with internal linkage (make them programatically invisible outside player.cpp),
and provide functions to access and update them.
And can't that be done with an object? Because then, what's the use of an object?
> what's the use of an object?

Objects are useful when there can be (many) instances of objects of the same type.

For instance, if your game had many players, each with its own name and its own stats, making each player a distinct object would be convenient.
Oh okok, and how would you do this with objects? Just to learn how to do it, I will probably do it with namespace :P
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/////////  player.h ////////////

// ...

struct player
{
    std::string name ;
    std::map<std::string,int> stats ;

    static player& instance( /* ... */ ) ; // public access to the only instance of player

    private: player() = default ; // constructor is visible, but not publicly accessible

    player( const player& ) = delete ; // non-copyable
};


1
2
3
4
5
6
7
8
9
10
/////////  player.cpp ////////////

#include "player.h"

player& player::instance()
{
    // Meyers singleton
    static player the_one_and_only_player ;
    return the_one_and_only_player ;
}



1
2
3
4
5
6
7
8
9
10
#include "player.h"

int main()
{
    player::instance().name = "erik341" ;
    player::instance().stats[ "gold" ] += 6 ;
    player& the_player = player::instance() ;
    the_player.stats[ "gold" ] += 8 ;
    // etc...
}
Topic archived. No new replies allowed.