After 24 hours I beg for debugging help.

I am making a game ( not in c++ ) and I am trying to use c++ to pre-generate puzzles to solve in said game. The game is simple, a riddle... You have two bottles, one a 5 gallon bottle, the other a 3, you need precisely 4 gallons. Passing water back in forth this is very achievable. I want 5 bottle puzzles, and have successfully made them in the past using c++, but alas, I can't find my code :-( Worse is, as much as I try I cant tell why my rewrite isn't working as intended. It should be tracking which moves its made to get the best speed solution. One of the points of this program is to find the fastest possible solution. But the best move set isn't true... meaning if I apply the moves to the puzzle itself they aren't actually a solution. Where am I going wrong? I am hesitant to release my code, but I know in this case... the whole picture may be needed. Thank you in advance for helping me lock it down!

Code is not sanitized, this is all code for the app.

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
#include <iostream>
#include <cstdlib>
#include <fstream>
#include <string>
using namespace std;

int bottlecount=0;
int b1c=0;int b1m=0;int b2c=0;int b2m=0;int b3c=0;int b3m=0;int b4c=0;int b4m=0;
int b5c=0;int b5m=0;int b1ct=0;int b1mt=0;int b2ct=0;int b2mt=0;int b3ct=0;
int b3mt=0;int b4ct=0;int b4mt=0;int b5ct=0;int b5mt=0;int goal=0;
int attemptcount=0;
int maxattempts=20000000;
int maxbottlesize=10;
int action=0;
int actioncount=0;
int actionlimit=25;
int bestactioncount=actionlimit;
string savestring="";
string movelist="";
string bestmovelist="";

int main () {
srand(time(NULL));
start:
attemptcount=0;
bestmovelist="";
bestactioncount=actionlimit;
///Generate seed data
bottlecount = rand() % 4 + 2;
b1m = rand() % maxbottlesize + 1;
b1c = 0;
b2m = rand() % maxbottlesize + 1;
b2c = 0;
b3m = rand() % maxbottlesize + 1;
b3c = 0;
b4m = rand() % maxbottlesize + 1;
b4c = 0;
b5m = rand() % maxbottlesize + 1;
b5c = 0;
goal = rand() % maxbottlesize + 1;
///Pre - Test the seed
//If anything is already goal fail
if(b1c == goal or b2c == goal or b3c == goal or b4c == goal or b5c == goal or b1m == goal or b2m == goal or b3m == goal or b4m == goal or b5m == goal){cout<<"\nFailed. Puzzle pre-solved\n";goto start;};
if(goal>b1m && goal>b2m && goal>b3m && goal>b4m && goal>b5m){cout<<"\nFailed. Goal doesn't fit in any containers.\n";goto start;};
cout<<"\nAttempting Puzzle:"<<b1c<<"/"<<b1m<<"   "<<b2c<<"/"<<b2m<<"   "<<b3c<<"/"<<b3m<<"   "<<b4c<<"/"<<b4m<<"   "<<b5c<<"/"<<b5m<<"   Goal:"<<goal<<"\n";
retest:
///Load seed
b1mt=b1m;
b2mt=b2m;
b3mt=b3m;
b4mt=b4m;
b5mt=b5m;
b1ct=b1c;
b2ct=b2c;
b3ct=b3c;
b4ct=b4c;
b5ct=b5c;
savestring="";
///Clean up data from previous attempts
actioncount=0;
movelist="";
///Find the fastest solve
while (actioncount < actionlimit && b1ct!=goal && b2ct!=goal && b3ct!=goal && b4ct!=goal && b5ct!=goal ){
action = rand() % 30 + 1;
if(action==1){if(b1ct>0){b1ct=0; actioncount=actioncount+1; movelist+="Empty Bottle 1\n";};}; // 1 empty 1
if(action==2){if(b2ct>0){b2ct=0; actioncount=actioncount+1; movelist+="Empty Bottle 2\n";};}; // 2 empty 2
if(action==3){if(b3ct>0){b3ct=0; actioncount=actioncount+1; movelist+="Empty Bottle 3\n";};}; // 3 empty 3
if(action==4){if(b4ct>0){b4ct=0; actioncount=actioncount+1; movelist+="Empty Bottle 4\n";};}; // 4 empty 4
if(action==5){if(b5ct>0){b5ct=0; actioncount=actioncount+1; movelist+="Empty Bottle 5\n";};}; // 5 empty 5
if(action==6){if(b1ct<b1mt) {b1ct=b1mt; actioncount=actioncount+1; movelist+="Fill Bottle 1\n";};}; // 6 fill 1
if(action==7){if(b2ct<b2mt) {b1ct=b1mt; actioncount=actioncount+1; movelist+="Fill Bottle 2\n";};}; // 7 fill 2
if(action==8){if(b3ct<b3mt) {b1ct=b1mt; actioncount=actioncount+1; movelist+="Fill Bottle 3\n";};}; // 8f ill 3
if(action==9){if(b4ct<b4mt) {b1ct=b1mt; actioncount=actioncount+1; movelist+="Fill Bottle 4\n";};}; // 9 fill 4
if(action==10){if(b5ct<b5mt) {b1ct=b1mt; actioncount=actioncount+1; movelist+="Fill Bottle 5\n";};}; // 10 fill 5
if(action==11){if(b2ct<b2mt){if(b1ct>0){if(b1ct<=(b2mt-b2ct)){b2ct=b1ct+b1ct; b1ct=0; actioncount=actioncount+1;movelist+="1 to 2\n";};if(b1ct>(b2mt-b2ct)){b1ct=b1ct-(b2mt-b2ct); b2ct=b2mt; actioncount=actioncount+1;movelist+="1 to 2\n";};}; };};// 11 1 to 2
if(action==12){if(b3ct<b3mt){if(b1ct>0){if(b1ct<=(b3mt-b3ct)){b3ct=b1ct+b1ct; b1ct=0; actioncount=actioncount+1;movelist+="1 to 3\n";};if(b1ct>(b3mt-b3ct)){b1ct=b1ct-(b3mt-b3ct); b3ct=b3mt; actioncount=actioncount+1;movelist+="1 to 3\n";};}; };};// 12 1 to 3

/// Removed code for forum constraint, it is iteration of the same logic, ending of that iteration preserved.

if(action==26){if(b5ct<b5mt){if(b4ct>0){if(b4ct<=(b5mt-b5ct)){b5ct=b4ct+b4ct; b4ct=0; actioncount=actioncount+1;movelist+="4 to 5\n";};if(b4ct>(b5mt-b5ct)){b4ct=b4ct-(b5mt-b5ct); b5ct=b5mt; actioncount=actioncount+1;movelist+="4 to 5\n";};}; };};// 26 4 to 5
if(action==27){if(b1ct<b1mt){if(b5ct>0){if(b5ct<=(b1mt-b1ct)){b1ct=b5ct+b5ct; b5ct=0; actioncount=actioncount+1;movelist+="5 to 1\n";};if(b5ct>(b1mt-b1ct)){b5ct=b5ct-(b1mt-b1ct); b1ct=b1mt; actioncount=actioncount+1;movelist+="5 to 1\n";};}; };};// 27 5 to 1
if(action==28){if(b2ct<b2mt){if(b5ct>0){if(b5ct<=(b2mt-b2ct)){b2ct=b5ct+b5ct; b5ct=0; actioncount=actioncount+1;movelist+="5 to 2\n";};if(b5ct>(b2mt-b2ct)){b5ct=b5ct-(b2mt-b2ct); b2ct=b2mt; actioncount=actioncount+1;movelist+="5 to 2\n";};}; };};// 28 5 to 2
if(action==29){if(b3ct<b3mt){if(b5ct>0){if(b5ct<=(b3mt-b3ct)){b3ct=b5ct+b5ct; b5ct=0; actioncount=actioncount+1;movelist+="5 to 3\n";};if(b5ct>(b3mt-b3ct)){b5ct=b5ct-(b3mt-b3ct); b3ct=b3mt; actioncount=actioncount+1;movelist+="5 to 3\n";};}; };};// 29 5 to 3
if(action==30){if(b4ct<b4mt){if(b5ct>0){if(b5ct<=(b4mt-b4ct)){b4ct=b5ct+b5ct; b5ct=0; actioncount=actioncount+1;movelist+="5 to 4\n";};if(b5ct>(b4mt-b4ct)){b5ct=b5ct-(b4mt-b4ct); b4ct=b4mt; actioncount=actioncount+1;movelist+="5 to 4\n";};}; };};// 30 5 to 4
};
attemptcount=attemptcount+1;
if(b1ct==goal && actioncount<bestactioncount ){bestactioncount=actioncount; cout<<"Success! Bottle 1 contains goal after " <<actioncount << " actions. This was attempt number "<< attemptcount <<".\n";attemptcount=0;bestmovelist=movelist;};
if(b2ct==goal && actioncount<bestactioncount ){bestactioncount=actioncount; cout<<"Success! Bottle 2 contains goal after " <<actioncount << " actions. This was attempt number "<< attemptcount <<".\n";attemptcount=0;bestmovelist=movelist;};
if(b3ct==goal && actioncount<bestactioncount ){bestactioncount=actioncount; cout<<"Success! Bottle 3 contains goal after " <<actioncount << " actions. This was attempt number "<< attemptcount <<".\n";attemptcount=0;bestmovelist=movelist;};
if(b4ct==goal && actioncount<bestactioncount ){bestactioncount=actioncount; cout<<"Success! Bottle 4 contains goal after " <<actioncount << " actions. This was attempt number "<< attemptcount <<".\n";attemptcount=0;bestmovelist=movelist;};
if(b5ct==goal && actioncount<bestactioncount ){bestactioncount=actioncount; cout<<"Success! Bottle 5 contains goal after " <<actioncount << " actions. This was attempt number "<< attemptcount <<".\n";attemptcount=0;bestmovelist=movelist;};
if(bestactioncount==actionlimit && attemptcount > 1000000){cout<<"Failed to solve in first million tries"; goto start;};
if(bestactioncount<3){cout<<"Puzzle not viable, too fast\n";goto start;};
if(attemptcount<maxattempts){goto retest;};
if(bestactioncount==actionlimit){cout<<"Puzzle not solved.\n"; goto start;};
ofstream myfile;
myfile.open("saved.txt", ios::out | ios::app);
myfile<<"Puzzle: ";
myfile<<b1m;
myfile<<" ";
myfile<<b2m;
myfile<<" ";
myfile<<b3m;
myfile<<" ";
myfile<<b4m;
myfile<<" ";
myfile<<b5m;
myfile<<" Goal:";
myfile<<goal;
myfile<<" Perfect:";
myfile<<bestactioncount;
myfile<<"Best Move set:";
myfile<<bestmovelist;
myfile<<" \n";
myfile.close();
}
So you can still compile and have intended function the other actions I removed for the content character limit are located below. Replace te comment above with the code below for the full code.

1
2
3
4
5
6
7
8
9
10
11
12
13
if(action==13){if(b4ct<b4mt){if(b1ct>0){if(b1ct<=(b4mt-b4ct)){b4ct=b1ct+b1ct; b1ct=0; actioncount=actioncount+1;movelist+="1 to 4\n";};if(b1ct>(b4mt-b4ct)){b1ct=b1ct-(b4mt-b4ct); b4ct=b4mt; actioncount=actioncount+1;movelist+="1 to 4\n";};}; };};// 13 1 to 4
if(action==14){if(b5ct<b5mt){if(b1ct>0){if(b1ct<=(b5mt-b5ct)){b5ct=b1ct+b1ct; b1ct=0; actioncount=actioncount+1;movelist+="1 to 5\n";};if(b1ct>(b5mt-b5ct)){b1ct=b1ct-(b5mt-b5ct); b5ct=b5mt; actioncount=actioncount+1;movelist+="1 to 5\n";};}; };};// 14 1 to 5
if(action==15){if(b1ct<b1mt){if(b2ct>0){if(b2ct<=(b1mt-b1ct)){b1ct=b2ct+b2ct; b2ct=0; actioncount=actioncount+1;movelist+="2 to 1\n";};if(b2ct>(b1mt-b1ct)){b2ct=b2ct-(b1mt-b1ct); b1ct=b1mt; actioncount=actioncount+1;movelist+="2 to 1\n";};}; };};// 15 2 to 1
if(action==16){if(b3ct<b3mt){if(b2ct>0){if(b2ct<=(b3mt-b3ct)){b3ct=b2ct+b2ct; b2ct=0; actioncount=actioncount+1;movelist+="2 to 3\n";};if(b2ct>(b3mt-b3ct)){b2ct=b2ct-(b3mt-b3ct); b3ct=b3mt; actioncount=actioncount+1;movelist+="2 to 3\n";};}; };};// 16 2 to 3
if(action==17){if(b4ct<b4mt){if(b2ct>0){if(b2ct<=(b4mt-b4ct)){b4ct=b2ct+b2ct; b2ct=0; actioncount=actioncount+1;movelist+="2 to 4\n";};if(b2ct>(b4mt-b4ct)){b2ct=b2ct-(b4mt-b4ct); b4ct=b4mt; actioncount=actioncount+1;movelist+="2 to 4\n";};}; };};// 17 2 to 4
if(action==18){if(b5ct<b5mt){if(b2ct>0){if(b2ct<=(b5mt-b5ct)){b5ct=b2ct+b2ct; b2ct=0; actioncount=actioncount+1;movelist+="2 to 5\n";};if(b2ct>(b5mt-b5ct)){b2ct=b2ct-(b5mt-b5ct); b5ct=b5mt; actioncount=actioncount+1;movelist+="2 to 5\n";};}; };};// 18 2 to 5
if(action==19){if(b1ct<b1mt){if(b3ct>0){if(b3ct<=(b1mt-b1ct)){b1ct=b3ct+b3ct; b3ct=0; actioncount=actioncount+1;movelist+="3 to 1\n";};if(b3ct>(b1mt-b1ct)){b3ct=b3ct-(b1mt-b1ct); b2ct=b2mt; actioncount=actioncount+1;movelist+="3 to 1\n";};}; };};// 19 3 to 1
if(action==20){if(b2ct<b2mt){if(b3ct>0){if(b3ct<=(b2mt-b2ct)){b2ct=b3ct+b3ct; b3ct=0; actioncount=actioncount+1;movelist+="3 to 2\n";};if(b3ct>(b2mt-b2ct)){b3ct=b3ct-(b2mt-b2ct); b2ct=b2mt; actioncount=actioncount+1;movelist+="3 to 2\n";};}; };};// 20 3 to 2
if(action==21){if(b4ct<b4mt){if(b3ct>0){if(b3ct<=(b4mt-b4ct)){b4ct=b3ct+b3ct; b3ct=0; actioncount=actioncount+1;movelist+="3 to 4\n";};if(b3ct>(b4mt-b4ct)){b3ct=b3ct-(b4mt-b4ct); b4ct=b4mt; actioncount=actioncount+1;movelist+="3 to 4\n";};}; };};// 21 3 to 4
if(action==22){if(b5ct<b5mt){if(b3ct>0){if(b3ct<=(b5mt-b5ct)){b5ct=b3ct+b3ct; b3ct=0; actioncount=actioncount+1;movelist+="3 to 5\n";};if(b3ct>(b5mt-b5ct)){b3ct=b3ct-(b5mt-b5ct); b5ct=b5mt; actioncount=actioncount+1;movelist+="3 to 5\n";};}; };};// 22 3 to 5
if(action==23){if(b1ct<b1mt){if(b4ct>0){if(b4ct<=(b1mt-b1ct)){b1ct=b4ct+b4ct; b4ct=0; actioncount=actioncount+1;movelist+="4 to 1\n";};if(b4ct>(b1mt-b1ct)){b4ct=b4ct-(b1mt-b1ct); b1ct=b1mt; actioncount=actioncount+1;movelist+="4 to 1\n";};}; };};// 23 4 to 1
if(action==24){if(b2ct<b2mt){if(b4ct>0){if(b4ct<=(b2mt-b2ct)){b2ct=b4ct+b4ct; b4ct=0; actioncount=actioncount+1;movelist+="4 to 2\n";};if(b4ct>(b2mt-b2ct)){b4ct=b4ct-(b2mt-b2ct); b2ct=b2mt; actioncount=actioncount+1;movelist+="4 to 2\n";};}; };};// 24 4 to 2
if(action==25){if(b3ct<b3mt){if(b4ct>0){if(b4ct<=(b3mt-b3ct)){b3ct=b4ct+b4ct; b4ct=0; actioncount=actioncount+1;movelist+="4 to 3\n";};if(b4ct>(b3mt-b3ct)){b4ct=b4ct-(b3mt-b3ct); b3ct=b3mt; actioncount=actioncount+1;movelist+="4 to 3\n";};}; };};// 25 4 to 3 
Let's start from the top.

1. Too many global variables.
2. No indentation and lack of whitespace make this code unreadable.
3. Using goto. You really need to learn to use one of the more accepted loop constructs.
4. Putting multiple statements on one line. This makes following the logic of the program impossible. Put each statement on a line of it's own.
if(action==23){if(b1ct<b1mt){if(b4ct>0){if(b4ct<=(b1mt-b1ct)){b1ct=b4ct+b4ct; b4ct=0; actioncount=actioncount+1;movelist+="4 to 1\n";};if(b4ct>(b1mt-b1ct)){b4ct=b4ct-(b1mt-b1ct); b1ct=b1mt; actioncount=actioncount+1;movelist+="4 to 1\n";};}; };};// 23 4 to 1
Should be more like:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    if(action == 23)
    {
        if(b1ct < b1mt)
        {
            if(b4ct > 0)
            {
                if(b4ct <= (b1mt - b1ct))
                {
                    b1ct = b4ct + b4ct; 
                    b4ct = 0; 
                    actioncount = actioncount + 1;
                    movelist += "4 to 1\n";
                };  // These semicolons are unneeded and will cause an error with some compilers.
                if(b4ct > (b1mt - b1ct))
                {
                    b4ct = b4ct - (b1mt - b1ct); 
                    b1ct = b1mt; 
                    actioncount = actioncount + 1;
                    movelist += "4 to 1\n";
                };
            }; 
        };
    };// 23 4 to 1              


5. Lack of helper functions. Functions should be your friends.
6. Use of "magic numbers" (23) in the above snippet.
7. Variables with numbers added (b4ct, b5ct, b3ct, etc) suggest that you should consider std::vector or arrays.
8. Cryptic variable names. Using meaningful variable and function names will make you program much easier to read and understand.

Fixing the above issues should get you started in the right direction.

Last edited on
I agree with everything jlb said and I would add the following:
9) No useful comments in the code.

Your program is incomprehensible.
It's no wonder you're having problems debugging it.
Last edited on
Thank you very much for the feedback. I will return in a few hours with a complete rewrite taking these ideas into account. I may need some direction with how to get away from so many global variables though, but Ill do my best at the rest and see if cleaner code gets us there! Thanks again. Sorry I suck, Completely autodidactic until this point when it comes to c++
Before rewriting the existing code, see if you can reduce it using functions. ANy time I see lots of code that looks nearly identical, I wonder if there's a way to factor out the comonality.
In the rewrite I have reduced a ton of it to user defined functions. Not done yet though, a preview though. I also by adding some cout's for debugging

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int pretestpuzzle(){
    if (bottle1max==goal or bottle2max==goal or bottle3max==goal or bottle4max==goal or bottle5max==goal){///Ditch puzzles which come pre-solved.
            if(debug==1){cout<<"Puzzle is pre-solved. Discarding.\n";}
    goto newpuzzle;}
    if (goal>bottle1max && goal>bottle2max && goal>bottle3max && goal>bottle4max && goal>bottle5max){///Ditch puzzles which can't fit the goal in any bottle.
            if(debug==1){cout<<"Goal doesn't fit anywhere. Discarding.\n";}
    goto newpuzzle;} 
}

int generatepuzzle(){
    bottle1max=rand() % maximumbottlesize + 1;
    bottle2max=rand() % maximumbottlesize + 1;
    bottle3max=rand() % maximumbottlesize + 1;
    bottle4max=rand() % maximumbottlesize + 1;
    bottle5max=rand() % maximumbottlesize + 1;
    goal=rand() % maximumbottlesize + 1;
}

int writecontainers(){
ostringstream s;
s << "B1:" << bottle1current << "/" << bottle1max << " " << "B2:" << bottle2current << "/" << bottle2max << " " << "B3:" << bottle3current << "/" << bottle3max << " " << "B4:" << bottle4current << "/" << bottle4max << " " << "B5:" << bottle5current << "/" << bottle5max << " \n" ;
std::string query(s.str());
movelog+=s.str();
}


Also cleaning up the way I am writing my conditions to make it more readable, and adding useful commenting.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/// Step 3: Randomly attempt only possible actions until the attempt count runs out, tracking the fastest solution along the way.
    //Step 3.1 Since we may loop back here on a failed puzzle generation we reset the bestactioncount value to the predefined limit.
        bestactioncount=maxactions;
    //Step 3.2 A while loop to run through between puzzle solves and fails, this will break the solving once there has not been a faster solution in maxattempts tries.
        while(attempt<maxattempts){
        movelog="";//I reset the movelog between attempts as I only want one attempt tracked at a time, to pass to the bestmovelog when it is faster than a previous attempt.
        //Step 3.2.1 A while loop which randomly brute forces the puzzle. If the puzzle goal is met, this attempt has taken longer than our best, or once its been attempted maxattempts times this while is broken.
            while(actions<maxactions && actions<=bestactioncount && bottle1current!=goal && bottle2current!=goal && bottle3current!=goal && bottle4current!=goal && bottle5current!=goal){
                action = rand() % 30 + 1;//Generate a random action to commit if it is a viable action.
                if(action==1 && bottle1current>0){
                    bottle1current=0;
                    actions=actions+1; 
                    movelog+="Emptied Bottle 1 ";writecontainers();
                    if(debug==1){cout<<"Emptied Bottle 1\n";};
                    };      
                if(action==2 && bottle2current>0){
                    bottle2current=0;
                    actions=actions+1; 
                    movelog+="Emptied Bottle 2 ";writecontainers();
                    if(debug==1){cout<<"Emptied Bottle 2\n";};};


I figure the debug text kinda satisfies the need for commenting there. I hope I am headed the direction you suggested. Once I am done with the rewrite Ill go through and remove the unneeded if semicolons. I wonder how many bugs have been caused by those over the years.
10. You need to consistently use indentation. Did you just not post the closing brace for the while statement or did you miss it?

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
                // Wrap these excessively long lines to make reading easier.
                while(actions < maxactions && actions <= bestactioncount && bottle1current != goal && 
                      bottle2current != goal && bottle3current != goal && bottle4current != goal && 
                      bottle5current != goal){
                    action = rand() % 30 + 1;//Generate a random action to commit if it is a viable action.

                    if(action == 1 && bottle1current > 0){
                        bottle1current = 0;
                        actions = actions + 1; 
                        movelog += "Emptied Bottle 1 ";
                        writecontainers();
                        if(debug == 1){
                            cout<<"Emptied Bottle 1\n";
                        }
                    }; ////////////////////////////// Get rid of these semicolons.      

                    if(action == 2 && bottle2current > 0){
                        bottle2current = 0;
                        actions = actions + 1; 
                        movelog += "Emptied Bottle 2 ";
                        writecontainers();
                        if(debug == 1){
                            cout << "Emptied Bottle 2\n";
                        }; ////////// Again get rid of these semicolons.
                    }; /////////// See above. 


Also note the added whitespace. Make you program readable by putting whitespace in your calculations and to help highlight program logic.

Also the following comment doesn't make much sense to me:
//Generate a random action to commit if it is a viable action.

I get the random part, but what is a viable action?
Last edited on
if(action == 2 && bottle2current > 0){
This is where I make sure its viable, Bottle 2 current needs to have something to empty for it to be viable, and one of these ifs has to go off for the action to be tracked due to
actions = actions + 1; nested inside the ifs.
The end of the while loop isnt there just because of a short copy paste, I was working between the braces still so unfinished code was there. I caught the lack of whitespace and have improved on it. Another snippet:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    while(actions<maxactions && actions<=bestactioncount && bottle1current!=goal && bottle2current!=goal && bottle3current!=goal && bottle4current!=goal && bottle5current!=goal){
                action = rand() % 30 + 1;//Generate a random action to commit if it is a viable action.

                if(action==1 && bottle1current>0){
                    bottle1current=0;
                    actions=actions+1;
                    movelog+="Emptied Bottle 1 ";writecontainers();
                        if(debug==1){cout<<"Emptied Bottle 1\n";};
                    };

                if(action==2 && bottle2current>0){
                    bottle2current=0;
                    actions=actions+1;
                    movelog+="Emptied Bottle 2 ";writecontainers();
                        if(debug==1){cout<<"Emptied Bottle 2\n";};};

                if(action==3 && bottle3current>0){
                    bottle3current=0;
                    actions=actions+1;
                    movelog+="Emptied Bottle 3 ";writecontainers();
                        if(debug==1){cout<<"Emptied Bottle 3\n";};};


Hopefully I am getting closer. I recognize which semicolons need removed, im just waiting to the end of the rewrite then pulling em out so I dont miss any. Looking better code guru's?
OMG ofcourse I can wrap it! it doesnt terminate til the parenthesis! THank you!
Still no whitespace, and multiple statements on one line, and semicolons after the ending braces, which should be placed to match the indentation not all grouped together.
1
2
3
4
5
6
7
8
9
10
11
if(action == 3 && bottle3current > 0) {
    bottle3current = 0; // Don't forget some whitespace.
    actions = actions + 1;
    movelog += "Emptied Bottle 3 ";

    writecontainers();

    if(debug == 1) {
        cout << "Emptied Bottle 3\n";
    }
}
I misunderstood what you meant by whitespace. Handling that now.
Okay after looking at the code a little more, you should use arrays. For example, Instead of
1
2
3
int b1c=0;int b1m=0;int b2c=0;int b2m=0;int b3c=0;int b3m=0;int b4c=0;int b4m=0;
int b5c=0;int b5m=0;int b1ct=0;int b1mt=0;int b2ct=0;int b2mt=0;int b3ct=0;
int b3mt=0;int b4ct=0;int b4mt=0;int b5ct=0;int b5mt=0;

do
1
2
3
const int BottleCount = 5;
int contents[BottleCount];  // current contents of each bottle
int capacity[BottleCount];   // capacity of each bottle 



Then you can write a function to transfer contents from one bottle to another

1
2
3
4
5
6
void pour (size_t from, size_t to)
{
    int amount = min(capacity[to] - contents[to], contents[from]);
    contents[from] -= amount;
    contents[to] += amount;
}


And you can pour between random bottle with somethink like

1
2
3
4
5
6
7
8
// Pick two random bottles
size_t from = rand() % BottleCount;
size_t to = rand() % BottleCount;

// If it's possible to pour from the one to the other then do it.
if (contents[from] > 0 && contents[to] < capacity[to]) {
    pour(from, to);
}
Last edited on
Its alive! Working as intended. Been hacking at this for 30 hours now, I need some sleep. Ill be back for a propper flogging to get my formatting etc in shape after I sleep. No clue what the error was, but I can say this, making the code readable, and using more modern looping mechanisms like while, and incorporating user defined functions all played a huge part in making it work. THANK YOU ALL SO MUCH for forcing me to try clean rather than lazy! Ill never go back!
Hi,

A couple of other things:

actions = actions + 1;

is better written as:

++actions; // increment operator

And this one is a pet hatred for me:

while(actions<maxactions && actions<=bestactioncount && bottle1current!=goal && bottle2current!=goal .....

Statements like that are error prone, UGLY, and non scalable. With dhayden's suggestions you can avoid the whole thing.


Also, can you avoid really long comments - your code is 3 screens wide on my system. There is a bit of a guideline that code shouldn't be any wider than 80 char - just for readability.

With the formatting of your code, hopefully you can get your IDE to do it auto-magically for you.
Topic archived. No new replies allowed.