Hello. I have some problems understanding the code. I'd like to ask for some help. I need someone to break it down for me. Just to explain what's going on and what's happening.

Well this is map.cpp:
I got the other bits but I am struggling with this one and I'd appreciate any help.

#include <iostream>
#include <string>
#include "map.h"
#include <Windows.h>
using namespace std;
Map::Map()
{
	map = new string[12];
	map[0]  = "XXXXXXXXXXXXXXXXXXXXXXXX";
	map[1]  = "X   X                XeX";
	map[2]  = "X   X                X X";
	map[3]  = "X   X                  X";
	map[4]  = "X   XX@XXXXXXXXXXXXXXXXX";
	map[5]  = "X              X       X";
	map[6]  = "X              X   k   X";
	map[7]  = "X   XXXXX      X       X";
	map[8]  = "X   X k X      X       X";
	map[9]  = "X   X          X       X";
	map[10] = "X>  X   X      @       X";
	map[11] = "XXXXXXXXXXXXXXXXXXXXXXXX";
}

void Map::draw()
{
	for(int i = 0; i < 12; i++)
	{
		cout << map[i] << endl;	
	}
	cout << "Keys: " << keys << endl;
}
void Map::pos(int& ppX, int& ppY)
{
	pX = ppX;
	pY = ppY;
}
char Map::getTile(int abc, int xyz)
{
	char tile = map[abc][xyz];
	return tile;
}
void Map::movePlayer(int leftright, int updown)
{
	switch(updown)
	{
	case -1:
		if(getTile((pX - 1), pY) != 'X' & getTile((pX - 1), pY) != 'k'  & getTile((pX - 1), pY) != '@' & getTile((pX - 1), pY) != ' ')
		{
			system("cls");
			cout << "YOU WIN" << endl;
			system("pause");
			exit (1);
		}
		if(getTile((pX - 1), pY) != 'X' & getTile((pX - 1), pY) != 'k'  & getTile((pX - 1), pY) != '@')
		{
			setTile(pX, pY, ' ');
			setTile((pX - 1), pY, '^');
			pX--;
		}
		else
		{
			if(getTile((pX - 1), pY) != 'X' & getTile((pX - 1), pY) != 'k'  & getTile((pX - 1), pY) != ' ')
			{
				if(keys > 0)
				{
					keys--;
					setTile(pX, pY, ' ');
					setTile((pX - 1), pY, '^');
					pX--;
				}
			}
			setTile(pX, pY, '^');
		}
		break;
	case 0:
		break;
	case 1:
		if(getTile((pX + 1), pY) != 'X' & getTile((pX + 1), pY) != 'k'  & getTile((pX + 1), pY) != '@')
		{
			setTile(pX, pY, ' ');
			setTile((pX + 1), pY, 'V');
			pX++;
		}
		else
		{
			if(getTile((pX + 1), pY) != 'X' & getTile((pX + 1), pY) != 'k'  & getTile((pX + 1), pY) != ' ')
			{
				if(keys > 0)
				{
					keys--;
					setTile(pX, pY, ' ');
					setTile((pX + 1), pY, 'V');
					pX++;
				}
			}
			setTile(pX, pY, 'V');
		}
		break;
	}
	switch(leftright)
	{
	case -1:
		if(getTile(pX, (pY - 1)) != 'X' & getTile(pX, (pY - 1)) != 'k'  & getTile(pX, (pY - 1)) != '@')
		{
			setTile(pX, pY, ' ');
			setTile(pX, (pY - 1), '<');
			pY--;
		}
		else
		{
			if(getTile(pX, (pY - 1)) != 'X' & getTile(pX, (pY - 1)) != 'k'  & getTile(pX, (pY - 1)) != ' ')
			{
				if(keys > 0)
				{
					keys--;
					setTile(pX, pY, ' ');
					setTile(pX, (pY - 1), '<');
					pY--;
				}
			}
			setTile(pX, pY, '<');
		}
		break;
	case 0:
		break;
	case 1:
		if(getTile(pX, (pY + 1)) != 'X' & getTile(pX, (pY + 1)) != 'k'  & getTile(pX, (pY + 1)) != '@')
		{
			setTile(pX, pY, ' ');
			setTile(pX, (pY + 1), '>');
			pY++;
		}
		else
		{
			if(getTile(pX, (pY + 1)) != 'X' & getTile(pX, (pY + 1)) != 'k'  & getTile(pX, (pY + 1)) != ' ')
			{
				if(keys > 0)
				{
					keys--;
					setTile(pX, pY, ' ');
					setTile(pX, (pY + 1), '>');
					pY++;
				}
			}
			setTile(pX, pY, '>');
		}
		break;
	}
}
void Map::setTile(int x, int y, char z)
{
	map[x][y] = z;
}
void Map::fire()
{
	char direction = getTile(pX, pY);
	switch(direction)
	{
	case '^':
		fX = pX;
		fY = pY;
		while(getTile((fX - 1), fY) != 'X' & getTile((fX - 1), fY) != '@')
		{
			if(getTile((fX - 1), fY) != ' ' & getTile((fX - 1), fY) != 'X' & getTile((fX - 1), fY) != '@')
			{
				keys++;
			}
			setTile((fX - 1), fY, '*');
			fX--;
			setTile((fX+1), fY, ' ');
			setTile(pX, pY, '^');
			system("cls");
			draw();
		}
		setTile(fX, fY, ' ');
		setTile(pX, pY, '^');
		break;
	case 'V':
		fX = pX;
		fY = pY;
		while(getTile((fX + 1), fY) != 'X' & getTile((fX + 1), fY) != '@')
		{
			if(getTile((fX + 1), fY) != ' ' & getTile((fX + 1), fY) != 'X' & getTile((fX + 1), fY) != '@')
			{
				keys++;
			}
			setTile((fX + 1), fY, '*');
			fX++;
			setTile((fX -1), fY, ' ');
			setTile(pX, pY, 'V');
			system("cls");
			draw();
		}
		setTile(fX, fY, ' ');
		setTile(pX, pY, 'V');
		break;
	case '<':
		fX = pX;
		fY = pY;
		while(getTile(fX, (fY - 1)) != 'X' & getTile(fX, (fY - 1)) != '@')
		{
			if(getTile(fX, (fY - 1)) != ' ' & getTile(fX, (fY - 1)) != 'X' & getTile(fX, (fY - 1)) != '@')
			{
				keys++;
			}
			setTile(fX, (fY - 1), '*');
			fY--;
			setTile(fX, (fY + 1), ' ');
			setTile(pX, pY, '<');
			system("cls");
			draw();
		}
		setTile(fX, fY, ' ');
		setTile(pX, pY, '<');
		break;
	case '>':
		fX = pX;
		fY = pY;
		while(getTile(fX, (fY + 1)) != 'X' & getTile(fX, (fY + 1)) != '@')
		{
			if(getTile(fX, (fY + 1)) != ' ' & getTile(fX, (fY + 1)) != 'X' & getTile(fX, (fY +  1)) != '@')
			{
				keys++;
			}
			setTile(fX, (fY + 1), '*');
			fY++;
			setTile(fX, (fY - 1), ' ');
			setTile(pX, pY, '>');
			system("cls");
			draw();
		}
		setTile(fX, fY, ' ');
		setTile(pX, pY, '>');
		break;
	}
}

void Map::setkeys(int keynum)
{
	keys = keynum;
}

Recommended Answers

All 9 Replies

Hi,
Welcome to DANIWEB
It would be better if you would tell us which parts are confusing you. Then MAYBE you will get faster replies

Thank you. Fair enough, I had to be more clear.

Alrighty, first we need the header file for that file called map, right, here it is.

#include <iostream>
#include <string>

using namespace std;

class Map
{
private:
	int pX;
	int pY;
	int fX;
	int fY;
	int keys;
	string* map;

public:
	Map();
	void pos(int&, int&);
	char getTile(int, int);
	void setTile(int, int, char);
	void movePlayer(int, int);
	void draw();
	void fire();
	void setkeys(int);
};

We are setting integers and chars for getTile and setTile, as far as I see it has to be for the collision, right? I couldn't find much info about that.
After we finish the class for the map

Map::Map()

we need the bloody player to move somehow and all is getting super confusing after

void Map::movePlayer(int leftright, int updown)

I mean the fire method should be the same as the moving process, they seem quite similar but I cannot understand any of them

void Map::fire()
{
	char direction = getTile(pX, pY);
	switch(direction)

So if someone could give it a go and try to explain the moving process

void Map::movePlayer(int leftright, int updown)
{
	switch(updown)
	{
	case -1:
		if(getTile((pX - 1), pY) != 'X' & getTile((pX - 1), pY) != 'k'  & getTile((pX - 1), pY) != '@' & getTile((pX - 1), pY) != ' ')
		{

it would be super cool. Kind Regards.

Can you explain the purpose of each argument in the movePlayer function ?
Also what is the function getTitle supposed to return ?

The way this is done is confusing a lot. I believe it could be better if it could be simplified.

Hello SQLPOWER,
The code which you have presented here is rather based upon several different considerations. I will put my best efforts in understanding the code and explaining it to you, However the writer of the code took a very obscure approach towards coding it.

So lets look at each question of yours and determine an answer.
1>>
We are setting integers and chars for getTile and setTile, as far as I see it has to be for the collision, right? I couldn't find much info about that.
After we finish the class for the map

Your map is like a big Grid of characters. Each row is represented as std::string (which is again a container for characters.)
So you have an array of strings.
Thereby each character on the map can be represented in the form of (x,y) coordinates.

So when we can do something like

char c= GetTile(0,0);
//returning the first character of the grid.
char d= GetTile (10,1);
//To get the 2nd character of the 9th row [since index starts from 0]

On the other hand

SetTile(0,0,'x');
//Would place x on the first character of the grid.
SetTile (10,1,'y');
would place y in the second character of the 9th row and so on.

Now I hope that functions GetTile and SetTile are clear.

Then NOW Let us examine the MovePlayer function.
I completely AGREE that this can be improved highly and significantly.
As I dont know the exact meanings of the characters. I would rather put it up like this.
Assumptions:

X-Represents a wall
@-Represents a Target
k-Represents a Key
' '- Represents an empty travellable space.
e-Is the ending location.
<,>,^,v -> All those characters represent the player and the side he faces.

So the method MovePlayer takes in two arguements.
A player can only travel up, down, right or left at a single instance. Failing which the algorithms working is seriously flawed.

So valid inputs maybe only MovePlayer (-1, 0)
or MovePlayer(0,1)
Note that it must be looked that atleast 1 argument must be 0 to work fine(I think).

So for a top-down movement

(0,-1) ->Moves the player(Character) one step 'up' unless there's a wall.
(0,1) ->Moves the player (Character) one step 'down' unless there's a wall.

And for sideways movement

(-1,0 ) ->Moves the player ONE step to the 'left' checking the conditions that there's no wall and so it is with (1,0) being passed.

The character changes symbols from <,>,v,^ basing upon the last moved direction.
And if the moved Block is a 'key' the variable key is incremented by one.

the fire() throws a fireball '*' towards the direction the character is facing until it reaches a target (@) or a wall (X).

Honestly speaking, This code is rather of not much use, As you can devise a better way of moving across the maze.

A suggestion would be to use '&&' logical AND rather than '&' which is the BIT-WISE AND.

Hope it helps.

Hey, SkyDiploma, thank you very much, helped me understand some bits and some things which were unclear. Anyway, I know this method is not very clear and seems super weird.

void Maze::movePlayer(int dx, int dy)
{
	// calculate the new player position (newx,newy)
	int newx = player.getX() + dx;
	int newy = player.getY() + dy;
	// get the tile at the new position
	char newt = getTile(newx, newy);

	// handle new position tile
	switch(newt)
	{
	case 'X':							// if it is a wall tile
		newx = player.getX();			// set newx to current x
		newy = player.getY();			// set newy to current y
		break;
	case 'k':							// if it is a key
		player.addKey();				// add a key to the player
		setTile(newx, newy, ' ');		// remove the key from the maze
		break;
	case '+':							// if it is a door
		if (player.useKey())			// try to use a key
		{
			setTile(newx, newy, ' ');	// open the door if the player used a key
		}
		else
		{
			newx = player.getX();		// set newx to current x 
			newy = player.getY();		// set newy to current y
		}
		break;
	}

This one has to be better. Well it is definitely clearer than the other one. Thanks for the help anyway. :)

I believe that this is rather very neat. However, How will you go about the fire-mechanism?
And how would the player move through empty spaces?

Don't need a fire mechanism now. I am now trying to put some wandering guards, patrolling around the rows but I don't know how to do it. Do you have any ideas how to add patrolling guards? I tried to put them as a case but they are just a static characters. So should I create a septate class for an enemy? Got confused about this guards. Another forum member told me to use time system but couldn't set it right.
The code it isn't mine I am just trying to add some additional features. Our teacher just gave it to us in order to understand it. The other was a poor attempt to program the game...

void main()
{
	Maze m;
	char key;

	while (!m.isEnd())
	{
		// draw the maze
		m.draw();
		// get the next keypress
		key = _getch();

		// handle the key press
		switch(key)
		{
		case 'w':
			m.movePlayer(0, -1);
			break;
		case 'a':
			m.movePlayer(-1, 0);
			break;
		case 's':
			m.movePlayer(0, 1);
			break;
		case 'd':
			m.movePlayer(1, 0);
			break;
		}
	}
;

Imagine this,
Consider for every move a player makes, the gaurd will also make a move. The player however is controlled by the user and the gaurd controlled by the computer.

So you could try to implement something like this.
Let's assume that the gaurd must move up/down. So each time the player moves, lets make the gaurd move. This can be done in the same way as you move the player . with the GetTile() and SetTile() functions. However here's the catch. When ever thee gaurd tries to move onto a wall.. he must reverse his direction.

Assume that the gaurd is moving down.. if he see's that the next Tile is a wall, he should then switch direction upwards.

Tip: A Clever implementation of a function and a static variable to move the gaurd can be a clear-cut way to make the gaurd move.

However this would work fine for 1 gaurd. For more than one gaurd. you should go to higher levels of code.
For a start try implementing what I've said in anyway you want.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.