-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
327 additions
and
45 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
""" | ||
Default implementations of AI modules | ||
""" | ||
from typing import Optional, List | ||
|
||
from neighborly import World, GameObject, SimDateTime, NeighborlyEngine | ||
from neighborly.builtin.components import LocationAliases, OpenToPublic, CurrentLocation | ||
from neighborly.core.action import Action, AvailableActions | ||
from neighborly.core.location import Location | ||
from neighborly.core.routine import Routine | ||
|
||
|
||
class DefaultMovementModule: | ||
|
||
def get_next_location(self, world: World, gameobject: GameObject) -> Optional[int]: | ||
date = world.get_resource(SimDateTime) | ||
routine = gameobject.try_component(Routine) | ||
location_aliases = gameobject.try_component(LocationAliases) | ||
|
||
if routine: | ||
routine_entry = routine.get_entry(date.weekday, date.hour) | ||
|
||
if ( | ||
routine_entry | ||
and isinstance(routine_entry.location, str) | ||
and location_aliases | ||
): | ||
return location_aliases.aliases[routine_entry.location] | ||
|
||
elif routine_entry: | ||
return int(routine_entry.location) | ||
|
||
potential_locations: List[int] = list( | ||
map( | ||
lambda res: res[0], | ||
world.get_components(Location, OpenToPublic), | ||
) | ||
) | ||
|
||
if potential_locations: | ||
return world.get_resource(NeighborlyEngine).rng.choice(potential_locations) | ||
|
||
return None | ||
|
||
|
||
class DefaultSocialAIModule: | ||
|
||
def get_next_action(self, world: World, gameobject: GameObject) -> Optional[Action]: | ||
current_location_comp = gameobject.try_component(CurrentLocation) | ||
|
||
if current_location_comp is None: | ||
return None | ||
|
||
current_location = world.get_gameobject(current_location_comp.location) | ||
|
||
available_actions = current_location.try_component(AvailableActions) | ||
|
||
if available_actions is None: | ||
return None | ||
|
||
for action in available_actions.actions: | ||
... | ||
|
||
return None |
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
from __future__ import annotations | ||
|
||
from typing import List, Set, Union, Tuple, Callable | ||
|
||
from neighborly.core.ecs import Component, World | ||
from neighborly.core.event import EventProbabilityFn, Event | ||
|
||
|
||
class AvailableActions(Component): | ||
""" | ||
Tracks all the Actions that are available at a given location | ||
Attributes | ||
---------- | ||
actions: Set[Action] | ||
The actions that characters can take | ||
""" | ||
|
||
__slots__ = "actions" | ||
|
||
def __init__(self, actions: List[Action]) -> None: | ||
super().__init__() | ||
self.actions: Set[Action] = set(actions) | ||
|
||
|
||
class Action: | ||
|
||
def __init__(self, uid: int, rules: List[ActionRule], *roles: str) -> None: | ||
self.uid: int = uid | ||
self.rules: List[ActionRule] = rules | ||
|
||
def find_match(self, world: World) -> Tuple[Event, float]: | ||
raise NotImplementedError() | ||
|
||
def __eq__(self, other: Action) -> bool: | ||
return self.uid == other.uid | ||
|
||
def __hash__(self) -> int: | ||
return self.uid | ||
|
||
|
||
class ActionRule: | ||
""" | ||
ActionRules are combinations of patterns and probabilities for | ||
when an action is allowed to occur. A single action is mapped | ||
to one or more action rules. | ||
""" | ||
|
||
def __init__(self, bind_fn: Callable[..., Event], probability: Union[EventProbabilityFn, float] = 1.0) -> None: | ||
self.bind_fn: Callable[..., Event] = bind_fn | ||
self.probability_fn: EventProbabilityFn = ( | ||
probability if callable(probability) else (lambda world, event: probability) | ||
) |
Oops, something went wrong.