+ 1

Dice roller/nested for loop?

I want to make a dice roller. I've made them before using nested for loops, with each loop being a dice setting the dice, but I want to make a program that can use different amount of dice. I was wondering if there was a way I can generate a nested for loop without coding it, like if I input 3 it'll generate a nested for loop of 3 loops. If not, is there any other way I can generate this program? EDIT: If needed I can provide the example, just need to rewrite it.

31st Mar 2017, 2:05 PM
JustSomeGuy
JustSomeGuy - avatar
18 Antworten
+ 1
@Dennis, I'm running into issues using your code. Heres the code I used: #include <iostream> #include <vector> #include <cmath> int validate (){ int given; while (!(std::cin >> given)|| (given <= 0)){ std::cout << "Incorrect Value! Try again!! \n\n"; std::cin.clear(); std::cin.ignore(1000000000,'\n'); } return given; } int main(){ int sides, diceNum, Wanted,TotalWanted = 0; std::cout << "How many sides?" << std::endl; sides = validate(); std::cout << "How many dice?" << std::endl; diceNum = validate(); std::cout << "What number you wanting to find the probability of?" << std::endl; Wanted = validate(); std::vector <int> AllDice(diceNum,1); unsigned long long loops = pow(sides,diceNum); for (unsigned long long looper; looper < loops; ++looper){ int last = AllDice.size() - 1, counter = 0; for ( int counting = 0; counting < diceNum; counting++){ counter += AllDice[counting]; } if(counter = Wanted){ TotalWanted+= 1; } if (++AllDice[last] > sides){ AllDice[last] = 1; for (int Looping =last - 1; Looping >= 0; --Looping){ ++AllDice[Looping]; if (AllDice[Looping] > sides){ AllDice[Looping] = 1; }else {break;} } } } std::cout << "Probability of " << Wanted << " is " << TotalWanted << " out of " << loops; return 0; } The problem I'm getting is that the TotalWanted is coming up zero when I run the program.
3rd Apr 2017, 2:23 PM
JustSomeGuy
JustSomeGuy - avatar
0
Hello again ^^. I'm kinda having a hard time to understand the question. An example would be nice indeed.
31st Mar 2017, 4:13 PM
Dennis
Dennis - avatar
0
kk, give me a bit. I'll post my old one in visual Basic. it doesn't batter if you don't know it, it's pretty self explanatory code if you know code already
31st Mar 2017, 4:14 PM
JustSomeGuy
JustSomeGuy - avatar
0
I think what you need is recursion, why you don't give it a try :)
31st Mar 2017, 4:20 PM
Moataz El-Ibiary
Moataz El-Ibiary - avatar
0
Private Sub btnFind_Click(sender As Object, e As EventArgs) Handles btnFind.Click Dim firstNum As Integer Dim secNum As Integer Dim thirNum As Integer Dim forthNum As Integer Dim options(-1) As Integer Dim Number(3) As Integer Dim sizeOfDice As Integer = 6 Const Total As Integer = 1296 lstOptions.Items.Clear() For firstNum = 1 To sizeOfDice For secNum = 1 To sizeOfDice For thirNum = 1 To sizeOfDice For forthNum = 1 To sizeOfDice Number(0) = firstNum Number(1) = secNum Number(2) = thirNum Number(3) = forthNum Array.Sort(Number) If Number(1) + Number(2) + Number(3) = cboProb.SelectedIndex + 3 Then ReDim Preserve options(options.Length) Dim count As Integer = options.Length - 1 options(count) = ((firstNum * 1000) + (secNum * 100) + (thirNum * 10) + (forthNum)) lstOptions.Items.Add(options(count)) End If Next Next Next Next Dim counter As Integer Dim Numerator As Decimal = options.Length Dim Denominator As Decimal = Total For counter = options.Length To 1 Step -1 If (Numerator % counter = 0) And (Denominator % counter = 0) Then Numerator /= counter Denominator /= counter End If Next lblProbability.Text = options.Length & "/" & Total & " or " & Numerator & "/" & Denominator End Sub End Class This is in VB, ask if you have any questions about the code, feel free to ask. The point of this is to find the probability of a dice roll for a said roll with 4 dice, keeping highest 3 rolls.
31st Mar 2017, 4:50 PM
JustSomeGuy
JustSomeGuy - avatar
0
@Dennis Got you your code you wanted. I'm looking at the nested for loop, to see if I can generate that without actually coding it. I'm going to try the recursion idea posted earlier.
31st Mar 2017, 4:53 PM
JustSomeGuy
JustSomeGuy - avatar
0
#include <iostream> #include <vector> #include <cmath> int main(){ const int SIDES = 6; const int ROLLS = 4; std::vector<int> v(ROLLS, 1); unsigned long long loops = pow(SIDES, v.size()); for(unsigned long long j = 0; j < loops; ++j){ int last = v.size() - 1; /* Do whatever with the data here */ if(++v[last] > SIDES){ v[last] = 1; for(int a = last - 1; a >= 0; --a){ ++v[a]; if(v[a] > SIDES) v[a] = 1; else break; } } } } This generates all combinations if that's what you want, do keep in mind that it does get slow with alot of SIDES/ROLLS.
31st Mar 2017, 6:45 PM
Dennis
Dennis - avatar
0
Okay, lets start breaking it down so I can understand and learn. -What's the purpose of the vector <int> v (ROLLS, 1) // Im guessing an array? -Why unassigned long long for the loop/j variable //Just checking, its power(base, exponent) right?
31st Mar 2017, 7:17 PM
JustSomeGuy
JustSomeGuy - avatar
0
vector is indeed an array, <int> tells the vector which type are going to be in it. The first constructor parameter tells the vector how big our initial size is gonna be, and the second parameter tells it what the default data is gonna be. Of course these 2 are optional, but it makes life easier sometimes. Since pow can get pretty big I want to save as much as possible. j is comparing to this 64 bit number. If j would be an int, it would overflow at 2^31, thus causing annoying problems. Making the j also 64 bit, it matches the type that it compares with. Since I'm not expecting to get negative I also use unsigned just for the extra space. Pow is indeed base, exponent
31st Mar 2017, 7:39 PM
Dennis
Dennis - avatar
0
Is there a reason you use vector instead of just declaring an array via int array[size] ? You mind explaining what you mean by default data for the second parameter, or how they are optional, but preferred? On a unrelated related note, why is C++ so obsessed with memory saving? I understand it doesn't allocate memory itself, but the fixation of data/memory saving confuses me still.
31st Mar 2017, 7:58 PM
JustSomeGuy
JustSomeGuy - avatar
0
A vector is actually very flexible, you can add to it as long as you have available memory in your pc, you can delete from it. It is very useful in game making where you keep adding and erasing from it. There are also many algorithms that work with it. Most important is that it's size is not hardcoded, so you should prefer it over normal arrays. This is C++ after all and not C. I don't have to use the first or second parameter, I could have done for(int i = 0; i < ROLLS; ++i) v.push_back(1); //Add 1 to it ROLLS times and it would have done the same thing. But you have to agree that the other way was much shorter. vector<int> v(4, 2) would have made an array of 4, all filled with the integer 2 C++'s library tries to keep memory management as far away from you as it can because it's really hard to manage correctly, especially when exceptions come into play. Vector handles that stuff for you. You can allocate memory yourself. int* arr = new int[5]; But you always have to remember to call delete, or delete[]. Gotta choose the correct one. delete[] arr; //In this case. Calling delete again from this point would cause memory corruption. But that's a different topic^^
31st Mar 2017, 8:28 PM
Dennis
Dennis - avatar
0
Sorry for responding so late @Dennis, but how are you going through each combination in that code you sent. I now understand up to declaring the 'last' variable, but don't quite understand what you're doing with the statements below that would step through every possible dice roll.
3rd Apr 2017, 11:13 AM
JustSomeGuy
JustSomeGuy - avatar
0
I keep incrementing the last number, when it goes over the maximum number I increment the next number by 1 and reset everything before that number to 1. 1 1 1 1 1 1 1 2 ... 1 1 1 6 1 1 1 7, it went over the max of 6 so it has to carry. 1 1 2 1 ... 1 1 6 6 1 1 6 7 then becomes 1 1 7 1 but now the 3rd number is above 6 as well, so it has to carry as well 1 2 1 1 etc...
3rd Apr 2017, 11:24 AM
Dennis
Dennis - avatar
0
Probably because you're doing an assignment instead of a comparison: if(counter = Wanted) -> if(counter == Wanted)
3rd Apr 2017, 2:29 PM
Dennis
Dennis - avatar
0
Nope, still not working right
3rd Apr 2017, 2:30 PM
JustSomeGuy
JustSomeGuy - avatar
0
And now give looper a starting value for (unsigned long long looper = 0; looper < loops; ++looper)
3rd Apr 2017, 2:41 PM
Dennis
Dennis - avatar
0
It works for me sides = 6 diceNum = 4 Wanted = 12 Output = Probability of 12 is 125 out of 1296
3rd Apr 2017, 2:45 PM
Dennis
Dennis - avatar
0
Did that, even put a cout inside the first loop, didnt get nearly enough output than I should. I used 4 6 sided dice, so 6^4 loops should play out EDIT: nvm, its hitting them all. It's not adding to TotalWanted though. It should though, it has the proper scope, right? EDIT: Don't know what I did, but it works now! I'll post the code on my codes.
3rd Apr 2017, 3:02 PM
JustSomeGuy
JustSomeGuy - avatar