Conditional while loop confusion

Hi,

I've written the beginning of a game. You move an '@' symbol around until the player either presses 'q' (which works fine) or moves to coordinates 9,9 (This doesn't work). I can't see any problem with it at all and it compiles fine. Can anyone help? Code is below.

#include <iostream>
#include <windows.h>
#include <conio.h>

using namespace std;

void gotoxy(int x, int y)
{
COORD coord;
coord.X = x;
coord.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}

int main()
{
int x = 11;
int y = 11;
char move=0;
cout << "To move, use the keys w,a,s and d.";
while ((move != 'q') || ((x != 9) && (y != 9)))
{
move = getch();
system("CLS");
switch (move)
{
case 'w': x-- ; gotoxy(y,x); cout << "@"; break;
case 's': x++ ; gotoxy(y,x); cout << "@"; break;
case 'a': y-- ; gotoxy(y,x); cout << "@"; break;
case 'd': y++ ; gotoxy(y,x); cout << "@"; break;
}
gotoxy(9,9);
cout << "*";
}
return 0;
}
while ((move != 'q') || ((x != 9) && (y != 9))) this is still true, even if x==9 && y==9. Go over this condition again.
while ((move != 'q') || ((x != 9) && (y != 9))) should be
while ((move != 'q') && ((x != 9) || (y != 9)))
Thanks for the help. I got it to work by switching && and ||. This makes absolutely no sense to me at all. I thought '&&' meant 'and' and '||' meant 'or'. Not the other way around.
@dave146

Here's a better way of doing it, without using the System command 'CLS'. The '@' symbal gets erases before the move.

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
// Conditional While loop.cpp : main project file.
#include <iostream>
#include <conio.h>
#include <windows.h>

using namespace std;

void gotoxy(int x, int y)
{
	COORD coord;
	coord.X = x;
	coord.Y = y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}

int main()
{
	int x = 11;
	int y = 11;
	char move=' ';
	bool home = false; 
	cout << "To move, use the keys w,a,s and d. 'q' to quit";
	gotoxy(x,y);
	cout << "@";
	do
	{
		gotoxy(5,3);
		cout << "x = " << x << " y = " << y << "  ";
		move = _getch();
		move = tolower(move); // Making sure to check lower letters, even if CAPS lock on
		//system("CLS"); Best not to use 'System' commands. 
		switch (move)
		{
		case 'w':
			gotoxy(x,y);
			cout << " ";
			y-- ; 
			gotoxy(x,y);
			cout << "@";
			break;
		case 's':
			gotoxy(x,y);
			cout << " ";
			y++ ; 
			gotoxy(x,y);
			cout << "@";
			break;
		case 'a':
			gotoxy(x,y);
			cout << " ";
			x-- ; 
			gotoxy(x,y);
			cout << "@";
			break;
		case 'd':
			gotoxy(x,y);
			cout << " ";
			x++ ; 
			gotoxy(x,y);
			cout << "@";
			break;
		case 'q': 
			gotoxy(x,y);
			cout << "*";
			gotoxy(x-5,y+1); //Position text under asterisk
			cout <<"I'm quitting";
			home = true;
			//x=9;
			//y=9;
			break;
		}
		if (x==9 && y==9)
			home = true;

	} while(!home);
	gotoxy(5,3);
	cout << "x = " << x << " y = " << y << "  ";
	if(x==9 && y==9)
	{
		gotoxy(9,9);
		cout << "*";
		gotoxy(5,10);
		cout <<"I'm home!!";
	}
	gotoxy(25,23);// position text at bottom of screen
	return 0;
}
Last edited on
Can anyone explain to me how the solution actually works? The code below appears to be absolute gibberish yet it works.

while ((move != 'q') && ((x != 9) || (y != 9)))

It appears to say that for the while loop to terminate you would have to press 'q' AND have the int x==9 OR int y==9

When what I want to say is for the loop to terminate you have to press 'q' OR x ==9 AND y == 9.

Thanks whitenight1, I like your alternative to using System commands.

Cheers.
Last edited on
Statement after while is a condition when loop is continued. In your code next iteration of the loop happens when move NOT equals q, AND either x or y NOT equals 9. In other words loop does not continuew when move equals q OR both x AND y equals 9.

About logical statements transformations:
http://en.wikipedia.org/wiki/De_Morgan%27s_laws
while ((move != 'q') && ((x != 9) || (y != 9)))
This is saying the loop will continue while both conditions are true.

In your question, you are asking about when the while loop will terminate, that is the opposite case, when the entire condition evaluates as false.

First, at a high level, the two main conditions are connected with &&. Hence it will be true when both conditions are true. But for it to be false, it is sufficient for either condition to be false.


-----------------------------------------------------------------

Warning - reading this next part could make your brain hurt :)

I didn't know whether posting this would help or hinder - feel free to ignore it.

You can consider this in terms of mathematical rules (usually known as De Morgan's laws or theorems).

In order to find the inverse of a boolean expression, such as
((move != 'q') && ((x != 9) || (y != 9)))
change "equals" to "does not equal" and change "AND" to "OR" and vice versa.
You could place a ! in front of this inverted form and it has the same meaning as the original expression, like this,
(!((move == 'q') || ((x == 9) && (y == 9))))
Last edited on
Hi Chervil,

I still don't understand what the problem with my original statement was. It looks absolutely fine to me. Logically I don't see anything wrong with it at all.

while ((move != 'q') || ((x != 9) && (y != 9)))

It says while 'q' isn't pressed OR BOTH X AND Y do not equal 9 at the same time do the following....

I assume it's a particular quirk of C++ or perhaps my use of != has created some weird double negative thing.

Thanks for your patience.
Think I'll use your suggestion of

(!((move == 'q') || ((x == 9) && (y == 9)))).

As this (kind of) makes sense to me.
Topic archived. No new replies allowed.