Programming Forums
User Name Password Register
 

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

Reply
 
Thread Tools Display Modes
Old Oct 6th, 2007, 9:23 AM   #21
Arevos
Programming Guru
 
Arevos's Avatar
 
Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 4 Arevos is on a distinguished road
Pretty good, but if you want to label your directions as "w", "e", "n" and "s", why not do something like:

python Syntax (Toggle Plain Text)
  1. foyer.exits["w"] = kitchen
  2. kitchen.exits["e"] = foyer
  3.  
  4. me = Player(foyer)
  5.  
  6. while True:
  7. choice = raw_input("What would you like to do? ").lower()
  8. if choice == "look":
  9. me.look()
  10. else:
  11. me.move(choice)
In other words, you assume that any command that you don't know about is a direction.

You can also have more than one direction leading to the same place:
python Syntax (Toggle Plain Text)
  1. foyer.exits["w"] = kitchen
  2. foyer.exits["west"] = kitchen
  3. foyer.exits["kitchen"] = kitchen
Arevos is offline   Reply With Quote
Old Oct 6th, 2007, 9:44 AM   #22
DaWei
Resident Grouch
 
DaWei's Avatar
 
Join Date: Jun 2005
Posts: 6,453
Rep Power: 10 DaWei is on a distinguished road
Without getting into the OO part, because I'd just repeat Arevos, I'll make some UI suggestions. Accept any unique left subset of a token. Devise and implement some appropriate synonyms. An example would be "get soul" and "take soul". "Get soup" might (or might not) result in, "There is no soup here".

"Go up" and "Go stairs" might be equivalent, if there were only one set of stairs, which had been described as leading upward. Verbs need some attention. "Kill goombah" might not work, where "throw grenade" might. "Kill spider" might work every time.

When one exits one place, one enters another (even if it's hyperspace). If an exit maneuver leads to the kitchen, have the transfer to the kitchen execute the kitchen.look (). This relieves the player, who can still execute the look at any subsequent time, if rereading is desirable.

In the original Adventure game there was no help. The player was expected to figure everything out, including valid commands. I recall encountering a chasm. I commanded "jump chasm". I was told that I could not jump the chasm, I would fall to the bottom and break every bone in my body. Not finding a suitable alternative right away, I commanded "jump chasm". The response was, "You are at the bottom of the chasm. Every bone in your body is broken. You are dead. Game over".
__________________
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 6th, 2007, 10:49 AM   #23
nisim777
Newbie
 
Join Date: May 2005
Posts: 17
Rep Power: 0 nisim777 is on a distinguished road
Thank you for the suggestion, DaWei. I did plan to add a much better UI, but I didn't want to get too deep into those aspects until I had a fuller understanding of what I was doing.
nisim777 is offline   Reply With Quote
Old Oct 6th, 2007, 4:45 PM   #24
nisim777
Newbie
 
Join Date: May 2005
Posts: 17
Rep Power: 0 nisim777 is on a distinguished road
Thanks for the tip on the move statement, Averos. Saves a lot of typing.
nisim777 is offline   Reply With Quote
Old Oct 6th, 2007, 7:22 PM   #25
nisim777
Newbie
 
Join Date: May 2005
Posts: 17
Rep Power: 0 nisim777 is on a distinguished road
re:

Thanks for the help guys. Here's where I am now. There is some erroneous code - just some things I've played around with. The things I'm trying to do now is set up a sort of commands database so that I don't have to have a billion if statements like

if choice == "examine head":
print foyer.items["head"]

That' fine for a room with only one object, but if I have a room with multiple objects, it could really start to pile up on me. I'm trying to think of the logic behind it - having all of my interact able objects in a dictionary or something, then having key words like EXAMINE, LOOK, TAKE, etc. Then the if statement could look along these lines:

if choice == "examine", object:
print <something>

I don't have my mind wrapped around how to do this yet.

Anyhow, here's the code for where I am:

[PHP]class Room(object):
def __init__(self, description):
self.description = description
self.exits = {}
self.items = {}

class Player(object):
def __init__(self, room):
self.room = room

def look(self):
print self.room.description

def examine(self):
print self.room.items

def move(self, direction):
if direction in self.room.exits:
self.room = self.room.exits[direction]
me.look()
else:
print "You cannot go in that direction."

#class Examines(object):
# def __init__(self, name, description):
# self.description = description
# self.name = name


foyer = Room("""
You are in the foyer of the house. The air is thick with death here.
Humidity has already caught the death stench and it permeates the house.
The house is dark. On the wall beside the entrance is a light switch.

Directly in front of you is a passage way leading deeper into the house.
At the far end of the passage way is a window, which allows a bit of
moonlight to shine into the darkness. On the left and right sides of the
hallway are small tables. Sitting on the right-hand table is the smiling
head of an elderly man, and he seems to be looking at you.
""")
kitchen = Room("You are in a dark kitchen...")

foyer.exits["west"] = kitchen
kitchen.exits["east"] = foyer
# head = Examines("head", "you see a head...")
foyer.items = {"head":"you see a head..."}



me = Player(foyer)

while True:
choice = raw_input("What would you like to do? ").lower()
if choice == "look":
me.look()
elif choice == "examine head":
print foyer.items["head"]
else:
me.move(choice)


[/PHP]

I know for those of you who are experienced in OOP it seems like I only added one thing. However, that one thing took me most of the day testing and playing around with different options to finally get an object to properly react to examination. I'll pick up steam as we go.

Last edited by nisim777; Oct 6th, 2007 at 7:40 PM.
nisim777 is offline   Reply With Quote
Old Oct 7th, 2007, 6:02 AM   #26
Arevos
Programming Guru
 
Arevos's Avatar
 
Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 4 Arevos is on a distinguished road
Quote:
Originally Posted by nisim777 View Post
I know for those of you who are experienced in OOP it seems like I only added one thing. However, that one thing took me most of the day testing and playing around with different options to finally get an object to properly react to examination. I'll pick up steam as we go.
Don't belittle yourself; adapting your way of thinking to a different programming technique is extremely difficult. Recently I've begun to delve into functional languages, and it initially took me quite some time to wrap my head around even the simplest of programs.

Regarding setting up a command database, this is a very good idea. Traditionally, adventure games use a "verb noun" format, such as DaWei's "jump chasm". You could expand this to handle multiple nouns, such as "put key lock" or "tie rope hook". These commands could be mapped onto methods like me.put("key", "lock") and me.tie("rope", "hook").

Another trick these old adventure games would use was to ignore common joining words, like "in", "the", "on", etc. So you could type in "put the key in the lock", and the program would ignore the unimportant words and leave only: ["put", "key", "lock"].
Arevos is offline   Reply With Quote
Old Oct 7th, 2007, 10:55 AM   #27
nisim777
Newbie
 
Join Date: May 2005
Posts: 17
Rep Power: 0 nisim777 is on a distinguished road
re:

Here is what I've been playing with to create the database. I know it needs to be more in depth because the result will be different if they examine, jump, put, etc.

[PHP]VERBS = ["examine", "look", "jump"]
NOUNS = {"head":"you see a head", "basket":"you see a basket"}

choice = raw_input("What would you like to do? ")

for verb in VERBS:
if verb in choice:
for noun in NOUNS:
if noun in choice:
print NOUNS[noun]

raw_input("Press enter to exit. ")[/PHP]

I did this mainly to figure out how to separate the data from a raw_input() statement. Would you suggest creating a separate dictionary for each type of verb? For example, instead of just NOUNS{}, I would have a JUMP_NOUNS{}, EX_NOUNS{}, PUT_NOUNS{}, and the dictionary definitions would be different based on which verb they use? Is their an easier or better way to do it?
nisim777 is offline   Reply With Quote
Old Oct 7th, 2007, 11:59 AM   #28
DaWei
Resident Grouch
 
DaWei's Avatar
 
Join Date: Jun 2005
Posts: 6,453
Rep Power: 10 DaWei is on a distinguished road
Your current implementation seems ineffective to me.

I don't know precisely what the difference is between "examine" and "look". If they're synonyms, they should have some relationship that is distinct from the relationship with "jump".

You might want to consider lists of lists, or something similar. For instance, the first list in verbs would contain "examine" and "look" and the second list would contain "jump" (and possibly "leap").

The first list in nouns (for "head") might contain "you see a head" and "you have just crushed a head and exposed a florb buried within", depending upon whether you were looking or jumping. The second (for "basket") might contain "you see a large basket, its bottom obscured by a thin layer of smoke" and "you have just jumped into a large basket, slid down the side, fallen through a hole, and are in the basement".

By making these things objects, you can exercise fine control in a tight locale without splattering complex conditionals throughout the code. You may have a parent basket with generalized basket-features from which you derive small baskets that get crushed when jumped on, or large baskets that one might jump into. You know where to put the actions, and it isn't throughout the code at each place where a basket is encountered.

In other words, you don't need tons of conditionals to determine the type of an object, when it's encountered, so that you may select an appropriate action. The action was determined when you invented the object and described its characteristics and actions. When an object of that type is encountered, it knows what to do.
__________________
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 7th, 2007, 12:48 PM   #29
Arevos
Programming Guru
 
Arevos's Avatar
 
Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 4 Arevos is on a distinguished road
When you have a small number of conditions in Python, one uses an if-statement. But if there are a large number of conditions that follow a common pattern, it's easier to use a dictionary:
python Syntax (Toggle Plain Text)
  1. commands = {
  2. "look" : me.look,
  3. "move" : me.move,
  4. "go" : me.move
  5. }
It can be used like this:
>>> commands["look"]
<bound method Player.look of <__main__.Player object at 0xb7dcf7ec>>
>>> commands["look"]()
You are in the foyer of a house...
Another useful technique in Python is the ability to turn a list as a set of arguments using "*". e.g.
>>> me.look()
You are in the foyer of a house...
>>> me.look(*[])
You are in the foyer of a house...
>>> me.move("west")
You are in a dark kitchen...
>>> me.move(*["east"])
You are in the foyer of a house...
Combining these two techniques:
python Syntax (Toggle Plain Text)
  1. commands = {
  2. "look" : me.look,
  3. "move" : me.move,
  4. "go" : me.move
  5. }
  6.  
  7. def parse(verb, *nouns):
  8. commands[verb](*nouns)
  9.  
  10. while True:
  11. parse(*raw_input(">").lower().split())
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.
Arevos is offline   Reply With Quote
Old Oct 10th, 2007, 12:07 AM   #30
TheMuffenMann
Newbie
 
Join Date: Jan 2007
Posts: 4
Rep Power: 0 TheMuffenMann is on a distinguished road
Oop

I myself have not yet worked on a "huge" project involving Object-Oriented Programming in Python, but the principle ideas behind this programming paradigm is quite clear, and I can see why it can be useful. OOP is about code reuse.

Programming with OOP, you code by "customizing". By overriding functionality inherited by a superclass, there's no need to change the code that the subclass inherits from. In this way, when it comes times to write a new project, most of your work is likely already done and it becomes just a matter of filling in (overriding/customizing) existing classes through subclassing to get the functionality you want.

This means that the 'base' code, or the classes at the top of your inheritance heirarchy is very general, and you create more specific classes below that to specialize behaviour for special cases. Let me show you an example:

If you have a general class named Car, which has attributes that applies to all cars, when you want to create another class, say, Rolls_Royce, all you have to do is inherit all the existing attributes from Car, and then change one or two attributes in Rolls_Royce (maybe price?) to get behaviour specific to that brand. Boom your work is done. This is alot nicer than starting from nothing. This is also a trivial example, but it illustrates how OOP works.

In the book 'Learning Python', Mark Lutz and David Ascher present another good example:

For instance if you have a general class called Processor, that has an interface for reading and writing data streams, you can simply subclass Processor and create another class such as SocketReader and override the read and write methods implementing the specifics of that particular method of communication. So the code that uses the read/write methods of these classes doesn't have to get involved in all the details, it can just use the simple interface and implementation details are handled by the classes. It allows you to write code that is general and can apply to many different types of objects, given that those objects conform to the expected protocol.

And it's not that OOP is "better" but sometimes, especially in commercial environments time is expensive and being able to recycle existing code is important. Personally, my main language is C, and i prefer procedural code as well.

Last edited by TheMuffenMann; Oct 10th, 2007 at 12:19 AM.
TheMuffenMann 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 9:43 PM.

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