Background: I’m working on a Ruby program to simulate horse races for
a fantasy horse racing league. It works off a csv file I put together
by hand with the information necessary for each race.
I realize it would be easier for people in the group to follow if I
was programming with objects. However, I just don’t understand OO
programming, my skills (such as they are) are procedural. Ruby was
pointed out to me as a language that would allow me to write
procedural programs and so far it is working out very nicely in that
regard.
After much hammering and fiddling, I have expanded the program
significantly since I last posted to the group. I can now run multiple
races off a single csv file, and I’ve added some additional features I
wanted.
What I’d like to be able to do, now, is provide minimally formatted
html “results” for each race.
What I’d like is output that would be something like this:
1a Mdn 2yoC/G Trot $3500
Winner: Ima Winnah, 2005 chestnut colt ABC
Bred by: Suzie Creamcheese
T= 2:00.1f
1(8) Ima Winnah, 05 cc, ABC, unplcd, pp4, by
neck, Given pace and in control from gate to wire, T=2:00.1f
Using my variable names, it would be something like this:
race_name
(race #1)
Winner, details, time, etc, not coded into original program yet
position[j](count + 1) horse_name[j], horse_info[j],
owners_initials[j], best_result[j], pp pole_new[j], by <margin - not
coded yet>, <Space for comments, added by hand for each race>, T=
<details on horse #2>
<details on horse #3>
race_name
(race #2)
For the most part, once someone shows me the basics of doing this, I
can fill in the rest.
Code included below:
#! /usr/bin/env ruby
require ‘csv’
Written by Jenny P. and Anthony Purcell based off starter code
provided by Robbert Haarman
assign counter to keep track of number of horses
count=-1
create new arrays
horse_name=Array.new(20)
horse_info=Array.new(20)
owners_initials=Array.new(20)
best_result=Array.new(20)
race_style=Array.new(20)
best_time=Array.new(20)
pre_points=Array.new(20)
start_points=Array.new(20)
luck_roll=Array.new(20)
roll_1=Array.new(20)
roll_2=Array.new(20)
roll_3=Array.new(20)
roll_4=Array.new(20)
roll_5=Array.new(20)
score=Array.new(20)
pre_point_string = String.new
race_name = String.new
race = 0
file_lines = Array.new
For each record in the CSV file…
CSV::Reader.parse(File.open(‘horses2.csv’)) do |record|
test_string = record[0]
if test_string == “” || test_string == nil then
if race == 1 then
# Randomizing Post Position
# i is a counter to count up to the number of horses
pole = Array.new(count + 1) { |m| m + 1 }
number = Array.new(count + 1) { |m| m + 1 }
position = Array.new(count + 1)
pole_new=pole.sort_by { rand }
# Determining each horse's finishing position
temp_score = Array.new(count + 1) {|c| 100 * score[c] + 20 -
pole_new[c]}
sort_score = temp_score.sort
sort_score.reverse!
number.each {|a| position[a - 1] = number.detect {|b|
sort_score[b - 1] == temp_score[a - 1]}}
i=0
line = CSV.generate_line([race_name])
file_lines.push(line)
while i <= count do
j = number.detect {|c| position[c - 1] == i + 1}
j = j - 1
# Push each horse's name, owner, score, pre_points, dice
rolls, and other info into a new csv file
line = CSV.generate_line([“pp#{pole_new[j]}”, horse_name[j],
horse_info[j], owners_initials[j], best_result[j], race_style[j],
best_time[j], “#{pre_points[j]} (#{start_points[j]} #{luck_roll[j]})”
, roll_1[j], roll_2[j], roll_3[j], roll_4[j], roll_5[j], score[j],
“#{position[j]}(#{count + 1})”])
# Here is where we put the new line on the end of the csv
array
file_lines.push(line)
i = i + 1
end
# generate a blank line and write it
line = CSV.generate_line([])
file_lines.push(line)
end
race = 0
elsif race == 0 then
race = 1
count = -1
race_name = record[0]
else
count = count + 1 # count the number of horses in a particular
race
# Now we assign the appropriate fields of the record to
# variables named after the fields in the CSV file.
horse_name[count] = record[0]
horse_info[count] = record[1]
owners_initials[count] = record[2]
best_result[count] = record[3]
race_style[count] = record[4]
best_time[count] = record[5]
pre_point_string = record[6]
# Extract lead character for luck rolls
pre_roll_check = pre_point_string[0, 1]
temp_string = pre_point_string[1, pre_point_string.length]
# Use the lead character to determine how many luck rolls are
needed
# Use the remainder of the input string to evaluate initial point
allotment
if pre_roll_check == “a” then
num_rolls = 3
elsif pre_roll_check == “b” then
num_rolls = 2
elsif pre_roll_check == “c” then
num_rolls = 1
else
num_rolls = 0
luck_roll[count] = 0
pre_points[count] = pre_point_string.to_i
start_points[count] = pre_points[count]
end
# Generate luck rolls if needed to calculate pre-point total
if num_rolls > 0 then
pre_roll_dice = (1..num_rolls).map { rand(4) + 1}
pre_points[count] = temp_string.to_i
start_points[count] = pre_points[count]
luck_roll[count] = 0
pre_roll_dice.each { |p| pre_points[count] = pre_points[count] +
p }
pre_roll_dice.each { |q| luck_roll[count] = luck_roll[count] + q
}
end
#puts CSV.generate_line([num_rolls, pre_points[count],
temp_string, pre_roll_check])
# Roll the dice.
# This generates an array containing five die rolls,
# each die roll ranging from 1 to 6
dice = (1..5).map { rand(6) + 1 }
# Calculate score.
# The score is the sum pre_points, and each of the die rolls
temp_score = pre_points[count]
dice.each { |n| temp_score = temp_score + n }
score[count]=temp_score
roll_1[count]=dice[0]
roll_2[count]=dice[1]
roll_3[count]=dice[2]
roll_4[count]=dice[3]
roll_5[count]=dice[4]
# Share out pre-points based on running style
# Assign margins based on final points
# end of over-arching conditional statement
end
#end of the "do" statement for reading in CSV files
end
# Write to a csv file to archive "full" results (all points, etc).
filename = 'results.csv'
File.open filename, 'w+' do |f|
f.puts file_lines
end