cout dealys my game of life

Hay all.

Im new to programming in Cpp. (3rd day now)
But i do have som experience programming AS2 (yea i know, flash)

And now!
I've run into a delay. sort of.

I started doing all of those dredfull standard excersises (halloworld and calculators) and at the same time read about arrays, functions, classes and such.
allong with OOP in general.

now, this morning i decided to do a GAME OF LIFE, from scratch.

And i suceeded.
with one minor BUT.

each update om my "map" to the consol window is delayed.
and as far as i can tell, it happens on the print function.

are there any way to speed this up?

any ways. here is the whole code (into one file for cimplicity here)
and below ill point out the snippet ithink is doing all of the delay.

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
// Game of life, made in MVS Cpp 10 express.
// 30 by 30 cells, with a "death space around it.
// live cells stays alive with 2 or 3 nibors,
// death cells sprigs to live with 3 nibors.
// all other cells dies.
// 100 milicecond delay between each update.

#include "stdafx.h"
#include <stdlib.h>
#include <iostream>
#include <Windows.h>	//used to get the Sleep effect (sleep 1000 = 1 sec)
#include <cstdlib>		//used to generate "random" numbers and initiate a seed.

using namespace std;

bool mapP[30][30];
bool mapNew[30][30];

void resetMapNew();
void mapNewToMap();
void initMap();
void calcMap();
void printMap();
void cellState();

short countNibors(int i, int k);

int main()
{
	cout << "type in a seed" << endl;		//Tell the user to enter a seed. change to new line.
	int seed;								// create a variable int to hold our seed.
	cin >> seed;							// when the user presses enter, get the seed.
	srand(3523 + seed);						// these lines creates a seed for the initial random map generation.
	int exits = 1;							// this line tells exit to be set to 1 (0 will exit the program), and there fore that the program will run for one loop.
	initMap();								// use initMap;
	Sleep(1000);							// Wait for 1 seconds.
	
	// this is the actual program loop.
	while(exits > 0) {						// as loong as there are more than 0 value in exits, run the program
		while(exits >= 1) {					// while the value is above 1, or equal to 1, run the program loop
											// i use 2 while loops to allow the user to add extra generations after the former has ended.
			system("cls");					// clear the screen before each loop.
			printMap();						// use printMap.
			calcMap();						// use calcMap.
			Sleep(100);						// waith for 1/10th of a  second
			exits -= 1;						// lower exits. (when exits hits 0, the game will stop this while loop.
		}
		cin >> exits;						//when exits is 0, allow for the user to set it higher, if the user types in 0, the program exits.
	}
	// this ends the program.
	return 0;
}

void initMap() {							// initial random map generation.
	for(int i=0;i<30;i++) {
		for(int k=0;k<30;k++) {
			int x = (rand() % (6))-4;
			if (x <0) x= 0;
			mapP[i][k] = x;
		}
	}
}

void printMap() {							//prints the curent mapP
	for(int i=0;i<30;i++) {
		for(int k=0;k<30;k++) {
			if(mapP[i][k] == 0) {
				cout << "  ";
			}
			if(mapP[i][k] == 1) {
				cout << "[]";
			}
		}
		cout << endl;
	}
}

void calcMap() {							//calculates mapNew, sets mapP to mapNew and resets mapNew.

	// reset mapNew.
	resetMapNew();

	//get and set the cell state of mapNew.
	cellState();

	//transfer mapNew to mapP.
	mapNewToMap();
}

void resetMapNew() {						// resets mapNew
	for(int i=0;i<30;i++) {
		for(int k=0;k<30;k++) {
			mapNew[i][k] = 0;
		}
	}
}

void cellState() {
	// get and set cells state.
	for(int i = 1;i<29;i++) {					//start i and k at 1 and end at 29, this way, we will have a blank line around the map of death cells.
		for(int k = 1;k<29;k++) {
			int alives = countNibors(i,k);		//use countNibors to tell how manny live nibors you have.

			if (mapP[i][k] == 0) {				// if the current cell is death, only the result of 3 nibors will turn it alive, all else will continue death.
				if(alives == 3) {
					mapNew[i][k] = 1;
				}
				else {
					mapNew[i][k] = 0;
				}
			}

			if (mapP[i][k] == 1) {				// if the current cell is alive, the result of 2 or 3 nibors will keep it alive, all else will kill it.
				if(alives == 2) {
					mapNew[i][k] = 1;
				}
				else if(alives == 3) {
					mapNew[i][k] = 1;
				}
				else {
					mapNew[i][k] = 0;
				}
			}
		}
	}
}

short countNibors(int i, int k) {			//calculates the amount of live nibors to a cell. and avoids the center (the cell itself)
	int liveOnes = 0;
	for(int x = -1;x<=1;x++){
		for(int y = -1;y<=1;y++){
			if (x != 0 || y != 0) {
				if(mapP[i+x][k+y] == 1) {
					liveOnes += 1;
				}
			}
		}
	}
	return (liveOnes);
}

void mapNewToMap() {						// transfers mapNew to mapP
	for(int i=0;i<30;i++) {
		for(int k=0;k<30;k++) {
			mapP[i][k] = mapNew[i][k];
		}
	}
}


And here is the part i think is making the delay:

1
2
3
4
5
6
7
8
9
10
11
12
13
void printMap() {							//prints the curent mapP
	for(int i=0;i<30;i++) {
		for(int k=0;k<30;k++) {
			if(mapP[i][k] == 0) {
				cout << "  ";
			}
			if(mapP[i][k] == 1) {
				cout << "[]";
			}
		}
		cout << endl;
	}
}


I Hope some one out there can help me... is there a faster way to do the printing?

//Michlas.

Measure, don't guess. It's very common in coding for people to spend ages optimising something that turns out to have barely any effect at all. How sure are you that this is the source of the delay? Have you measured it?
Can you explain what you mean by delayed? When I run your code (with a few modifications to run on Linux) I notice no delays other than what the Sleep calls are causing.

Is it delayed if you remove the calls to Sleep? Is it better if you remove system("cls");?
Last edited on
Good spot by Pete; system("cls"); is going to be very expensive. system calls cost a fortune.
Hay both of you.

Yea I do see your point, and yes i have tested it.

Unless the flow of Cpp is weary diffrent from AS2 (not going a you read it)

system and Sleep are both slow (system ofcourse and Sleep 1 10th of a sec)
but the delay first happens when i print to the screen.
(ak. I can see the printing going trugh the "for" loops)
removing cout a the for(k) loop speeds up tramendus (but kind of ruiens the whole printing idea)

removing Sleep, also speeds up, inbetween the prints. but since id like to be able to see the cells "evolve" id like to have some kind of delay between each print.

the system clr i cant see any visible change by removing (other than my map now prints below its former self insteat of untop.)

dos that make any sence at all?

hope you can help.
So. just to recap.

i got some help from another forum. telling me to use printf and to set the coordinates for each live cell to print, instead of printing even the empty ones.

this helped i ton.

heres the new (better but not perfect, code)

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
// Game of life, made in MVS Cpp 10 express.
// 30 by 30 cells, with a "death space around it.
// live cells stays alive with 2 or 3 nibors,
// death cells sprigs to live with 3 nibors.
// all other cells dies.
// 100 milicecond delay between each update.

#include "stdafx.h"
#include <stdlib.h>
#include <iostream>
#include <Windows.h>	//used to get the Sleep effect (sleep 1000 = 1 sec)
#include <cstdlib>		//used to generate "random" numbers and initiate a seed.

#include <stdio.h>



using namespace std;

bool mapP[30][30];
bool mapNew[30][30];

void resetMapNew();
void mapNewToMap();
void initMap();
void calcMap();
void printMap();
void cellState();
void setXY(int x, int y);

short countNibors(int i, int k);

int main()
{
	cout << "type in a seed" << endl;		//Tell the user to enter a seed. change to new line.
	int seed;								// create a variable int to hold our seed.
	cin >> seed;							// when the user presses enter, get the seed.
	srand(3523 + seed);						// these lines creates a seed for the initial random map generation.
	int exits = 1;							// this line tells exit to be set to 1 (0 will exit the program), and there fore that the program will run for one loop.
	initMap();								// use initMap;
	Sleep(1000);							// Wait for 1 seconds.
	
	// this is the actual program loop.
	while(exits > 0) {						// as loong as there are more than 0 value in exits, run the program
		while(exits >= 1) {					// while the value is above 1, or equal to 1, run the program loop
											// i use 2 while loops to allow the user to add extra generations after the former has ended.
			system("cls");					// clear the screen before each loop.
			printMap();						// use printMap.
			calcMap();						// use calcMap.
			Sleep(100);						// waith for 1/10th of a  second
			exits -= 1;						// lower exits. (when exits hits 0, the game will stop this while loop.
		}
		setXY(0,35);						// use setXY
		cout << "State an amount of generations to loop trough, then press enter" <<endl;
		cin >> exits;						//when exits is 0, allow for the user to set it higher, if the user types in 0, the program exits.
	}
	// this ends the program.
	return 0;
}

void initMap() {							// initial random map generation.
	for(int i=0;i<30;i++) {
		for(int k=0;k<30;k++) {
			int x = (rand() % (6))-4;
			if (x <0) x= 0;
			mapP[i][k] = x;
		}
	}
}

void printMap() {							//prints the curent mapP
	for(int i=0;i<30;i++) {
		for(int k=0;k<30;k++) {
			if(mapP[i][k] == 1) {
				setXY(i*2,k);				//if cell is alive, print it at XY
				printf ("[]");
			}
		}
		//printf ("n");
	}
}

void calcMap() {							//calculates mapNew, sets mapP to mapNew and resets mapNew.

	// reset mapNew.
	resetMapNew();

	//get and set the cell state of mapNew.
	cellState();

	//transfer mapNew to mapP.
	mapNewToMap();
}

void resetMapNew() {						// resets mapNew
	for(int i=0;i<30;i++) {
		for(int k=0;k<30;k++) {
			mapNew[i][k] = 0;
		}
	}
}

void cellState() {
	// get and set cells state.
	for(int i = 1;i<29;i++) {					//start i and k at 1 and end at 29, this way, we will have a blank line around the map of death cells.
		for(int k = 1;k<29;k++) {
			int alives = countNibors(i,k);		//use countNibors to tell how manny live nibors you have.

			if (mapP[i][k] == 0) {				// if the current cell is death, only the result of 3 nibors will turn it alive, all else will continue death.
				if(alives == 3) {
					mapNew[i][k] = 1;
				}
				else {
					mapNew[i][k] = 0;
				}
			}

			if (mapP[i][k] == 1) {				// if the current cell is alive, the result of 2 or 3 nibors will keep it alive, all else will kill it.
				if(alives == 2) {
					mapNew[i][k] = 1;
				}
				else if(alives == 3) {
					mapNew[i][k] = 1;
				}
				else {
					mapNew[i][k] = 0;
				}
			}
		}
	}
}

short countNibors(int i, int k) {			//calculates the amount of live nibors to a cell. and avoids the center (the cell itself)
	int liveOnes = 0;
	for(int x = -1;x<=1;x++){
		for(int y = -1;y<=1;y++){
			if (x != 0 || y != 0) {
				if(mapP[i+x][k+y] == 1) {
					liveOnes += 1;
				}
			}
		}
	}
	return (liveOnes);
}

void mapNewToMap() {						// transfers mapNew to mapP
	for(int i=0;i<30;i++) {
		for(int k=0;k<30;k++) {
			mapP[i][k] = mapNew[i][k];
		}
	}
}

void setXY(int x, int y) {					//makes the cursor goto a spesific X and Y location.
    COORD pos = { x, y };
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(handle, pos);
}
Topic archived. No new replies allowed.