From: Jenny Purcell Date: 2007-07-22T11:15:03+09:00 Subject: Method to return elements of an array in numeric 'rank'? 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. Included in this is a set of "pre-points" which is a sort of quality rating for each horse which shows how it's expected to race. Then, the program rolls 5d6, adds the pre-points and random points together, and comes up with a total result for each horse. The below program does just that. However, now I get to the next step of what I'd like it to do, and I'm stuck. What I'd like is to get a variable which shows each horse's final position (did they finish 1 for 1st, 2 for 2nd, etc). I have the "score" (score[i]), and the horse with the largest score number is the winner, but, I don't know how to count/sort the array in such a way that I return that the horse #7 is 1, horse #4 is 2, etc. I would expect there would be an existing method that works off of the array class that would do this, and I'd like to check on that before (painfully) writing my own nested loops that would do the same thing. Jenny #! /usr/bin/env ruby require 'csv' # Written by Jenny 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) 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) # For each record in the CSV file... CSV::Reader.parse(File.open('horses.csv')) do |record| # Now we assign the appropriate fields of the record to # variables named after the fields in the CSV file. # Note that we need to call .to_i on the 6th field # to convert it from strings to integers. count = count + 1 # count the number of horses in a particular race 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_points[count] = record[6].to_i # 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] # Display each horse's name, owner, score, pre_points, and other # info #end of the "do" statement for reading in CSV files end # Randomizing Post Position # i is a counter to count up to the number of horses pole = Array.new(count + 1) { |m| m + 1 } pole_new=pole.sort_by { rand } i=0 while i <= count do puts CSV.generate_line([pole_new[i], horse_name[i], horse_info[i], owners_initials[i], best_result[i], race_style[i], best_time[i], pre_points[i], roll_1[i], roll_2[i], roll_3[i], roll_4[i], roll_5[i], score[i]]) i = i + 1 end # Features to add # Break ties. # Have it calculate race times # Have it calculate margins # Have it share out pre_points based on running style (adapt to # numbered "legs") # Have it export to basic HTML file (for archive/email results) # all sixes = possible NTR? # Two consecutive ones is a break in pace.