Last active
August 29, 2015 14:01
-
-
Save CoderPuppy/fa4820c1915363d762d9 to your computer and use it in GitHub Desktop.
Applied Energistics like system written in Fancy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ItemSpec { | |
read_slots: ('name, 'dmg, 'data) | |
def initialize: @name with_dmg: @dmg with_data: @data | |
def initialize: @name with_dmg: @dmg | |
def initialize: @name with_data: @data { | |
@dmg = 0 | |
} | |
def initialize: @name { | |
@dmg = 0 | |
} | |
def key { (@name, @dmg, @data) inspect } | |
def of_qty: qty { | |
ItemStack new: self of_qty: qty | |
} | |
def inspect { | |
(@name to_s) + ":" + (@dmg to_s) | |
} | |
} | |
class ItemStack { | |
read_slot: 'spec | |
read_write_slot: 'qty | |
def initialize: @spec of_qty: @qty | |
def initialize: @spec { | |
@qty = 1 | |
} | |
def dup { | |
ItemStack new: @spec of_qty: @qty | |
} | |
def key { @spec key } | |
def increase_qty: amt { | |
@qty = @qty + amt | |
self | |
} | |
def decrease_qty: amt { | |
@qty = @qty - amt | |
self | |
} | |
def with_qty: qty { | |
ItemStack new: @spec of_qty: qty | |
} | |
def inspect { | |
@spec inspect + " x #{@qty}" | |
} | |
} | |
class Inventory { | |
def initialize { | |
@items = Hash new | |
} | |
def get: spec { | |
@items fetch: (spec key) else_put: { spec of_qty: 0 } | |
} | |
def insert: stack { | |
existing_stack = get: $ stack spec | |
existing_stack . increase_qty: $ stack qty | |
Console println: $ "inserting #{stack inspect}, now: #{existing_stack inspect}" | |
self | |
} | |
def extract: spec { | |
if:(has?: spec) then: { | |
@items delete: $ spec key | |
} | |
} | |
def extract: qty of: spec { | |
if:(has: qty of?: spec) then: { | |
stack = @items at: $ spec key | |
if:(stack qty > qty) then: { | |
stack decrease_qty: qty | |
stack with_qty: qty | |
} else: { | |
@items delete: $ spec key | |
} | |
} | |
} | |
def has: amt of?: spec { | |
if:(has?: spec) then: { | |
(@items at: $ spec key) qty >= amt | |
} else: { | |
false | |
} | |
} | |
def has?: spec { | |
@items includes?: $ spec key | |
} | |
def inspect { | |
"#<Inventory [ " + (@items values map: |stack| { stack inspect } . join: ", ") + " ]>" | |
} | |
} | |
class Crafter { | |
read_slots: ('inv, 'recipes, 'operations) | |
def initialize: @inv { | |
@recipes = [] | |
@operations = Set new | |
} | |
def add_recipe: recipe { | |
@recipes << recipe | |
} | |
def run { | |
@operations each: |operation| { | |
operation run | |
} | |
} | |
def craft: spec { | |
craft: 1 of: spec | |
} | |
def craft: qty of: spec without_using: blacklist (Set new) { | |
op = CraftingOperation new: self make: qty of: spec without_using: blacklist | |
@operations << op | |
op | |
} | |
def inspect { | |
"#<Crafter [ " + (@recipes map: |recipe| { recipe inspect } . join: ", ") + " ]>" | |
} | |
class CraftingOperation { | |
read_slots: ('crafter, 'spec, 'qty, 'result, 'recipe, 'blacklist) | |
def is_done? { @is_done } | |
def initialize: @crafter make: @qty of: @spec without_using: @blacklist { | |
@is_done = false | |
} | |
def complete: result { | |
@result = result | |
@is_done = true | |
@crafter operations remove: self | |
} | |
def find_potential_recipes { | |
@recipe = nil | |
@dependencies = nil | |
@potential_recipes = @crafter recipes select: |recipe| { | |
(@blacklist includes?: recipe) false? &&$ recipe ingredients none?: |ingredient| { | |
@blacklist includes?: $ ingredient spec | |
} &&$ recipe makes?: @spec | |
} . map: |recipe| { (recipe, recipe makes_how_much: @spec) } . sort: |a, b| { | |
if:(a[1] == (b[1]) ||$ a[1] > @qty &&$ b[1] > @qty) then: { | |
a_cost = a[0] ingredients map: @{qty} . reduce: |a, b| { a + b } | |
b_cost = b[0] ingredients map: @{qty} . reduce: |a, b| { a + b } | |
a_cost <=> b_cost | |
} else: { | |
if:(a[1] > @qty) then: { | |
-1 | |
} else: { | |
if:(b[1] > @qty) then: { | |
1 | |
} else: { | |
b[1] <=>$ a[1] | |
} | |
} | |
} | |
} . map: |recipe| { recipe[0] } | |
} | |
def find_recipe { | |
if:(@is_done false? &&$ @dependencies == nil &&$ @recipe == nil) then: { | |
@recipe = @potential_recipes find: @{is_possible?: $ @crafter inv} | |
if:(@recipe != nil) then: { | |
Console println: $ "trying to craft: " +$ @recipe inspect | |
@dependencies = @recipe ingredients map: |ingredient| { | |
@crafter craft: (ingredient qty) of: (ingredient spec) without_using: $ @blacklist +$ Set[[@spec, @recipe]] | |
} | |
} | |
} | |
} | |
def craft { | |
if:(@is_done false? &&$ @recipe != nil &&$ @dependencies != nil) then: { | |
if:(@dependencies all?: |dep| { dep.is_done? }) then: { | |
@recipe ingredients each: |ingredient| { | |
@crafter inv extract: (ingredient qty) of: (ingredient spec) | |
} | |
@recipe results each: |result| { | |
@crafter inv insert: result | |
Console println: $ "crafted: #{result inspect} from: [ " + (@recipe ingredients map: |ingredient| { ingredient inspect } . join: ", ") + " ]" | |
} | |
@recipe = nil | |
@dependencies = nil | |
} | |
} | |
} | |
def run { | |
if:(@is_done false? &&$ (@potential_recipes == nil ||$ @crafter recipes inspect != @old_recipes)) then: { | |
find_potential_recipes | |
@old_recipes = @crafter recipes inspect | |
} | |
find_recipe | |
craft | |
if:(@crafter inv has: @qty of?: @spec) then: { | |
complete: $ @crafter inv get: @spec | |
} | |
} | |
def inspect { | |
"#<CraftingOperation:#{object_id} @spec=#{@spec inspect} @qty=#{@qty} @is_done=#{@is_done inspect} @result=#{@result inspect} @recipe=#{@recipe inspect} @dependencies=#{@dependencies inspect}>" | |
} | |
} | |
} | |
class Recipe { | |
read_slots: ('ingredients, 'results) | |
def initialize: @ingredients makes: @results | |
def makes?: spec { | |
@results find: |stack| { | |
(stack spec key) == (spec key) | |
} != nil | |
} | |
def makes_how_much: spec { | |
stack = @results find: |stack| { | |
stack spec key ==$ spec key | |
} | |
if:(stack nil?) then: { | |
0 | |
} else: { | |
stack qty | |
} | |
} | |
def is_possible?: inv { | |
@ingredients all?: |ingredient| { | |
inv has: (ingredient qty) of?: $ ingredient spec | |
} | |
} | |
def inspect { | |
(@ingredients inspect) + " => " + (@results inspect) | |
} | |
} | |
items = { | |
items = DynamicSlotObject new | |
items dirt: $ ItemSpec new: 'dirt | |
items diamond: $ ItemSpec new: 'diamond | |
items diamond_block: $ ItemSpec new: 'diamond_block | |
items object | |
} call | |
inv = Inventory new | |
crafter = Crafter new: inv | |
crafter add_recipe: $ Recipe new: [items dirt of_qty: 1] makes: [items diamond of_qty: 1] | |
crafter add_recipe: $ Recipe new: [items diamond_block of_qty: 1] makes: [items diamond of_qty: 9] | |
crafter add_recipe: $ Recipe new: [items diamond of_qty: 9] makes: [items diamond_block of_qty: 1] | |
# inv insert: $ items dirt of_qty: 64 | |
# inv insert: $ items diamond_block of_qty: 64 | |
Console println: $ inv inspect | |
op = crafter craft: 81 of: $ items diamond | |
Console println: $ op inspect | |
base_time = Time.now | |
done1 = false | |
done2 = false | |
while: { op is_done? false? } do: { | |
crafter run | |
sleep: 0.1 | |
now = Time.now | |
if:(done1 false? &&$ now >=$ base_time + 10) then: { | |
inv insert: $ items diamond_block of_qty: 8 | |
done1 = true | |
} | |
if:(done2 false? &&$ now >=$ base_time + 20) then: { | |
inv insert: $ items dirt of_qty: 10 | |
done2 = true | |
} | |
} | |
Console println: $ inv inspect |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment