instead of multiple bools?

So i cant figure out how to make this efficient. I could easily just put multiple if's but that seems unethical.

So Lets say you have a player, That can pick up one thing at a time.
When he picks it up , that object equals true,
 
  toothpick = true;


but when he picks something else up , make that and/or anything else he could be holding false

1
2
3
4
5
6
7
if(toothpick == true){
toothpick = false
}
else if (phone == true){
phone = false;
}
carkeys = true;

That kind of system seems... improper.'
what method seems better fit for this?
You probably want to use an enumeration:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
enum struct Powerup
{
    None,
    Toothpick,
    Phone,
    CarKeys,
};

//...

Powerup p = Powerup::None;

//...

if(p == Powerup::Toothpick)
{
    //...
}
Last edited on
A list of some kind. This might not directly be what you want:
1
2
3
4
5
6
7
8
std::vector<std::string> items {"nothing", "toothpick", "phone", "carkeys" };

size_t mything {0};
std::cout << "I have " << items[mything] << '\n';
mything = 2; // pick
std::cout << "I have " << items[mything] << '\n';
mything = 1; // pick
std::cout << "I have " << items[mything] << '\n';
Last edited on
LB is right. If they can only hold a single item then encode it that way: have a single variable that identifies the one item that they are holding.
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
#include <iostream>

enum thing : unsigned int { NOTHING = 0, TOOTHPICK = 1, PHONE = 2, CAR_KEYS = 4, BOOK = 8, PEN = 16 /* etc. */ } ;

struct object_in_hand
{
    object_in_hand() = default ;
    object_in_hand( thing t ) : thing_held(t) {}

    bool is( thing t ) const { return thing_held & t || thing_held == t ; } // EDIT
    void replace( thing t ) { thing_held = t ; }
    void aggregate( thing t ) { thing_held |= t ; }

    private: unsigned int thing_held = NOTHING ;
};

struct player
{
    bool holds( thing t ) const { return object.is(t) ; }
    void pick( thing t ) { object.aggregate(t) ; } // pick without dropping anything
    void repick( thing t ) { object.replace(t) ; } // drop everything and then pick anew
    void drop() { object = NOTHING ; } // drop everything

    private: object_in_hand object ;
};

int main()
{
    player p ;
    std::cout << std::boolalpha
              << p.holds(NOTHING) << ' ' << p.holds(TOOTHPICK) << ' ' << p.holds(PHONE) << ' ' << p.holds(CAR_KEYS) << '\n' ;

    p.pick(PHONE) ;
    std::cout << p.holds(NOTHING) << ' ' << p.holds(TOOTHPICK) << ' ' << p.holds(PHONE) << ' ' << p.holds(CAR_KEYS) << '\n' ;

    p.repick(CAR_KEYS) ; // drop phone, pick car keys
    std::cout << p.holds(NOTHING) << ' ' << p.holds(TOOTHPICK) << ' ' << p.holds(PHONE) << ' ' << p.holds(CAR_KEYS) << '\n' ;

    p.pick(TOOTHPICK) ; // pick toothpick without dropping car keys. (one in each hand, perhaps)?
    std::cout << p.holds(NOTHING) << ' ' << p.holds(TOOTHPICK) << ' ' << p.holds(PHONE) << ' ' << p.holds(CAR_KEYS) << '\n' ;

    p.drop() ; // drop everything. also: p.repick( {} ) ;  or p.repick(NOTHING) ;
    std::cout << p.holds(NOTHING) << ' ' << p.holds(TOOTHPICK) << ' ' << p.holds(PHONE) << ' ' << p.holds(CAR_KEYS) << '\n' ;
}

http://coliru.stacked-crooked.com/a/6c21db4cf2058e74
Last edited on
p.holds(NOTHING) always yields false. Perhaps start the enumeration from a value other than zero?
> p.holds(NOTHING) always yields false.

Yes, that was rather silly of me. Thank you, booradley.


> Perhaps start the enumeration from a value other than zero?

Or keep NOTHING as zero and modify object_in_hand::is().
bool object_in_hand::is( thing t ) const { return thing_held & t || thing_held == t ; }

Aesthetically, NOTHING == 0 is pleasing.
JLBorges wrote:
Aesthetically, NOTHING == 0 is pleasing.

More importantly, given the rest of the implementation, it prevents you from doing something like holding NOTHING and holding CAR_KEYS at the same time.
Topic archived. No new replies allowed.