Help with programming assignment

I'm working on a programming assignment right now, but i can't really figure out a way to get it to work, and what loops I'll need. Some guidance would be appreciated!

"Over an 8-block line, the home of an intoxicated person is at block 8, and a pub is at block 1. Our poor friend starts at block n, 1 < n < 8, and wanders at random, one block at a time, either toward or away from home. At any intersection, our friend moves toward the pub with a probability of 2/3 and toward home with a probability of 1/3. When our friend arrives either at the pub or at home, they stay there.
Write a program to simulate 500 trips in which our friend starts at block 2, another 500 trips starting at block 3, and so forth up to block 7. For each starting point, calculate and print the percentage of time our friend ends up at home and the average number of blocks walked on each trip.
Hint: Generate a random number from 1 to 3 where 1, 2 means the person walks back to the pub, and 3 means the person walks toward home. "

I tried using a do-while loop so it would loop through 500 times, but i just kept getting a random amount of runs.
Any kind of loop can be written to work for you. I would use a for loop. It seems like the simplest to get the semantics correct.

Before you look at the 500 iterations, Do you have a single iteration working correctly? Within the single iteration, do you have the move toward home/move toward the pub logic working correctly (i.e., does the drunkard change location properly based on the random value)? Do you have the termination conditions correct (i.e., do you stop your iteration when the drunkard reaches home or the pub)?

If you have learned about functions, put the entire iteration (including variable initialization) in a single function and call it from main. Then change main to call the function 500 times in a loop.

If you have not learned about functions, then take the entire iteration and wrap it in {}, and make it the body of a for loop.

But start with making sure a single iteration works correctly.

The problem I'm having is i tried that, I tried a do-while loop while the variable is less than 500, then it went into a for loop that would keep executing until the number reaches either 1 or 8(the pub and his home) and nothing i do is working.
The problem I'm having is i tried that, I tried a do-while loop while the variable is less than 500


Those 2 statements are contradictory. You need to make sure that a single iteration works first. There is no "500" in a single iteration. A single iteration could take as few a 1 or as many as 10000000 (or more) direction choices to get to either 1 or 8. Write the code to loop until you get to either 1 or 8 AND THEN STOP! That is a single iteration. After you have a single iteration, you can work on running it 500 times.

Until you get a single iteration working, "500" should not be in your code at all.

If you cannot get a single iteration working, post your code and we can figure out what you are doing wrong.
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
#include <iostream>
#include <iomanip>
#include <cstdlib>

using namespace std;

int main() {

	const int RUNS = 500;
	int home = 8,
		pub = 1,
		endHome = 0,
		endPub = 0,
		block = 2,
		timesRun = 1;
	double randomNumber;

	srand(time(NULL));

	for (block; block == pub || block == home;) {
		randomNumber = (rand() % 3) + 1;
		if (randomNumber <= 2) {
			block--;
		}
		if (randomNumber <= 3) {
			block++;
		}
		if (block == pub) {
			endPub++;
		}
		if (block == home) {
			endHome++;
		}
	}

	cout << "Number of times the drunk made it home: " << endHome << endl;
	cout << "Number of times the drunk made it to the pub: " << endPub << endl;

	return 0;
}


This is the code i have so far. It doesn't calculate anything and just automatically terminates.
You're close. Look at line 20. A for statement has 3 parts: initialization, a check to see if we should continue processing, and a statement to execute before the next loop. Your initialization does nothing, and your check says, "if block is the pub or block is home, keep looping". That is backwards logic.

In this loop, there is not reason to use a for loop. (Above, I suggested using a for loop when counting to 500, but that's not the loop you're looking at right now.) An infinite loop with break statements when home or the pub is reached seems more intuitive to me.

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
while (true)
{
    randomNumber = (rand() % 3) + 1;
    if (randomNumber <= 2)
    {
        block--;
    }
    else
    {
        block++;
    }

    // DEBUG PRINT TO VERIFY THAT THE ITERATION WORKS
    std::cout << "Random number: " << randomNumber
            << "    Next Block: " << block << std::endl;

    if (block == pub)
    {
        endPub++;
        break;
    }
    if (block == home)
    {
        endHome++;
        break;
    }
}


Notice line 14. While you are debugging you code, this line will show you what random number is being generated and make sure that the drunkard is moving in the correct direction. That's how you make sure your single iteration works. (A debugger can be used for this, too--learn how to use one.)
This is the first class so stuff like this makes me feel like I'm way out of my depth. Why do you use std:: cout instead of just cout? And what exactly do you mean by debug print?
Using std::cout instead of cout in combination with using namespace std is a habit that many programmers develop. They do the same, for as long as you don't forget to declare that you are using namespace std for everything in the file.

The main reason for developing this habit is that once you start working on projects using different namespaces, it can become very confusing to find out from what namespace a function should be used. It could even happen that you are using two different namespaces that both contain the same function with the same arguments, but totally different implementation. If you don't specify which namespace you intend to use the compiler will have a problem.

By getting used to typing the namespace in front of a call instead of declaring it once for everything in the file, you can prevent problems later on, but it does of course require more typing when you are learning and still only use the namespace std.

Have a look at: http://www.cplusplus.com/doc/tutorial/namespaces/

A debug-print or debug-output or debug-<anything> is something that you would only use to test if your code is working properly, once it does you could remove it because it is not really needed.
Last edited on
One of the people in my class helped me rework the code a bit, but now i need to figure out how to add totals for each block.
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
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>

using namespace std;

int main() {

	const int RUNS = 500;
	int home = 8,
		pub = 1,
		endHome = 0,
		endPub = 0,
		block = 2,
		randomNumber,
		sentinel = 0,
		originalBlock = 2;

	srand(time(NULL));

	while (originalBlock < 8) {
		for (int i = 0; i < RUNS; i++) {
			block = originalBlock;
			while (sentinel != 7) {
				randomNumber = (rand() % 3) + 1;
				if (randomNumber < 3) {
					block--;
				}
				if (randomNumber == 3) {
					block++;
				}
				if (block == pub) {
					endPub++;
					sentinel = 7;
				}
				if (block == home) {
					endHome++;
					sentinel = 7;
				}
			}
			sentinel = 0;
		}
		originalBlock++;
	}

	cout << endHome << endl;
	cout << endPub << endl;

	return 0;
}
Your code looks pretty good. The senitinel value of 7 seems a bit contrived. If you want to use a sentinel, why not a boolean? (Not trying to get too critical of a newby's first attempts, just trying to get you to think about what you are doing and why.)

Now that you have code that works, compare lines 25-41 with the loop that I suggested in my previous post. Do you see how the two solutions are essentially the same? Making decisions of what syntax to use to solve a problem is frequently a matter of personal opinion or style. But it is good to understand code that is written by others and understand what it does. If you understand how the 2 solutions are pretty much the same then you have a fairly good grasp of these looping constructs.

So, to answer your question. You have 3 loops. The first (innermost) loop is in line 25. This loop does the work of a single iteration. The result of this loop is either +1 home or +1 pub. We do not do anything with a total in this loop.

The second loop is in line 23. This is where we do the 500 iterations. This is where we want to calculate the totals for each starting point. Inside the loop we increment the 2 totals. When the loop is done, there will have been 500 iterations, some ending at home and some ending at the pub.

The third loop is in line 22. This runs the 500 iterations for each of the starting points. For each of the starting points, you want to initialize the totals (so we don't get carryover values from the previous starting point). We probably also want to print out the results for each starting point. Anything you want to do for each starting point must be done within this loop. So, you can initialize your totals between lines 22 and 23, and you can print out your results (as well as the starting point, hint hint) before line 45.
Topic archived. No new replies allowed.