CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 15 of 24

Hybrid View

  1. #1
    Join Date
    May 2012
    Posts
    57

    Which container to do what I need?

    Sorry for this long post but I don't know how to explain it in a shorter form.

    What container allows fast finding of a specific item -and- also allows scanning by using iterators that can be incremented in a "for" loop? My data:

    Code:
    Number of players:  4
    
    BetInfo for each player:
    ---------------------------
    Passline:  betAmount, coordX, coordY
    No Pass :  betAmount, coordX, coordy
    Field   :  betAmount, coordX, coordY
    Place4  :  betAmount, coordX, coordY
    Place5  :  betAmount, coordX, coordY
    
    --- continues for about 50 different bets ---
    QUESTION 1:
    When dice is rolled, the diceSum dictates which bet amount I need to access. For instance, if the diceSum is a 2 on the first roll, the Passline bet loses for all 4 players so I need to access the Passline betAmount for each player to see of a bet was made (betAmount > 0). Then handle it.

    (Player1 > Passline > betAmount), then
    (Player2 > Passline > betAmount), then
    (Player3 > Passline > betAmount), then
    (Player4 > Passline > betAmount)

    Which container will provide fast access to the betAmount for each player? Note that I have to do also do this for other bets like NoPass bets, Field bets, oneRoll2 bets, anyCrap bets, Horn bets and World bets to pay each player.

    ----------

    QUESTION 2:
    When a shooter 7's out, I need to pay some bets then zero all bets on the table for all 4 players. When I zero all bets on the table for 4 players, I would like to do it using iterators like in a "for" loop. So the container needs to be able to do this also. Which container can do #1 above and #2?

    ----------

    Hope my explanation is clear enough. I think I need to use a 3 dimensional array to hold all of the BetInfo.

    50 rows will be for each bet. (approximate)
    3 columns will be for betAmount, coordX, coordY.
    4 layers will be for the 4 players.

    Code:
    enum {Passline, NoPass, Field, Place4, Place5, ...etc.};   (bet-name)
    enum {BetAmount, CoordX, CoordY};                          (bet-data)
    enum {Player1, Player2, Player3, Player4};                 (player-number)
    
    int betInfo[bet-name][bet-data][player-number]

    But is there a better container to use to hold all of the betInfo, yet do what I need?

    Thanks,
    Raptor
    Last edited by raptor88; October 16th, 2012 at 11:16 PM.

  2. #2
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: Which container to do what I need?

    almost all containers allow you to iterate over the items. So this is probably a moot requirement. What cannot always be guaranteed is specific ordering or indexed access.

    "Fast finding" would mean you need a std::map or something like this.

    If iterating (statistically over half the items) in the container is enough speed to qualify for "fast finding", then any container will do. and you can use the std::find() algorithm to do the searching.

  3. #3
    Join Date
    May 2012
    Posts
    57

    Re: Which container to do what I need?

    Quote Originally Posted by OReubens View Post
    "Fast finding" would mean you need a std::map or something like this.
    I can envision using a std::map for one player. In that case, the key could be the bet name like "Passline", "NoPass", "Field", etc. The mapped value could be a pointer to a struct which contains the "betAmount", "coordX" and "coordY" integer values.

    How would I set up the map for 4 players where I can iterate through the 4 players in a loop?

    Thanks,
    Raptor (coding my first C++ program)

  4. #4
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Which container to do what I need?

    Quote Originally Posted by raptor88 View Post
    The mapped value could be a pointer to a struct which contains the "betAmount", "coordX" and "coordY" integer values.
    As S_M_A stated, you should be striving to use either value semantics (no pointers), or if pointers are needed, smart pointers.
    Code:
    #include <map>
    #include <string>
    #include <iostream>
    
    struct SomeStruct
    {
       int x;
       int y;
       int z;
       SomeStruct(int xVal=0, int yVal=0, int zVal=0) : x(xVal), y(yVal), z(zVal) {}
    };
    
    typedef std::map<std::string, SomeStruct> StringToStructMap;
    
    using namespace std;
    
    int main()
    {
       StringToStructMap sMap;
       sMap.insert(make_pair("Joe", SomeStruct()));
       sMap.insert(make_pair("Bob", SomeStruct(1,2,3)));
       sMap.insert(make_pair("Sam", SomeStruct(4,5,6)));
    
       StringToStructMap::iterator it = sMap.begin();
       while (it != sMap.end() )
       {
           cout << it->first << " -> (" << it->second.x << "," << it->second.y << "," << it->second.z << ")\n";
           ++it;
       }
    }
    There is no pointer usage in the code above.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; October 18th, 2012 at 11:48 AM.

  5. #5
    Join Date
    May 2012
    Posts
    57

    Re: Which container to do what I need?

    Quote Originally Posted by Paul McKenzie View Post
    As S_M_A stated, you should be striving to use either value semantics (no pointers), or if pointers are needed, smart pointers.
    Code:
    #include <map>
    #include <string>
    #include <iostream>
    
    struct SomeStruct
    {
       int x;
       int y;
       int z;
       SomeStruct(int xVal=0, int yVal=0, int zVal=0) : x(xVal), y(yVal), z(zVal) {}
    };
    
    typedef std::map<std::string, SomeStruct> StringToStructMap;
    
    using namespace std;
    
    int main()
    {
       StringToStructMap sMap;
       sMap.insert(make_pair("Joe", SomeStruct()));
       sMap.insert(make_pair("Bob", SomeStruct(1,2,3)));
       sMap.insert(make_pair("Sam", SomeStruct(4,5,6)));
    
       StringToStructMap::iterator it = sMap.begin();
       while (it != sMap.end() )
       {
           cout << it->first << " -> (" << it->second.x << "," << it->second.y << "." << it->second.z << ")\n";
           ++it;
       }
    }
    There is no pointer usage in the code above.

    Regards,

    Paul McKenzie
    That is really helpful Paul. I'll try to figure out how to use that for 4 players. Maybe an array to hold the maps.

    Thanks!
    Raptor

  6. #6
    Join Date
    May 2012
    Posts
    57

    Re: Which container to do what I need?

    Quote Originally Posted by Paul McKenzie View Post
    struct SomeStruct
    {
    int x;
    int y;
    int z;
    SomeStruct(int xVal=0, int yVal=0, int zVal=0) : x(xVal), y(yVal), z(zVal) {}
    };

    typedef std::map<std::string, SomeStruct> StringToStructMap;

    using namespace std;

    int main()
    {
    StringToStructMap sMap;
    sMap.insert(make_pair("Joe", SomeStruct()));
    sMap.insert(make_pair("Bob", SomeStruct(1,2,3)));
    sMap.insert(make_pair("Sam", SomeStruct(4,5,6)));
    Hi Paul,

    Going over your code, that's an extremely clever method of setting up the structure so it can be initialized in the format you show in main. I Googled for over 2 hours and could never find an explanation or even an example to match your method. Could I burden you to explain it to me (and other lurkers)?

    How does this statement work?

    Code:
     SomeStruct(int xVal=0, int yVal=0, int zVal=0) : x(xVal), y(yVal), z(zVal) {}
    1. Why does nesting SomeStruct (the same name) in SomeStruct make it work?

    2. I learned that the single colon signifies the start of an initialization list. But why does x(xVal) work instead of x=xVal? IOW, how did you figure out to put the xVal in parenthesis?

    3. How did you figure out that the {} is needed at the end of the statement without a semicolon';' ?

    If you know of a link that explains it, please post it.

    Your code is better than most books,
    Raptor

  7. #7
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Which container to do what I need?

    Quote Originally Posted by raptor88 View Post
    How does this statement work?

    Code:
     SomeStruct(int xVal=0, int yVal=0, int zVal=0) : x(xVal), y(yVal), z(zVal) {}
    1. Why does nesting SomeStruct (the same name) in SomeStruct make it work?
    That is a constructor. Yes, even structs can have constructors.
    2. I learned that the single colon signifies the start of an initialization list. But why does x(xVal) work instead of x=xVal? IOW, how did you figure out to put the xVal in parenthesis?
    Since the call is a constructor, all you need to do is to look up how to write constructors that initialize member variables in the initialization list.
    3. How did you figure out that the {} is needed at the end of the statement without a semicolon';' ?
    The entire constructor function body is inlined into the struct. That is just an empty function block, no different than doing this:
    Code:
    SomeStruct(int xVal=0, int yVal=0, int zVal=0) : x(xVal), y(yVal), z(zVal) 
    {
       // a do nothing constructor body
    }
    If you know of a link that explains it, please post it.
    Well, as ahoodin pointed out, that "link" is a C++ book or good tutorial on the C++ language. Nothing that I wrote is out of the ordinary, i.e. every C++ vetaran that responds to you on this board will understand that code right away.

    Regards,

    Paul McKenzie

  8. #8
    Join Date
    Oct 2006
    Location
    Sweden
    Posts
    3,654

    Re: Which container to do what I need?

    Try forgetting that pointers exists when using STL containers. The containers are capable of handling new/delete for you so you neither have to worry about memory leaks nor invalid pointers. In this case declaring your map as
    Code:
    #include <map>
    std::map< 'key', 'Some struct' > betInfo;
    would probably meet what you need.
    See http://cplusplus.com/reference/stl/map/
    Debugging is twice as hard as writing the code in the first place.
    Therefore, if you write the code as cleverly as possible, you are, by
    definition, not smart enough to debug it.
    - Brian W. Kernighan

    To enhance your chance's of getting an answer be sure to read
    http://www.codeguru.com/forum/announ...nouncementid=6
    and http://www.codeguru.com/forum/showthread.php?t=366302 before posting

    Refresh your memory on formatting tags here
    http://www.codeguru.com/forum/misc.php?do=bbcode

    Get your free MS compiler here
    https://visualstudio.microsoft.com/vs

  9. #9
    Join Date
    May 2012
    Posts
    57

    Re: Which container to do what I need?

    Quote Originally Posted by S_M_A View Post
    Try forgetting that pointers exists when using STL containers. The containers are capable of handling new/delete for you so you neither have to worry about memory leaks nor invalid pointers. In this case declaring your map as
    Code:
    #include <map>
    std::map< 'key', 'Some struct' > betInfo;
    would probably meet what you need.
    See http://cplusplus.com/reference/stl/map/
    Thanks much for your help,
    Raptor

  10. #10
    Join Date
    Mar 2001
    Posts
    2,529

    Re: Which container to do what I need?

    Paul's code is great, but you also aren't looking at the right books.
    ahoodin
    To keep the plot moving, that's why.

  11. #11
    Join Date
    May 2012
    Posts
    57

    Re: Which container to do what I need?

    Quote Originally Posted by ahoodin View Post
    Paul's code is great, but you also aren't looking at the right books.
    OK, am more than willing to buy another C++ book. Please tell me the name of a book that explains what Paul did with his constructor statement within a struct. None of my 6 or 7 C++ books nor hours of Googling even mention doing anything like that, let alone how to do it.

    EDIT: No need for another book info. I understand Paul's code pretty well now.

    Thanks,
    Raptor
    Last edited by raptor88; October 18th, 2012 at 01:59 PM.

  12. #12
    Join Date
    Oct 2006
    Location
    Sweden
    Posts
    3,654

    Re: Which container to do what I need?

    Both yes and no. The code you show produce the same result as Paul's but it cause the created object first to be default initialized and then assigned new values in the constructor body.
    Debugging is twice as hard as writing the code in the first place.
    Therefore, if you write the code as cleverly as possible, you are, by
    definition, not smart enough to debug it.
    - Brian W. Kernighan

    To enhance your chance's of getting an answer be sure to read
    http://www.codeguru.com/forum/announ...nouncementid=6
    and http://www.codeguru.com/forum/showthread.php?t=366302 before posting

    Refresh your memory on formatting tags here
    http://www.codeguru.com/forum/misc.php?do=bbcode

    Get your free MS compiler here
    https://visualstudio.microsoft.com/vs

  13. #13
    Join Date
    May 2012
    Posts
    57

    Re: Which container to do what I need?

    Quote Originally Posted by S_M_A View Post
    Both yes and no. The code you show produce the same result as Paul's but it cause the created object first to be default initialized and then assigned new values in the constructor body.
    Guess I need to do more research since I really don't understand why the code I showed works different from Pauls. Thanks for pointing that out.

  14. #14
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Which container to do what I need?

    Quote Originally Posted by raptor88 View Post
    Guess I need to do more research since I really don't understand why the code I showed works different from Pauls. Thanks for pointing that out.
    There is a difference. The code I showed you initializes the member variables, i.e. as soon as the members of the struct are created, those members are initialized to a value. Note that this occurs outside (before) the constructor body, emphasizing the fact that those members have initial values before the constructor body is invoked.

    Your version doesn't give the members any values until the constructor body is invoked. You can see the difference if you place a breakpoint on the first line of the constructor. You will see that those members have values with my method, while with your method those variables have undefined or junk values.

    Even though initialization list isn't required in this scenario, in other scenarios you are required to use the initialization list. For example, if the struct or class has members that cannot be default-constructed, or if the struct is derived from a struct/class that cannot be default constructed, you're required to use an init-list.
    Code:
    class A
    {
       public:
         A(int x);
    };
    
    class B : public A
    {
       B() { } // error
    };
    The fix:
    Code:
    class A
    {
       public:
         A(int x);
    };
    
    class B : public A
    {
       B() : A(0) { } // ok now
    };
    Regards,

    Paul McKenzie

  15. #15
    Join Date
    May 2012
    Posts
    57

    Re: Which container to do what I need?

    Quote Originally Posted by Paul McKenzie View Post
    There is a difference.
    ... snip ...
    Thanks for clearing that up Paul. Learned a lot from this thread. I did plan to only use your method in the future since it's easier to type but now I know it also works better.

    Thanks,
    Raptor

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured