Beginner help - txt dungeon

  • Thread starter Jonathon Hartoon
  • Start date
J

Jonathon Hartoon

Hi. I have tried to learn other programming languages before and ruby
was the first one that really stuck. Anyways, I own both Prgramming
Ruby & Beginning Ruby. The later has a tutorial for making a text
dungeon. I expanded the example in the book to accept commands from a
user and load new maps from a txt file. I am now trying to build in an
inventory system, and smashing my face into the rocks. I can't even
come up with an acceptable way to do it. I also want my items to load
from a text file. My end goal is to have a text dungeon maker. Where
you have 2 or 3 text files (or even one I guess) that my engine will
create an entire dungeon from. Any help on an inventory system would be
great as I don't even know where to start.

The rooms.txt is pretty simple syntax (if thats what I would call it).
On one line you put a room.

reference~ Name #The player sees this~description~ #The next 8 places
seperated by "~" are connections, they are split up into pairs and
stored in a hash. The first part of the pair is input from the user and
the second is returned.

Working example:

cavecell~ Cave cell~a small cell in the side of a cave wall. The gate
on the north side is open.~north~cellblocka1~south~n~east~n~west~n~

cellblocka1~ Cell Block A~a long corridor full of jail cells. To the
south is an open cell. The corridor runs east and west, and seems to go
on for quite
sometime.~north~n~south~n~east~cellblocka2~west~cellblocka0~

cellblocka2~ Cell Block A~a long corridor full of jail cells. The
corridor runs east and west, and seems to go on for quite
sometime.~north~n~south~n~east~cellblocka0~west~cellblocka1~

cellblocka0~ Cell Block A~a long corridor full of jail cells. The
corridor runs east and west, and seems to go on for quite
sometime.~north~n~south~n~east~cellblocka1~west~cellblocka2~


This just loops back on itself. An "n" returned is impassable.

Attachments:
http://www.ruby-forum.com/attachment/1409/Dungeon.rb
 
J

Jonathon Hartoon

Huw said:
I'm not familiar with the example you are following. However, you may
find my adventure game tutorial useful...?

http://www.bitwisemag.com/2/Adventures-In-Ruby
http://www.bitwisemag.com/2/Adventures-In-Ruby-Part-2
http://www.bitwisemag.com/2/Adventures-In-Ruby-Part-3

best wishes
Huw

SapphireSteel Software
Ruby and Rails In Visual Studio
http://www.sapphiresteel.com

Your tutorial looks interesting and easy to follow. I am going to work
my way through it over the next days. My program is attached to my
original post. Thanks for the help.
 
J

Jonathon Hartoon

I read your comments and some questions did in fact come up. You
commented on my file opening system. I agree with your reasoning, as it
is very hard to work with. The reason I made it that way is because it
was simple to code. I do not know how I would seperate it the way you
suggested.

The next comment was on my find_room method.
"You are using an Array as a Hash. The following line could just be:"
"@rooms[reference] # using a Hash"

I am confused by this. Maybe some more explaination. The next comments
are on my command system. I figured there had to be a much better way
to do this, but it was the first thing I had written without help or
examples. I however do not know what "case" means. A link to some
explanation might help. Your suggestions on the inventory definitely
helped keep my train of thought on the tracks that lead to resultopia.
 
J

James Gray

I read your comments and some questions did in fact come up. You
commented on my file opening system. I agree with your reasoning,
as it
is very hard to work with. The reason I made it that way is because
it
was simple to code. I do not know how I would seperate it the way you
suggested.

It is a bit harder. Save that for when you have learned a bit more.
The next comment was on my find_room method.
"You are using an Array as a Hash. The following line could just be:"
"@rooms[reference] # using a Hash"

I am confused by this. Maybe some more explaination.
class Room
# ...
?> end
=> nil
rooms = {:some_room => Room.new, :another_room => Room.new}
rooms[:some_room]
=> # said:
I however do not know what "case" means. A link to some
explanation might help.
=> "unknown"

Hope that helps.

James Edward Gray II
 
J

Jonathon Hartoon

=> "unknown"

Hope that helps.

James Edward Gray II

That is rather simple. Maybe I will leave the array being used as a
hash for another time. At the moments the funtionality remain intact.
Thx again for the help.
 
T

Thufir

I am now trying to build in an
inventory system, and smashing my face into the rocks.

Well, one approach would be to use a database. By using a db from the
get go you get the advantage of, well, organizing your data. Then, you
just connect to the db.

If you're using text files that's more fragile because one small change
will cause other things to break.

I kinda, sorta, had thoughts along your line for a game, but was using
_why's poignant ruby for inspiration :)

It's a bit rough (I don't do anything with the creatures once they're
created), but the db part, for me, looks like:

require 'rubygems'
require 'fileutils'
require 'active_record'
require 'creature'
require 'dragon'
require 'instantiate'
include Instantiate


system("rm dwemthys.db")

ActiveRecord::Base.logger = Logger.new(STDERR)
ActiveRecord::Base.colorize_logging = true

ActiveRecord::Base.establish_connection(
:adapter => "sqlite3",
:dbfile => "dwemthys.db"
)

ActiveRecord::Schema.define do
create_table :creatures do |table|
table.column :type, :string
table.column :life, :integer
table.column :strength, :integer
table.column :charisma, :integer
table.column :weapon, :integer
end
end




99.times do |index|
creature = Instantiate.randomCreature
p creature
creature.save
end


http://dwemthys.googlecode.com/svn/trunk/db_crud_create.rb


HTH,

Thufir
 
C

Christopher Dicely

Looking through that, there are a few things that jump out:

1. You've got a bunch of rooms that you reference by symbols, and you
are storing them in an Array. You might want to look into changing
this to a Hash keyed by the reference. This would change
Dungeon#find_room from:

def find_room(reference)
@rooms.detect { |room| room.reference == reference }
end

to:

def find_room(reference)
@rooms[reference]
end

(Really, since find_room is only called within Dungeon, you can
probably do without the method in that case, and just replace
find_room(reference) calls with @rooms[reference])

2. You are doing your own file handling, which may be a good way to
learn Ruby's generic file handling facilities. On the other hand, you
may also want to try using the standard YAML library (discussed in
Chapter 9 of Begging Ruby: From Novice to Professional) to store your
rooms. It stores and loads arbitrary Ruby objects very simply in a
format that is easy to create/edit by hand, and if you keep expanding
what your program does (and what it loads and stores), it'll be easier
to expand than updating a custom format with each change.

3. The Dungeon#command method uses a series of independent if
statements, where only one of them can be true. There are several
improvements possible with this. The smallest change would be to use
an if [...] elsif [...] elsif [...] end idiom instead of if [...] end
if [...] end etc. The next would be to use a case statement, like
this:
case input
when "west"
...
when "east"
...
when "north"
...
when "south"
...
when "look"
...
when "inventory"
...
end

You could also consider, though this is more advanced, having a
@commands instance variable that is a Hash keyed by the name of
commands with values that are procs that are called for each command.
Then to process a command, you could just do @commands[command].call.

4. Your initialize method for Dungeon calls create and run at the end.
You might want think about to pulling those out of initialize, and
letting "create" take a parameter identifying the file name to use.
Then you would use Dungeon.new.create("file.txt").run to load and run
a dungeon. Only do this if you might ever want to create a blank
dungeon without loading structure from a file, or to load the
structure without running the dungeon.
 
T

Thufir

Looking through that, there are a few things that jump out:

1. You've got a bunch of rooms that you reference by symbols, and you
are storing them in an Array. You might want to look into changing
this to a Hash keyed by the reference.
[...]

Actually, an array makes sense to me. Can you explain the advantages
of a Hash? With an array, the array can later be made to a Singleton
which could be iterated through.


-Thufir
 
C

Christopher Dicely

Since the main use is lookup by reference, and hash is designed for
keyed access, hash would seem to be the natural container to use. I'm
not sure I quite get what you are saying about iterating through a
singleton instead, could you explain a little more?

Looking through that, there are a few things that jump out:

1. You've got a bunch of rooms that you reference by symbols, and you
are storing them in an Array. You might want to look into changing
this to a Hash keyed by the reference.
[...]

Actually, an array makes sense to me. Can you explain the advantages
of a Hash? With an array, the array can later be made to a Singleton
which could be iterated through.


-Thufir
 
T

Thufir

Since the main use is lookup by reference, and hash is designed for
keyed access, hash would seem to be the natural container to use. I'm
not sure I quite get what you are saying about iterating through a
singleton instead, could you explain a little more?
[...]

There's one set of rooms, which may have sub-sets, of course. But,
for the set of rooms you may want to iterate through each room for
whatever reason. Putting the rooms into a Singleton allows such
iteration in an inherently thread-safe way.

Admittedly, I don't really understand Hash that well.


-Thufir
 
T

Todd Benson

Since the main use is lookup by reference, and hash is designed for
keyed access, hash would seem to be the natural container to use. I'm
not sure I quite get what you are saying about iterating through a
singleton instead, could you explain a little more?
[...]

There's one set of rooms, which may have sub-sets, of course. But,
for the set of rooms you may want to iterate through each room for
whatever reason. Putting the rooms into a Singleton allows such
iteration in an inherently thread-safe way.

I'm not sure I follow you. As far as I understand it, singletons
refer to templates (the singleton classes) that allow instances of a
class to have unique behavior if need be. It seems to me that
instances of a Room would not need that. The only way I can currently
imagine why one would need that is if the behavior of a single
instance of a room changes during runtime.
Admittedly, I don't really understand Hash that well.

It's just key/value pairs (where the key or the value can be any object).

Todd
 
F

fedzor

do you really want to call 'system', which calls a shell, which
executes the
'rm' program?
Why not just use File.unlink()?

whats the difference between File.delete and File.unlink?

_______________________________|
- Ari
I just bought another case of RockStar. Expect architectural changes.
 
H

Huw Collingbourne

I understand your thoughts about singletons. In a sense, each game might
be represented by a singleton. In my own simple Ruby adventure game
system (mentioned earlier in this thread) I have three classes -
Adventure (the game itself), Implementor (the thing that 'controls' the
nitty-gritty details of the game) and the Map - all of which have only
one instance. I haven't myself implemented them as singletons as I
couldn't see any obvious benefit in doing so and I tend to think that
singletons reduce the clarity of the class hiererchy so I don't use them
habitually.

I have also opted for an array for simplicity. A map can easily be
created by having numbered rooms and attributes indicting the rooms to
which they adjoin e.g.

1 -- 2
|
3 -- 4

In the above, room 1's east attribute is 2, its south attribute is 3
etc.

The attraction of a hash is that the key would not need to be a number -
it could actually the name of a room { :east => :dungeon, :south =>
:cave } and so on.

In fact, I wrote a simple example of a game framework in Smalltalk that
uses exactly this method:

map at: 'Station 1' put: 'Belsize Park';
at: 'Station 2' put: 'Chalk Farm';
at: 'Station 3' put: 'Camden Town';
at: 'Your destination' put: 'Mornington Crescent'.

http://www.bitwisemag.com/copy/programming/smalltalk/smalltalk2.html

This has some attractions of readability (names not numbers) but I'm not
really convinced it is more practical than a simple indexed array. The
secret is to draw out a map on a sheet of paper first, give all the
rooms numbers, draw lines showing the exits and then create the array
with all the correct numbers as attributes to show which room number is
in which direction.

best wishes
Huw

SapphireSteel Software
Ruby and Rails In Visual Studio
http://www.sapphiresteel.com
 
A

Arlen Cuss

[Note: parts of this message were removed to make it a legal post.]

whats the difference between File.delete and File.unlink?

None: they are defined to refer to the same function in the code:
rb_define_singleton_method(rb_cFile, "unlink", rb_file_s_unlink, -2);
rb_define_singleton_method(rb_cFile, "delete", rb_file_s_unlink, -2);

Aliased, if you like. Still, `unlink' is the preferred terminology, I think.
(besides, that's the name used for the C function [rb_file_s_unlink])

Arlen
 
T

Thufir

The attraction of a hash is that the key would not need to be a number -
it could actually the name of a room { :east => :dungeon, :south =>
:cave } and so on.

In fact, I wrote a simple example of a game framework in Smalltalk that
uses exactly this method:

map at: 'Station 1' put: 'Belsize Park';
at: 'Station 2' put: 'Chalk Farm';
at: 'Station 3' put: 'Camden Town';
at: 'Your destination' put: 'Mornington Crescent'.


Yes, that's much more readable than mapping integers around :)

Ok, I'm starting to see the advantages to Hash!


-Thufir
 
T

Thufir

This has some attractions of readability (names not numbers) but I'm not
really convinced it is more practical than a simple indexed array. The
secret is to draw out a map on a sheet of paper first, give all the
rooms numbers, draw lines showing the exits and then create the array
with all the correct numbers as attributes to show which room number is
in which direction.


Well, just thinking aloud:

There may be different worlds/planets dimensions in the game. So that
maybe you might have (forgive my poor ruby syntax pls):

class earthRoom < room
def special_earth_method
end
end

and then a marsRoom class, etc?

You wouldn't want to be able to go from an earthRoom to marsRoom under
normal circumstances, I expect.

Also, some rooms might have north, south, east, west but other rooms
might have no directions, but perhaps a secret door, or "pull
candlestick" or "go out" or similar.

While the intention at this stage is to get something workable, I, for
one, would like to know how to keep options open down the road (without
overly complicating what's meant to be an exercise).


-Thufir
 
F

fedzor

You wouldn't want to be able to go from an earthRoom to marsRoom under
normal circumstances, I expect.

Also, some rooms might have north, south, east, west but other rooms
might have no directions, but perhaps a secret door, or "pull
candlestick" or "go out" or similar.

While the intention at this stage is to get something workable, I, for
one, would like to know how to keep options open down the road
(without
overly complicating what's meant to be an exercise).

If you're using a hash, put whatever exits you want! use the user's
input as a basis for indexing the hash.

Don't necessarily make different rooms under different classes for
dealing with exits only. Use different classes for things like....
gravity..

Ari
-------------------------------------------|
Nietzsche is my copilot
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,817
Latest member
DicWeils

Latest Threads

Top