Orc game not looping right

Two glitches - 1) Phantom round 2) Seeing "You go back to camp..." line after pressing Y to fight next orc. You find the missing round and the camp line when you scroll up. Below is more detail.

When asking if want to battle next orc, if you press Y or y, there is a phantom round. So on screen it will go from round 8 to 10 for example. When you scroll up you find this missing round in which you take damage while the orc does not. And if you scroll further up you see the "You go back to camp..." line that you normally only see if you press any other key than Y or y. I've tried placing - if (next_orc != 'Y' || next_orc != 'y') - in other places but it creates more glitches. What is wrong with my inner-loops? Or is my design/structure just generally flawed?

Any help is appreciated.

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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#include <iostream>
#include <windows.h>
#include <ctime>
#include <random>

void intro_text ();
void clear_screen ();
void stats_screen (int& human_health, int& current_orc_health, int& number_of_orcs, int& human_damage, int& orc_damage, int& round);

using namespace std;

int main ()
{
    mt19937 random_engine (time(0));
    uniform_int_distribution <int> dice_roll (1, 8);

    char next_orc = 'Y';
    char turn = 'H';

    int round = 0;
    int number_of_orcs = 1;

    int human_health = 50;
    int orc_health = 15;

    int human_result = 0;
    int human_damage = 0;

    int orc_result = 0;
    int orc_damage = 0;

    int current_orc_health = orc_health;

    intro_text ();

    while (next_orc == 'Y' || next_orc == 'y')
    {
        round ++;
        stats_screen (human_health, current_orc_health, number_of_orcs, human_damage, orc_damage, round);
        clear_screen ();

        cout << "Press Enter to battle!";
        cin.get ();
        cout << endl;

        while (turn == 'H') // human turn
        {
            human_result = dice_roll (random_engine);

            if (human_result > 2)
            {
                human_damage = dice_roll (random_engine) + 1;
                current_orc_health -= human_damage;

                turn = 'O';

                if (current_orc_health < 0)
                {
                    clear_screen ();
                    stats_screen (human_health, current_orc_health, number_of_orcs, human_damage, orc_damage, round);
                    clear_screen ();

                    cout << "Press Enter.";
                    cin.get ();
                    cout << "     ------- Orc Hunting -------      " << endl << endl << endl;
                    cout << "This orc has died." << endl << endl << endl << endl << endl << endl << endl << endl;
                    number_of_orcs ++;
                    current_orc_health = orc_health;

                    clear_screen ();

                    cout << "Battle another orc? (Y or N)";
                    next_orc = cin.get ();
                    clear_screen ();

                    turn = 'O';

                    if (next_orc != 'Y' || next_orc != 'y')
                        {
                            clear_screen ();
                            cout << "     ------- Orc Hunting -------      " << endl << endl << endl;
                            cout << "You go back safely to camp." << endl << endl;
                            cout << "You killed " << number_of_orcs -1 << " orcs." << endl << endl << endl;
                            clear_screen ();
                        }
                    }
                }

                    else
                    {
                        human_damage = 0;
                        turn = 'O';
                    }
        }

        orc_result = dice_roll (random_engine); // orc turn

        if (orc_result > 3)
            {
                orc_damage = dice_roll (random_engine);
                human_health -= orc_damage;

                turn = 'H';

                if (human_health < 0)
                {
                    clear_screen ();
                    stats_screen (human_health, current_orc_health, number_of_orcs, human_damage, orc_damage, round);
                    clear_screen ();

                    cout << "Press Enter.";
                    cin.get ();
                    cout << "     ------- Orc Hunting -------      " << endl << endl << endl;
                    cout << "You died." << endl << endl;
                    cout << "But you killed " << number_of_orcs - 1 << " orcs first." << endl << endl << endl;
                    clear_screen();
                    break;
                }
            }

            else
            {
                orc_damage = 0;
                turn = 'H';
            }
    }

    return 0;
}

void intro_text ()
{
    cout << "     ------- Orc Hunting -------      " << endl << endl << endl;
    cout << "You will hunt and fight orcs " << endl;
    cout << "one at a time." << endl << endl << endl << endl;
    clear_screen ();
    cout << "Press Enter to begin.";

    cin.get ();

    clear_screen ();
}

void clear_screen ()
{
    for (int i = 0; i < 13; i ++)
    {
        cout << endl;
    }
}

void stats_screen (int& human_health, int& current_orc_health, int& number_of_orcs, int& human_damage, int& orc_damage, int& round)
{
    cout << "     ------- Orc Hunting -------      " << endl << endl << endl;
    cout << "Round: " << round << endl << endl;
    cout << "Orc number: " << number_of_orcs << endl << endl;
    cout << "Your attack damage: " << human_damage << endl;
    cout << "Orc attack damage: " << orc_damage << endl << endl;
    cout << "Your health: " << human_health << endl;
    cout << "Orc health: " << current_orc_health;

}
Hi,

If you make use of the toupper or tolower functions, then you can halve your logic. For example if using toupper, you can compare to just the 'Y'. If you do this your problems will probably go away.

I think you could also do with more use of functions, split the code into individual tasks with them. There is a kind of a rule that functions should not be more 40LOC, some go for even less. This can also apply to the main function. For example lines 99 to 125 could be in a function.

Just a matter of style and formatting, one can do this:

1
2
3
4
5
6
7
8
9
10
11
12
void stats_screen (int& human_health,  // 1 parameter per line
                   int& current_orc_health, 
                   int& number_of_orcs, 
                   int& human_damage, 
                   int& orc_damage, 
                   int& round
                  )
{
    cout << "     ------- Orc Hunting -------      \n\n\n"; // use "/n" instead of std::endl
    cout << "Round: " << round << "\n\n";
    // ....
}
Last edited on
Thanks for you reply. I've never heard of toupper or tolower before. After a quick search I see how those can be handy.

I agree, I can do more functions. And I like how you formatted my stat screen; it just looks much cleaner.

As to my 2 bugs, I believe it has to do with placement in the code of next_orc. Where it's placed, it's creating an extra battle round that's hidden unless you scroll up. And what doesn't make sense is that going back to camp code after you press Y or y, because as long as you press either one of those it should skip that bit of code and go to the next battle round.
And what doesn't make sense is that going back to camp code after you press Y or y, because as long as you press either one of those it should skip that bit of code and go to the next battle round.


There is a specific reason for that to do with the logic of line 78. There is a way to fix that, but I wanted to propose something simpler and much better. Fixing the logic of that line leads to a construct for which I have psychotic hatred for, so I didn't mention it :+D Have a go with toupper - see if fixes your problem.
All fixed, finally, after spending 1.5 hrs after work playing through the game repeatedly and looking through my code. Thanks for your help, and I didn't even need to use toupper.

1) First I fixed the Going Back To Camp screen from showing up ever time I started the next round of battle. I removed line 78, not needed since I already have the same thing as a while loop in line 36. (Don't know why I didn't see that before). And I just moved that whole block of text outside the while loop. I also changed line 73 to read cin >> next_orc; but I don't think that makes any difference.

2) Next I figured out what was causing the phantom battle round each time you press Y to battle next orc. Line 73 is also involved in this glitch. After you press Y and Enter, the game will immediately go to the next battle because you pressed Enter, then immediately go to the one after that, causing you to miss it. I fixed this by including a get.cin (); in line 74.

Also, in line 117 I replaced the break with a return 0 to avoid the dying screen then immediately going to the back to camp screen.

3) I also discovered 2 minor glitches I didn't see yesterday. Anytime an orc died, or I died, the battle round didn't increase. This was solved by including a round ++ in each of those blocks.

Now to improve my code by adding more functions, etc....
Topic archived. No new replies allowed.