CITS3001-Algorithms-Agents-.../agents/abstract_influencer_agent.py
2022-10-24 21:04:39 +08:00

79 lines
2.6 KiB
Python

from abc import ABC, abstractmethod
import pickle
import shelve
from typing import Dict, List, Tuple, Union
import etc.gamestate as gs
from etc.messages import MESSAGE_UNDEFINED, Message
from etc.util import NoCopyShelf, RecursiveDict
from agents.action_state import ActionState
class AbstractInfluencerAgent(ABC):
last_message: Message
# Number of red opinions [int]
# Number of blue opinions [int]
# Number of red followers [int]
# Blue energy [int - convert from continuous float to discrete]
state_action_lut: Dict[int, Dict[int, Dict[int, Dict[int, Dict[int, List[Union[int, float]]]]]]]
__state_action_lut: NoCopyShelf
short_term_mem: List[ActionState]
def __init__(self, state_action_lut_path: str) -> None:
self.last_message = MESSAGE_UNDEFINED
self.__state_action_lut = NoCopyShelf.open(
state_action_lut_path,
protocol=pickle.HIGHEST_PROTOCOL,
writeback=True # Yes this makes it less performant, but it will be more readable.
)
# Create data for new shelve
try:
self.__state_action_lut["data"]
except KeyError:
self.__state_action_lut["data"] = RecursiveDict()
self.state_action_lut = self.__state_action_lut["data"]
self.short_term_mem = []
@abstractmethod
def influence(self, state: "gs.GameState", *args, **kwargs) -> None:
pass
@abstractmethod
def smart_influence(self, state: "gs.GameState") -> None:
pass
@abstractmethod
def choices() -> List[Tuple]:
pass
@abstractmethod
def update_short_term_mem(self, old_state: "gs.GameState", resulting_state: "gs.GameState") -> None:
pass
@abstractmethod
def update_lut(self) -> None:
pass
def __update_lut_rating__(self, action_state: ActionState, rating: float) -> None:
# Number of red opinions [int]
# Number of blue opinions [int]
# Number of red followers [int]
# Blue energy [int - convert from continuous float to discrete]
# Action
previous_state_ratings: List[int, float] = self.state_action_lut[action_state.n_red_opinion_bin][action_state.n_blue_opinion_bin][
action_state.n_red_followers_bin][action_state.blue_energy_bin]
action = action_state.action.id
if (type(previous_state_ratings[action]) != list):
previous_state_ratings[action] = [0, 0.0]
previous_state_ratings[action][0] += 1
previous_state_ratings[action][1] += rating
def close_lut(self) -> None:
self.__state_action_lut.close()
def sync_lut(self) -> None:
self.__state_action_lut.sync()