"""
Module to build experiments (worlds, agents, etc.).
"""

import model.interaction
import model.agent
import experiment

class BasicExperiment(experiment.Experiment):
    world_representation = [
        "wwwwwwwwwwwwwww",
        "w.............w",
        "w.wwwwwww.....w",
        "w.......wwwww.w",
        "w.wwwww.......w",
        "w.w.......w...w",
        "w.w.wwwww.w...w",
        "w.w.w...w.ww.ww",
        "w.www.....w...w",
        "w.....wwwww.a.w",
        "wwwwwwwwwwwwwww"
        ]

    def __init__(self):
        super(BasicExperiment, self).__init__()

        # Parse world
        self.world = self.parse_world(self.world_representation)

        # Set up primitives
        step = model.interaction.PrimitiveInteraction("Step")
        turn_right = model.interaction.PrimitiveInteraction("Turn Right")
        turn_left = model.interaction.PrimitiveInteraction("Turn Left")
        feel = model.interaction.PrimitiveInteraction("Feel")
        no_feel = model.interaction.PrimitiveInteraction("No Feel")
        bump = model.interaction.PrimitiveInteraction("Bump")

        # Define environment logic for primitives, these functions will be
        # registered to the primitive interactions and will be called once
        # the agent attempts to enact the primitive interaction. 
        # The function can manipulate the world and the agents.
        # The return value is the actual enacted interaction (i.e., can be 
        # different form the attempted interaction).
        def _step(world, agent, interaction):
            if world.can_step(agent):
                agent.step()
                return step
            else:
                return bump

        def _turn_right(world, agent, interaction):
            agent.add_rotation(-90)
            return turn_right
        
        def _turn_left(world, agent, interaction):
            agent.add_rotation(90)
            return turn_left

        def _feel(world, agent, interaction):
            if world.can_step(agent):
                return no_feel
            else:
                return feel

        # Register the previously defined functions.
        enact_logic = {}
        enact_logic[step] = _step
        enact_logic[turn_right] = _turn_right
        enact_logic[turn_left] = _turn_left
        enact_logic[feel] = _feel

        # Set primitives known/enactable by the agents.
        primitives = []
        primitives.append(step)
        primitives.append(turn_right)
        primitives.append(turn_left)
        primitives.append(feel)
        primitives.append(no_feel)
        primitives.append(bump)

        # Set intrinsic motivation values.
        motivation = {}
        motivation[step] = 7
        motivation[turn_right] = -1
        motivation[turn_left] = -1
        motivation[feel] = 0
        motivation[no_feel] = -1
        motivation[bump] = -10

        for entity in self.world.get_entities():
            if isinstance(entity, model.agent.Agent):
                self.world.add_enact_logic(entity, enact_logic)
                entity.set_primitives(primitives)
                entity.set_motivation(motivation)


    def get_world(self):
        return self.world
@@ -2713,9 +2713,9 @@
 %5D = 
-7
+1
 %0A   
@@ -2741,25 +2741,25 @@
 n_right%5D = -
-1
+2
 %0A        mot
@@ -2776,25 +2776,25 @@
 rn_left%5D = -
-1
+2
 %0A        mot

Make intrinisic motivation values more interesting.