crafting done ?

This commit is contained in:
2023-01-13 20:07:21 +01:00
parent 7539863ace
commit 4f1044b87e
7 changed files with 554 additions and 52 deletions
+50 -38
View File
@@ -10,7 +10,7 @@ from ai_economist.foundation.base.base_component import (
BaseComponent,
component_registry,
)
from ai_economist.foundation.entities.resources import resource_registry
from ai_economist.foundation.entities.resources import Resource, resource_registry
@component_registry.add
@@ -47,7 +47,7 @@ class Craft(BaseComponent):
skill_dist="none",
**base_component_kwargs
):
#append commodities
#setup commodities
for v in commodities:
res_class=resource_registry.get(v)
res=res_class()
@@ -74,10 +74,10 @@ class Craft(BaseComponent):
self.builds = []
super().__init__(*base_component_args, **base_component_kwargs)
def agent_can_build(self, agent):
def agent_can_build(self, agent, recipe):
"""Return True if agent can actually build in its current location."""
# See if the agent has the resources necessary to complete the action
for resource, cost in self.resource_cost.items():
for resource, cost in recipe.items():
if agent.state["inventory"][resource] < cost:
return False
return True
@@ -93,7 +93,7 @@ class Craft(BaseComponent):
"""
# This component adds 1 action that mobile agents can take: build a house
if agent_cls_name in self.agent_subclasses:
return 1
return len(self.commodities)
return None
@@ -106,7 +106,7 @@ class Craft(BaseComponent):
if agent_cls_name not in self.agent_subclasses:
return {}
if agent_cls_name == "BasicMobileAgent":
return {"build_payment": float(self.payment), "build_skill": 1}
return {}
raise NotImplementedError
def component_step(self):
@@ -131,29 +131,32 @@ class Craft(BaseComponent):
pass
# Build! (If you can.)
elif action == 1:
if self.agent_can_build(agent):
else:
comm=self.commodities[action]
if self.agent_can_build(agent,comm.craft_recp):
# Remove the resources
for resource, cost in self.resource_cost.items():
for resource, cost in comm.craft_recp.items():
agent.state["inventory"][resource] -= cost
# Receive payment for the house
agent.state["inventory"]["Coin"] += agent.state["build_payment"]
# Receive crafted commodity
agent.state["inventory"][comm.name] += agent.state["craft_amount"][comm.name]
# Incur the labor cost for building
agent.state["endogenous"]["Labor"] += self.build_labor
agent.state["endogenous"]["Labor"] += agent.state["craft_labour"][comm.name]
build.append(
{
"builder": agent.idx,
"build_skill": self.sampled_skills[agent.idx],
"income": float(agent.state["build_payment"]),
"crafter": agent.idx,
"craft_commodity": comm.name,
"craft_skill": agent.state["craft_skill"][comm.name],
"craft_amount": agent.state["craft_amount"][comm.name],
"craft_labour": agent.state["craft_labour"][comm.name]
}
)
else:
agent.bad_action=True
else:
raise ValueError
self.builds.append(build)
@@ -168,10 +171,10 @@ class Craft(BaseComponent):
obs_dict = dict()
for agent in self.world.agents:
if agent.name in self.agent_subclasses:
obs_dict[agent.idx] = {
"build_payment": agent.state["build_payment"] / self.payment,
"build_skill": self.sampled_skills[agent.idx],
}
obs_dict[agent.idx]["craft_skill"]={}
for k in self.commodities:
obs_dict[agent.idx]["craft_skill"][k.name] = agent.state["craft_skill"][k.name]
return obs_dict
@@ -186,7 +189,8 @@ class Craft(BaseComponent):
# Mobile agents' build action is masked if they cannot build with their
# current location and/or endowment
for agent in self.world.agents:
masks[agent.idx] = np.array([self.agent_can_build(agent)])
if agent.name in self.agent_subclasses:
masks[agent.idx] = np.array([self.agent_can_build(agent,k.name) for k in self.commodities])
return masks
@@ -227,27 +231,35 @@ class Craft(BaseComponent):
"""
world = self.world
self.sampled_skills = {agent.idx: 1 for agent in world.agents}
PMSM = self.payment_max_skill_multiplier
MSAB= self.max_skill_amount_benefit
MSLB= self.max_skill_labour_benefit
for agent in world.agents:
if self.skill_dist == "none":
sampled_skill = 1
pay_rate = 1
elif self.skill_dist == "pareto":
sampled_skill = np.random.pareto(4)
pay_rate = np.minimum(PMSM, (PMSM - 1) * sampled_skill + 1)
elif self.skill_dist == "lognormal":
sampled_skill = np.random.lognormal(-1, 0.5)
pay_rate = np.minimum(PMSM, (PMSM - 1) * sampled_skill + 1)
else:
raise NotImplementedError
if agent.name not in self.agent_subclasses | agent.is_setup():
continue
agent.state["craft_skill"]={}
agent.state["craft_labour"]={}
agent.state["craft_amount"]={}
agent.state["build_payment"] = float(pay_rate * self.payment)
agent.state["build_skill"] = float(sampled_skill)
for comm in self.commodities:
if self.skill_dist == "none":
sampled_skill = 1
amount= 1
labour = 1
elif self.skill_dist == "pareto":
labour = 1
sampled_skill = np.random.pareto(2)
amount = np.minimum(MSAB, MSAB * sampled_skill)
labour_modifier = 1 - np.minimum(1 - MSLB, (1 - MSLB) * sampled_skill)
else:
raise NotImplementedError
agent.state["craft_skill"][comm.name]=sampled_skill
agent.state["craft_labour"][comm.name]=comm.craft_labour_base*labour_modifier
agent.state["craft_amount"][comm.name]=amount
self.sampled_skills[agent.idx] = sampled_skill
self.builds = []