Creating a simple text game

I'm creating a simple text game. The code is too long, I'll just give an idea:--

You're in a house,would you like to go up ,basement or remain here.
(upstairs)
There is an apple,a door and a sword. do you want to 1)pick (up the sword) ,2)eat (the apple) or 3)open (the door)
(eat the apple)
The apple was poisoned !You died!



Stuff like that.
I just want to know two things:
1) How can 'space' be treated as valid input. Like in the above example, if the user types --"pick up the sword" the last three words will be taken as input for the next 'cin' statement.
2) how can input not be case sensitive,i.e ,so that the computer treats 'Sword','sword' ,'SWORD' and 'SWorD' the same way.

To read a complete line of text, including white space: std::getline
http://www.cplusplus.com/reference/string/string/getline/

To make input non-case-sensitive, one way is to convert every upper case character in the input to lower case.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <string>
#include <cctype>
#include <iomanip>

std::string to_lower( std::string str )
{
    for( char& c : str ) c = std::tolower(c) ;
    return str ;
}

int main()
{
    std::cout << "enter a line of text: " ;
    std::string input ;
    std::getline( std::cin, input ) ;
    std::cout << "input as entered: " << std::quoted(input) << '\n' ;

    input = to_lower(input) ;
    std::cout << "input in all lower case: " << std::quoted(input) << '\n' ;
}

http://coliru.stacked-crooked.com/a/c2073522b4ec85aa
Hi,

You could use string for picking up the sword

http://www.cplusplus.com/reference/string/string/

But still it will be more convenient to ask the user choice like this

There is an apple,a door and a sword. do you want to

1) pick up the sword
2) eat the apple
3) open the door

ENTER YOUR CHOICE (1,2,3): 3

The apple was poisoned !You died!


by asking for numbers (or single alphabets) you will save some time as a gamer and it will be better
Last edited on
programmer007 > by asking for numbers (or single alphabets) you will save some time as a gamer and it will be better

Yes. +1
i tried using cin.getline (x,99)

what it did was it took input before i even typed anything.

For example ,I used a goto statement to redirect to a if-else condition. If the user types anything other than"u","U" ,"b","B" ,"R"or"r" ,it would be regarded as invalid.

So my code is like this:

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
char x[100],y[100];

FirstStart:
cout <<"Do you wanna play a game?";<<"\n";
cin>>x;
if (x[0]=='y')
{cout<<"ok";
goto start}

else if (x[0]=='n')
{cout <<"bye";
goto end;
}

else 
{cout <<"Inavlid Entry ";
goto FirstStart;}


start:
	cout <<"You're in a house . Where would you like to go :--1)upstairs,2)basement or 3)remain here? ";
cin.getline(y,99)	;
if ((y[0]=='U')or (y[0]=='u'))
{cout <<"You chose to go upstairs"<<"\n"<<"\n";
goto upstairs;
}
else if ((y[0]=='B')or (y[0]=='b'))
{goto basement;
}
else if ((y[0]=='r')or (y[0]=='R'))

{ goto remainhere;
}
else 
{cout <<"Invalid Entry .Please try again."<<"\n"<<"\n";
goto start;
}


I have defined the labels later in the code. I actually do test only the first digit in the if-else,but if the user types in more than one word,it'll take the next two words as input for the next cin statement.
if i use cin.getline, it print "Invalid Entry " and redirects me back to the condition,after which it works fine.



Do you wanna play a game? yes
ok.You're in a house .Where would you like to go -1)upstairs,2)basement or 3)remain here? Invalid entry.Please try again.

You're in a house .Where would you like to go -1)upstairs,2)basement or 3)remain here?

I'm using Dev C++, if that makes a difference.
Last edited on
i saw your programme have many errors in if-else statement... token errors. how u gonna solve them.
Last edited on
closed account (48bpfSEw)
I would first separate the game-logic into a database.

Table Scenario:
ScenarioNo, Description
1, You are in a Room.

Table DirectionsInScenario
ScenarioNo, Direction, ScenarioNo_Next

Table PersonsInScenario:
ScenarioNo, Action, ScenarioNo_Next

etc.

Coding would be the controller of the scenarios and selected directions.

Using functions will be a lot helpful and readable than using goto statements
Last edited on
Necip
Slow down a lil bit. Can you elaborate what you mean?I'm a bit new to this.

programmer 007
I do use functions, a lot more than goto. In my actual code, I use goto statements only when a function would be ridiculously short
I would post my code, but its too long.
Last edited on
closed account (48bpfSEw)
First: Design your Storyboard with Excel (or any other database)

Next: find out how to access to the tables in Excel and control the play-flow with your code in C++
> it print "Invalid Entry " and redirects me back to the condition,after which it works fine.

There is an unformatted input cin.getline(y,99); immediately after the formatted input cin>>x;.
The new-line character remaining in the input buffer needs to be extracted and discarded before the next line can be read with getline()

More information:
http://www.cplusplus.com/forum/general/63681/#msg344406
http://www.cplusplus.com/forum/general/69685/#msg372532
Got it. So I do a cin>>anyVariable before cin.getline(x,99)?
Ok now I get an infinite loop .Here's the 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

void upstairs ()

{char z[100];
	int test;

	cout <<"There is an apple , a sword and a door. Would you like to 1)eat (the apple),    2)pick (up the sword) ,or 3)open (the door)?[Answer with 'eat','pick' or'open']"<<"\n";
cin>>test;	

cin.getline(z,99) ;
	//---apple---
	      if ((z[0]=='e') or (z[0]=='E'))
{cout <<"The apple was poisoned !"<<"\n"<<"\n";
died();
	}	
	//-----sword----
	     else if ((z[0]=='p') or (z[0]=='P'))
{cout <<"You acquired a sword"<<"\n"<<"\n";  // you get a sword.
cout <<"There is nothing else in this room . You go back downstairs."<<"\n"<<"\n";//go to start(according to user. you actually go to a code where you are equipped with the sword. everything else is same.
sword();
	}	//-----door---- 
	     else if ((z[0]=='o')or (z[0]=='O'))
{cout <<"You opened the door"<<"\n"<<"\n";
getch();

cout <<"There is nothing to be found here . You go back into the room."<<"\n"<<"\n"; // dead end. choose again.
upstairs();




and the output is:

There is an apple , a sword and a door. Would you like to 1)eat (the apple),    2)pick (up the sword) ,or 3)open (the door)?[Answer with 'eat','pick' or'open']
Invalid entry .Please try again.

There is an apple , a sword and a door. Would you like to 1)eat (the apple),    2)pick (up the sword) ,or 3)open (the door)?[Answer with 'eat','pick' or'open']
Invalid entry .Please try again.

There is an apple , a sword and a door. Would you like to 1)eat (the apple),    2)pick (up the sword) ,or 3)open (the door)?[Answer with 'eat','pick' or'open']
Invalid entry .Please try again.

There is an apple , a sword and a door. Would you like to 1)eat (the apple),    2)pick (up the sword) ,or 3)open (the door)?[Answer with 'eat','pick' or'open']
Invalid entry .Please try again.

There is an apple , a sword and a door. Would you like to 1)eat (the apple),    2)pick (up the sword) ,or 3)open (the door)?[Answer with 'eat','pick' or'open']
Invalid entry .Please try again.

There is an apple , a sword and a door. Would you like to 1)eat (the apple),    2)pick (up the sword) ,or 3)open (the door)?[Answer with 'eat','pick' or'open']
Invalid entry .Please try again.





And this continues



edit:
Got it .Finally . I used cin with int test. Tried it with cin>>ws and it worked.
What does ws stand for?Why does this specific variable work?
Last edited on
> So I do a cin>>anyVariable before cin.getline(x,99)?

We have to remove the leading white space (new line) from the input buffer. It can be done with
either std::cin.ignore( 1024, '\n' ) ; or with with: std::cin >> std::ws ;


> I'm using Dev C++, if that makes a difference.

If the Dev C++ is the old Bloodshed Dev-C++, switch to a current version. For instance
https://sourceforge.net/projects/orwelldevcpp/


To read just one character, use a variable of type char.

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>

int main()
{
       char answer ;

       std::cout <<"Do you wanna play a game (y/n)? ";
       std::cin >> answer ;

       if( answer == 'Y' || answer == 'y' )
       {
           
    start:
           std::cout << "You're in a house . Where would you like to go :--\n"
                        "1)upstairs,2)basement or 3)remain here (u/b/r)? ";
           std::cin >> answer ;

           switch(answer)
           {
               case 'U' : case 'u' :
                   std::cout << "You chose to go upstairs\n" ;
                   // ...
                   break ;

              case 'B' : case 'b' :
                   std::cout << "You chose to go to the basement\n" ;
                   // ...
                   break ;

              case 'R' : case 'r' :
                   std::cout << "You chose to remain here\n" ;
                   // ...
                   break ;

              default:
                   std::cout << "invalid choice. try again\n" ;
                   goto start ;
           }

           // ...
       }

       std::cout << "bye\n" ;
}
Last edited on
Ok ,if i used char , but what if the user entered more than one letter.
Thats why I use arrays , but the condition is put on the first letter.

The logo of my Dev C++ is the same as the one on the website you have posted.
(Sorry if this seems stupid)
> but what if the user entered more than one letter. Thats why I use arrays , but the condition is put on the first letter.

1
2
3
4
char answer ;
// ...
std::cin >> answer ; // read in the first non-white-space character
std::cin.ignore( 1000000, '\n' ) ; // extract and discard the rest of the characters in the input line 
closed account (48bpfSEw)
and this is my concept of a simple text game

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

#include <map>
#include <string>

int main() {

  typedef multimap<string, string>   MapGame;         // game relations 
  typedef map     <string, string>   MapDescription;  // object descriptions 
  typedef map     <string, string>   MapCommand;      // commands (user input)

  typedef MapGame::iterator          ItMapGame;
  typedef MapDescription::iterator   ItMapDescription;
  typedef MapCommand::iterator       ItMapCommand;


  MapGame           g;    // game relations 
  MapDescription    d;    // object descriptions 
  MapCommand        c;    // commands (user input)


  // A simple game: 
  // There is a room, a user, a key and a door. 
  // The User have to "get the key" and "open the door".
  
  g["game"] = "started";      // game state
  g["room"] = "user";         // room has user  resp. user is in room 
  g["room"] = "key";          // room has key
  g["room"] = "door";         // room has door
  g["door"] = "closed";       // door is closed (state)
  
  d["room"] = "This is the room where you woke up this morning.";
  d["door"] = "The room has a door where you can escape!";
  d["key" ] = "This is a key."
  d["user"] = "You are the user trying to find the way out."
    
  //  if command is "open door" then 
  //    check condition "user has key"
  //    check condition "door is closed"
  //      if all conditions ok 
  //        then "door is open" and "game is finished"
  c["open door"] = "[user key;door closed][door open;game finished]";
  
  //  if command is "get key" then 
  //    check condition "room has key"
  //      if all conditions ok 
  //        then "user has key", delete "room has key"
  c["get key"  ] = "[room key][user key from room]"; 


  
  while (true) {
    ItMapGame itG = g.find("game");
    if (itG == g.end())
      return -1;   // assert
    
    if (itG->second == "finished")
      return 1; // success
    
    string strInput;
    cin >> strInput;

    ItMapCommand itC = c.find(strInput);
    if (itC == c.end()) {
      cout << "What?" << endl;
      continue;
      }
  
    // PseudoCode:
    string strCommand = itC->second;
    
    // split strCommand in 2 strings, enclosed in [ ... ]
    //  e.g. strPreReq = "user key;door closed"
    //       strAction = "door open;game finished"
  
    // check the conditions in strPreReq (splitting again in : "user key" and "door closed"
    // e.g. itG = g.find("user"); 
    //      if (itG == g.end()) return -1; // assert
    //      if (itG->second != "key") { cout << "prereq. failed. user has not the key to open the door!"; continue; }    
    
    // if the code is here, all conditions were fullfilled
    // Now do strAction : split string in "door open", "game finised"
    //   itG = g.find("door");  // check assert ...
    //   itG->second = "open";  cout << "door open!" << endl;
    //   itG = g.find("game");  // check assert ...
    //   itG->second = "finished"; cout << "game finished!" << endl;
  
    }
  return 0;
  }

>Necip
My game has a wider storyline, but my coding is simple.
I have used standard functions(cout,cin) ,arrays, loops and functions.
That's all.
I would have posted my code ,but its 1000 lines long,and the max allowed is 8192.

BTW You didn't include <iostream>in the above code.
Topic archived. No new replies allowed.