You can get rid of the branching if statements by using a data driven design.
At the base you have a loop that checks for input and using the current context evaluates the input and then changes context.
Each of those if statements becomes a 'scene' (or room or state, choose a name that has meaning for the program you are writing). Each scene has an id, a description, and a set of valid inputs and scene numbers that the result is.
You have a scene that represents the end.
You have a loop that goes:
loop until current scene is the end
Print current scene description
Ask for input
Evaluate input
Evaluate input checks the input against the valid input for the current scene and if valid sets current scene to the specified scene.
The program initialises the current scene to the first scene and then starts the loop.
So for your example (obviously incomplete, but should give you the idea of the data you'd need) you would have the scenes of:
id: 1
description: "Pick 1 , 2, or 3"
inputs: "1" => 2, "2" =>, "3" =>
id: 2
description: "pick 1, 2, 3/ some storry line"
inputs: "1" =>, "2" =>, "3" => 3
id: 3
description: " storyline...123...."
inputs: "1" =>, "2" =>, "3" =>
Usually the data would come from files.
Here is an example (This hasn't been compiled or debugged):
struct Scene
{
Scene(int id_, int description_)
: id(id_)
, description(description_)
{
}
int id;
std::string description;
std::map<std::string, int> inputToNextScene;
};
void main(int, char **)
{
std::map<int, Scene> scenes;
int ids = [1,2,3];
std::string descriptions = ["first", "second", "third"];
int nextScenes [3][3] = [ [1, 2, 3], [1, 3, 2], [1, 2, 0]];
std::string input[3] = ["1", "2", "3"];
for (int i = 0; i != 3; ++i)
{
scenes[ ids[i] ] = Scene(ids[i], descriptions);
Scene& scene = scenes.at(ids[i]);
for (int j = 0; j != 3; ++j)
{
scene.inputToNextScene[ input[j] ] = nextScenes[i][j];
}
}
int currentScene = 1;
std::string input;
while (currentScene != 0)
{
Scene& scene = scenes.at(currentScene);
std::cout << scene.description;
//Maybe put in a prompt and check currentscene against previous before printing description
std::cin >> input;
if (scene.inputToNextScene.find(input) != scene.inputToNextScene.end())
{
currentScene = scene.inputToNextScene.at(input);
}
}
cout << "The end!";
}