[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Re: [QUIZ] Space Merchant (#71

Ross Bamford

3/20/2006 8:42:00 AM

Here is my Galaxy implementation. It seems to do everything it needs to
do, but I didn't go overboard with extra stuff since I don't know what
kind of stuff might be useful for the Galaxy to do...

The easiest way to use this with the GalaxyLoader seems to be to remove
the 'require galaxy' from GalaxyLoader and do it the other way around.
Then you can run the tests including the dump test with:

ruby -rgalaxy_loader galaxy.rb

There are some naive benchmarks I used to make the obvious
optimizations, run them with:

ruby galaxy.rb -bm

One additional thing I did consider was multiplayer - it's fairly easy
to get a galaxy working over DRb, and I did work up a basic multiplayer
version like this but had one overriding problem - all output ends up on
the server, or the game ends up useless because of constantly
marshalling sectors to send down the wire. I toyed with routing output
through the Player but still had problems... Ho hum.

Finally, I need to thank a couple of people: Dominik Bathon's solution
to Ruby Quiz 31 ( see
http://www.ruby-talk.org/cgi-bin/scat.rb/ruby/ruby-t... ) gave me
a much-needed start with Dijkstra's shortest path algorithm (in fact
it's only very slightly modified from his original) and Mauricio
Fernandez's WeakHash class let's me cache stuff irresponsibly (see
http://eigenclass.org/hiki.rb?weakhash+a... )

--
Ross Bamford - rosco@roscopeco.REMOVE.co.uk
12 Answers

James Gray

3/20/2006 2:22:00 PM

0

On Mar 20, 2006, at 2:41 AM, Ross Bamford wrote:

> One additional thing I did consider was multiplayer - it's fairly easy
> to get a galaxy working over DRb, and I did work up a basic
> multiplayer
> version like this but had one overriding problem - all output ends
> up on
> the server, or the game ends up useless because of constantly
> marshalling sectors to send down the wire. I toyed with routing output
> through the Player but still had problems... Ho hum.

This might be a fun follow-up quiz someday, if we can get the other
two pieces we need. Anyone working on station.rb or planet.rb?

I'll see if I can steal a few hours tonight and knock one out...

James Edward Gray II


Timothy Bennett

3/20/2006 2:31:00 PM

0

I'm working on a planet.rb.

Tim

On Mar 20, 2006, at 6:21 AM, James Edward Gray II wrote:

>
> This might be a fun follow-up quiz someday, if we can get the other
> two pieces we need. Anyone working on station.rb or planet.rb?
>
> I'll see if I can steal a few hours tonight and knock one out...
>
> James Edward Gray II
>



Timothy Bennett

3/20/2006 4:36:00 PM

0

Here is my improved sector.rb. Yes, I know I said I wasn't going to
fix it up, but once Ross posted a working Galaxy implementation, I
couldn't resist testing it and fixing it up. I fixed a few more bugs
and some problems it had due to a misunderstanding of Ross's galaxy
implementation. One thing with this is that it no longer prepends
"Sector" in front of the sector name, since Ross's randomly generated
galaxy has sectors named "Sector 530" and so forth, and it looked
really stupid to have "Sector Sector 530." The sample galaxy file
for the galaxy loader, on the other hand, just has the numbers, so if
used with that galaxy, it will just print "530" without any real
indication that 530 is a sector. Still, I figured this was better
than "Sector Sector," and I didn't want to take the time to prepend
Sector if it wasn't all ready there.

Anyway, I'll be going ahead and putting together a planet.rb.


Joel VanderWerf

3/20/2006 5:08:00 PM

0

Ross Bamford wrote:
> One additional thing I did consider was multiplayer - it's fairly easy
> to get a galaxy working over DRb, and I did work up a basic multiplayer
> version like this but had one overriding problem - all output ends up on
> the server, or the game ends up useless because of constantly
> marshalling sectors to send down the wire. I toyed with routing output
> through the Player but still had problems... Ho hum.

What about including DRbUndumped in the sector class, to keep them on
the server?

--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407


Timothy Bennett

3/20/2006 5:11:00 PM

0

James (or whoever else is doing station.rb), how are you representing
cargo and passengers, and where are you putting them in the player?
I was just starting to work on classes to represent items and people
that can be found and/or used on planets, and realized that there may
be a bit of overlap between items found on planets and bought at
stations, so they should at least be the same duck type. I was
thinking that they'd be stored in player[:cargo] and player[:passengers]

Tim


James Gray

3/20/2006 5:26:00 PM

0

On Mar 20, 2006, at 11:10 AM, Timothy Bennett wrote:

> James (or whoever else is doing station.rb), how are you
> representing cargo and passengers, and where are you putting them
> in the player?

I'm thinking I will introduce a Ship object in there. I've cleared
some hours this evening to work on it and will post some details when
I get something going...

James Edward Gray II


Stephen Waits

3/20/2006 5:27:00 PM

0


On Mar 20, 2006, at 8:35 AM, Timothy Bennett wrote:

> Here is my improved sector.rb.
>
> <sector.rb>

Would you guys like a public svn repository for this? That way you
could all keep all of the various parts together.

If so, just say the word, I'll gladly host one for you..

--Steve



Jacob Fugal

3/20/2006 5:31:00 PM

0

On 3/20/06, Timothy Bennett <timothy.s.bennett@gmail.com> wrote:
> James (or whoever else is doing station.rb), how are you representing
> cargo and passengers, and where are you putting them in the player?
> I was just starting to work on classes to represent items and people
> that can be found and/or used on planets, and realized that there may
> be a bit of overlap between items found on planets and bought at
> stations, so they should at least be the same duck type. I was
> thinking that they'd be stored in player[:cargo] and player[:passengers]

I'm working on an implementation of Station and just representing
cargo items as symbols. Ie. the Station has a @trading hash keyed by
:machinery, :organics, etc. (whatever the world builder populates the
station with). When the player docks at the station, they see what's
available for what prices and are presented with a Buy/Sell/Exit
choice. When they, for instance, Buy, the Station will call two
methods on the Player: Player#pay(price) and Player#load_cargo(good,
quantity) where 'good' is the symbol representing that good. As such,
I don't need to know anything about the Player's representation, I
just require that Players visiting my Station provide the appropriate
methods. This representation of goods by symbols of course assumes
that a transported good has no state or operations beyond
classification.

Jacob Fugal


James Gray

3/20/2006 11:35:00 PM

0

On Mar 20, 2006, at 11:10 AM, Timothy Bennett wrote:

> I was thinking that they'd be stored in player[:cargo] and player
> [:passengers]

I haven't had time to introduce ships yet, so I went with pretty much
what you said. Here's a very basic Station class to get this sucker
feeling more like a game:

#!/usr/local/bin/ruby -w

begin
require "highline/import"
rescue LoadError
begin
require "rubygems"
require "highline/import"
rescue LoadError
puts "#{__FILE__} requires HighLine be installed."
exit 1
end
end

class Numeric
def commify
to_s.reverse.gsub(/(\d\d\d)(?=\d)(?!\d*\.)/, '\1,').reverse
end
end

module SpaceMerchant
class Station
Good = Struct.new(:name, :cost)
GOODS = [ Good.new(:plants, 0.5),
Good.new(:animals, 0.8),
Good.new(:food, 1),
Good.new(:luxuries, 1.2),
Good.new(:medicine, 2),
Good.new(:technology, 3) ]

def initialize( sector, name )
@sector, @name = sector, name

@goods = GOODS.sort_by { rand }[0..2].sort_by { |good|
good.cost }.
map { |good| good.dup }.
map { |g| [g, [:buy, :sell][rand(2)], rand
(10_000) + 1] }
@goods.each { |good| good.first.cost *= rand + 0.5 }
end

attr_reader :sector, :name

def handle_event( player )
player[:cargo_space] ||= 20
player[:cargo] ||= Array.new

puts "Welcome pilot. Come to do some trading? What'll it be?
\n\n"

credits = player[:credits].commify.sub(/\.(\d+)$/) { |d| d
[0..2] }
puts "Credits: #{credits}"
if player[:cargo].empty?
puts " Cargo: none\n\n"
else
cargo = player[:cargo].map do |g|
"#{g.first.to_s.capitalize} (#{g.last})"
end.join(", ")
puts " Cargo: #{cargo}\n\n"
end

choose do |menu|
menu.index = :none
menu.shell = true
menu.case = :capitalize

menu.prompt = "Make an offer or blast off? "

printf "%10s %7s %5s %6s\n", "Item".center(10),
"Trade".center(7),
"Price", "Amount"
puts "---------- ------- ----- ------"
@goods.each do |good|
if good.include? :buy
menu.choice( sprintf( "%-10s Buying %1.2f",
good.first.name.to_s.capitalize,
good.first.cost ) ) do |good,
details|
sell_goods(
player,
@goods.find { |g| g.first.name == good[/\w
+/].downcase.to_sym },
details.split
)

puts "You unload the goods and blast off from the
station..."
player[:location] = sector
end
else
menu.choice( sprintf( "%-10s Selling %1.2f %6s",
good.first.name.to_s.capitalize,
good.first.cost,
good.last.commify ) ) do |good,
details|
buy_goods(
player,
@goods.find { |g| g.first.name == good[/\w
+/].downcase.to_sym },
details.split
)

puts "You load up the goods and blast off from the
station..."
player[:location] = sector
end
end
end

menu.choice("Blast off") { player[:location] = sector }
end
end

private

def buy_goods( player, good, details )
can_afford = [ good.last,
(player[:credits] * good.first.cost).to_i,
player[:cargo_space] -
player[:cargo].inject(0) { |sum, item|
item.last } ].min
if can_afford == 0
puts "I don't think you are in any position to be buyin'."
return
end

amount = if details.first.nil? or details.first.to_i > can_afford
ask("How much? ", Integer) { |q| q.in = (1..can_afford) }
else
details.shift.to_i
end

player[:credits] -= good.first.cost * amount
if add_on = player[:cargo].find { |g| g.first ==
good.first.name }
add_on[-1] += amount
else
player[:cargo] << [good.first.name, amount]
end

reset_good(good, amount)
end

def sell_goods( player, good, details )
begin
max_sale = player[:cargo].find { |g| g.first ==
good.first.name }.last
rescue
puts "Uh, you don't have any of that to sell Mac."
return
end

amount = if details.first.nil? or details.first.to_i > max_sale
ask("How much? ", Integer) { |q| q.in = (1..max_sale) }
else
details.shift.to_i
end

player[:credits] += good.first.cost * amount
player[:cargo].find { |g| g.first == good.first.name }[-1] -=
amount

reset_good(good, amount)
end

def reset_good( good, amount )
if (good[-1] -= amount) <= 0
good[1..2] = [([:buy, :sell] - [good[1]]).first, rand
(10_000) + 1]
end
end
end
end

if __FILE__ == $PROGRAM_NAME
player = {:credits => 1000}

loop do
if player[:location].nil?
player[:location] = SpaceMerchant::Station.new(nil, "Test")
end

player[:location].handle_event(player)
end
end

__END__

James Edward Gray II



Timothy Bennett

3/21/2006 12:30:00 AM

0


On Mar 20, 2006, at 3:34 PM, James Edward Gray II wrote:

> On Mar 20, 2006, at 11:10 AM, Timothy Bennett wrote:
>
>> I was thinking that they'd be stored in player[:cargo] and player
>> [:passengers]
>
> I haven't had time to introduce ships yet, so I went with pretty
> much what you said.
>

Ok, great, I'll work with that then.

Tim