Roulette Color Streak Program

Pages: 12
Hi all -

Brief history - long time back I wrote a VB program to simulate spinning a roulette wheel and was curious what the longest streak of any particular color would be over time (Black, Red, or Green). It's almost the same as a coin-flip type of program, but used Roulette because it was more interesting. That morphed into a Javascript/Web page that did it more graphically with tables and such. Then I moved it onto Powershell, and was getting a lot of speed (450,000 spins per minute, per PC that I ran it on). Not being satisfied and wanting to try another language, I just ported it all over to C++. I try to keep the logic all the same among languages to not introduce too many changes, but with C++ I'm getting about a million spins per SECOND on the same PCs. Amazing. I may port it over to Fortran for kicks but seriously, a million spins per second is impressive to me.

Anyway, program is pretty simple, starts up, picks a random number, checks the color associated with that spot on the roulette board I coded into a switch statement, if it's the same color as last time add to the high streak, if not set the streak back to one. Every one minute, write out the count of everything (and the PC Name) to a file, which gets aggregated via a DB stored procedure.

Highest streak with Powershell was 43, and I have a few PCs at 42.

C++ started on about 20 nodes, and they are stuck on 27 as a high streak, which seems odd to me. There's nothing that I'm seeing that would cause a stop at 27, so I'm wondering if this is something going on at a lower level that I'm not aware of (Compiler/random number/etc).

Code here. I haven't gone through to optimize it so to speak, I just wanted to get it running to do a speed test (to see if it's worth optimizing and learning more). It is/will be. .

Thank for any help on this silly experiment.


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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <thread>
#include <chrono>
#include <cmath>
#include <ctime>

#pragma warning(disable : 4996);

using namespace std;

int main(int argc, char* argv[])
{
	int streakCount = 0;                                            
	string colorPicked = "";               
	string lastColorPicked = "";										 
	int highestStreak = 0;                                               
	unsigned long long spinCount = 0;                                    
	int wheelSpot = 0;                                                   
	string PCName = getenv("COMPUTERNAME");
	string fileStats = "C:\\XXX\\XXX\\" + PCName + ".txt";
	time_t nowtime = time(NULL);            
	int minutes = 0;                                             
	int seconds = 0;                                                     
	int ms = 0;                                                          
	string fileLineText = "";                                            
	size_t firstCommaPos = 0;                                            
	size_t lastCommaPos = 0;                                             
	string str3 = "";                                                    
	int fileLineTextLength = 0;                                          
	int fileWritten = 0;                                                 
	ofstream outfile;                                                    
	ifstream infile;                                                     

	infile.open(fileStats);

	if (infile) {

		getline(infile, fileLineText);
		fileLineTextLength = fileLineText.length();

		//while (getline(infile, fileLineText)) {
		//	cout << fileLineText << endl;
		//}

		firstCommaPos = fileLineText.find_first_of(",");      // position of first comma in line of text from file
		PCName = fileLineText.substr(0, firstCommaPos);       // load PCName variable
		//cout << "PCName variable is " << PCName << endl;
		
		str3 = fileLineText.substr(firstCommaPos);            // get from firstCommaPos to the end
		str3 = str3.substr(1);
		// at this point we have stripped off the PC Name and first comma, so we have ####,#######
		firstCommaPos = str3.find_first_of(",");              	
		//str3 = str3.substr(0, firstCommaPos);
		//spinCount = stoi(str3);
		spinCount = stoull(str3);
		//cout << "spinCount variable is " << spinCount << endl;
		
		// at this point we have the spinCount variable loaded with data
		//cout << "str3 variable " << str3 << endl;
		firstCommaPos = str3.find_first_of(",");
		str3 = str3.substr(firstCommaPos);
		str3 = str3.substr(1);
		highestStreak = stoi(str3);
	    //cout << "highestStreak variable is " << highestStreak << endl;
		
	}

	infile.close();

	srand(time(0));
	
		while (true) {

			wheelSpot = rand() % 38 + 0;

			switch (wheelSpot) {

			case 0:
				colorPicked = "Green";
				break;
			case 1:
				colorPicked = "Red";
				break;
			case 2:
				colorPicked = "Black";
				break;
			case 3:
				colorPicked = "Red";
				break;
			case 4:
				colorPicked = "Black";
				break;
			case 5:
				colorPicked = "Red";
				break;
			case 6:
				colorPicked = "Black";
				break;
			case 7:
				colorPicked = "Red";
				break;
			case 8:
				colorPicked = "Black";
				break;
			case 9:
				colorPicked = "Red";
				break;
			case 10:
				colorPicked = "Black";
				break;
			case 11:
				colorPicked = "Black";
				break;
			case 12:
				colorPicked = "Red";
				break;
			case 13:
				colorPicked = "Black";
				break;
			case 14:
				colorPicked = "Red";
				break;
			case 15:
				colorPicked = "Black";
				break;
			case 16:
				colorPicked = "Red";
				break;
			case 17:
				colorPicked = "Black";
				break;
			case 18:
				colorPicked = "Red";
				break;
			case 19:
				colorPicked = "Red";
				break;
			case 20:
				colorPicked = "Black";
				break;
			case 21:
				colorPicked = "Red";
				break;
			case 22:
				colorPicked = "Black";
				break;
			case 23:
				colorPicked = "Red";
				break;
			case 24:
				colorPicked = "Black";
				break;
			case 25:
				colorPicked = "Red";
				break;
			case 26:
				colorPicked = "Black";
				break;
			case 27:
				colorPicked = "Red";
				break;
			case 28:
				colorPicked = "Black";
				break;
			case 29:
				colorPicked = "Black";
				break;
			case 30:
				colorPicked = "Red";
				break;
			case 31:
				colorPicked = "Black";
				break;
			case 32:
				colorPicked = "Red";
				break;
			case 33:
				colorPicked = "Black";
				break;
			case 34:
				colorPicked = "Red";
				break;
			case 35:
				colorPicked = "Black";
				break;
			case 36:
				colorPicked = "Red";
				break;
			case 37:
				colorPicked = "Green";
				break;
			}

			if (colorPicked == lastColorPicked) {
				streakCount++;
			}
			else {
				streakCount = 1;
			}

			lastColorPicked = colorPicked;

			if (streakCount > highestStreak) {
				highestStreak = streakCount;
			}

			spinCount++;

			nowtime = time(NULL);
			//minutes = (nowtime / 60) % 60;
			seconds = nowtime % 60;
			
			

			if (seconds == 0) {
				outfile.open(fileStats);
				outfile << PCName << "," << spinCount << "," << highestStreak << endl;
				outfile.close();
			}

			
			
		}  // ends while loop
				
}   // ends main 






Last edited on
Please edit your post to put [code][/code] tags around your code.
One thought is that the standard rand() can be very poor.
Some can be so bad that they essentially alternate 0,1,0,1,0,1 in the LSB.
Which would be a big issue for you, since you have what is basically a glorified coin tosser.

Anyhoo.
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
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <random>
using namespace std;

enum colours {
    EMPTY,
    GREEN,
    RED,
    BLACK,
};

int main(int argc, char *argv[])
{
  int streakCount = 0, highestStreak = 0;
  int spinCount = 0;
  colours colorPicked, lastColorPicked = EMPTY;

  //  srand(time(0));
  // http://www.cplusplus.com/reference/random/
  std::default_random_engine generator;
  std::uniform_int_distribution<int> distribution(0,37);

  while (spinCount<1E9) {
    // int wheelSpot = rand() % 38 + 0;
    int wheelSpot = distribution(generator);
    if ( wheelSpot < 18 ) {
        colorPicked = RED;
    } else if ( wheelSpot < 36 ) {
        colorPicked = BLACK;
    } else {
        colorPicked = GREEN;
    }
    if (colorPicked == lastColorPicked) {
      streakCount++;
    } else {
      streakCount = 1;
    }
    lastColorPicked = colorPicked;
    if (streakCount > highestStreak) {
      highestStreak = streakCount;
    }
    spinCount++;
  }
  cout << "Longest streak="
       << highestStreak
       << " after "
       << spinCount
       << " iterations"
       << endl;
}


$ g++ -std=c++11 -O2 bar.cpp
$ time ./a.out 
Longest streak=27 after 1000000000 iterations

real	0m24.501s
user	0m24.500s
sys	0m0.000s

Some points.
1. Comparing integers is a lot quicker than comparing strings.
2. You don't have to literally alternate R/B with a couple of G mixed in.


Did you find that the 27 was a weird number to get as well even with the alternative coding? Seems odd either way, but meanwhile Powershell has gone beyond 27 without issue, but just slower.

I modeled the switch/case after a wheel I had in front of me (photo), the optimizing like you suggest is doing the exact same thing and faster, so that's a great tip.

1
2
3
4
5
6
7
8
9
10
11
			nowtime = time(NULL);
			//minutes = (nowtime / 60) % 60;
			seconds = nowtime % 60;
			
			

			if (seconds == 0) {
				outfile.open(fileStats);
				outfile << PCName << "," << spinCount << "," << highestStreak << endl;
				outfile.close();
			}


I think you are making a mistake here.

Every time through your loop you check the time. If the number of seconds after the last minute is 0, you log your results.

If your intention is to log 1 time per minute, this will give you problems. When a second and third etc. loop comes through before the next 1-second threshold, the logging will take place again. So, you will actually have multiple logs per minute.

You need to have a flag to indicate when a log has been written that gets set after you write the log and cleared if seconds != 0.
I tried that same option, because I noticed like you said, that it's essentially logging out for an entire second, until the second flips to one. I wasn't overly concerned with it because I figured the worst that would happen is it would just log a new high streak if one happened during that brief time. With the flag, it seemed to be blowing right through it and not doing what I wanted, but I fiddled with it briefly, I will revisit though.
[I] was getting a lot of speed (450,000 spins per minute)
When I first read this, I thought "maybe for a computer in 1980."
with C++ I'm getting about a million spins per SECOND
That's more like it, but honestly, still not impressive.

People don't realize how fast modern computers are. Your PC can execute about 2 billion instructions per second. If you get a million spins/second then that's about 2,000 instructions per spin. Not too efficient. Looking at your code, the waste is probably in using strings, just as salem c said. His code is getting almost 41 million spins/second for about 49 instructions per spin. Sweet.

Did you find that the 27 was a weird number
The probability of spinning the same color in N spins is 1 in 2N-1. 27 seems pretty reasonable for 1 billion spins.

meanwhile Powershell has gone beyond 27 without issue, but just slower
Both your code and salem c's use an integer for the random number. I suspect that the random number generators recycle after about 232 ~ 4 billion numbers. So 27 is the longest run for that random number cycle. When I change salem c's code as follows, I get a run of 28:
line 17: long spincount=0;
Line 22: std::uniform_int_distribution<long> distribution(0,37);
Line 25: while (spinCount<1E10L) {
Last edited on
I tried to hybrid new and old quickly and am at this point - and what's weird is that the code is slower, about 15 million per minute slower. I'll keep messing with it, trying to get framework here while it's fresh in my mind.

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
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <thread>
#include <chrono>
#include <cmath>
#include <ctime>
#include <random>

#pragma warning(disable : 4996);

using namespace std;

int main(int argc, char* argv[])
{
	int streakCount = 0;                                            
	string colorPicked = "";               
	string lastColorPicked = "";										 
	int highestStreak = 0;                                               
	unsigned long long spinCount = 0;                                    
	long long wheelSpot = 0;
	string PCName = getenv("COMPUTERNAME");
	string fileStats = "C:\\XXX\\XXX\\" + PCName + ".txt";
	time_t nowtime = time(NULL);            
	int seconds = 0;                                                     
	string fileLineText = "";                                            
	size_t firstCommaPos = 0;                                            
	string str3 = "";                                                    
	int fileLineTextLength = 0;                                          
	int fileWritten = 0;                                                 
	ofstream outfile;                                                    
	ifstream infile;                                                     

	infile.open(fileStats);

	if (infile) {

		getline(infile, fileLineText);
		fileLineTextLength = fileLineText.length();

		//while (getline(infile, fileLineText)) {
		//	cout << fileLineText << endl;
		//}

		firstCommaPos = fileLineText.find_first_of(",");      // position of first comma in line of text from file
		PCName = fileLineText.substr(0, firstCommaPos);       // load PCName variable
		//cout << "PCName variable is " << PCName << endl;
		
		str3 = fileLineText.substr(firstCommaPos);            // get from firstCommaPos to the end
		str3 = str3.substr(1);
		// at this point we have stripped off the PC Name and first comma, so we have ####,#######
		firstCommaPos = str3.find_first_of(",");              	
		//str3 = str3.substr(0, firstCommaPos);
		//spinCount = stoi(str3);
		spinCount = stoull(str3);
		//cout << "spinCount variable is " << spinCount << endl;
		
		// at this point we have the spinCount variable loaded with data
		//cout << "str3 variable " << str3 << endl;
		firstCommaPos = str3.find_first_of(",");
		str3 = str3.substr(firstCommaPos);
		str3 = str3.substr(1);
		highestStreak = stoi(str3);
	    //cout << "highestStreak variable is " << highestStreak << endl;
		
	}

	infile.close();

	//srand(time(0));

	std::default_random_engine generator;
	std::uniform_int_distribution<long long> distribution(0, 37);
	
		while (true) {

			//wheelSpot = rand() % 38 + 0;

			wheelSpot = distribution(generator);

			if (wheelSpot < 18) {
				colorPicked = "Red";
			}
			else if (wheelSpot < 36) {
				colorPicked = "Black";
			}
			else {
				colorPicked = "Green";
			}

			if (colorPicked == lastColorPicked) {
				streakCount++;
			}
			else {
				streakCount = 1;
			}

			lastColorPicked = colorPicked;

			if (streakCount > highestStreak) {
				highestStreak = streakCount;
			}

			spinCount++;

			nowtime = time(NULL);
			seconds = nowtime % 60;
			
			if (seconds == 0 && fileWritten == 0) {
				outfile.open(fileStats);
				outfile << PCName << "," << spinCount << "," << highestStreak << endl;
				outfile.close();
				fileWritten = 1;
			}
			else if (seconds > 0 && fileWritten == 1) {
				fileWritten = 0;
			}
						
		}  // ends while loop
				
}   // ends main





Last edited on
You switch statement was probably converted to a jump table which may have been faster than the if/then/else. The big speedup comes from using enums to represent the colors instead of strings.
There is a possibility of a speedup at line 119. Is comparing fileWritten faster or slower than assigning fileWritten? If you just go ahead and assign fileWritten whenever seconds > 0, you might get a speedup.

Optimizations may take care of this already, and you should measure things to find out, but you have an awful lot of loops through here, and even a small improvement here may be noticeable.

And I agree with @dhayden that making colorPicked and lastColorPicked enum values rather than strings will have a noticeable improvement in performance.


Out of curiosity (no impact of performance), you use true in your while loop, so you know about bools. Why did you make fileWritten an int rather than a bool?
Last edited on
No reason whatsoever honestly, usually when I do code stuff, I essentially let my brain do whatever it wants until it works (within reason). Then, I go through and optimize it and try to make it better.

Why not do it all at once? I'm not sure, probably because I'm not a full time programmer anymore and I'm out of practice. I'm going to mess with the enums and see what happens as well. I'll be back with the next iteration.

Thanks everyone for having some chatter about this, I know it's not a good use of a computer by any means, it's more just interesting.

Where I'm at now - and it's still slower than the first version which is baffling to me. I don't particularly care, it's more just a "huh?" thing.

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
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <thread>
#include <chrono>
#include <cmath>
#include <ctime>
#include <random>

#pragma warning(disable : 4996);

using namespace std;

enum colors {
	EMPTY,
	GREEN,
	RED,
	BLACK,
};

int main(int argc, char* argv[])
{
	int streakCount = 0;                                            
	//string colorPicked = "";               
	//string lastColorPicked = "";										 
	colors colorPicked, lastColorPicked = EMPTY;
	int highestStreak = 0;                                               
	unsigned long long spinCount = 0;                                    
	long long wheelSpot = 0;
	string PCName = getenv("COMPUTERNAME");
	string fileStats = "C:\\XXX\\XXX\\" + PCName + ".txt";
	time_t nowtime = time(NULL);            
	int seconds = 0;                                                     
	string fileLineText = "";                                            
	size_t firstCommaPos = 0;                                            
	string str3 = "";                                                    
	int fileLineTextLength = 0;                                          
	//int fileWritten = 0;                                                 
	bool fileWritten = false;
	ofstream outfile;                                                    
	ifstream infile;                                                     

	infile.open(fileStats);

	if (infile) {

		getline(infile, fileLineText);
		fileLineTextLength = fileLineText.length();

		//while (getline(infile, fileLineText)) {
		//	cout << fileLineText << endl;
		//}

		firstCommaPos = fileLineText.find_first_of(",");      // position of first comma in line of text from file
		PCName = fileLineText.substr(0, firstCommaPos);       // load PCName variable
		//cout << "PCName variable is " << PCName << endl;
		
		str3 = fileLineText.substr(firstCommaPos);            // get from firstCommaPos to the end
		str3 = str3.substr(1);
		// at this point we have stripped off the PC Name and first comma, so we have ####,#######
		firstCommaPos = str3.find_first_of(",");              	
		//str3 = str3.substr(0, firstCommaPos);
		//spinCount = stoi(str3);
		spinCount = stoull(str3);
		//cout << "spinCount variable is " << spinCount << endl;
		
		// at this point we have the spinCount variable loaded with data
		//cout << "str3 variable " << str3 << endl;
		firstCommaPos = str3.find_first_of(",");
		str3 = str3.substr(firstCommaPos);
		str3 = str3.substr(1);
		highestStreak = stoi(str3);
	    //cout << "highestStreak variable is " << highestStreak << endl;
		
	}

	infile.close();

	//srand(time(0));

	std::default_random_engine generator;
	std::uniform_int_distribution<long long> distribution(0, 37);
	
		while (true) {

			//wheelSpot = rand() % 38 + 0;

			wheelSpot = distribution(generator);

			if (wheelSpot < 18) {
				colorPicked = RED;
			}
			else if (wheelSpot < 36) {
				colorPicked = BLACK;
			}
			else {
				colorPicked = GREEN;
			}

			if (colorPicked == lastColorPicked) {
				streakCount++;
			}
			else {
				streakCount = 1;
			}

			lastColorPicked = colorPicked;

			if (streakCount > highestStreak) {
				highestStreak = streakCount;
			}

			spinCount++;

			nowtime = time(NULL);
			seconds = nowtime % 60;
			
			if (seconds == 0 && fileWritten == false) {
				outfile.open(fileStats);
				outfile << PCName << "," << spinCount << "," << highestStreak << endl;
				outfile.close();
				fileWritten = true;
			}
			else if (seconds > 0) {
				fileWritten = false;
			}
						
		}  // ends while loop
				
}   // ends main





Last edited on
Don't do the I/O check every time through the loop. Put lines 119-130 inside this:
if (spinCount & 1023) == 0) {
// lines 119-130
}
When I make this change the time to run 100 million loops drops from 6.5s to 4.6s.
I actually tried something else - instead of using a while loop, I run a for loop to 100 million, and after that, write out spinCount and the highest streak, then the while loop outside that continues on. I was figuring if the PC had nothing else to do for 100 million spins, it'd speed up.

Oddly, it didn't. I think the switch/case/break change is what slowed me up. I'll try to switch it back and see if it speeds back up.
while (true) {

The if/else if/else in this "do forever" loop has the potential to jeopardize the CPU's instruction pipelining -- https://en.wikipedia.org/wiki/Instruction_pipelining
This could be the reason for the slow down compared to your previous code.

But, BTW, why do you try to "prove" by computing what you could calculate by some probability calculus?

Edit: It does not help for the subject, just a minor detail, in the routine of your OP you obviously use a wheel with two green bins, like the one shown here: https://www.ripleys.com/weird-news/roulette-wheel-666
One of the green is tagged with an 'O', the other one -- being opposite -- is tagged with a 'double O' (for whatever reason). In the select/case-gridiron the two green stand side by side.
1
2
3
4
5
6
 			case 0:
			colorPicked = "Green";
			break;
...
			case 37:
			colorPicked = "Green";

Wheel size is 38.
Last edited on
It was just a fun project for me to try out pretty much. Once I saw a 20 streak hit when I first messed with this, I was thinking, wow, with more spins, I could see potentially higher streaks. When I saw a 43 streak, the probability of that was so ridiculously small even with such a large sample size, i started the process up again just to try to have some fun.

Why build a race car when you could calculate/simulate the race? I'll take the race car!

:)

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
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <thread>
#include <chrono>
#include <cmath>
#include <ctime>
#include <random>

#pragma warning(disable : 4996);

using namespace std;

enum colors {
	EMPTY,
	GREEN,
	RED,
	BLACK,
};

int main(int argc, char* argv[])
{
	int streakCount = 0;                                            
	colors colorPicked, lastColorPicked = EMPTY;
	int highestStreak = 0;                                               
	unsigned long long spinCount = 0;                                    
	long long wheelSpot = 0;
	string PCName = getenv("COMPUTERNAME");
	string fileStats = "C:\\XXX\\XXX\\" + PCName + ".txt";
	time_t nowtime = time(NULL);            
	int seconds = 0;                                                     
	string fileLineText = "";                                            
	size_t firstCommaPos = 0;                                            
	string str3 = "";                                                    
	int fileLineTextLength = 0;                                          
	bool fileWritten = false;
	ofstream outfile;                                                    
	ifstream infile;
	int countTo = 100000000;
	int i = 0;
	int loopCount = 0;
	
	infile.open(fileStats);

	if (infile) {

		getline(infile, fileLineText);
		fileLineTextLength = fileLineText.length();

		//while (getline(infile, fileLineText)) {
		//	cout << fileLineText << endl;
		//}

		firstCommaPos = fileLineText.find_first_of(",");      // position of first comma in line of text from file
		PCName = fileLineText.substr(0, firstCommaPos);       // load PCName variable
		//cout << "PCName variable is " << PCName << endl;
		
		str3 = fileLineText.substr(firstCommaPos);            // get from firstCommaPos to the end
		str3 = str3.substr(1);
		// at this point we have stripped off the PC Name and first comma, so we have ####,#######
		firstCommaPos = str3.find_first_of(",");              	
		//str3 = str3.substr(0, firstCommaPos);
		//spinCount = stoi(str3);
		spinCount = stoull(str3);
		//cout << "spinCount variable is " << spinCount << endl;
		
		// at this point we have the spinCount variable loaded with data
		//cout << "str3 variable " << str3 << endl;
		firstCommaPos = str3.find_first_of(",");
		str3 = str3.substr(firstCommaPos);
		str3 = str3.substr(1);
		highestStreak = stoi(str3);
	    //cout << "highestStreak variable is " << highestStreak << endl;
		
	}

	infile.close();

	std::default_random_engine generator;
	std::uniform_int_distribution<long long> distribution(0, 37);
	
		while (true) {

			//wheelSpot = rand() % 38 + 0;

			for (i = 0; i < countTo; i++) {

				wheelSpot = distribution(generator);

				if (wheelSpot < 18) {
					colorPicked = RED;
				}
				else if (wheelSpot < 36) {
					colorPicked = BLACK;
				}
				else {
					colorPicked = GREEN;
				}

				if (colorPicked == lastColorPicked) {
					streakCount++;
				}
				else {
					streakCount = 1;
				}

				lastColorPicked = colorPicked;

				if (streakCount > highestStreak) {
					highestStreak = streakCount;
				}

				//spinCount++;

			}  // ends for loop

			//loopCount++;

			spinCount = spinCount + countTo;

			outfile.open(fileStats);
			outfile << PCName << "," << spinCount << "," << highestStreak << endl;
			outfile.close();
						
		}  // ends while loop
				
}   // ends main




Last edited on
Why build a race car when you could calculate/simulate the race? I'll take the race car!
LOL! -- tell Greta and her followers, https://en.wikipedia.org/wiki/Greta_Thunberg
BTW, not all may afford a real one: https://www.pagnianimports.com.au/media/catalog/product/cache/1/image/1200x1200/9df78eab33525d08d6e5fb8d27136e95/l/o/logitechie.jpg
Some even prefere those: https://www.technikdirekt.de/media/image/b6/42/b1/202547_00.jpg ;)
tenkman wrote:
I may port it over to Fortran for kicks but seriously, a million spins per second is impressive to me.


Let's have a go then ...
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
program roulette
   implicit none
   real, parameter :: redLimit = 18.0 / 38.0, blackLimit = 36.0 / 38.0

   integer spinCount
   integer :: longestStreak = 0, currentStreak = 0, lastColour = 0, colour
   integer i
   real, allocatable :: R(:)
   real start, finish

   write( *, "( 'How many spins? ' )", advance="no" );   read( *, * ) spinCount
   allocate( R(spinCount) )

   start = getTime()
   call random_seed
   call random_number( R )             ! generate size(R) random numbers in [0,1)
   do i = 1, spinCount
      if ( R(i) < redLimit ) then
         colour = 1
      else if ( R(i) < blackLimit ) then
         colour = 2
      else
         colour = 3
      end if
      if ( colour == lastColour ) then
         currentStreak = currentStreak + 1
      else
         if ( currentStreak > longestStreak ) longestStreak = currentStreak
         currentStreak = 1
         lastColour = colour
      end if
   end do
   if ( currentStreak > longestStreak ) longestStreak = currentStreak     ! just the final one
   finish = getTime()

   write( *, "( 'Longest streak = ' , i0 )"         ) longestStreak
   write( *, "( 'Time taken = '     , f6.3, ' s' )" ) finish - start


contains

   real function getTime()
      integer t(8)
      call date_and_time( values=t )
      getTime = 3600 * t(5) + 60 * t(6) + t(7) + 0.001 * t(8)
   end function getTime

end program roulette


How many spins? 100000000
Longest streak = 24
Time taken =  2.324 s


Last edited on
GEEZE!!!! That's impressive!! I don't know Fortran, but I was looking at it and couldn't figure out the random number generation in Fortran, then got sidetracked and haven't gone back to it.

I'm so happy someone else thought this would be interesting enough to do!
and you can get a straight linear speedup with threading it. so you could potentially do at least 4 times that many per second on a typical current home PC CPU. This is almost small enough to think graphics card... then you could do 30 or so times that many per second on a gaming home PC. And that is without really tuning it any more. If it were tuned it could possibly get another 20-30% more. How much is enough... computers have gotten insanely good at tight loop crunching. My first class, bubble sort of 1000 numbers ran for hours...
Last edited on
Is there a "long" variable type for Fortran? I've tried 6 different syntaxes and i'm clearly missing something in my reading. Or even bigger than long?

Also stuck on getting it to run standalone (the exe), I'm using CodeBlocks with GNU Fortran. It's compiling but if I move the EXE to another PC and run I get 2 dll errors, libgfortran-3.dll and libgcc_s_sjlj-1.dll missing. Have to find a way to build with everything in the EXE. Compiles fine and runs fine within the IDE, but the EXE won't run by itself. I fixed this with Visual Studio 2019 for the C++ version, looking in CodeBlocks for similar.
Pages: 12