Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Oct 10th, 2007, 4:31 PM   #31
nisim777
Newbie
 
Join Date: May 2005
Posts: 17
Rep Power: 0 nisim777 is on a distinguished road
Quote:
Originally Posted by Arevos View Post
The above code is only a few lines, but will enable you to use commands such as "look" and "go west", and is easily extensible. It may be rather tricky to understand at first, but it may be worth taking the time to figure out how it works. If you've any questions, don't hesitate to ask! Sometimes I'm not all that clear.
Sorry, I've been sick the last few days so I haven't even looked at the code - finally had a chance to look at it this afternoon. Confused the crap out of me at first, but I think I've got it now. I'm still trying to wrap my mind around DaWei's suggestion of a list of lists. I know about nested lists, but I'm trying to figure out how to integrate his idea and yours so that if a user says 'examine head' it picks examine from the verbs section and head from the nouns section and the proper description. Then if they say 'jump head' it does the same thing, with the appropriate description. I'm on my way to grasping it and then I run into the need for conditionals. If they examine the head, then jump on the head, and then examine it again, the last examine statement for that head needs to be different, like 'the head is crushed.'

I'll get there. I learn as I need. For instance, I never had a need in PHP for regular expressions until I needed to verify that data inserted into an e-mail field was actually an e-mail (with the @ and .com/.net, etc.), so I learned how to do it. In Python I could not do it. I've never needed to use * for parsing and the split() function. Now I need it, so I'll learn it.
nisim777 is offline   Reply With Quote
Old Oct 10th, 2007, 11:00 PM   #32
DaWei
Resident Grouch
 
DaWei's Avatar
 
Join Date: Jun 2005
Posts: 6,453
Rep Power: 10 DaWei is on a distinguished road
The state of an object, if it has multiple states, would just be a variable of some sort. The head could be there, missing, crushed, etc., just part of a particular object's design. There might be a parent enemy object with derived objects which are defeatable in differing ways, for instance.

Again, the object, by design, know how to react to a stimulus. You don't need to test the object for type every time you encounter one.
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code.
Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers
DaWei is offline   Reply With Quote
Old Oct 11th, 2007, 6:07 AM   #33
Arevos
Programming Guru
 
Arevos's Avatar
 
Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 5 Arevos is on a distinguished road
Quote:
Originally Posted by nisim777 View Post
Then if they say 'jump head' it does the same thing, with the appropriate description. I'm on my way to grasping it and then I run into the need for conditionals. If they examine the head, then jump on the head, and then examine it again, the last examine statement for that head needs to be different, like 'the head is crushed.'
As DaWei says, you'd encapsulate the conditionals in the object itself. For example:

python Syntax (Toggle Plain Text)
  1. class Room(object):
  2. def __init__(self, description):
  3. self.description = description
  4. self.exits = {}
  5. self.items = []
  6.  
  7. def find_item(self, name):
  8. for item in self.items:
  9. if item.name == name:
  10. return item
  11.  
  12. class Player(object):
  13. def examine(self, noun):
  14. self.action("examine", noun)
  15.  
  16. def jump(self, noun):
  17. self.action("jump", noun);
  18.  
  19. def action(self, verb, noun)
  20. item = self.room.find_item(noun)
  21. method = "on_" + verb
  22.  
  23. if item is None:
  24. print "I don't see that anywhere."
  25. elif method not in dir(item):
  26. print "You can't %0 on that!" % verb
  27. else:
  28. getattr(item, method)()
  29.  
  30. class Head(object):
  31. def __init__(self):
  32. self.name = "head"
  33. self.state = "intact"
  34.  
  35. def on_examine(self):
  36. if self.state == "intact":
  37. print "An intact head."
  38. elif self.state == "crushed":
  39. print "A horribly crushed head."
  40.  
  41. def on_jump(self):
  42. print "You jump on the head"
  43. self.state = "crushed"
The above code is complex, but shouldn't contain too many strange features. The only bits you might not have run across are "dir" and "getattr".

dir gets you the names of all the attributes of an object (methods, variables, etc.), whilst getattr gets a named attribute from an object. So getattr(item, "on_jump") is the same as item.onjump.

Sorry to keep throwing code at you! If you need any explanations, I'll be happy to expand on anything that's difficult to understand.
Arevos is offline   Reply With Quote
Old Oct 11th, 2007, 9:55 PM   #34
Jessehk
The Oblivious One
 
Jessehk's Avatar
 
Join Date: May 2005
Location: Ontario, Canada
Posts: 641
Rep Power: 4 Jessehk is on a distinguished road
This might be a bit off topic, but I was having fun. I took the code that was started and made a little item system that I like.

I added an items property to both the Room class and the Player class. Then I wrote an actions.py file that contains the definitons for any generic actions.

For example:
python Syntax (Toggle Plain Text)
  1. """
  2. Functions that define actions.
  3. """
  4.  
  5. def makeCall(player=None):
  6. number = raw_input("Enter phone #: ")
  7. print "Oops. %s is not answering right now." % number
  8.  
  9.  
  10. def heal(amt):
  11. def healN(player):
  12. print "You have recovered %s health points." % amt
  13.  
  14. return healN

And then in items.py:
python Syntax (Toggle Plain Text)
  1. import hag.actions
  2.  
  3. class Item(object):
  4. def __init__(self, name, description, useAction, isGlobal, singleUse):
  5. """
  6. An item's action is a function (or method) that
  7. is called when the item is used. For example, an item
  8. such as a potion may have an action called heal() that heals
  9. a specific player a given amount of health.
  10.  
  11. isGlobal: Defines if the item is globally available, or local to a certain room
  12. singleUse: Defines if the item can be used only once.
  13. """
  14. self.name = name
  15. self.description = description
  16. self.use = useAction
  17. self.isGlobal = isGlobal
  18. self.singleUse = singleUse
  19.  
  20. phone = Item(name="phone",
  21. description="an old fashioned telephone. It looks like it still works.",
  22. useAction=hag.actions.makeCall,
  23. isGlobal=False,
  24. singleUse=False)
  25.  
  26. potion = Item(name="potion",
  27. description="a strange looking vial filled with a clear liquid.",
  28. useAction=hag.actions.heal(10),
  29. isGlobal=True,
  30. singleUse=True)

Oh, and by the way, hag = House Adventure Game.

So the way I've set it up:
==> look
You are in a large, dark foyer. An immense crystal chandelier hangs
rougly six feet about your head. The room is dark and menacing, though
you can't quite explain why. There is some furniture in the corner that
looks antique -- this place must be old. You notice a telephone in the
other corner. It might prove useful if you want to call over some friends
to help investigate. 

Straight ahead, you can just make out a stove through a long, twisting hallway.
It must be a kitchen. You are very hungry...

==> pickup phone

You pick up an old fashioned telephone. It looks like it still works.

==> use phone
Enter phone #: 555-555-5555
Oops. 555-555-5555 is not answering right now.
==> move north
>> You can no longer use the phone.

You move north to a vast kitchen. There are at least three large stoves
that look like they're still working. Above you, rows and rows of pots,
pans, and utensils are hanging. Several of the drawers contain knives
and other items -- they may be useful.

In the corner, there is a large fireplace that somehow
looks enticing.


==> move south

You move south to a large, dark foyer. An immense crystal chandelier hangs
rougly six feet about your head. The room is dark and menacing, though
you can't quite explain why. There is some furniture in the corner that
looks antique -- this place must be old. You notice a telephone in the
other corner. It might prove useful if you want to call over some friends
to help investigate. 

Straight ahead, you can just make out a stove through a long, twisting hallway.
It must be a kitchen. You are very hungry...


==> move east

You move east to a bright, sunny garden. There are a collection of
very exotic vines and bushes that haveoverun the place. At one time,
this garden might have been beautiful, though years of neglect have reduced to
a veritable jungle. A pair of peers at you from withing a
dark bush -- it must be a squirrel.

You notice an empty watering-pail. Maybe there is something you could water?


==> pickup potion

You pick up a strange looking vial filled with a clear liquid.

==> inventory

Your bag contains:
-- potion: a strange looking vial filled with a clear liquid.

==> move west

You move west to a large, dark foyer. An immense crystal chandelier hangs
rougly six feet about your head. The room is dark and menacing, though
you can't quite explain why. There is some furniture in the corner that
looks antique -- this place must be old. You notice a telephone in the
other corner. It might prove useful if you want to call over some friends
to help investigate. 

Straight ahead, you can just make out a stove through a long, twisting hallway.
It must be a kitchen. You are very hungry...


==> pickup phone

You pick up an old fashioned telephone. It looks like it still works.

==> inventory

Your bag contains:
-- phone: an old fashioned telephone. It looks like it still works.
-- potion: a strange looking vial filled with a clear liquid.

==> use potion
You have recovered 10 health points.

I realize that the descriptions don't quite match up with the available actions and items, but I'm playing right now.

This is a lot of fun.
__________________
Dr. Zoidberg: [ecstatic] I'm going to a movie... with FRIENDS!
Jessehk is online now   Reply With Quote
Old Oct 12th, 2007, 12:54 AM   #35
nisim777
Newbie
 
Join Date: May 2005
Posts: 17
Rep Power: 0 nisim777 is on a distinguished road
re:

DaWei: Thank you for your help. Your advice enlightens me on the theory side of all of this. I'm still getting there, but you have definitely helped.

Jessehk: Awesome code. I'd like to see the whole game. I'm sure there is a lot I could learn looking at all of your code.

Arevos: Thank you so much for your help on the practical side. I haven't always understood your examples at first, but usually after a couple of days of racking my brain, I grasp it. On the latest code, only two things confuse me. First of all, I don't fully understand the point of the method variable. In fact, I'm not sure what it does at all, and the "on_" confuses me. My other issue is not really and issue but rather a question. To produce a malleable item I should create create a class for each type of item in my game? As per your example, you have a class for the head. Then, each time I had a head in the game I would just create an instance. So I should Knife class - for any knives in my game; a Body class - for any bodies in my game; etc.? I was already considering putting a state variable in a generic Items class, but I was not sure how to implement it, but it seems easier if I create a class for each type of item.

Anyhow, thanks you all. Like I said before, I've been sick the past few days and have not touched my code. I'm going to work on it this weekend and try to implement everything you guys have shown me. Hopefully I have some results to show you guys be the beginning of next week.
nisim777 is offline   Reply With Quote
Old Oct 12th, 2007, 7:06 AM   #36
Arevos
Programming Guru
 
Arevos's Avatar
 
Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 5 Arevos is on a distinguished road
Quote:
Originally Posted by nisim777 View Post
On the latest code, only two things confuse me. First of all, I don't fully understand the point of the method variable. In fact, I'm not sure what it does at all, and the "on_" confuses me.
The "on_" is purely convention. When a verb is called on the Player object, it calls a "on_verb" method on the item being examined. e.g.

python Syntax (Toggle Plain Text)
  1. me.action("examine", "head") # calls head.on_examine
  2. me.action("jump", "head") # calls head.on_jump
  3. me.action("flubble", "head") # calls head.on_flubble

I use the "on_" notation to distinguish between the examiner, and the examinee. I could have called it "verb_event" or "verb_callback", or anything else. It's just a small convention so that the action has a different name from the response.

In other words:

a.examine(b)    - a examines b
a.on_examine(b) - a is examined by b

Quote:
Originally Posted by nisim777 View Post
My other issue is not really and issue but rather a question. To produce a malleable item I should create create a class for each type of item in my game? As per your example, you have a class for the head. Then, each time I had a head in the game I would just create an instance. So I should Knife class - for any knives in my game; a Body class - for any bodies in my game; etc.? I was already considering putting a state variable in a generic Items class, but I was not sure how to implement it, but it seems easier if I create a class for each type of item.
Inheritance allows you to have your cake and eat it, too. It gives you the advantages of generic classes like "Item", and the advantages of specific classes like "Body" or "Head":

python Syntax (Toggle Plain Text)
  1. class Item(object):
  2. def on_examine(self):
  3. print self.description
  4.  
  5. def on_take(self, player):
  6. self.room.items.remove(self)
  7. player.inventory.append(self)
  8. print "You take the " + self.name
  9.  
  10. class Body(Item):
  11. name = "body"
  12. description = "It is a rotten body"
  13.  
  14. class Head(Item)
  15. name = "head"
  16. state = "intact"
  17.  
  18. def on_examine(self):
  19. if self.state == "intact":
  20. print "An intact head."
  21. elif self.state == "crushed":
  22. print "A horribly crushed head."
  23.  
  24. def on_jump(self):
  25. print "You jump on the head"
  26. self.state = "crushed"

The Head and Body classes inherit the on_examine and on_take methods from the generic Item class. In addition to this, the Head class introduces a new on_jump method, and overrides the on_examine method to implement custom behaviour. Whilst other items only have one description, Heads have two, depending on whether they are crushed or intact.
Arevos is offline   Reply With Quote
Old Oct 12th, 2007, 6:16 PM   #37
Darkhack
Hobbyist Programmer
 
Darkhack's Avatar
 
Join Date: Dec 2005
Location: Kansas City
Posts: 102
Rep Power: 3 Darkhack is on a distinguished road
Send a message via AIM to Darkhack
OOP has been completely beyond my grasp too. I just don't see any valid reason to use it. It isn't better, just different. If you can't get the same amount of code reuse or modularity procedurally, then you're doing it wrong. Plain and simple. Linux and GNOME both have millions of lines of source code and they're all written in plain C. Do you really think they would have had a huge advantage if they were written in C++? I don't see developers falling all over themselves to write programs with Qt over GTK+ other than the fact that Qt is simply a more mature library because of its commercial backing. When it comes to technical comparisons, GTK+ is fully capable of doing anything Qt can.

Personally, I struggle when trying to write OOP code. It's very natural for me to break my code up into functions and libraries written in C, where as with OOP I find myself trying to fit a round peg into a square hole. Procedural programming lets you write your code in the fashion you think is best while the OOP methodology slaps your wrists for creating functions and variables outside of classes. Sure, you can do it, but if you are following the true OOP methodology that the object oriented nazis want you to, then you will bastardize the meaning and purpose of an object at some point in the project. That's not the fault of OOP, but there are people out there that seriously believe that if every single line of code isn't inside of "class { }" then you belong in a concentration camp until you fix your ways.

Don't even get me started on inheritance. It's like spaghetti code without the "goto". Procedural programming has you build up to more complex functions like a pyramid where as inheritance with objects reminds me of crazy stairs. As soon as you want functionality from two inherited classes as one object, you either have to create a new class that extends both (wait. Wasn't inheritance supposed to provide code reuse?) or use backwards ass coding logic to try to implement both of these ideas.

For example I have a human class and then a artist or fighter class that extends from human.

class Human
{
    string name;
    int age;

    void eat() {...}
    void sleep() {...}
}

class Artist : extends Human
{
    void paint() {...}
}

class Fighter : extends Human
{
    void punch() {...}
}

If I was a teacher and assigned you to create a text based game that had an artist and fighter characters and you took this approach, you might do okay to start out with. I give you an assignment sheet that goes through everything that the game should do. It's about 10 pages long. You go through page and by page and it is Sunday at midnight and the project is due Monday. All of a sudden you get to page 10 and you see that it asks you to make a character that is both an artist and a fighter. OOPs! (pun intended) With procedural programming I just call the functions as I need them. With OOP, I have to either waste time creating a new class, use multiple inheritance (oh help me Jesus), or use some backwards-ass logic of create a new ArtistAndFigher() class which has instances of both Artist and Fighter objects.

Don't get me wrong. OOP can be used very effectively in a lot of situations. But at the same time it becomes easier to paint yourself into a corner and it usually just adds complexity anyway because in addition to keeping track of what a function does, you are now burdened with the task of managing the relationships between objects and classes to fully understand the big picture of the project.
Darkhack is offline   Reply With Quote
Old Oct 12th, 2007, 8:37 PM   #38
Arevos
Programming Guru
 
Arevos's Avatar
 
Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 5 Arevos is on a distinguished road
Quote:
Originally Posted by Darkhack View Post
Linux and GNOME both have millions of lines of source code and they're all written in plain C. Do you really think they would have had a huge advantage if they were written in C++?
You seem to be labouring under the assumption that you need a language specifically created for OOP, which, as DaWei has pointed out several times in the past, is simply not the case.

You can write OO programs in C, and GNOME is actually good example of this. GNOME and GTK are based on a framework called GObject that provides all the usual OO tools, such as inheritance and public/protected/private permissions.

Quote:
Originally Posted by Darkhack View Post
Don't even get me started on inheritance. It's like spaghetti code without the "goto". Procedural programming has you build up to more complex functions like a pyramid where as inheritance with objects reminds me of crazy stairs. As soon as you want functionality from two inherited classes as one object, you either have to create a new class that extends both (wait. Wasn't inheritance supposed to provide code reuse?) or use backwards ass coding logic to try to implement both of these ideas.
This isn't a problem with inheritance, but more a problem with languages like Java that don't provide a mechanism for multiple inheritance. For instance, in Python, you can do:

python Syntax (Toggle Plain Text)
  1. class Person:
  2. def talk():
  3. print "Blah, blah, blah"
  4.  
  5. class Fighter(Person):
  6. def punch():
  7. print "I punch you!"
  8.  
  9. class Artist(Person):
  10. def paint():
  11. print "I paint you!"
  12.  
  13. class AngryPainter(Fighter, Artist):
  14. pass
  15.  
  16. person = AngryPainter()
  17. person.talk()
  18. person.paint()
  19. person.punch()
I agree Java sucks because you can't include methods from multiple sources, without manually outsourcing them to a static class. But this is more a problem with Java than a problem with OOP. Java simply doesn't do OOP very well, and if your experience of OOP all comes from Java, then I don't blame you if you come away with a bad impression of OOP.

However, I'd contend that your problems are more with Java's crappy object model that problems inherent to OOP itself.
Arevos is offline   Reply With Quote
Old Oct 12th, 2007, 9:43 PM   #39
Harakim
Hobbyist Programmer
 
Join Date: May 2006
Location: West Jordan, Utah, United States
Posts: 176
Rep Power: 3 Harakim is on a distinguished road
If you consider any group of elements to be oop programming, then there are very few non-OOP languages. However, if you take the wider view that languages are OOP is they support inheritence, abstract classes, and support for information hiding, then there is a schism.

Quite frankly, I feel that the best reason to use OOP is that the OOP languages generally have better libraries and more users. Also, they tend to have advanced features like garbage collection.

The other reason is reusability. The standard Java API increases my productivity 100-fold. Whenever I need the user to select a file graphically, I use JFileChooser. It takes me about 5 seconds. Some guy at Sun sat down for 10 hours and wrote a really good class for this.
Let's say one million people use this feature.
using API: one million people * 5 seconds + 10 hours = almost two man-months
without: one million people * 10 hours + 0 hours = over a thousand man-years
Thus, efficiency is gained.

If you are a good programmer, you do this in any language you use (actually, I have never used a functional language.) Procedural programming is kind of like the opposite of OOP. In OOP, you have data and things that act on the data. In Procedural, you have functions and data that gets acted ON by your function.
Harakim is offline   Reply With Quote
Old Oct 12th, 2007, 9:49 PM   #40
DaWei
Resident Grouch
 
DaWei's Avatar
 
Join Date: Jun 2005
Posts: 6,453
Rep Power: 10 DaWei is on a distinguished road
I'm somewhat aghast at the amount of poisonous viturpitude that accompamanies this subject.

I am personally against operating by edicts laid down by false priests and self-anointed gurus. If you have a couple of years to waste, review all my posts.

I challenge anyone, however, to back away from programming, and design something useful to the human race, while ignoring object-oriented design.

If one succeeds in that, in any reasonably complex endeavor, without resorting to the design of objects, I will kiss their ass on the quarterdeck in front of God, the admiral, and a bevy of scantily clad beauties.

Generally speaking, things don't behave as they are instructed from moment to moment. Left to themselves, they behave in a manner consistent with what they ARE.

This is not entirely consistent with the nature of the current crop of microprocessors. I spent YEARS talking to uPs in their native language. One can work wonders doing that (relatively speaking). It hurts.

It is a wonderful thing that someone, anyone, can present abstractions, despite the overwhelming costs, that free one from having to do that.

Really, get a grip. Being a dummy is not cool.
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code.
Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers
DaWei is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Learning old languages Wizard1988 Coder's Corner Lounge 26 Sep 16th, 2007 10:10 PM
OOP design question rwm C++ 7 May 28th, 2007 2:46 AM




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 11:44 PM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC