Problems with variable initilization

Pages: 12
Feb 21, 2013 at 10:57pm
Hello When i compile the following program it runs but when there is input for Player one the compiler stops and says variable b is being used without being initialized and can figure out why

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
#include <iostream>

using namespace std;

char square[3][3] = {'1', '2', '3', '4', '5' ,'6', '7', '8', '9'};
bool CheckWin(int a, int b);
void Board();
int Turn;
int move(int Turn, char Player);

int main()
{	
	int Turn;
	int Valid = 0;
	bool gamewon = false;
	int charsplaced = 0;
	char Player = 'O';
	int a;
	int b;



	Board();
	cout << "Above is how the various moves are identified" << endl;
	system("pause");

	for(int a = 0; a <= 3; a++)
	{
		for(int b = 0; b <= 3; b++)
			square[a][b] = ' ';
	}
	Board();
	while(!gamewon)
	{
		if (Valid != -1)
		{
			if(Player == 'O')
			{
				cout << "Your' move" << endl;
				Player = 'X';
			}
			else
			{
				cout << "TEST";
				Player = 'O';
			}
		}
		while(true)
		{
			if(charsplaced == 9)
			{
				break;
			}
			cin >> Turn;
			if(Turn <=9 && Turn >=1)
			{
				break;
			}
			else
			{
				cout << "\nPlease enter a value between 1 and 9: ";
				if(cin.fail())
				{
					cin.clear();
					char c;
					cin >> c;
				}
			}
		}
		if(charsplaced == 9)
		{
			break;
		}
		Valid = move(Turn, Player); 
			if(Valid == -1)
				cout << "That is an invalid move try again";
			else
			{
				gamewon = CheckWin(a, b);
				charsplaced ++;
				system("cls");
				Board();
			}
			}
	system("cls");
	if(charsplaced == 9)
	{
		cout << "Draw\n";
		system("pause");
		return 0;
	}
	if (Player == 'X')
	{
		cout << "You win";
	}
	else
	{
		cout << "I win";
	}
	system("pause");
	return 0;
}

int move(int Turn, char Player)
{
	if (Turn >=0 && Turn <= 9)
	{
		int a;
		int b;
		for (a = 0, b = 0; ((a*3)+(b+1)) != Turn; a++, b++)
			if(square[a][b] == ' ')
			{
			square[a][b] = Player;
			return a, b;
			}
			else
			{
				return -1;
			}
	}
}
bool CheckWin(int a, int b)
{
	int vertical = 1;
	int horizontal = 1;
	int diagonal1 = 1;
	int diagonal2 = 1;
	char Player = square[a][b];
	int i;
	int ii;


	for(i = a + 1; square[i][b] == Player && i <= 4; i++, vertical++);
	for(i = a - 1; square[i][b] == Player && i >= 0; i--, vertical++);
		if(vertical >= 3)
			return true;
	for(i = b - 1; square[a][i] == Player && i >= 0; i--, horizontal++);
	for(i = b + 1; square[a][i] == Player && i <= 4; i++, horizontal++);
		if(vertical >= 3)
			return true;
	for(i = a - 1, ii = b - 1; square[i][ii] == Player && i >= 0 && ii >=0; i--, ii--, diagonal1++);
	for(i = a + 1, ii = b + 1; square[i][ii] == Player && i <= 4 && ii <=4; i++, ii++, diagonal1++);
		if(diagonal1 >= 3)
			return true;
	for(i = a - 1, ii = b + 1; square[i][ii] == Player && i >= 0 && ii <=4; i--, ii++, diagonal2++);
	for(i = a + 1, ii = b - 1; square[i][ii] == Player && i <= 4 && ii <=0; i++, ii--, diagonal2++);
		if(diagonal2 >= 3)
			return true;
	return false;
}

void Board()
{
	system("cls");
	cout << "Player 1 (X) - Computer (O)" << endl << endl;
	cout << endl;

	cout << "     |     |     " << endl;
	cout << "  " << square[0][0] << "  |  " << square[0][1] << "  |  " << square[0][2] << endl;

	cout << "_____|_____|_____" << endl;
	cout << "     |     |     " << endl;
	
	cout << "  " << square[1][0] << "  |  " << square[1][1] << "  |  " << square[1][2] << endl;

	cout << "_____|_____|_____" << endl;
	cout << "     |     |     " << endl;

	cout << "  " << square[1][0] << "  |  " << square[2][1] << "  |  " << square[2][2] << endl;

	cout << "     |     |     " << endl << endl;
}
Feb 21, 2013 at 11:14pm
Lines 18 and 19, variables a and b are defined, but not initialised with any particular value.

Then at line 70, function CheckWin(a, b) is called.

Are either a or b ever given any value before that function call?

Feb 21, 2013 at 11:15pm
they are within function move(int Turn, char Player) and those are the values id like to use
Feb 21, 2013 at 11:16pm
Your call to CheckWin on line 79 uses a and b, but in the current scope they have never been initialized. You declare them, but then for your for loops you actually declare NEW variables also named a and b, which go out of scope once the for loops end. So you're left with a and b variables that have garbage values. Set them to something before your call and you'll be fine.
Feb 21, 2013 at 11:19pm
the reason your getting the segmentation fault is from line 79
gamewon = CheckWin(a, b);

in the begining you do
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int a;
	int b;



	Board();
	cout << "Above is how the various moves are identified" << endl;
	system("pause");

	for(int a = 0; a <= 3; a++)
	{
		for(int b = 0; b <= 3; b++)
			square[a][b] = ' ';
	}

redeclaring int a =0 and int b = 0 in the for loop shadows your original declarations so when the program reaches line 79 the is nothing in a and b. your for loops should be
1
2
3
4
5
	for(a = 0; a <= 3; a++)
	{
		for(b = 0; b <= 3; b++)
			square[a][b] = ' ';
	}
Last edited on Feb 21, 2013 at 11:19pm
Feb 21, 2013 at 11:20pm
Function move() has local variables called a and b. Those are unrelated to the variables a and b in function main().
Feb 21, 2013 at 11:22pm
ok i thank you all for the help i see whats wrong now but now im unsure how i would get the value i get for a and b in function move() out to the function CheckWin()
Feb 21, 2013 at 11:26pm
Instead of defining new variables in function move(), you could pass by reference the variables from main().

http://www.cplusplus.com/doc/tutorial/functions2/
Feb 21, 2013 at 11:31pm
Thank you i got past that variable now i need to figure out why the move function isn't moving where i want but that's just a math error..... I think
Feb 22, 2013 at 12:03am
if anybody is still checking in here i got that math issue i was talking baout earlier fixed everything works but my function move take a long time to happen unless move is 1 how would i fix it
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int move(int a, int b, int Turn, char Player)
{
	if (Turn >=0 && Turn <= 9)
	{
		
		while (((a*3)+(b+1)) != Turn)
		{
			while (((a*3)+(b+1)) != Turn && b <= 3)
			{
				b++;
			}
			a++;	

	}
Feb 22, 2013 at 3:04am
if you post the full new code ill run it and see whats causing it since you seemed to change quite a bit and even in that last chunk you seem to be missing a }(or they are misaligned and in the unposted section)
Last edited on Feb 22, 2013 at 3:04am
Feb 22, 2013 at 3:05am
1
2
3
4
5
for(int a = 0; a <= 3; a++) {
	for(int b = 0; b <= 3; b++) {
		square[a][b] = ' ';
        }
}


There is a problem with the subscripts going out of bounds. Use < not <=. The for loop ends when the end condition becomes false, so the following code stops when it reaches 2:

1
2
3
4
5
for(a = 0; a < 3; a++) {
	for(b = 0; b < 3; b++) {
		square[a][b] = ' ';
        }
}


Valid subscripts are 0, 1, 2.

Get into the habit of always using braces, even when there is only 1 statement following, it will save you one day when you add more code.

Also, you had already declared a & b, so no need to redeclare them in the for loop.

HTH
Last edited on Feb 22, 2013 at 3:07am
Feb 22, 2013 at 3:28am
while (((a*3)+(b+1)) != Turn && b <= 3

If Turn is 1 to 9, then this expression goes outside of that range for values of a or b larger than 2. This results in loops that keep going until the int overflows & becomes negative (about 2.1 billion ), then it keeps going until it gets to zero and then 1 at which point it does something. And you have 2 of these loops, so the loop executes at least 8.4 billion times.

So what was the purpose of the expression & why is it there twice?

Also, you have code to validate the Turn value before it calls the move function, so why do it again in the move function?

HTH
Feb 22, 2013 at 3:33am
it was to find the proper spot on the array for the Turn input thank you for the clarification as to what was happening there i replaced it with
1
2
3
4
5
6
7
8
9
10
11
int Getb(int row, int Turn)
{
		int col = (Turn - row*3)-1;
		return col;
}

int Geta(int Turn)
{
		int row =  floor(float (Turn/3));
		return row;
}


now im trying to create an AI for the user to play against and well as you may have learned from reading this its tough for me lol
Feb 22, 2013 at 3:42am
You can convert Turn into row & col like this:

1
2
row = (Turn-1) / 3; // integer division no need for float answer is 0, 1, 2
col = (Turn-1) % 3; //remainder of division by 3  answer is 0, 1, 2 


This uses the Turn format:

123
456
789
Feb 22, 2013 at 3:56am
i had tried what you suggested there but the issue i ran into is would round up and i needed it to always round down
Feb 22, 2013 at 5:32am
But my code works though - there is no need for rounding.
Feb 22, 2013 at 6:08am
Chervil wrote:
Instead of defining new variables in function move(), you could pass by reference the variables from main().

Notice the code subsequently posted here, this is passing the parameters by value, not by reference:
int move(int a, int b, int Turn, char Player)

The code should look like this:
int move(int &a, int &b, int Turn, char Player)

Just as important, the aim of that change is to ensure that a and b are properly initialised before being used. From the code posted above, I'm not reassured that the problem is resolved.
Last edited on Feb 22, 2013 at 6:09am
Feb 22, 2013 at 1:15pm
@TheIdeasman hmmm then you did something different from when i tried that i don't see

@Chervil the code does work now for two player purposes 'm trying to replace player two with an AI
Feb 22, 2013 at 1:35pm
Maybe it does indeed work, the code may have changed completely since the earlier post. If you need any further help then it would be useful if you could post the current code.
Pages: 12