IF Statements Taking Multiple Numbers for Analysis and Output

Greetings. I am working on a text-based command prompt game for fun and ran into a situation I find to be relatively difficult to solve.

I am using a simple Inventory system, int Inventory = 90000, where 9 is a placeholder and each 0 following that is a different item and it's quantity. For example, an Inventory of 91028 would include 1 Health Kit, 0 Stamina Injections, 2 Medical Packs, and 8 Boosters.

I use the same method for determining the inventory in chests and lockers that can be found while playing the game. To determine what is first in the container, I set up something like int Chest1 = 90010, Locker1 = 91001. I have hit a stumbling block in outputting what is in the chest. To the best of my knowledge, I'm using an IF statement to first analyze the container's contents, then output it in a condensed form (only showing what's available, so not including x0 of an item).

It looks something like
1
2
3
4
5
6
7
8
9
10
11
12
int Locker1 = 91001;
...
if(Locker1 > 90000){
	cout << endl << " --You find something in the locker.--" << endl << endl;
	Sleep(500);
	if(Locker1 == 91*** || Locker1 == 92*** || Locker1 == 93*** || Locker1 == 94***
			|| Locker1Contents == 95*** || Locker1Contents == 96*** || Locker1Contents == 97***
			|| Locker1 == 98*** || Locker1 == 99***){
		cout << " x" << (Locker1 - 90000) / 1000 << "  Health Kits" << endl;
		Sleep(500);
	}
...
and so on and so forth.

I would like this to output
 --You find something in the locker.--

 x1 Health Kits


The asterisks are my point of confusion, because if they were zeros I would have no way of adding additional items (as in the example where Locker1 is 91001). My question is: How do I simplify this IF statement to analyze a container's contents and then output how many of a specific item there is available? I have a theory that arrays would be most useful here, but I have trouble grasping their application when it comes to writing code like this.

A more complete view can be found below, of the entire IF statement block.



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
string LockerAction;
int Inventory = 90000, Locker1 = 91001;
...
if(Locker1 > 90000){
	cout << endl << " --You find something in the locker.--" << endl << endl;
	Sleep(500);
	if(Locker1 == 91*** || Locker1 == 92*** || Locker1 == 93*** || Locker1 == 94***
			|| Locker1 == 95*** || Locker1 == 96*** || Locker1 == 97***
			|| Locker1 == 98*** || Locker1 == 99***){
		cout << " x" << (Locker1 - 90000) / 1000 << "  Health Kits" << endl;
		Sleep(500);
	}
	else{
		cout << "";
	}
	if(Locker1 == 9*1** || Locker1 == 9*2** || Locker1 == 9*3** || Locker1 == 9*4**
			|| Locker1 == 9*5** || Locker1 == 9*6** || Locker1 == 9*7**
			|| Locker1 == 9*8** || Locker1 == 9*9**){
		cout << " x" << (Locker1 - 90000) / 100 << "  Stamina Injections" << endl;
		Sleep(500);
	}
	else{
		cout << "";
	}
	if(Locker1 == 9**1* || Locker1 == 9**2* || Locker1 == 9**3* || Locker1 == 9**4*
			|| Locker1 == 9**5* || Locker1 == 9**6* || Locker1 == 9**7*
			|| Locker1 == 9**8* || Locker1 == 9**9*){
		cout << " x" << (Locker1 - 90000) / 10 << "  Medical Packs" << endl;
		Sleep(500);
	}
	else{
		cout << "";
	}
	if(Locker1 == 9***1 || Locker1 == 9***2 || Locker1 == 9***3 || Locker1 == 9***4
			|| Locker1 == 9***5 || Locker1 == 9***6 || Locker1 == 9***7
			|| Locker1 == 9***8 || Locker1 == 9***9){
		cout << " x" << (Locker1 - 90000) / 1 << "  Boosters" << endl << endl;
		Sleep(500);
	}
	else{
		cout << "";
	}

	Locker1Selection:

	Sleep(3000);
	cout << endl << " --What would you like to do?--" << endl;
	Sleep(500);
	cout << "          1. Take the items" << endl;
	Sleep(500);
	cout << "          2. Leave" << endl;
	Sleep(500);
	cout << endl << " ";

	getline(cin, LockerAction);

	if(LockerAction == "Take the items" || LockerAction == "1"){
		Sleep(1500);
		cout << endl << " --You have taken 1 Health Kit and 1 Booster.--" << endl;

		Inventory = Inventory + 1001;
		Locker1 = 90000;

		Sleep(2000);

		goto LockerOne; // Unlisted in this example.
	}
	else if(LockerAction == "Leave" || LockerAction == "2"){
		cout << string(50, '\n');
		goto Armory; // Unlisted in this example.
	}
	else{
		cout << endl << endl << " --Invalid command. Please retry your response.--" << endl << endl;

		goto Locker1Selection;
	}
}
else{
	cout << endl << " --The locker is empty.--" << endl;
	Sleep(3000);
	cout << string(50, '\n');
	goto ArmorySelection; // Unlisted in this example.
}
...


I would like this to output
 --You find something in the locker.--

 x1  Health Kits
 x1  Boosters


 --What would you like to do?--
          1. Take the items
          2. Leave

 1 (User Input)

 --You have taken 1 Health Kit and 1 Booster.--


I know that goto is shunned by some, and that many of this code can be condensed, but I'm just looking for a solution to the IF statements before I work on the code itself. I will eventually change Locker1 to Container and use it as a call so that it only repeats once.
Last edited on
Please, do change your inventory system.
I suggest you learn about classes before you start with game development.
Thank you for the suggestion. I will start looking into Classes.
I'm also in the middle of writing a game (a roguelike) from scratch, and I'd suggest that you look at some of the tricks that were used in the original code for rogue. There are some really clever ways to store information efficiently in that code.

For example, consider:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#define HEALTHKIT 0
#define STIM 1
#define MEDPACK 2
#define BOOSTER 3
#define ITEM_TYPES 4 // dimension

typedef struct { unsigned int counts[ITEM_TYPES] ; } Inventory ;

Inventory locker ;
locker.counts = { 1, 0, 2, 8 } ;

if( locker.counts[HEALTHKIT] > 0 )
  cout << "This locker contains "
       << locker.counts[HEALTHKIT]
       << ( locker.counts[HEALTHKIT] == 1 ? " health kit." : " health kits." )
       ;


Source code for various verisons of rogue (it's generally in C) is widely available online. I am quickly finding out that those guys were way better at this than I am yet.
That was an excellent idea! Not only did it make it easier for me to see the values, but it made it easier to make checks for and output what is available.

I did run into one problem though, which is after defining the items, creating the Inventory structure, and defining variables as Inventory, the part where I would enter the numbers (1, 0, 2, and 8 from above) I get an error that says the variables must be a modifiable lvalue. I looked it up and understand that the variables must be able to hold a value. So in the above example, locker.counts = { 1, 0, 2, 8 } ; where the underlined section is giving me the modifiable lvalue error.

Am I putting the variables in the wrong place, defining them wrong?


Full code from beginning of definitions to end of error below. I have tried putting the variables before int main(), with the same result.


*Actual 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
...
#define HIMi 0
#define HI 1
#define HIMa 2
#define EMK 3
#define ArmorHead 4
#define ArmorChest 5
#define ArmorHands 6
#define ArmorLegs 7
#define ArmorFeet 8
#define Item_Types 9

typedef struct { unsigned int counts[Item_Types] ; } Inventory ;

Inventory UserInventory;
Inventory ArmoryLocker1;
Inventory ArmoryLocker5;
Inventory ArmoryLocker8;

string Name;
string Class;
string Quest1Quick = "Yes";
string AskGP1 = "No";
string CentralRoomAction;
string InfirmaryAction, NurseAction, Buy;
string ArmoryAction, LockerAction;
string OutsideAction;
string DoGP1, ActGP1;
int classskillcheck = 0; //Checks the class to assign relevant skills.
int Skill1 = 0, Skill2 = 0, Skill3 = 0; //Determines the class skills based on the selected class.
      //1/2/3-7/8/9 Is for Snipers, 11/12/13-17/18/19 is for Foot Soldiers, 21/22/23-27/28/29 is for Grenadiers.
int InfirmaryDoor = 1, ArmoryDoor = 0, CentralRoomDoor = 0, GP1Door = 1, GP2Door = 0; //Checks for locked doors.
int Credits = 1000; //Starting credits.

int Head = 0, Chest = 0, Hands = 0, Legs = 0, Feet = 0; //Armor value.

int main(){
	UserInventory.counts = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
	ArmoryLocker1.counts = { 1, 0, 0, 1, 0, 0, 0, 0, 0 };
	ArmoryLocker5.counts = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
	ArmoryLocker8.counts = { 0, 0, 0, 0, 1, 0, 1, 0, 1 };

// This code contains the opening sequence of the game, with the user's name.
...
After hours of searching for alternate answers and toying with the code, I've fixed the error by simply stuffing everything into one line.

struct Inventory { int counts[Item_Types] ; } UserInventory = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, ArmoryLocker1 = { 1, 0, 0, 1, 0, 0, 0, 0, 0 }, ArmoryLocker5 = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, ArmoryLocker8 = { 0, 0, 0, 0, 2, 0, 1, 0, 1 } ;

As far as I've been able to test it, everything works perfectly fine. Just have to tweak the code so it's more user-friendly.

Big thanks to zerobandwidth for providing the starting blocks for the overhauled Inventory system, as through the research I just did I've found it would be one hell of a long IF statement or a complex while statement to get it to work the way I was trying to do it.
Last edited on
Topic archived. No new replies allowed.