Hi Sharon,
Everyone says that...
I'm actually Dave, but I use my wife's email
Many many thanks for your kind response. As you guessed I'm new to
programming. The code works fine. Only it doesn't display messages
asking for user input, for instance "Enter the valuation" message
doesn't appear.
What sort of environment are you running this on?
Perhaps you could alter get_num to include STDOUT.flush (like your
original)
def get_num msg
print "#{msg} >"
STDOUT.flush
gets.to_i
end
Probably the most important thing I'd like to get across is that
whenever you see yourself writing something like
a_margin = max_price_A - reservePrice
b_margin = max_price_B - reservePrice
c_margin = max_price_C - reservePrice
d_margin = max_price_D - reservePrice
e_margin = max_price_E - reservePrice
you're repeating yourself unnecessarily and making it difficult to
change the programme (what if we had an extra investor? what if we had
100?)
Ruby (unlike a number of other languages) makes it very simple to
manage lists of things.
Here's your original code again, but all I've done is put all the
a_margin (etc) bits into a list and change the bidding section to use
this list
Cheers,
Dave
# set up list (array) to hold our investor information
investors= []
# Change the number of bidders by changing this value
BIDDER_COUNT=5
#Get the valuation price i.e the Auctioneer's expected price of the
property
puts"Enter the valuation: "
STDOUT.flush
valuation = gets.to_i
#Get the Reserve price i.e. the minimum acceptable price of the property
puts "Enter the reserve price: "
STDOUT.flush
reservePrice = gets.to_i
# get the max_price for each investor
for index in (1..BIDDER_COUNT)
# we'll use a hash to keep all the information we need about this
investor
# much tidier than having sperate lists for bids, margins and
max_prices
this_investor= {:index => index}
#Each agent knows the maximun amount it can afford to pay for the
property
puts "How much is invester #{index} willing to spend? "
STDOUT.flush
this_investor[:max_price]= gets.to_i
# add the new investor to our list
investors << this_investor
end
investors.each do |investor|
#Calculate invester bid magins
#i.e. difference btw an agent's max willing price and the reserve
price
investor[:margin] = investor[:max_price] - reservePrice
#Initialize bids for the investers here. First bid is reserve price
plus half of the margin.
#The other half will be incrementally bidded at 50% per round of
bidding
investor[:bid] = reservePrice + investor[:margin]/2
end
=begin
Assumptions
1. Probability of two or more investers having the same max price is
negligible
2. Investers do not know each other's willing prices
3. A margin can't be zero...to be explained later
=end
#Continue bidding as long as the highest bid is less or equal to
valuation price.
#Trivially, the property will be sold to the agent that reaches or
exceeds the valuation price
# keep going untill we have a winner.
# NOTE ** this will continue forever if none of the bidders has a
max_price
# >= the valuation
# You'll need to add a check for this as well
# Hint: you'll reach a round where those_still_bidding will be empty
# (everyone has dropped out)
#initialize out winner as no one
winner= nil
while winner.nil? do
# check who should bid first
# we need to find the lowest bid that's not greater than that
investors'
# max_price
# To do this, let's take out list of investors, and narrow it down
to only
# those still bidding (bid <= max_price)
those_still_bidding= investors.select do |investor|
# if the following evaluates as true, this investor will join our
new list
investor[:bid] <= investor[:max_price]
end
# Now, from those let's find the lowest bidder.
# One way to do this is to sort the list by bid, then pick the
first one
# Step 1: sort them
those_still_bidding.sort! do |investor_a, investor_b|
investor_a[:bid] <=> investor_b[:bid]
end
# Step 2: get the first
lowest_bidder= those_still_bidding.first
puts "Investor #{lowest_bidder[:index]} is bidding
#{lowest_bidder[:bid]}"
# Two possibilities now:
# 1: This bid wins, and the action ends
# 2: This bid doesn't win, this investor raises their bid and we
continue
if lowest_bidder[:bid]>= valuation then
# Only need to set winner here.
# This will cause the while loop to stop (winner is no longer nil)
# We'll display the winning details at the end
winner= lowest_bidder
else
lowest_bidder[:bid]+= lowest_bidder[:margin] * 0.25
end
end # whle
# The programme will only get to here once a winner has been declared
puts "\nThis property has been sold to Invester #{winner[:index]} for
#{winner[:bid]}"