-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
incorporate objects defined in yaml configuration into gridworld #248
Changes from 1 commit
5805389
1aacbf7
61936c2
9beb69d
e9654de
1757b62
2eabd8b
a2e7e90
6442db1
d2c809e
61730ae
43c5a73
130301c
17b8f4c
fe9ef39
4f88723
ef257ff
03b09e7
02cbb59
6abf932
a2494ee
4be6708
4789d8d
44e8614
24a775a
8ddd3fe
b44192a
2b86e49
2d9e251
c768385
b831c99
a2fcae5
7b09115
31e06c6
e795dc7
3d1419b
395f571
2410991
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -303,43 +303,46 @@ def __init__(self, **kwargs): | |
# Items and transitions | ||
self.item_config = kwargs.get("item_config", DEFAULT_ITEM_CONFIG) | ||
self.transition_config = kwargs.get("transition_config", {}) | ||
self.player_config = kwargs.get("player_config", {}) | ||
|
||
if self.player_config.get('available_colors'): | ||
self.player_color_names = [] | ||
self.player_colors = [] | ||
for name, value in self.player_config['available_colors'].items(): | ||
self.player_color_names.append(name) | ||
self.player_colors.append(value) | ||
|
||
# Any maturing items? | ||
self.includes_maturing_items = any( | ||
item["maturation_threshold"] > 0.0 for item in self.item_config.values() | ||
) | ||
|
||
# Get item spawning probability distribution function and args | ||
# Get item spawning probability distribution and public good calories | ||
for item_type in self.item_config.values(): | ||
item_type["probability_function_args"] = [] | ||
parts = item_type["probability_distribution"].split() | ||
if len(parts) > 1: | ||
item_type["probability_distribution"] = parts[0] | ||
item_type["probability_function_args"] = parts[1:] | ||
probability_distribution = "{}_probability_distribution".format( | ||
item_type["probability_distribution"] | ||
) | ||
item_type["probability_function"] = getattr( | ||
distributions, probability_distribution, None | ||
) | ||
if item_type["probability_function"] is None: | ||
logger.info( | ||
"Unknown item probability distribution: {}.".format( | ||
item_type["probability_distribution"] | ||
) | ||
) | ||
item_type[ | ||
"probability_function" | ||
] = distributions.random_probability_distribution | ||
item_type["probability_function"], item_type["probability_function_args"] = self._get_probablity_func_for_config(item_type["probability_distribution"]) | ||
|
||
# public good | ||
for item_type in self.item_config.values(): | ||
item_type["public_good"] = ( | ||
item_type["calories"] | ||
* item_type["public_good_multiplier"] | ||
/ self.num_players | ||
) | ||
|
||
# Player probability distribution | ||
self.player_config["probability_function"], self.player_config["probability_function_args"] = self._get_probablity_func_for_config(self.player_config["probability_distribution"]) | ||
|
||
def _get_probablity_func_for_config(self, probability_distribution): | ||
probability_function_args = [] | ||
parts = probability_distribution.split() | ||
if len(parts) > 1: | ||
probability_distribution = parts[0] | ||
probability_function_args = parts[1:] | ||
probability_distribution = f"{probability_distribution}_probability_distribution" | ||
probability_function = getattr(distributions, probability_distribution, None) | ||
if probability_function is None: | ||
logger.info(f"Unknown item probability distribution: {probability_distribution}.") | ||
probability_function = distributions.random_probability_distribution | ||
return probability_function, probability_function_args | ||
|
||
def can_occupy(self, position): | ||
if self.player_overlap: | ||
return not self.has_wall(position) | ||
|
@@ -863,11 +866,9 @@ def replenish_items(self): | |
|
||
def spawn_player(self, id=None, **kwargs): | ||
"""Spawn a player.""" | ||
# For player position, use same distribution as first configured item. | ||
item_id = list(self.item_config.keys())[0] | ||
player = Player( | ||
id=id, | ||
position=self._random_empty_position(item_id), | ||
position=self._random_empty_position(player=True), | ||
num_possible_colors=self.num_colors, | ||
motion_speed_limit=self.motion_speed_limit, | ||
motion_cost=self.motion_cost, | ||
|
@@ -885,16 +886,24 @@ def spawn_player(self, id=None, **kwargs): | |
self._start_if_ready() | ||
return player | ||
|
||
def _random_empty_position(self, item_id): | ||
def _random_empty_position(self, item_id=None, player=False): | ||
"""Select an empty cell at random, using the configured probability | ||
distribution.""" | ||
rows = self.rows | ||
columns = self.columns | ||
empty_cell = False | ||
if item_id: | ||
prob_func = self.item_config[item_id]["probability_function"] | ||
func_args = self.item_config[item_id]["probability_function_args"] | ||
elif player: | ||
prob_func = self.player_config["probability_function"] | ||
func_args = self.player_config["probability_function_args"] | ||
else: | ||
prob_func = distributions.random_probability_distribution | ||
func_args = [] | ||
|
||
while not empty_cell: | ||
position = self.item_config[item_id]["probability_function"]( | ||
rows, columns, *self.item_config[item_id]["probability_function_args"] | ||
) | ||
position = prob_func(rows, columns, *func_args) | ||
empty_cell = self._empty(position) | ||
|
||
return position | ||
|
@@ -1202,6 +1211,7 @@ def __init__(self, session=None): | |
log_event=self.record_event, | ||
item_config=self.item_config, | ||
transition_config=self.transition_config, | ||
player_config=self.player_config, | ||
**self.config.as_dict(), | ||
) | ||
self.session.commit() | ||
|
@@ -1231,6 +1241,8 @@ def configure(self): | |
(t["actor_start"], t["target_start"]): t | ||
for t in self.game_config.get("transitions", ()) | ||
} | ||
|
||
self.player_config = self.game_config.get("player_config") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that at least for now, we'll need to JSON serialize There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We already pass the player color stuff directly, and the probability distribution is definitely server only. I think we're OK here for now, but if we eventually have client side player config in this structure, we'll probably need it. For now I don't think we do. |
||
# This is accessed by the grid.html template to load the configuration on the client side: | ||
# TODO: could this instead be passed as an arg to the template in | ||
# the /grid route? | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,14 @@ | ||
--- | ||
player_config: | ||
probability_distribution: "random" | ||
available_colors: | ||
BLUE: [0.50, 0.86, 1.00] | ||
YELLOW: [1.00, 0.86, 0.50] | ||
ORANGE: [0.91, 0.50, 0.02] | ||
RED: [0.64, 0.11, 0.31] | ||
PURPLE: [0.85, 0.60, 0.85] | ||
TEAL: [0.77, 0.96, 0.90] | ||
|
||
item_defaults: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like the idea of being able to configure the defaults across all items. |
||
item_id: 1 | ||
item_count: 8 | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't this need to be
getattr(distributions, self.item_config[item_id]["probability_function"])
(the config value is just a string)?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I see... you've already created a map to the actual functions earlier. 👍🏼