diff --git a/lib/bike_club.rb b/lib/bike_club.rb index b83c6db..b07b049 100644 --- a/lib/bike_club.rb +++ b/lib/bike_club.rb @@ -1,3 +1,26 @@ class BikeClub + attr_reader :name, :bikers + def initialize(name) + @name = name + @bikers = [] + end + + def add_biker(biker) + @bikers << biker + end + + def most_rides + @bikers.max_by { |biker| biker.ride_count} + end + + def best_time(ride) + @bikers.min_by { |biker| biker.personal_record(ride) } + end + + def bikers_eligible(ride) + @bikers.select do |biker| + biker.acceptable_terrains.include?(ride.terrain) && biker.max_distance >= ride.total_distance + end + end end \ No newline at end of file diff --git a/lib/biker.rb b/lib/biker.rb index db234de..29b9882 100644 --- a/lib/biker.rb +++ b/lib/biker.rb @@ -1,3 +1,36 @@ class Biker + attr_reader :name, :max_distance, :rides, :acceptable_terrains -end \ No newline at end of file + def initialize(name, max_distance) + @name = name + @max_distance = max_distance + @rides = {} + @acceptable_terrains = [] + end + + def learn_terrain!(terrain_type) + @acceptable_terrains << terrain_type + end + + def log_ride(ride, time) + if @acceptable_terrains.include?(ride.terrain) && @max_distance >= ride.total_distance + if @rides.key?(ride) + @rides[ride] << time + else + @rides[ride] = [time] + end + end + end + + def personal_record(ride) + if @rides.key?(ride) + rides[ride].min + else + false + end + end + + def ride_count + rides.values.flatten.count + end +end diff --git a/lib/ride.rb b/lib/ride.rb index 1be20f0..5e94a9e 100644 --- a/lib/ride.rb +++ b/lib/ride.rb @@ -1,3 +1,22 @@ class Ride + attr_reader :name, :distance, :loop, :terrain + def initialize(info) + @name = info[:name] + @distance = info[:distance] + @loop = info[:loop] + @terrain = info[:terrain] + end + + def loop? + @loop + end + + def total_distance + if loop? == false + @distance + @distance + else + @distance + end + end end \ No newline at end of file diff --git a/spec/bike_club_spec.rb b/spec/bike_club_spec.rb new file mode 100644 index 0000000..7cde4ec --- /dev/null +++ b/spec/bike_club_spec.rb @@ -0,0 +1,108 @@ +require './lib/ride' +require './lib/biker' +require './lib/bike_club' +require 'rspec' + +RSpec.describe BikeClub do + describe '#initialize' do + it 'has a name' do + bikeclub = BikeClub.new("Sons of Anarchy") + + expect(bikeclub.name).to eq "Sons of Anarchy" + end + + it 'has a list of bikers' do + bikeclub = BikeClub.new("Sons of Anarchy") + + expect(bikeclub.bikers).to eq [] + end + end + + describe 'behaviors' do + it 'can add new Bikers' do + bikeclub = BikeClub.new("Sons of Anarchy") + biker1 = Biker.new("Kenny", 30) + bikeclub.add_biker(biker1) + biker2 = Biker.new("Athena", 15) + bikeclub.add_biker(biker2) + + expect(bikeclub.bikers).to eq [biker1, biker2] + end + + it 'can tell which Biker has logged the most rides' do + biker1 = Biker.new("Kenny", 30) + biker1.learn_terrain!(:gravel) + biker1.learn_terrain!(:hills) + biker2 = Biker.new("Athena", 30) + biker2.learn_terrain!(:gravel) + biker2.learn_terrain!(:hills) + + ride1 = Ride.new({name: "Walnut Creek Trail", distance: 10.7, loop: false, terrain: :hills}) + ride2 = Ride.new({name: "Town Lake", distance: 14.9, loop: true, terrain: :gravel}) + biker1.log_ride(ride1, 92.5) + biker1.log_ride(ride1, 91.1) + biker1.log_ride(ride2, 60.9) + biker1.log_ride(ride2, 61.6) + biker2.log_ride(ride1, 95.0) + biker2.log_ride(ride2, 65.0) + + bikeclub = BikeClub.new("Sons of Anarchy") + bikeclub.add_biker(biker1) + bikeclub.add_biker(biker2) + + expect(bikeclub.most_rides).to eq (biker1) + end + + it 'can tell which Biker has the lowest PR for a ride' do + biker1 = Biker.new("Kenny", 30) + biker1.learn_terrain!(:gravel) + biker1.learn_terrain!(:hills) + biker2 = Biker.new("Athena", 30) + biker2.learn_terrain!(:gravel) + biker2.learn_terrain!(:hills) + + ride1 = Ride.new({name: "Walnut Creek Trail", distance: 10.7, loop: false, terrain: :hills}) + ride2 = Ride.new({name: "Town Lake", distance: 14.9, loop: true, terrain: :gravel}) + biker1.log_ride(ride1, 92.5) + biker1.log_ride(ride1, 91.1) + biker1.log_ride(ride2, 60.9) + biker1.log_ride(ride2, 61.6) + biker2.log_ride(ride1, 95.0) + biker2.log_ride(ride2, 65.0) + + bikeclub = BikeClub.new("Sons of Anarchy") + bikeclub.add_biker(biker1) + bikeclub.add_biker(biker2) + + expect(bikeclub.best_time(ride1)).to eq biker1 + end + + it 'can tell which Bikers are eligible for a given ride' do + biker1 = Biker.new("Kenny", 30) + biker1.learn_terrain!(:gravel) + biker1.learn_terrain!(:hills) + + biker2 = Biker.new("Athena", 30) + biker2.learn_terrain!(:gravel) + biker2.learn_terrain!(:hills) + + ride1 = Ride.new({name: "Walnut Creek Trail", distance: 10.7, loop: false, terrain: :hills}) + ride2 = Ride.new({name: "Town Lake", distance: 14.9, loop: true, terrain: :gravel}) + + biker1.log_ride(ride1, 92.5) + biker1.log_ride(ride1, 91.1) + biker1.log_ride(ride2, 60.9) + biker1.log_ride(ride2, 61.6) + + biker2.log_ride(ride1, 95.0) + biker2.log_ride(ride2, 65.0) + + bikeclub = BikeClub.new("Sons of Anarchy") + bikeclub.add_biker(biker1) + bikeclub.add_biker(biker2) + + expect(bikeclub.bikers_eligible(ride1)).to eq [biker1, biker2] + + end + end +end \ No newline at end of file diff --git a/spec/biker_spec.rb b/spec/biker_spec.rb new file mode 100644 index 0000000..f9cf701 --- /dev/null +++ b/spec/biker_spec.rb @@ -0,0 +1,130 @@ +require './lib/ride' +require './lib/biker' +require 'rspec' + +RSpec.describe Biker do + describe '#initialize' do + it 'assigns a name' do + biker = Biker.new("Kenny", 30) + + expect(biker.name).to eq "Kenny" + end + + it 'assigns a max_distance' do + biker = Biker.new("Kenny", 30) + + expect(biker.max_distance).to eq 30 + end + + it 'holds an empty hash of logged rides' do + biker = Biker.new("Kenny", 30) + + expect(biker.rides).to eq ({}) + end + + it 'holds an empty array of acceptable terrains' do + biker = Biker.new("Kenny", 30) + + expect(biker.acceptable_terrains).to eq [] + end + end + + describe 'behaviors' do + it 'can add different elements to the #acceptable_terrains array' do + biker = Biker.new("Kenny", 30) + biker.learn_terrain!(:gravel) + biker.learn_terrain!(:hills) + + expect(biker.acceptable_terrains).to eq [:gravel, :hills] + end + + it 'can add a ride/time key-value pair to the #rides hash' do + biker = Biker.new("Kenny", 30) + biker.learn_terrain!(:gravel) + biker.learn_terrain!(:hills) + ride1 = Ride.new({name: "Walnut Creek Trail", distance: 10.7, loop: false, terrain: :hills}) + ride2 = Ride.new({name: "Town Lake", distance: 14.9, loop: true, terrain: :gravel}) + biker.log_ride(ride1, 92.5) + biker.log_ride(ride1, 91.1) + biker.log_ride(ride2, 60.9) + biker.log_ride(ride2, 61.6) + + expected_rides = { + ride1 => [92.5, 91.1], + ride2 => [60.9, 61.6] + } + + expect(biker.rides).to eq(expected_rides) + end + + it 'can return the lowest stored time for a given ride' do + biker = Biker.new("Kenny", 30) + biker.learn_terrain!(:gravel) + biker.learn_terrain!(:hills) + ride1 = Ride.new({name: "Walnut Creek Trail", distance: 10.7, loop: false, terrain: :hills}) + ride2 = Ride.new({name: "Town Lake", distance: 14.9, loop: true, terrain: :gravel}) + biker.log_ride(ride1, 92.5) + biker.log_ride(ride1, 91.1) + biker.log_ride(ride2, 60.9) + biker.log_ride(ride2, 61.6) + + expect(biker.personal_record(ride1)).to eq 91.1 + expect(biker.personal_record(ride2)).to eq 60.9 + end + + it 'will not add a ride to the #rides hash if the terrain has not been learned' do + biker2 = Biker.new("Athena", 15) + ride1 = Ride.new({name: "Walnut Creek Trail", distance: 10.7, loop: false, terrain: :hills}) + ride2 = Ride.new({name: "Town Lake", distance: 14.9, loop: true, terrain: :gravel}) + + biker2.log_ride(ride1, 97.0) + biker2.log_ride(ride2, 67.0) + + expect(biker2.rides).to eq ({}) + end + + it 'will not add a ride to the #rides hash if the ride distance is greater than the rider max_distance' do + biker2 = Biker.new("Athena", 15) + biker2.learn_terrain!(:gravel) + biker2.learn_terrain!(:hills) + + ride1 = Ride.new({name: "Walnut Creek Trail", distance: 10.7, loop: false, terrain: :hills}) + ride2 = Ride.new({name: "Town Lake", distance: 14.9, loop: true, terrain: :gravel}) + + biker2.log_ride(ride1, 95.0) + biker2.log_ride(ride2, 65.0) + + expect(biker2.rides).to eq({ ride2 => [65.0] }) + end + + it 'can return the lowest ride time or false' do + biker2 = Biker.new("Athena", 15) + biker2.learn_terrain!(:gravel) + biker2.learn_terrain!(:hills) + + ride1 = Ride.new({name: "Walnut Creek Trail", distance: 10.7, loop: false, terrain: :hills}) + ride2 = Ride.new({name: "Town Lake", distance: 14.9, loop: true, terrain: :gravel}) + + biker2.log_ride(ride1, 95.0) + biker2.log_ride(ride2, 65.0) + biker2.rides + + expect(biker2.personal_record(ride2)).to eq 65.0 + expect(biker2.personal_record(ride1)).to eq false + end + + it 'can calculate the total number of rides taken' do + biker = Biker.new("Kenny", 30) + biker.learn_terrain!(:gravel) + biker.learn_terrain!(:hills) + ride1 = Ride.new({name: "Walnut Creek Trail", distance: 10.7, loop: false, terrain: :hills}) + ride2 = Ride.new({name: "Town Lake", distance: 14.9, loop: true, terrain: :gravel}) + biker.log_ride(ride1, 92.5) + biker.log_ride(ride1, 91.1) + biker.log_ride(ride2, 60.9) + biker.log_ride(ride2, 61.6) + + expect(biker.ride_count).to eq 4 + end + end +end \ No newline at end of file diff --git a/spec/ride_spec.rb b/spec/ride_spec.rb new file mode 100644 index 0000000..c4e63f0 --- /dev/null +++ b/spec/ride_spec.rb @@ -0,0 +1,52 @@ +require './lib/ride' +require 'rspec' + +RSpec.describe Ride do + describe "#initialize" do + it 'assigns a name' do + ride1 = Ride.new({name: "Walnut Creek Trail", distance: 10.7, loop: false, terrain: :hills}) + + expect(ride1.name).to eq "Walnut Creek Trail" + end + + it 'assigns a distance' do + ride1 = Ride.new({name: "Walnut Creek Trail", distance: 10.7, loop: false, terrain: :hills}) + + expect(ride1.distance).to eq 10.7 + end + + it 'describes terrain' do + ride1 = Ride.new({name: "Walnut Creek Trail", distance: 10.7, loop: false, terrain: :hills}) + + expect(ride1.terrain).to eq :hills + end + + it 'describes loop status as true/false' do + ride1 = Ride.new({name: "Walnut Creek Trail", distance: 10.7, loop: false, terrain: :hills}) + + expect(ride1.loop).to eq false + end + end + + describe "behaviors" do + it 'indicates if a ride is a loop' do + ride1 = Ride.new({name: "Walnut Creek Trail", distance: 10.7, loop: false, terrain: :hills}) + + expect(ride1.loop?).to eq false + + ride2 = Ride.new({name: "Town Lake", distance: 14.9, loop: true, terrain: :gravel}) + + expect(ride2.loop?).to eq true + end + + it 'calculates total ride distance' do + ride1 = Ride.new({name: "Walnut Creek Trail", distance: 10.7, loop: false, terrain: :hills}) + + expect(ride1.total_distance).to eq 21.4 + + ride2 = Ride.new({name: "Town Lake", distance: 14.9, loop: true, terrain: :gravel}) + + expect(ride2.total_distance).to eq 14.9 + end + end +end \ No newline at end of file