The Cursed Forest: WIP console game

Pages: 12
I've been working on in this for a while, it's currently around 515 lines long.
The game is divided into chapters, each chapter has a different gameplay style:
1=Correct option; 2=Puzzles; 3=Labyrinth and/or Interactive(?); 4=Mystery; 5=Fighting(?).

The game is currently Work in Progress, in its 0.5 version with full Chapter 1 and half of Chapter 2. It's full of ASCII images, good ones. I don't want to ruin the story for everyone, so I'll show you <only> 3 images:

http://img706.imageshack.us/img706/4/tcf1.png

http://img259.imageshack.us/img259/6548/tcf2.png

http://img528.imageshack.us/img528/491/sinttuloze.png


You can download the game here: http://bit.ly/TCF_Samrux
The code in .cpp(also readable by any text editor): http://bit.ly/TCF_Samrux_Code

I need a better name for it. Suggestions accepted.

Please comment.
Last edited on
Well, you have way too many gotos...and they aren't even named very well. You could probably do with less global variables as well, although at least those are well named.

As for your actual code, sometimes your indentation is really unhelpful in understanding what the code is doing. Sometimes you have like if statements within if statements all crammed onto 1 line for some reason and I can't tell what you are trying to do there.

Finally, I think Chapter 1 in the game is annoying, to say the least. It always irks me when entire parts of games are basically guide dang its. It's not like you can even go a different path and have something else happen, you just insta-lose.

The actual output looks pretty enough though, so that's fine. The code itself just is really hard to follow (mainly due to the large amounts of gotos).
I would make a lot of functions into classes, but the problem is calling them. I want to make the code in order, first the global variables and functions (All the gobal variables are completelly necesary), then the main menu, then chapter 1 part 1, then chapter 1 part 2, then chapter 2 etc, wich is very hard if not impossible to do with lots of classes and functions. I like goto because it's extremely easy to code and plan, and with code::blocks and some other compilers it's very easy to rigth click and go to the label declaration.


I think the code is'nt hard to read, and i make the labels with short names (C1_P3 for Chapter 1 label/part 3) to make the code to fit better in their lines.

Finally, i sometimes put if/else in a single line because they're easy and/or short things, and i don't want to use 4 lines in a thing that can be done in 1. Yeah, i will probably re-order it, only to make the code easier to read for other people.

Now that i think it, some people say chapter 1 is way too easy, and others say it's very annoying and hard to complete. I have one thing to say: It's about luck. The gameplay style for chapter 1 is choosing the correct option, it's the try-and-fail part of the game, and it's very short. I won't change it.
Last edited on
I want to make the code in order, first the global variables and functions (All the gobal variables are completelly necesary), then the main menu, then chapter 1 part 1, then chapter 1 part 2, then chapter 2 etc, wich is very hard if not impossible to do with lots of classes and functions.


I disagree. Choice and x are a useless global variables; they should be temporaries made when you need them. Exit shouldn't be a global variable. The finished chapter doesn't need to be a global variable, and the chapter conditions definitely don't need to be.

Honestly, with this kind of a game the only thing you really need is to know where the player currently is. If you want to keep info like which chapters the player has completed, just put that in a class and pass that around.

I just noticed you call main() in some of your functions. You shouldn't be doing that. You could easily recurse too much and run out of stack space.
Well, yeah! It's completely true! x and choice are useless, i will put choice in the switch function and declare x when i need it. EDIT: I can't... but i'll put it at the starting of the functions.

but wait, you said more. Well, i need the Exit as global to use it inside chapters and recognize it in main.

I need the chapter conditions as global functions for small things that change if i did 'x' thing or not. Currently, if you climb the tree and see the temple, when you get there it'll tell you it's the building you saw from the top of the tree. If you choosed only to see what's in the hole (wich is needed for the other chapters) and to examine the blood instead of climbing the tree (Condition1 && (Condition2 || Condition3) is needed to continue) it'll obviously not say that.
As potion creating is the second part of chapter 2, in chapter 4 (and maybe chaoter 3 too) the options you take while mixing ingredients will affect slightly and maybe even change a part of the gameplay.

The finished chapters will be used when i learn completely how to store variable data in external files, the currently chapter choosing is a debug feature wich will be only possible to do if you already finished at least chapter 1, and if you finished a chapter the next will be unlocked in the chapter selection, it won't show you the name of it until you finish it to avoid a little bit of spoiling.

How to do that? as far as i know i an't put a variable in a class and make it to work when i want. Because i'm still VERY 'noob', please explain me the basics of this to me.

i only call main in the death screen when you choose the chapter selection... How to do that without calling main? another void with the chapter selection? No, i need the exit feature of return 0 (Yeah, it sounds very stupid, but it's the only way i know to close, at least wthout non-conventional libraries, and needs to be in main.) And the mian would be extremely short, wich in some way annoys me... DK why.



EDIT: I put the lock class inside of the chapter 2 function, and i can't put the lock variables anywhere to work between all the lock functions, so i had to put it as a global variable just before chapter 2. It gives me an error if i put them directly into the chapter 2 function or declare it at the starting of the class (wich almost obviously won't work).
Last edited on
I need the chapter conditions as global functions for small things that change if i did 'x' thing or not. Currently, if you climb the tree and see the temple, when you get there it'll tell you it's the building you saw from the top of the tree. If you choosed only to see what's in the hole (wich is needed for the other chapters) and to examine the blood instead of climbing the tree (Condition1 && (Condition2 || Condition3) is needed to continue) it'll obviously not say that.
As potion creating is the second part of chapter 2, in chapter 4 (and maybe chaoter 3 too) the options you take while mixing ingredients will affect slightly and maybe even change a part of the gameplay.


If you want that kind of information, your first idea should be "pass an argument with it" not "make a global variable."

but wait, you said more. Well, i need the Exit as global to use it inside chapters and recognize it in main.


This is exactly the kind of situation where you want to pass things as arguments. The function needs information, so you should give it the information, not make the entire program able to edit it.

How to do that? as far as i know i an't put a variable in a class and make it to work when i want. Because i'm still VERY 'noob', please explain me the basics of this to me.


Then you should probably go look up classes and look for a tutorial. Play around with them a bit and get a feel for what they are supposed to used for, then think about how you can use them to clean up the game.

i only call main in the death screen when you choose the chapter selection... How to do that without calling main? another void with the chapter selection? No, i need the exit feature of return 0 (Yeah, it sounds very stupid, but it's the only way i know to close, at least wthout non-conventional libraries, and needs to be in main.) And the mian would be extremely short, wich in some way annoys me... DK why.


IMO, the simplest way would have that function return a value indicating what the user wanted to do.

And main being short is fine, heh.
Read again my last post (because i edited it) before this one and answer both.

First, i know how to use classes.

So you want me to use functions for the exit, completed chapter and choices. How. The. Heck? How can i make it with arguments to know if X is Y or not? I'm sure it'll not work normally as if it was a global variable.

FTW, can you think of a better name for this?
Last edited on

EDIT: I put the lock class inside of the chapter 2 function, and i can't put the lock variables anywhere to work between all the lock functions, so i had to put it as a global variable just before chapter 2. It gives me an error if i put them directly into the chapter 2 function or declare it at the starting of the class (wich almost obviously won't work).


You should probably define the lock class in a separate header/source combo. I can't really tell where the error is since the source code is hard to follow.

However, looking just at the class, it seems you have designed it badly. It is coupled way too tightly with your game. I'd probably make the lock class just have some functions like display, modify, and let the chapter function deal with calling the modify functions and stuff.

First, i know how to use classes.


Knowing how to use them is different then knowing what to use them for. You seem to have the right idea but you are thinking too much about how your game needs to use it I think.

So you want me to use functions for the exit, completed chapter and choices. How. The. Heck? How can i make it with arguments to know if X is Y or not? I'm sure it'll not work normally as if it was a global variable.


Here is a short example for how I might lay out some things:

1
2
3
4
5
6
7
8
struct Player {
    Player(); //implement this with whatever you want really
    int score;
    //the progress variable is a number that represents the "state" of the player in the chapter
    //i.e. 1 could mean start, 2 could mean picked option 1 at start, 3 could mean picked option 2 at start, etc.
    int current_chapter, chapter_progress;
    //...
};


1
2
3
4
5
6
7
8
9
10
11
12
13
int main() {
    bool continue = true;
    Player the_player;
    do {
        switch(the_player.chapter) {
            case 1: continue = Chapter_One(the_player); break;
            //...
        }
    } while(continue);
    std::cout<<"\nGame Over.\n"
        "Your score is: "<<the_player.score;
    std::cin.get();
}


FTW, can you think of a better name for this?


Not really...I'm bad with names. -_-
Last edited on
In the spanish forums the same happened. A lot of suggestions wich meant that my game is very bad made and i need to remake all the code with pro things. I think it's fine as i have it now. What is the problem with goto? It's a jump in the code wich is proven to not affect the performance. Wich is the problem with a global variable? It's just a little bit more space in the memory, and who cares? This is a 400kb game. In a batch file. Windows 95 could run this perfectly.

If i can use a label to go to X place instead of loops or functions inside a class, then i'll use a label. If i can use a global variable instead of structures and functions then i'll use the global variable. I know the extremely basics of C++ and i will stick with what i know until i need more complex programs.

With complex programs and games it'll be obviously harder to make and i'll need everything you say. But remember, this is a simple plain text game.

I know i need to learn more and stop angrying with everything they tell me, but there are 5 years left until i reach university and start making serious stuff. Thanks for your help, but i just noticed that i'll probably not learn more like this. I'll search videos in youtube.

Have a good day.
Last edited on
You're looking at C++ all the wrong way. I completely agree with the advice that firedraco has offered. C++ shouldn't be about avoiding features that'll help you in the long run, but about embracing them and learning more to make your program more efficient. Granted, goto/labels don't affect performance, but it greatly affects readability. I refuse to look over anyone's code that relies heavily on labels.

There is also several reasons why global functions are bad, but the one that you should focus on the most is what happens when you decide to change one of the variables. It will have a ripple affect through every single function. For example, you decide you want to change choice to an int instead of a char. This isn't a huge deal, for now, but later on, you decide to make it a string ("Yes", "No" "Chapter 1", etc.). All of your switch statements are now broken and you're stuck trying to fix plenty of errors (or just giving up on implementing some cool new feature, which is more likely to end up happening).

The goto/labels you have are fairly ineffective. Why not just implement a while loop or something else? Also, I'd highly suggest firedraco's idea of creating a character class to store all of the necessary information. You could then easily create a save file that you can read/write to very easily.

Programming shouldn't revolve around the here and now, but you should be able to plan out what you might want to do in the future. Imagine, you decide you come back to this in 2 months after you know all about this OOP stuff and you look at your code and decide it's not even worth trying to implement since you would have to change so much. What happens when you learn an API or a toolkit that integrates graphics and an actual user interface? Are you just going to abandon the game altogether? Give up on learning new things because it's too hard to implement?

Not trying to be rude, just hopefully opening your eyes for reusability. That is part of the bigger picture of C++.
The basic problem is that i don't understand anything. I don't know if i am very stupid, too immature (?), the people explains it badly, or i need to start from the beggining searching things like "C++ for dummies" (But i actually learned C++ in videos, and the person wich made them stoped making them...)

I really want to learn more, but i can't.

About the while loops, no. It is'nt and will never be the same. NEVER. It will just become a lot of whiles everywhere, and won't be as flexible as a goto. What if i want to go to a completely different spot in the middle of the chapter?
Last edited on
The basic problem is that i don't understand anything. I don't know if i am very stupid, too immature (?), the people explains it badly, or i need to start from the beggining searching things like "C++ for dummies" (But i actually learned C++ in videos, and the person wich made them stoped making them...)


I would probably suggest just rewriting this entire game, trying to do it the way we are suggesting. It'll help you learn how to write programs and it'll make it much more readable.

I used to use lots of gotos and globals in my programs too in the beginning, but then I realized it just became a huge mess and was pretty much impossible to add or remove features without breaking everything.

About the while loops, no. It is'nt and will never be the same. NEVER. It will just become a lot of whiles everywhere, and won't be as flexible as a goto.


That's exactly why you shouldn't use gotos. You can goto somewhere from (almost) anywhere; you have can't assume anything about the state of the program when you are at a goto statement. If you instead have functions with arguments, then you can more easily validate information and deal with state.

What if i want to go to a completely different spot in the middle of the chapter?


In my system, you'd just update one or two variables inside the player class and you'd be done.
Give me an example, but more than likely, your chapters should contain functions for each area as well. Labels are seriously a horrible thing to use. There is a time and place for them, and you don't completely abuse them (I've seen much worse) but the labels that I did see would have been much better off with whiles.

As for learning, I'd suggest going to the public library (if you have one) and sitting down and reading a few pages from each of the C++ books they have (try to find the ones that look like they're from this century, 2000+) and see which ones you like. If you find atleast one that is easy to understand, either keep reading it, check it out and read it at home, or look into buying it. If you don't have a library, or there isn't one close by, surf the internet. I suggest starting here (the tutorial on this site is far from perfect, but it does serve as a great reference if you know the language, and also as a good teaching tool if you're unsure about something.) and then look at random posts, try to learn things. I will read just about every post on the forums to see if something is covered that I didn't know before. I learned about pointers through someone else's post, started my own post (to keep from hijacking theirs) and learned a great deal more.

Also, what techniques do you learn from the best? Visual? Hands-on? Verbal? Find which one is easiest to learn from and try to stick with that. If you find that you can read and absorb the knowledge right out of the book (a skill a lot of programmers lack) pick up several books and reread them as much as you need to. If you find it's easier to view code and just understand it, look everywhere for code (there is a lot of code online that is open source and in C++, aside from that, anything posted on the forums is open source as well). Need4Sleep created a thread about programs to try if you're stuck for ideas. I highly suggest them (there is also an answer sheet (of other poster's responses) that you can use if you're completely stuck.). If you find you learn best from being told how to program, you're pretty much out of luck if your school doesn't offer it, if you can't take any programming classes, or if you don't know anyone that will verbally explain the language to you.

The flexibility is there, you just need to explore it.

(Sorry about the long, complicated sentences, I get lost in thoughts sometimes.)
In my system, you'd just update one or two variables inside the player class and you'd be done.

Ok. Slowly, calmly and precisely explain to me everything you want to me to learn and use sending me a private message. Then everyone will be happier. And maybe rewriting 500 lines of code won't be neccesary at all.

If you find you learn best from being told how to program, you're pretty much out of luck if your school doesn't offer it, if you can't take any programming classes, or if you don't know anyone that will verbally explain the language to you.

In Chile, the only way of learning C++ is in an university or in the internet. I think in other countries they teach programming in school too if the student chooses to.
Last edited on
Books still exist in Chile, you can purchase them, but I don't feel that's going to be any easier than an online tutorial. A good tutorial coupled with a good forum and you'll learn everything you need to. You English is very good (is it your second language?) so I feel you shouldn't have too many issues picking up another language. You might struggle with some more technical terms in the language, but it's about finding someone who can explain it to you in a different way. Crossing one language barrier is hard enough, but you have two that you must tackle.

It might be beneficial to start with conditional statements and loops since you seem to understand basic variables and data types as well as input/output. Once you learn the loops a little more, move on to functions and learning the different types of parameters and return features of functions (some things just aren't covered by tutorials, but that's why you're a member here). The next thing should be OOP, such as classes and structs (essentially the same thing).

All while doing this you should be trying to look up examples, read the examples supplied with the tutorial, and creating your own from what you learned. If you stumble across something that doesn't make sense or doesn't work the way you believe it should, create a new thread and you'll get a personalized answer (typically explaining the reasons fairly well, if not exceptionally well in some cases) and maybe another example of how it will work, or how to get your code to work properly.

Programmers typically enjoy helping other programmers since we tend to go unappreciated in the world. No matter how small, we typically try to help others out.
Your English is very good (is it your second language?)

Yes. My first language is spanish. But i think i can pretty much understand anything in english about programming without problems.

It might be beneficial to start with conditional statements and loops since you seem to understand basic variables and data types as well as input/output. Once you learn the loops a little more, move on to functions and learning the different types of parameters and return features of functions (some things just aren't covered by tutorials, but that's why you're a member here). The next thing should be OOP, such as classes and structs (essentially the same thing).

If you looked at the code, you probably noticed that there are if/elses everywhere and there's a class with the Chapter 2 Lock functions. I still need to learn more about classes, tough. Another problem is the 'for' loops, but it's very easy and i'll see the video explaining it again.
Last edited on
There is no question about if you know how to use the if/else conditions, but I would still recommend looking them over again. Same goes for functions. I believe you know what a function looks like, and how to call one, but do you understand any function you might run across? I'm sure I could dig for about 30 minutes and find a function that would make you ask what it does. It would be most beneficial to at least understand the concept of reference parameters and return values. As for classes, I have no idea what you know with them. I'm still learning classes and I started learning them, oh, 6 or 7 years ago.

I'm not saying that your program is bad, but it's something I'd see on a graphing calculator, not in a C++ Code Gallery. Your head is in the right spot (with the dedication anyways), you just need to get your coding knowledge to the same level. You'd be able to create programs that you'd be proud of by yourself and would be praised by others. There is just a lot to learn yet (as there always is in C++).
Well, that's true. The maximum proof of my knowledge is the 70-lines-long Lock class. But it's still very simple. Functions can be a very simple or extremely hard thing, depending on what it does and how it's written. A "Do.Add(129, 215)" or a "Do.Multiply(27, 9)" is very simple to understand and make, but a "GameMain.Display(27, 5, GPl, etc)" will be obviously harder (if you get the point).

Why to re-learn if/elses? they're very easy and i think i correctly understood everything about them.

With functions, i pretty much understood it, but the basics of them. I still think there's not that much left to learn from functions, just the more advanced stuff that can be done inside them. I need to start with structures and classes (I still know a little bit about both).

Edit: i Remade the Lock class. Now it's shorter and easier to read i think.

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
int C2_Lstate[5];
bool C2_Lexit=false, C2_Lcorrect=false, C2_Lwrong=false;

class Lock {public:

    static void State(int circle, int line) {
        const char* sym1l1 = "|  -\\   |"; const char* sym1l2 = "|   /;  |";
        const char* sym2l1 = "|  \\|-  |"; const char* sym2l2 = "|   V   |";
        const char* sym3l1 = "|  .$.  |"; const char* sym3l2 = "|  -^   |";
        const char* sym4l1 = "|  __*  |"; const char* sym4l2 = "|   |\"  |";
        const char* sym5l1 = "|  /),  |"; const char* sym5l2 = "|  /-   |";
        if(C2_Lstate[circle]==1){if(line==1){cout << sym1l1;} else{cout << sym1l2;}}
        if(C2_Lstate[circle]==2){if(line==1){cout << sym2l1;} else{cout << sym2l2;}}
        if(C2_Lstate[circle]==3){if(line==1){cout << sym3l1;} else{cout << sym3l2;}}
        if(C2_Lstate[circle]==4){if(line==1){cout << sym4l1;} else{cout << sym4l2;}}
        if(C2_Lstate[circle]==5){if(line==1){cout << sym5l1;} else{cout << sym5l2;}}
        cout << " ";
    };

    static void Display(int Position) {
        const char* lockt = "\n\n   _____     _____     _____     _____\n ,/     \\, ,/     \\, ,/     \\, ,/     \\,\n";
        const char* lockb = "\n `\\_____/' `\\_____/' `\\_____/' `\\_____/'";
        system("cls");
        cout << "\n There's a door with some sort of combination lock.\n The digits are strange symbols.\n";
        cout << "\n@ Arrow keys to move the pointer and change the symbols.\n\n B = Back | C = Check";
        cout << lockt << " ";
        Lock::State(1, 1);
        Lock::State(2, 1);
        Lock::State(3, 1);
        Lock::State(4, 1);
        cout << "\n ";
        Lock::State(1, 2);
        Lock::State(2, 2);
        Lock::State(3, 2);
        Lock::State(4, 2);
        cout << lockb;
        if(Position==1){cout << "\n     ^";}
        if(Position==2){cout << "\n               ^";}
        if(Position==3){cout << "\n                         ^";}
        if(Position==4){cout << "\n                                   ^";}
        if(C2_Lwrong){cout << "\n@ Wrong Password\n";}
        cout << "\n@ ";
        Choice=getch();
    };

    static void Main() {
        int Position=1;
        while(!C2_Lexit)
        {
            Lock::Display(Position);
            C2_Lwrong=false;
            if(C2_Lcorrect){return;}
            if(C2_Lexit){return;}
            if(Choice==77) { // Right arrow key
                if(Position<4){Position=Position+1;}
                else{Position=1;}
            }
            else if(Choice==75){ // Left arrow key
                if(Position>1){Position=Position-1;}
                else{Position=4;}
            }
            else if(Choice==72) { // Up arrow key
                if(C2_Lstate[Position]<5) {C2_Lstate[Position]=C2_Lstate[Position]+1;}
                else{(C2_Lstate[Position])=1;}
            }
            else if(Choice==80){ // Down arroy key
                if(C2_Lstate[Position]>1){C2_Lstate[Position]=C2_Lstate[Position]-1;}
                else{C2_Lstate[Position]=5;}
            }
            else if(Choice=='b' || Choice=='B') {C2_Lexit=true;} // 'Back' button
            else if(Choice=='c' || Choice=='C') { // 'Check' button
                if((C2_Lstate[1]==5)&&(C2_Lstate[2]==3)&&(C2_Lstate[3]==2)&&(C2_Lstate[4]==1))
                {C2_Lcorrect=true;} else{C2_Lcorrect=false; C2_Lwrong=true;}
                if(C2_Lcorrect || C2_Lexit){return;}
            }
        }
    };
}Lock;


You can start the whole Lock class with Lock.Main(), the functions will do the rest for you.


Edit 2: I uploaded some sort of "v0.5.1", with easier to recognize labels, chapter label lists and the remade Lock class in chapter 2
Last edited on
I started out the same, watching C++ videos (thenewboston's and anti-rtfm's spoonfed) some of them did things which I don't do now, because I consider them bad habits, thankfully goto wasn't one of the things they did.

what made me better at C++ was doing small things I enjoyed, games, like a guessing game, tic tac toe, etc, and reading these forums every once in a while.

I started some text RPG's but never got far, 100 lines or so, the menu system always stomped me, couldn't think of a good way to implement it, so it was never a good learning project, it may be for you.

when it is just a few hundred lines of code there isn't any harm in re-doing it, a lot of it can be pasted, I re-wrote my ping-pong game so that I was happy with it.

put your text rpg on hold for a day, read some articles on programming, like the ones at gamedev or gamasutra, they're written by people who know their shit, and you should pay attention to it.

the next day if you open your RPG you may not even understand what that line of code does there, or that function over there, because it wasn't written very well.
I made a tic-tac-toe, but it works weirdly.
http://www.cplusplus.com/forum/beginner/76641/
Pages: 12