Skip to content

Instantly share code, notes, and snippets.

@blackwatertepes
Last active December 14, 2015 05:29
Show Gist options
  • Save blackwatertepes/5035897 to your computer and use it in GitHub Desktop.
Save blackwatertepes/5035897 to your computer and use it in GitHub Desktop.
# This is how you define your own custom exception classes
class NoFruitError < StandardError
end
class FruitTree
attr_reader :age, :height, :fruit_type
@fruit_type = "fruit"
def initialize
@age = 0
@height = 0
@fruit = []
@max_age = 100
@max_height = 30
@bearing_range = (10..80)
@fruit_range = (100..300)
end
def type
return @fruit_type
end
# Ages the tree one year
def age!
@age += 1
@height += [(@max_height - @height) / 4.0, 4].min
grow_fruit if @age > @bearing_range.first && alive?
end
def grow_fruit
perfect_year = (@bearing_range.last - @bearing_range.first) / 2 + @bearing_range.first
fruit_multiplyer = @age < perfect_year ? @age / perfect_year.to_f : (@bearing_range.last - @age) / (@max_age - perfect_year).to_f
buds = @fruit_range.to_a.sample * fruit_multiplyer
buds.to_i.times do
add_fruit
end
end
def add_fruit
@fruit << Fruit.new(1 + rand(10) / 10.0)
end
def dead?
@age > @max_age
end
def mature?
@bearing_range.include? @age
end
def alive?
@age <= @max_age
end
# Returns +true+ if there is any fruit on the tree, +false+ otherwise
def any_fruit?
@fruit.length > 0
end
# Returns an Fruit if there are any
# Raises a NoOrangesError otherwise
def pick_a_fruit!
raise NoFruitError, "This tree has no #{FRUIT_TYPE}" unless self.any_fruit?
# fruit-picking logic goes here
@fruit.pop
end
end
class Fruit
attr_reader :diameter, :type
def initialize(diameter)
@diameter = diameter
@type = "fruit"
end
end
class OrangeTree < FruitTree
def initialize
super
@fruit_type = "orange"
@max_age = 120
@max_height = 30
@bearing_range = (4..80)
@fruit_range = (200..300)
end
def add_fruit
@fruit << Orange.new
end
def any_oranges?
any_fruit?
end
def pick_an_orange!
pick_a_fruit!
end
end
class Orange < Fruit
def initialize
super 3 + rand(10) / 10.0
@type = "orange"
end
end
class AppleTree < FruitTree
def initialize
super
@fruit_type = "apple"
@max_age = 80
@max_height = 27
@bearing_range = (2..70)
@fruit_range = (300..400)
end
def add_fruit
@fruit << Apple.new
end
def any_apples?
any_fruit?
end
def pick_an_apple!
pick_a_fruit!
end
end
class Apple < Fruit
def initialize
super 2 + rand(10) / 10.0
@type = "apple"
end
end
class PearTree < FruitTree
def initialize
super
@fruit_type = "pear"
@max_age = 70
@max_height = 25
@breaing_range = (3..60)
@fruit_range = (250..350)
end
def add_fruit
@fruit << Pear.new
end
def any_pears?
any_fruit?
end
def pick_a_pear!
pick_a_fruit!
end
end
class Pear < Fruit
def initialize
super 2 + rand(10) / 10.0
@type = "pear"
end
end
class TreeGrove
attr_reader :trees
TREE_TYPES = [OrangeTree, AppleTree, PearTree]
def initialize
@trees = []
50.times do
@trees << TREE_TYPES.sample.new
end
end
def age!
@trees.each do |tree|
tree.age!
end
end
def get_type(type)
@trees.select do |tree|
tree.type == type.downcase
end
end
def get_mature(type)
@trees.select do |tree|
tree.type == type && tree.mature?
end
end
def mature_trees
@trees.select do |tree|
tree.any_fruit?
end
end
def mature_trees?
mature_trees.length > 0
end
def avg_age
collective_age = @trees.inject(0) do |sum, tree|
sum + tree.age
end
return collective_age / @trees.length
end
def avg_height
collective_height = @trees.inject(0) do |sum, tree|
sum + tree.height
end
return (collective_height / @trees.length).round(2)
end
def any_fruit?
fruit = []
@trees.each do |tree|
return true if tree.any_fruit?
end
return false
end
def shake_down_tree!
basket = []
@trees.each do |tree|
if tree.any_fruit?
while tree.any_fruit?
basket << tree.pick_a_fruit!
end
return basket
end
end
return false
end
def dead_trees
@trees.select do |tree|
tree.dead?
end
end
def alive_trees
@trees.select do |tree|
!tree.dead?
end
end
def dead?
alive_trees.length == 0
end
end
grove = TreeGrove.new
puts "The grove contains #{grove.get_type('orange').length} orange, #{grove.get_type('apple').length} apple, and #{grove.get_type('pear').length} pear trees."
sleep(1)
until grove.mature_trees?
grove.age!
#puts "#{grove.trees.length} trees are #{grove.avg_age} years old and #{grove.avg_height} feet tall"
end
until grove.dead?
truck = []
# It places the oranges in the basket
# IT PLACES THE ORANGES IN THE BASKET
while grove.any_fruit?
truck << grove.shake_down_tree!
truck.flatten!
end
#avg_diameter = (basket.inject(0){|sum,orange| sum + orange.diameter} / basket.length).round(3) # It's up to you to calculate the average diameter for this harvest.
puts "Yearly Report"
puts "Avg Tree Age: #{grove.avg_age}"
puts "Avg Tree Height: #{grove.avg_height} feet"
puts "Fruit Bearing Trees: #{grove.get_mature('orange').length} orange \t #{grove.get_mature('apple').length} apple \t #{grove.get_mature('pear').length} pear"
oranges = truck.select { |fruit| fruit.type == 'orange' }
apples = truck.select { |fruit| fruit.type == 'apple' }
pears = truck.select { |fruit| fruit.type == 'pear' }
puts "Harvest: #{oranges.length} oranges \t #{apples.length} apples \t #{pears.length} pears \t #{truck.size} total"
puts ""
# Age the grove another year
grove.age!
#sleep(5)
end
puts "Alas, the grove, all are dead!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment