Problem with my text game.

Started by
6 comments, last by GotenRulezU 19 years, 6 months ago
Ok you guys are going to hate me for this gigantic piece of uncommented code. The first problem I have is that the map is printing the monster (m) 1 to the right of where it should be. I specified 5,2 and it put it at 6,2. The second problem I have is that when I run my program it prints the map once then just sits there. It doesn't terminate or anything like that it just sits there.When I click the x it doesn't give me an error message or anything it just stops. The problem must be in the update function of the map class or in the collision detection function of the player class. BTW I know i'm stupid for most of my classes I could have used inheritance to make it less code but stupid me :) I have my monsters and items stored in vectors. Is there a way to have the items and monsters added to the vectors inside their constructors. I thought this would work but it didn't. cItem(....){items.push_back(this);} Anyways here is my incredibly long but SIMPLE source code. I will be very greatfull for any help I can get on this. I'm stumped. I tried the debugger but since it doesn't terminate and I cant see any changes in variables I can't figure it out. I bow to the knowledge of the code gods and pray for answers :) Thanks SOURCE

#include<iostream>
#include<string>
#include<vector>
using namespace std;
class cPlayer;
class cGame;
class cMap;
class cMonster;
class cItem;
vector<cMonster> monsters;
vector<cItem> items;
class cPlayer{
private:
	int x;
	int y;
	string name;
public:
	cPlayer(int sx, int sy, string sname);
	int getX();
	int getY();
	void setX(int newx);
	void setY(int newy);
	void setXY(int newx, int newy);
	void up();
	void down();
	void left();
	void right();
	void collisionDetect(cGame game, cMap map);
	bool isValid(cMap map, int newx, int newy);
	string getName();
	void setName(string newname);
};
class cMonster{
private:
	int x;
	int y;
	string name;
public:
	cMonster(int sx, int sy, string newname);
	int getX();
	int getY();
	void setX(int newx);
	void setY(int newy);
	void setXY(int newx,int newy);
	void up();
	void down();
	void left();
	void right();
};
class cGame{
private:
	bool gameover;
public:
	cGame();
	void gameOver();
	void startMenu();
	void gameMenu(cPlayer player);
	void run(cGame game, cMap map, cPlayer player);
};
class cMap{
private:
	int x;
	int y;
public:
	cMap(int sx,int sy);
	int getX();
	int getY();
	void update();
};
class cItem{
private:
	bool used;
	int x;
	int y;
	int effect;
public:
	cItem(int sx, int sy, int seffect);
	int getX();
	int getY();
	int getEffect();
	bool isUsed();
	void setX(int newx);
	void setY(int newy);
	void setXY(int newx, int newy);
	void use();
};
cPlayer player1(0,0,"");
int main(){
	cGame game;
	cMap map(10,10);
	cItem item1(2,2,3);
	items.push_back(item1);
	cMonster monster1(5,2,"Fred");
	monsters.push_back(monster1);
	game.run(game,map,player1);
	return 0;
}

cPlayer::cPlayer(int sx,int sy, string sname){
	x = sx;
	y = sy;
	name = sname;
}
void cPlayer::collisionDetect(cGame game,cMap map){
	for(int c = 0; c < monsters.size(); c++){	
		for(int i = map.getY(); i > 0; i--){
			for(int j = map.getX(); j > 0; j++){
				if(monsters[c].getX() == j && monsters[c].getY() == i){
					game.gameOver();
					return;
				}
			}
		}
	}
	for(int d = 0; d < items.size(); d++){
		for(int a = map.getY(); a > 0; a++){
			for(int b = map.getX(); b > 0; b++){
				if(items[d].getX() == b && items[d].getY() == a && items[d].isUsed() == false){
					cout<<"got item!";
				}
			}
		}
	}
}
void cPlayer::down(){
	y--;
}
int cPlayer::getX(){
	return x;
}
int cPlayer::getY(){
	return y;
}
bool cPlayer::isValid(cMap map, int newx, int newy){
	if(newx <= map.getX() && newy <= map.getY() && newx >= 0 && newy >= 0){
		return true;
	}
	return false;
}
void cPlayer::left(){
	x--;
}
void cPlayer::right(){
	x++;
}
void cPlayer::setX(int newx){
	x = newx;
}
void cPlayer::setXY(int newx, int newy){
	x = newx;
	y = newy;
}
void cPlayer::setY(int newy){
	y = newy;
}
void cPlayer::up(){
	y++;
}
string cPlayer::getName(){
	return name;
}
void cPlayer::setName(string newname){
	name = newname;
}
cMonster::cMonster(int sx, int sy, string newname){
	x = sx;
	y = sy;
	name = newname;
}
void cMonster::down(){
	y--;
}
int cMonster::getX(){
	return x;
}
int cMonster::getY(){
	return y;
}
void cMonster::left(){
	x--;
}
void cMonster::right(){
	x++;
}
void cMonster::setX(int newx){
	x = newx;
}
void cMonster::setXY(int newx, int newy){
	x = newx;
	y = newy;
}
void cMonster::setY(int newy){
	y = newy;
}
void cMonster::up(){
	y++;
}
cGame::cGame(){
}
void cGame::gameOver(){
	gameover = true;
}
void cGame::startMenu(){
	string name = "";
	cout<<"What is your name?";
	cin>>name;
	player1.setName(name);
}
void cGame::gameMenu(cPlayer player){
	int move = 0;
	cout<<"1 up, 2 down, 3 left, 4 right:";
	cin>>move;
	if(move == 1){
		player.up();
	}
	if(move == 2){
		player.down();
	}
	if(move == 3){
		player.left();
	}
	if(move == 4){
		player.right();
	}
	system("cls");
}
void cGame::run(cGame game, cMap map, cPlayer player){
	startMenu();
	while(gameover!= true){
		map.update();
		player.collisionDetect(game,map);
		gameMenu(player);
	}
}
cMap::cMap(int sx, int sy){
	x = sx;
	y = sy;
}
int cMap::getX(){
	return x;
}
int cMap::getY(){
	return y;
}
void cMap::update(){
	int done = 0;
	int key = 0;
	if( items.size() > monsters.size()){
		key = items.size();
	}
	if( items.size() < monsters.size()){
		key = monsters.size();
	}
	else{
		key = items.size();
	}	
	for(int i = y; i > 0; i--){
		for(int j = x; j > 0;j--){
			done = 0;
			if(j!=0 && j%x == 0){
				cout<<endl;
			}
			for(int k = 0; k < key; k++){ 
				if(items[k].getX() != NULL){
					if(items[k].getX() == j && items[k].getY() == i && items[k].isUsed() == false){
						cout<<"i ";
						done = 1;
					}
				}
				if(monsters[k].getX() != NULL && done != 1){
					if(monsters[k].getX() == j && monsters[k].getY() == i){
						cout<<"m ";
						done = 1;
					}
				}
				if(done == 0){
					cout<<"x ";
				}
			}
		}
	}
}
cItem::cItem(int sx, int sy, int seffect){
	x = sx;
	y = sy;
	effect = seffect;
}
int cItem::getEffect(){
	return effect;
}
int cItem::getX(){
	return x;
}
int cItem::getY(){
	return y;
}
bool cItem::isUsed(){
	return used;
}
void cItem::setX(int newx){
	x = newx;
}
void cItem::setXY(int newx,int newy){
	x = newx;
	y = newy;
}
void cItem::setY(int newy){
	y = newy;
}
void cItem::use(){
	used=true;
}



AGAIN VERY VERY SORRY FOR NO COMMENTS THANKS GUYS The source code is available for download here!
-Goten
Advertisement
Well, I'm extremely bored, so I went ahead and found your errors. I have no life.

Anyway, first off your monster is exactly where you told it to be - you're drawing the map wrong. In cMap::update, you're looping downwards in both X and Y, causing your origin to be at the bottom-right, instead of at the bottom-left, where I'm guessing you intended it to be. You need to reverse the loop for the X coordinates.

The freezing one looks like a typo. You wrote this line in cPlayer::collisionDetect:

for(int j = map.getX(); j > 0; j++){

That loop is never going to terminate, becuase you're going up and waiting for a lower bound.

I think that's it. I stopped when I found the errors you mentioned, so I don't know if there's anything else.

-RC
Can someone run the source on their debugger and see if they can find the problem?
Thanks,
-Goten
Wow dude lemme change it and see if that will fix it :)
Your insanely fast.
Ok I got that to work but its still not drawing my map right. Also I added drawing the player which also doesn't work;
update()
void cMap::update(){	int done = 0;	int key = 0;	if( items.size() > monsters.size()){		key = items.size();	}	if( items.size() < monsters.size()){		key = monsters.size();	}	else{		key = items.size();	}		for(int i = y; i > 0; i--){		for(int j = x; j > 0;j--){			done = 0;			if(j!=0 && j%x == 0){				cout<<endl;			}			for(int k = 0; k < key; k++){ 				if(items[k].getX() != NULL){					if(items[k].getX() == j && items[k].getY() == i && items[k].isUsed() == false){						cout<<"i ";						done = 1;					}				}				if(monsters[k].getX() != NULL && done != 1){					if(monsters[k].getX() == j && monsters[k].getY() == i){						cout<<"m ";						done = 1;					}				}				if(done == 0){					if(players[k].getX() == j && players[k].getY() == i){						cout<<"p ";						done = 1;					}				}				if(done == 0){					cout<<"x ";				}			}		}	}}

Thx bro,
-Goten
Quote:Original post by GotenRulezU
Can someone run the source on their debugger and see if they can find the problem?
Thanks,


Debugging is an incredibly important skill for programmers to have. Don't short-change yourself by relying on others to find and fix your bugs for you.
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
This is the line I was referring to earlier that was looping in the wrong direction was this one, which is still the same:

for(int j = x; j > 0;j--){

You are starting at a big number and going down. Instead, you should be starting at 1 and going up, like this:

for(int j = 1; j <= x; j++){

Also, this bit in your new function doesn't work at all:

if(done == 0){ if(players[k].getX() == j && players[k].getY() == i){  cout<<"p ";  done = 1; }}

First off, I would recommend you use some else ifs instead of relying on variable to decide if you've already printed anything. Next, you have no players array (unless you changed that since your first message - I've just got a variable of type cPlayer that's called player1). Third, you initialize the player you do have to the coordinates (0,0), which isn't on the map (your map goes from (1,1) to (x,y)); I changed the starting coordinates to (1,1) and it worked fine.

A few changes I would recommend are as follows:
- As already mentioned, use some else ifs in cMap::update, instead of relying on the done variable. It will make your code easier to read and harder to break.
- Make your map coordinates go from (0,0) to (x-1,y-1) instead of from (1,1) to (x,y). If you plan to have walls and other terrain features eventually (and why else would you have a class for storing the map?), this will make dealing with the arrays/vectors/whatever a lot easier.
- Change the drawing order of things. If the player is in the same square as an item, you will see the item and not the player. Likewise, a monster could hide under an item, or the player under a monster. Make sure the most important objects aren't covered up by other stuff.

-RC

EDIT: Another bit that needs to be changed, and you might not catch right away - the bit with cout<<endl needs to be changed so it doesn't put the newlines in the wrong places when the loop is modified.
Quote:Original post by JohnBolton
Quote:Original post by GotenRulezU
Can someone run the source on their debugger and see if they can find the problem?
Thanks,


Debugging is an incredibly important skill for programmers to have. Don't short-change yourself by relying on others to find and fix your bugs for you.


I agree. In fact, if I wasn't feeling bored and unusually helpful, and happen to be writing a similar game, I would probably say "figure it out yourself." If you rely on somebody else to do all of the work (that's me, right now), then you won't figure out how to do it yourself. I find these things by executing the program by hand (or in my head in this case, as there's not much to keep track of) - I recommend you try it at least try it once, regardless of whether or not you actually debug the entire program that way.

-RC
Thanks. I tried the debugger several times but I couldn't figure it out. I inserted some breakpoints and narrowed it down to which functions were messed up. Hmm I guess I could have went into the functions code and made a whole bunch of breakpoints or something. me = not skilled debugger :-/ I normally can catch the errors in my code but I guess I jus really needed some sleep last night. I tried to get too much done in one night I think. Well thank you very much for your help and suggestions. I was thinking about the player not showing up on top of items last night. I just decided to wait to change it til tonight when I get home from work. But heh I guess making a text game can be pretty complex if you want it to be :)
Again thx a lot,
-Goten

This topic is closed to new replies.

Advertisement