If Statement Help

Hey guys, complete noob here. I need help with figuring out how to get an if statement to check all values up to a specific number.

I have a Horizontal Coordinate and a Vertical Coordinate and I don't want players moving past either set values.

I understand the logic of what I need to do but I can't word it correctly. I'm wanting the player to be blocked from moving (in this case, left) at all positions that are furthest to the left of the screen. I know how to make this happen, but it's all very repetitive and doesn't allow me to change the value of the maximum horizontal value.


1
2
case 'a':
if (player_coord - 1 < 0  || player_coord - 1 == HORIZONTAL-1 || player_coord - 1 == HORIZONTAL*2-1 || player_coord - 1 == HORIZONTAL*3-1 || player_coord - 1 == HORIZONTAL*4-1)


I know I need something along the lines of:

1
2
case 'a':
if (player_coord - 1 < 0  || player_coord - 1 == HORIZONTAL*[i]-1, i++, i!=HORIZONTAL+1)


Or something like that. I used to be in a programming course and I'm just doing it as a hobby now, so don't think I'm just asking for code snippets or anything. I'm just not sure how to set this up in a way that works if I change the Horizontal value to something else, i.e. a larger map.

Thanks!
Last edited on
if (int i=0; player_coord - 1 < 0 || player_coord <= HORIZONTAL*i-1; i++)

Something like this? Doesn't wanna compile though. Also doesn't stop at the maximum Horizontal value.
.
Last edited on
I appreciate the response but I have a mapping system that works. The coordinates aren't the problem, the problem is the logic in the if-statement.
I think you really just have to put the if in a loop and store the result in a bool so that you can use ors and ands to combine them.
I'm wanting the player to be blocked from moving (in this case, left) at all positions that are furthest to the left of the screen.


I understand, but at the same time I don't - let me see if I got this right.

In your code, player_coord represents the player's position on the x-axis, yes?
When the user presses 'a' to move left, and if there is nothing stopping the player from moving in that direction, the player will move "one unit" to the left (in other words, player_coord -= 1;), is this correct?

Just want to make sure I get what you're trying to do. I have no idea what HORIZONTAL is supposed to be though. I understand that it's a border of some kind, but of what? The screen? The window size? The edges of some immovable object? Why do you need so many conditions in the if-control structure? Help me understand what exactly HORIZONTAL represents and I'd love to help you further.
Yes, correct. Here is my code for when the A key is hit:

1
2
3
4
5
6
7
8
9
10

if (player_coord - 1 < 0  ||  player_coord == HORIZONTAL*1){
			input = true;
			cout << "\rCharacter cannot complete move. Try again.";
					break; }
else {
	player_coord -= 1;
			input = false;
			                break; }




I have two constant variables for the Horizontal and Vertical size of the map. I can change these variables to alter the size of the map which prints out to be a box using " " as a filler. The player can move up, down, left and right using WASD.

So if I change the Horizontal and Vertical integers the playable area will change, allowing me to create different levels and whatnot.

I'm just having trouble blocking off the left and right sides of the screen so the player doesn't loop around to the end of the previous "line" on the map, or the beginning of the next "line" on the map respectively.

So in the code I provided, since each "new line" is the Horizontal value multiplied by the vertical line value at that spot, I know how to block that movement - I just don't know how to do it consistently enough so that the code doesn't repeat itself.

1
2
case 'a':
if (player_coord - 1 < 0  || player_coord  == HORIZONTAL || player_coord == HORIZONTAL*2 || player_coord  == HORIZONTAL*3 || player_coord  == HORIZONTAL*4)


That iteration works - what it's doing is taking the Horizontal value, say for example, 10, and multiplying it each time there is a new line and blocking the movement there. So you can't go left while you're on the 20th Horizontal space, or the 30th, etc. Is there a way to condense it so that the movement is blocked regardless of how many vertical lines there are?

Sorry if I rambled or repeated myself, I'm wracking my brain here.
Last edited on
Oh, I see. Now I understand.

I propose the use of the modulo operator (%). Here is a pseudo-code example I put together based on your snippets:

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
int main(int argc, char* argv[]) {

	//Our world is 10x10. There are 100 spaces to move around in.
	const int world_width = 10;
	const int world_height = 10;

	char world[world_width][world_height] = {' '};

	//Player coordinates
	int player_coord = 0;

	bool game_running = true;
	while (game_running) {

		//Input
		char input = get_user_keypress();

		//Check for collisions with world borders
		//This implementation assumes that the top left corner of the world is (0, 0).
		//The way you choose to do this is pretty implementation specific.

		switch (input) {
		//Up
		case 'w':
			if ((player_coord - world_width) >= 0) {
				//Move is valid
				player_coord -= world_width;
			}
			break;

		//Left
		case 'a':
			if ((player_coord) % world_width != 0) {
				//Move is valid
				player_coord -= 1;
			}
			break;

		//Down
		case 's':
			if ((player_coord + world_width) < (world_width * world_height)) {
				//Move is valid
				player_coord += world_width;
			}
			break;

		//Right
		case 'd':
			if (player_coord % world_width != (world_width - 1)) {
				//Move is valid
				player_coord += 1;
			}
			break;
		default:
			break;
		}
		//Print
		//Sleep
		//Clear screen
	}
	return 0;
}


If you don't know what the modulo operator does, I recommend researching it more in depth as it is very convenient for various applications. Essentially, it gives the remainder of a division of two values. For example:

int x = 11 % 3;

results in variable x containing the value 2, since dividing 11 by 3 results in 3, with a remainder of 2.

In this way, the use of the modulo operator won't necessitate you to explicitly check every possible player_coord position, in which the condition would be true.

EDIT - also, sorry for the late response. If you have any other questions don't hesitate to ask.
Last edited on
Awesome, that should be all I need. Really appreciate the help.
Well, I figured out the LEFT side of the screen:

1
2
3
4
5
6
7
8
9
10
case 'a':
case 'A':
     if (player_coord % HORIZONTAL == 0){
	inputReq = true;
	cout << "\rCharacter is going out of range, try again.";
					break;
				}
		player_coord -= 1;
		inputReq = false;
			break;


So the movement is blocked at the left side of the map.

NOW I need to figure out the right-side of the map. I can't seem to figure out a formula that works for the right using the 'd' key.


1
2
3
4
5
6
7
8
9
10
11
12

case 'd':
case 'D':
                
	if (player_coord == HORIZONTAL*VERTICLE-1){
	inputReq = true;
	cout << "\rCharacter is going out of range, try again.";
					break;
				} 
	player_coord += 1;
	inputReq = false;
		break;


This blocks movement at the VERY BOTTOM RIGHT of the screen, but obviously not the lines before it. If I do something like

(player_coord % HORIZONTAL != (HORIZONTAL - 1)

it will block the movement altogether.

Any logic around this? I'm exhausted. lol
Last edited on
Hello again,

I suspect this has something to do with how you chose to represent the world. In the code I provided, I made some comments about however you choose to do this is "implementation specific". My code only works properly if the world is set up in the following way:

1.) top-left of the world is (0, 0).
2.) top-right of the world is (world_width, 0).
3.) bottom-left of the world is (0, world_height).
4.) bottom-right of the world is (world_width, world_height).

Is this how your world is configured? Or is (0, 0) in the center? Or something else? Let me know if this is the case and I can help you further. In the mean time, I will do some testing to see if there is another potential culprit.
If you're comfortable sharing more of your code, that would help me also.
Last edited on
I was able to get it working through some brute force testing.

1
2
3
4
5
6
7
8
9
10
11
case 'd':
case 'D':

	if ((player_coord + 1) % HORIZONTAL == 0 ){
		inputReq = true;
		cout << "\rCharacter is going out of range, try again.";
			break;
		}
		player_coord += 1;
		inputReq = false;
			break;


It'll check if the player's next move to the next line will be divisible by the Horizontal Value. If the map is, for example, 10 by 10, and the player is at the very last spot (9), it will check if the next move of the player will send them to the position at 10, which will be the next line of the map. If it will, it'll block the movement.

I'll leave it up in case anyone else has similar logic issues. It's very simple logic that took me a while to understand but I got it. Thanks a ton for the help.
So now I'm having a completely different issue. I don't know if the same logic can apply to this code. I'm generating enemies, or "mobs" that will have events when stepped on.

I'm trying to generate the mobs onto the map, but I'm running into an issue.


1
2
3
4
5
6
for (int i=0; i <= mobQTY; i++) {
	mobs[i] = rand() % HORIZONTAL * VERTICLE + i;	
		while (mobs[i] == 0 || mobs[i] == 1 || mobs[i] == HORIZONTAL) {
			mobs[i]++;
		}
	}

This will generate the mobs in random spots that can fit inside the map, and ensure they wont trap the player in the beginning.


To put them onto the map, I'm trying to use this:

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
void map (char board[VERTICLE][HORIZONTAL], int mobs[], int levelEnd, int& player_coord)
{
	char c = ' ';
	int place = 0;
	int mobNum = 0;
	bool mobGen = true;

	system("cls");

	for (int i=0; i<VERTICLE; i++){
		for (int k=0; k<HORIZONTAL; k++){

			if (mobGen == true){
			    if (mobs[mobNum] == place){
				c = 'x';
				mobNum++;
			           if (mobNum == mobQTY){
                                     mobGen = false;
				}} }

			else if (levelEnd== place){
				c = 'O';
			}

			else if (player_coord == place){
				c = 'T';
			}
			else{
				c = '-';
			}

			board[i][k] = c;
			cout << " " << board[i][k];
			place++;
		}
		cout << endl;
	}
}


So what this is doing is checking to see if mobs should be placed on the map - if the mobs should be placed based on the random coordinate it was given in the other function, they will be placed.
However, I can't seem to figure out how to make the number of mobs placed controllable.

I think I just don't know how to use arrays properly.

Is there a way to make the Mob-generation stop when it hits the mobQTY set at the beginning of the code?
Last edited on
Topic archived. No new replies allowed.