Class: CraftingTable::RecipeManager

Inherits:
Object
  • Object
show all
Defined in:
lib/crafting_table/recipe_manager.rb

Overview

A class which contains recipes, and allows to search through them.

Since:

  • 0.2

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(item_manager) ⇒ RecipeManager

Create a new RecipeManager

Parameters:

  • item_manager (ItemManager)

    ItemManager which contains the items on which this manager’s recipes are based.

Since:

  • 0.2



17
18
19
20
# File 'lib/crafting_table/recipe_manager.rb', line 17

def initialize(item_manager)
  @item_manager = item_manager
  @recipes = []
end

Instance Attribute Details

#item_managerObject (readonly)

Since:

  • 0.2



11
12
13
# File 'lib/crafting_table/recipe_manager.rb', line 11

def item_manager
  @item_manager
end

#recipesObject (readonly)

Since:

  • 0.2



10
11
12
# File 'lib/crafting_table/recipe_manager.rb', line 10

def recipes
  @recipes
end

Instance Method Details

#add(recipe) ⇒ void

This method returns an undefined value.

Add a new recipe to the internal collection.

Parameters:

  • recipe (Recipe)

    Recipe which to add to the collection.

Since:

  • 0.2



26
27
28
# File 'lib/crafting_table/recipe_manager.rb', line 26

def add(recipe)
  @recipes << recipe
end

#add_from_file(path) ⇒ void

This method returns an undefined value.

Add new recipes by reading them from a YAML file.

Parameters:

  • path (String)

    The path to the file from which to read recipes from.

Since:

  • 0.2



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/crafting_table/recipe_manager.rb', line 35

def add_from_file(path)
  YAML.load_file(path).each do |recipe_hash|
    raw_input = recipe_hash.fetch('input', {})
    raw_output = recipe_hash.fetch('output', {})
    name = recipe_hash.fetch('name', 'UNKNOWN')

    input = {}
    output = {}
    raw_input.each do |identifier_string, amount|
      identifier = identifier_string.split(':').map(&:to_i)
      item = item_manager.find_by_identifier(identifier).first
      input[item] = amount
    end

    raw_output.each do |identifier_string, amount|
      identifier = identifier_string.split(':').map(&:to_i)
      item = item_manager.find_by_identifier(identifier).first
      output[item] = amount
    end

    @recipes << Recipe.new(name, input, output)
  end
  
end

#clearvoid

This method returns an undefined value.

Clear the internal collection of recipes.

Since:

  • 0.2



62
63
64
# File 'lib/crafting_table/recipe_manager.rb', line 62

def clear
  @recipes.clear
end

#find {|builder| ... } ⇒ Array<Recipe>

Find recipes.

Examples:

Searching for name.

results = manager.find do |search|
  search.name = 'slab'
  search.exact = false
  search.case_sensitive = false
end
results.map(&:name)
#=> ['Cobblestone slab', 'Wooden slab', 'Stone slab', '...']

Searching for recipes which result in torch(es).

manager.find do |search|
  manager.output = Item.new('Torch', 50)
end

Searching for recipes which require oak planks.

results = manager.find do |search|
  manager.input = Item.new('Oak Wood Planks', 5)
end
results.map(&:name)
#=> ['Sticks', 'Crafting Table', 'Chest', 'Bed', '...']

Yield Parameters:

  • builder (SearchBuilder)

    An instance of the SearchBuilder class which allows to easily specify multiple search conditions.

Returns:

  • (Array<Recipe>)

    Recipes which matched the search conditions.

Since:

  • 0.3



96
97
98
99
100
101
# File 'lib/crafting_table/recipe_manager.rb', line 96

def find(&block)
  builder = Search::SearchBuilder.new
  yield builder

  builder.searches.inject(recipes) { |recipes, search| search.apply_to(recipes) }
end

#find_by_input(item) ⇒ Array<Recipe>

Deprecated.

Use #find instead.

Find recipes by their input.

Examples:

Searching for recipes which require planks.

manager.find_by_input(Item.new('Oak Wood Planks', 5, 0)).map(&:name)
#=> ['Sticks', 'Crafting Table', 'Chest', 'Bed', '...']

Parameters:

  • item (Item)

    Item for which to search.

Returns:

  • (Array<Recipe>)

    Collection of recipes which matched the search condition.

Since:

  • 0.2



147
148
149
# File 'lib/crafting_table/recipe_manager.rb', line 147

def find_by_input(item)
  recipes.select { |recipe| recipe.input.key? item }
end

#find_by_name(name, options = {}) ⇒ Array<Recipe>

Deprecated.

Use #find instead.

Find recipes by their name.

Examples:

Search using default parameters.

manager.find_by_name('Torch').first.input.map(&:name) #=> ['Wooden Planks', 'Coal']

Case-insensitive search, non-exact matching.

manager.find_by_name('slab').map(&:name) #=> ['Cobblestone Slab', 'Wooden slab', 'Stone slab', '...']

Parameters:

  • name (String)

    The name for which to search.

  • options (Hash) (defaults to: {})

    Options which influence the search.

Options Hash (options):

  • :exact (Boolean) — default: true

    Whether to match names exactly.

  • :case_sensitive (Boolean) — default: true

    Whether to search case-sensitively.

Returns:

  • (Array<Recipe>)

    Collection of recipes which matched the search condition.

Since:

  • 0.2



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/crafting_table/recipe_manager.rb', line 118

def find_by_name(name, options = {})
  default_options = { exact: true, case_sensitive: true }
  default_options.update(options)

  if default_options[:case_sensitive]
    if default_options[:exact]
      recipes.select { |recipe| recipe.name == name }
    else
      recipes.select { |recipe| recipe.name.include? name }
    end
  else
    if default_options[:exact]
      recipes.select { |recipe| recipe.name.downcase == name.downcase }
    else
      recipes.select { |recipe| recipe.name.downcase.include? name.downcase }
    end
  end
end

#find_by_output(item) ⇒ Array<Recipe>

Deprecated.

Use #find instead.

Find recipes by their output.

Examples:

Searching for recipes which result in Coal.

manager.find_by_output(Item.new('Coal', 263, 0)).map(&:name)
#=> ['Coal']

Returns:

  • (Array<Recipe>)

    Collection of recipes which matched the search condition.

Since:

  • 0.2



160
161
162
# File 'lib/crafting_table/recipe_manager.rb', line 160

def find_by_output(item)
  recipes.select { |recipe| recipe.output.key? item }
end

#resolve_recipe(recipe, amount) ⇒ Hash{Item => Integer}

Resolve a recipe into its base components.

Examples:

Components required to craft 50 torches.

torch = recipe_manager.find_by_name('Torch').first
components = recipe_manager.resolve_recipe(recipe_torch, 50)
components.map { |item, amount| item.name => amount }
#=> { "Wood" => 2, "Coal" => 13 }

Parameters:

  • recipe (Recipe)

    The recipe which to resolve to its components.

  • amount (Integer)

    Desired amount of the recipe.

Returns:

  • (Hash{Item => Integer})

    A hash mapping the base components to the required amount of each.

Since:

  • 0.3



180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/crafting_table/recipe_manager.rb', line 180

def resolve_recipe(recipe, amount)
  # Todo: Allow to specify arbitrary outputs.
  # Todo: Fail if the specified output is not part of the recipe.
  desired_output = recipe.output.keys.first
  amount_per_iteration = recipe.output[desired_output]
  # If we get four items per iteration, and want 21 items in
  # total, we'll need 6 iterations.
  iterations = (amount.to_f / amount_per_iteration).ceil

  requirements = Hash.new(0)
  
  recipe.input.each do |input, amount|
    # Finding potential recipes for the input.
    recipes_for_input = find_by_output(input)

    # Todo: Allow for other criteria where the recipe should be ignored.
    if recipes_for_input.empty?
      requirements[input] += amount * iterations
    else
      recipe_for_input = recipes_for_input.first
      requirements_for_input = resolve_recipe(recipe_for_input,
                                              amount * iterations)

      requirements.merge!(requirements_for_input) do |key, old_amount, new_amount|
        old_amount + new_amount
      end

    end
  end

  requirements
  
end