Jump to content

n00b class question

- - - - -

This topic has been archived. This means that you cannot reply to this topic.
15 replies to this topic

#1
MerakSpielman

MerakSpielman

    Learning Programmer

  • Members
  • PipPipPip
  • 44 posts
Hi, I'm fairly new to C++. As a programming friend puts it, "Ah, you're still learning to speak C." But I'm learning through setting goals and then trying to solve them. Currently, my self-appointed assignment is to develop a very basic text game. My prime focus is to really understand classes and exactly what I can do with them.

Here's the problem I'm having at the moment. I'm defining a class called "room." I want it to contain all the fundamental properties of a room in this text game, such as its description, exits, and so on. The description was easy. The exits are harder.

I want the variable I'm using for the exits to be able to directly relate to their destination. My first idea was to make each room have a string variable called, "N_Exit" (for the North exit of the room) for instance, which I could later assign to be "Room_2".

Let me say it in code, even though it didn't work. I'll cut out the extraneous stuff.


class room

{

Public:

string N_Exit, S_Exit, E_Exit, W_Exit;

} room001, room002, room003;

later on, I define the exits of those particular rooms.

room001.N_Exit = "room002";

room002.S_Exit = "room001";

See where I'm going here? I'm trying to make it so that when the user inputs that he wants to move north, the game will look at the N_Exit designation for the room he's currently in, and switch the current room designation to the value of N_Exit.

To do this I created another object of class room, and designated it to contain the data of room001 (the starting room).

room Current_Room;

Current_Room = room001;

It seemed to work, at least, when I input the command to show the room description of Current_Room, it outputted the description of room001. But maybe I should be using a pointer here? I don't quite understand when I should use pointers yet. Should Current_Room just be a pointer?

But I'm having a devil of a time getting the Current_Room to change. This is the sequence I tried when the user inputs the command to travel North from room001 (into room002):


if (usercommand = "n") and (Current_Room.N_Exit != "0")

  {

  Current_Room = Current_Room.N_Exit;

  }

(I'm assigning "0" as the value for the exit if you can't go that way)

This seemed a little iffy to me, and indeed, the compiler rejected it. The deal is, the text string for Current_Room.N_Exit is valid text for an existing object of class room, so I thought maybe it would work.

Ultimately, I guess my question boils down to how do I use the contents of a string to designate a class?

The compiler doesn't like it when I mix types. It says Current_Room is a class, and Current_Room.N_Exit is a string, and can't make one of them equal another.

I know this has GOT to be really basic, and all I need is the right syntax, so that's why it's a n00b question. But if I can't figure out the basic stuff, I'm not going to be able to do complex stuff later on. :)

#2
MerakSpielman

MerakSpielman

    Learning Programmer

  • Members
  • PipPipPip
  • 44 posts
Hm... I'm also trying to make a function that returns a string. It says

'string' does not name a type.

Hm.....


edit: Figured this part out. Just worry about my initial post... :D

#3
dargueta

dargueta

    Writes binary right handed and hex left handed

  • Moderators
  • 4,720 posts
Actually, it's not as basic as it seems. What it looks like you need to do is the following:
(1) Create a class (or struct) called Exit that contains two fields, a string called name and a pointer to a Room class. Put these in your Room class instead of the strings. Set the nextRoom pointer to null if you can't go that way.
(2) When you input the direction, just use a simple if-else block to check which way the user wants to go, and then set the currRoom variable to the room pointer in your current room. For example:

[HIGHLIGHT="C++"]
class Room;

struct Exit
{
string exitName;
Room *nextRoom;
};

class Room
{
public:
Exit north;
Exit south;
Exit east;
Exit west;
//constructors and other methods here.
};

int main(int argc, char **argv)
{
Room *currRoom = new Room();
//other stuff, i.e. inputting commands, whatever.
if((usercommand == "n")&&(currRoom->north.nextRoom != NULL))
currRoom = currRoom->north.nextRoom;
else if((usercommand == "s")&&(currRoom->south.nextRoom != NULL))
currRoom = currRoom->south.nextRoom;
//etc.
}
[/HIGHLIGHT]

#4
MerakSpielman

MerakSpielman

    Learning Programmer

  • Members
  • PipPipPip
  • 44 posts
Thanks, I'll give it a shot! I'll learn this yet...

edit: I wonder if I'll be able to figure out a grammar parser... lol


edit again:

a question about you code. I see the line

Room *currRoom = new Room();

I think I mentioned I'm a bit confused about pointers... I see you're declaring a pointer of class Room. I see that you're assigning it to point somewhere. But I don't understand the syntax of "new Room();"
It looks like you're calling a Room like it was a function. How does that work?

If you start in Room_001, for instance, wouldn't you just say
Room *currRoom = Room_001;
?

#5
dargueta

dargueta

    Writes binary right handed and hex left handed

  • Moderators
  • 4,720 posts
No. currRoom is a pointer to a room, whereas Room_001 is a Room object itself. You have to do this with pointers, otherwise you'd have to copy the data members one by one. Are you familiar with constructors, destructors, and the like? If not, then look at these tutorials:

Classes I.
Classes II - Advanced Stuff (You probably won't need this)
Pointers
Using new and delete

#6
MerakSpielman

MerakSpielman

    Learning Programmer

  • Members
  • PipPipPip
  • 44 posts
OK, I've now figured out constructors, deconstructors, and prototypes. Or at least I have a general idea how to declare them and get them doing what I want them to do, which will have to be good enough for the moment.

new and delete, those are new for me. I'm also getting the clue that the << and >> operators might be useful for me, too. I'm trying to get it so I can use user input to name new objects, so the player can input their own name and it will be saved as an object of class "player" for instance.

I'm getting there, slowly but surely. Thanks for your help, dargueta. :)

#7
dargueta

dargueta

    Writes binary right handed and hex left handed

  • Moderators
  • 4,720 posts
You're quite welcome. Feel free to ask any more questions.

#8
MerakSpielman

MerakSpielman

    Learning Programmer

  • Members
  • PipPipPip
  • 44 posts
aaaack!

I have a new situation that's driving me nuts.

I've done as you suggested. But for some reason it's insisting my "exit" class doesn't exist.

That is to say, class exit is declared before class room, but class room still can't see it.

class room;
    
class exit
{
      public:
             string Exit_Name;
             room *nextroom;
             exit();
             ~exit();
};

class room
{
      public:
             string description;
             exit Nexit;
             exit NEexit;
             exit Eexit;
             exit SEexit;
             exit Sexit;
             exit SWexit;
             exit Wexit;
             exit NWexit;
             exit Uexit;
             exit Dexit;     
             room();
             ~room();          
}Room_001, Room_002; 

If I don't include the first empty "class room;" line, I get the following error:
ISO C++ forbids declaration of `room' with no type

So I figured I needed to declare "room" first, and stuck an empty "class room;" line above it. That successfully eliminated that error. (edit: though now I worry that it was created without the proper variables)

My next errors are for each of the "exit" lines inside class room. Each one of them returns the compilation error:
'exit' does not define a type

This is a different error than the other one, though grammatically it seems to be saying the same thing. But it's saying this when I have the class exit clearly defined right above it. In fact, no matter where in my code I try to define an object of class exit it returns the same error.

I tried changing the name of class exit, in case 'exit' was somehow a reserved word, but it didn't help.

A google search indicated that often this error occurs when "use namespace.std" is missing. But I have it, so that's not the problem either.

edit: in case it matters, there are prototypes defined for both exit and room, directly underneath the code you see above, like so:

room::room()
{};

exit::exit()
{};


#9
MerakSpielman

MerakSpielman

    Learning Programmer

  • Members
  • PipPipPip
  • 44 posts
Odd... I swear I messed around with changing the spelling of the "exit" class, but it didn't work.

But on a whim I decided to capitalize it ("Exit"), and now it's compiling.

Let's give it a whirl and see how it goes...

#10
WingedPanther

WingedPanther

    A spammer's worst nightmare

  • Moderators
  • 16,831 posts
exit is a pre-defined function in C++. You can't redefine it to be a class.
Programming is a branch of mathematics.
My CodeCall Blog | My Personal Blog

#11
dargueta

dargueta

    Writes binary right handed and hex left handed

  • Moderators
  • 4,720 posts
As a programming convention, type names start with a capital letter, e.g. MyClass. Variable names start with a lowercase letter, e.g. myVar. That way, the chance of name clashing is reduced significantly.

#12
MerakSpielman

MerakSpielman

    Learning Programmer

  • Members
  • PipPipPip
  • 44 posts
Ah, programming conventions. I should learn those. Won't do me much good if I can program like a wizard but only I can make sense of my code...


Anyway, I'm making progress now. I can freely move between rooms I define, and they'll display their room titles and descriptions as I go. If I wanted to, I could design a huge text-game world map and enter it in, but since the only thing the player could do is move around in it, there isn't much point.

Next I have to figure out how to create items in the world for the character to interact with or pick up. :)

And if I can figure that out (I've been pondering how to do an "inventory" for about 3 days now), I'll start working on saving and loading games.

If I can get THAT working, maybe I'll try my hand at a language parser, the bit of technology that really made ZORK shine, back in its day. This will easily be the most complicated and longest thing involved in this project, but I figure I'll learn a lot, even if I fail. :)