Game Loop For Text-Based Adventure Game

Hey all,

I am currently in the process of making a text-based adventure game and am looking for some help with creating a game loop. I have a decent understanding of C++(Classes, Objects, Inheritance, ect.) but can't seem to come up with something that works the way I want it to.

I already have the game's "texts" set up, therefore, all I need to finish my program is the game loop. I will refer to these text-screens as "chapters" for the rest of this post to make things more clear.

I need a game loop that displays the appropriate chapter and then updates the chapter based on the user's decisions. I know I could just run the program as a series of sequences that leads the player from point A to point B, however, I want the player to be able to return to previous chapters (with an updated scenario/set of options) and thus need a game loop that can get the appropriate chapter, display it until the user makes a decision that calls for the current chapter to end, and then repeats by getting the next appropriate chapter.

I have posted two pseudo code examples below to 1) further explain my "chapters" design and 2) show you the "big picture" I have for the game's design.

Thanks for taking the time to read this post and even more thanks to those who reply!

Phasstw



Last edited on
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
Chapters:

cout << Chapter: Name_of_Chapter_Here (a.k.a location name)
if previouslyCompleted != true
  cout << Scenario: Scenario_description_here
  cout << Options: display_options user_can_choose_here
else
  cout << SecondScenario: Scenario_description_here
  cout << SecondOptions: display_options_user_can_choose_here
endif




Whole Program:

start
  Declarations
    bool displayMenu, continueLoop, quitGame, playerWon
  while displayMenu != false
    mainMenu()
  endwhile
  while continueLoop != false
    playGame()
  endwhile
  if quitGame != true
    if playerWon == true
      victoryMessage()
    endif
    displayScore()
  endif
stop
  
mainMenu()
  Declarations
    userChoice (can be string or int)
  display menu options (Play, Help, Quit)
  input userChoice
  if userChoice == Play
    displayMenu = false
  else if userChoice == Help
    helpScreen()
  else if userChoice == Quit
    displayMenu = false
    continueLoop = false
    quitGame = true
  endif
return

playGame()
  display "chapter" scenario/options
  receive input from player
  if player chooses option that results in chapter ending
    set chapter to new chapter
  else if player chooses option that updates a variable (such as health points)
    update appropriate variable (will be local to a player class and available via public function of the same)
  else if player chooses option that results in quitting the game
    continueLoop = false
    quitGame = true
  endif
return
  [code]
[/code]
closed account (N36fSL3A)
There really isn't a difference between a graphical-based game loop and a text-based game loop. They really are exactly the same. What it will look like is:
1
2
3
4
5
6
7
8
9
10
11
void Loop()
{
    Init(); // * Initialize
    while(Running)
    {
        Input();
        Update();
        Render();
    }
    Cleanup(); // Clean up allocated memory.
}


If you want the user change something, just use if and switch statements based on previous knowledge.

Example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// I want to get the user's name. First we need a User struct/class (I'll use a struct)

std::string input = "";

struct User
{
    std::string name;
    int x;
    int y;
};

User user;

void Input
{
    std::cout << "What would you like to do next\n";
    
    std::cin >> input;
}



Then just use if statements etc. to see what the user wants to do, and do it.
1
2
3
4
5
6
7
8
if(input == enter name)
{
    std::cout << "What's your name then?";
    
    std::cin >> input;
    
    user.name = input;
}
Last edited on by Fredbill30
How are you storing all of you text?

as fredbill said,

just
1
2
3
4
5
6
While ( game_on ){
DisplayInfo();
DisplayOptions();
getOption();
checkValid();
}


seems like it would work just fine?
it looks like you are trying to use c++ but where are the braces? {}
closed account (Dy7SLyTq)
as he said in the wot its pseudo code
Wow, thanks for the fast replies guys. It is greatly appreciated!

I would like to ask a couple of questions as well as answer a few:


@Fredbill30 and Paoletti301
In your while loop, you have the condition "game_on". I am assuming that is a bool variable. If so, is it a global variable? If not, how do you go about changing it when the player is ready to quit ( I am assuming I would use some sort of argument/parameter passing with functions?)

To answer Paoletti301's question about my text-storage, I will post an example of my chapter code format. In addition to this I will post a few other snippits. Maybe after seeing the way I have things set up, you all could suggest the best way to handle the loop based on my current functions/classes?

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

#include "Interactions.h"
#include "Chapters.h"

using namespace std;

void Chapters::sideOfRoad()
{
    //Object used to access interactions
    Interactions interaction;

    //Intro
    cout << "****Current Zone: Side of Road****" << endl << endl;
    cout << ">You find yourself at the side of a highway in the middle of nowhere on Halloween night. To your right side is your car. At the side of the highway is a field. To the north is a path leading up to a large home. It is getting late and you cannot help but feel you are being watched. You already know that this is going to be one shit night." << endl << endl;
    
    //Determine which set of interactions to offer/display by checking appropriate bool flag
    if (sideOfRoadComplete == false)
    {
        interaction.sideOfRoadInteractionsA();
        
    }
    else
    {
        interaction.sideOfRoadInteractionsB();
        
    }

    

}

Last edited on
This is from my Interactions class (Essentially this is what allows the user to make choices/update variables/leave current chapter)...

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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122

void Interactions::sideOfRoadInteractionsA()
{
    while (leaveZoneFlag != true)
    {
        //Prompt
        cout << ">What would you like to do?" << endl << endl;
    
        //Display Available Inspections
        cout << "----Inspections----" << endl;
        cout << ">Inspect: Car" << endl;
        cout << ">Inspect: Self" << endl;
        cout << ">Inspect: Path" << endl;
        cout << ">Inspect: House" << endl;
        cout << ">Inspect: Highway" << endl;
        cout << ">Inspect: Field" << endl;
        cout << "-------------------" << endl << endl;
    
        //Display Available Actions
        cout << "----Actions----" << endl;
        cout << ">Repeat: Zone" << endl;
        cout << ">Check: Inventory" << endl;
        cout << ">Game: Quit" << endl;
        cout << "---------------" << endl << endl;
    

        //Get Decision
        cin >> choice;
    

        //While loop used to assure a valid entry from user for variable "choice"
        while (choice != "Car" && choice != "car"
            && choice != "Self" && choice != "self"
            && choice != "Path" && choice != "path"
            && choice != "House" && choice != "house"
            && choice != "Highway" && choice != "highway"
            && choice != "Field" && choice != "field")
        {
            cout << "Invalid Entry. Please, try again." << endl;
            cin >> choice;
        }
    
        //Read and Print choice results///////////////////////////////////////////////////////////////////////////////////////
        if (choice == "Car" || choice == "car")
        {
            //Display Choice Title
            cout << "----Car----" << endl;
            cout << ">Your car, given to you by your brother ..." << endl << endl;
        
            cout << ">It’s out of gas. You ran out right in front of this path leading up to the house." << endl;
            cout << "-----------" << endl << endl << endl;
        
            //Pause
            Interactions::pauseThenContinue();
        }
        if (choice == "Self" || choice == "self")
        {
            cout << "----Self----" << endl;
            cout << ">You look as you always have. What were you expecting, you’d be some body-builder or something? Get real, fatty." << endl;
            cout << "------------" << endl;
        
            //Pause
            Interactions::pauseThenContinue();
        }
        if (choice == "Path" || choice == "path")
        {
            cout << "----Path----" << endl;
            cout << ">It is a basic gravel path, overgrown from disuse." << endl;
            cout << "------------" << endl << endl;
            
            //Offer player chance to use path (leads to next zone)
            cout << "----Actions----" << endl;
            cout << "Use Path to: Leave" << endl;
            cout << "Do not use: Path" << endl;
            cout << "---------------" << endl;
            
            //Get input from user to see if they want to leave to new zone or remain in current zone
            cin >> choice;
            
            while (choice != "Leave" && choice != "leave" && choice != "Path" && choice != "path")
            {
                cout << "Invalid Input. Please, try again." << endl;
            }
            if (choice == "Leave" || choice == "leave")
            {
                //Get new zone, Enter new zone
                leaveZoneFlag = true;
            }
            if (choice == "Path" || choice == "path")
            {
                cout << ">You decide to stick around a while longer..." << endl;
            }
            
            //Pause
            Interactions::pauseThenContinue();
        }
        if (choice == "House" || choice == "house")
        {
            cout << "----House----" << endl;
            cout << ">Looming in the distance is a large building that seems to be the color black. Right into your soul, it sends vibes of unease and some other unknown feeling . . . You can’t quite place your finger on it." << endl
            << endl;
            cout << ">Maybe you should walk up the path to take a closer look..." << endl;
        cout << "-------------" << endl;
        
        //Pause
        Interactions::pauseThenContinue();
        }
        if (choice == "Highway" || choice == "highway")
        {
            cout << "----Highway----" << endl;
            cout << ">A boring road. You haven’t seen anyone on it for hours since driving, and you’re sure no one’s going to come by right now." << endl;
            cout << "---------------" << endl;
        
            //Pause
            Interactions::pauseThenContinue();
        }
        if (choice == "Field" || choice == "field")
        {
            cout << "----Field----" << endl;
            cout << ">The field of tall grain sways quietly in the sunset." << endl;
            cout << "-------------" << endl;


Note that it is only when the player request to use the path to leave that the current chapter ends.
Last edited on
The way I am handling the "return to previous chapters" idea is as follows:

The game loop calls a Chapter function which displays the scenario/intro text for the chapter and then checks a bool flag to see which Interaction function to call.

The interactions function allows users to make decisions, update variables based on decisions, and then end the loop once the user selects the appropriate option (in the case above, "path" is the option that leads to the chapter ending. However, before the interactions function ends I would like it to pass an argument to another function that tells the game loop which chapter to call next.

Last edited on
Have you ever checked out functions like toupper()?

http://www.cplusplus.com/reference/cctype/toupper/?kw=toupper

making the input all uppercase would make comparisons alot nicer to look at and code. ive personally never used that function, but nevertheless it would be quite easy to implement you own version of it.

as for the loop, you just need to mess around and see what works best
I have never heard of toupper(). Thanks! I will give it a try. It would clean my code up a lot.

I will mess around with the game loop and see if I can get something working. Thanks for all the help.

I have one last questions, what is the "running" condition inside the while loop you all posted. As in, what kind of variable is it? Why is it not: while (Running == true)?
closed account (Dy7SLyTq)
because a loop will execute only if resolved to true so running == true resolves to true and so does running.
Last edited on
a while loop checks whether its condition is true, if you but a boolean in it that is true, that while loop will run until that boolean is false.

1
2
3
bool condition = true;
while ( condition ) {} //loops while condition is true
while ( !condition ){}//loops while condition is false 


Thanks! You all are very helpful!
Topic archived. No new replies allowed.