Example #1
0
/**
 * @brief Remember a particular interaction between two beings
 * @param local_sim Pointer to the simulation object
 * @param local Pointer to the being
 * @param other Pointer to the being being interacted with
 * @param event The type of event
 * @param affect The affect associated with the interaction
 * @param arg Any additional argument
 */
void episodic_interaction(
    noble_being * local,
    noble_being * other,
    being_episodic_event_type event,
    AFFECT_TYPE affect,
    n_byte2 arg)
{
    episodic_store_memory(
        local, event, affect,
        being_gender_name(local),being_family_name(local),
        being_gender_name(other),being_family_name(other), arg);
}
Example #2
0
/**
 * @brief Store an episodic memory about the self
 * @param local_sim Pointer to the simulation object
 * @param local Pointer to the being
 * @param event The type of event
 * @param affect An affect value associated with the event
 * @param arg Any additional argument
 */
void episodic_self(
    noble_being * local,
    being_episodic_event_type event,
    AFFECT_TYPE affect,
    n_byte2 arg)
{
    episodic_store_memory(local, event, affect,
                          being_gender_name(local), being_family_name(local),
                          0, 0, arg);
}
Example #3
0
/**
 * @brief Returns a celebrity factor based upon how many apes within
 * the episodic memory of the given ape have a similar name to the
 * met ape, and their friend or foe values.
 * This means that initial beliefs about other apes are partly
 * a form of stereotyping
 * @param local_sim pointer to the simulation
 * @param meeter_being pointer to the ape
 * @param met_being pointer to another ape
 * @return celebrity value of the met ape
 */
n_int episodic_met_being_celebrity(
    noble_being * meeter_being,
    noble_being * met_being)
{
    n_int i,j,celebrity=0,ctr,aff;
    noble_episodic * meeter_episodic = being_episodic(meeter_being);
    n_byte2 first_name = being_gender_name(met_being);
    n_byte2 family_name = being_family_name(met_being);

    if (!meeter_episodic) return 0;

    /** check all episodic memories of the meeter */
    for (i=0; i<EPISODIC_SIZE; i++)
    {
        aff = (n_int)(meeter_episodic[i].affect) - EPISODIC_AFFECT_ZERO;
        if (aff>1) aff=1;
        if (aff<-1) aff=-1;

        /** check both the meeter and the met ape for each memory */
        for (j=BEING_MEETER; j<=BEING_MET; j++)
        {
            ctr=0;
            /** same first name */
            if (meeter_episodic[i].first_name[j]==first_name)
            {
                celebrity+=aff;
                ctr++;
            }
            /** same family name */
            if (meeter_episodic[i].family_name[j]==family_name)
            {
                celebrity+=aff;
                ctr++;
            }
            /** if both first name and family name match then
            increase the celebrity value further */
            if (ctr==2)
            {
                celebrity+=aff*2;
            }
        }
    }

    /** limit within range */
    if (celebrity>16) celebrity=16;
    if (celebrity<-16) celebrity=-16;
    return celebrity;
}
Example #4
0
/**
 * @brief Generate an intention.
 * Note that intentions are stored together with episodic memories,
 * with the event type making the difference between a memory about
 * the past and an intention about the future.
 * @param local_sim Pointer to the simulation
 * @param local Pointer to the ape
 * @param episode_index Episodic memory array index to use.
 * @param mins_ahead The number of minutes into the future for which the intention will last.
 * @param args Any additional arguments
 * @return Returns 1 if the update was successful, or 0 otherwise.
 */
n_byte episodic_intention(
    noble_being * local,
    n_int episode_index,
    n_byte2 mins_ahead,
    n_byte args)
{
    n_byte4 date;
    n_byte4 time;
    n_int   replace;
    n_byte  event;

    noble_episodic * local_episodic = being_episodic(local);

    if (local_episodic == 0L)
    {
        return 0;
    }

    event = local_episodic[episode_index].event;

    if (event==0) return 0;

    time = land_time();
    date = local_episodic[episode_index].space_time.date;
    if (time >= TIME_DAY_MINUTES)
    {
        /** increment date by one day */
        time %= TIME_DAY_MINUTES;
        date++;
    }

    if (event >= EVENT_INTENTION)
    {
        /** extend the time of an existing intention */
        local_episodic[episode_index].space_time.time = time;
        local_episodic[episode_index].space_time.date = date;
        local_episodic[episode_index].arg = args;
        /** if this was someone else's intention it now becomes yours */
        local_episodic[episode_index].first_name[BEING_MEETER] = being_gender_name(local);
        local_episodic[episode_index].family_name[BEING_MEETER] = being_family_name(local);
        return 1;
    }

    /** only certain types of events become intentions */
    if (!((event==EVENT_GROOM) || (event==EVENT_CHAT)))
    {
        return 0;
    }

    /** find a memory index to replace */
    replace = noble_episodic_replace_index(
                  EVENT_INTENTION + event,
                  (n_int)(local_episodic[episode_index].affect)-EPISODIC_AFFECT_ZERO,
                  being_gender_name(local),
                  being_family_name(local),
                  local_episodic[episode_index].first_name[BEING_MET],
                  local_episodic[episode_index].family_name[BEING_MET],
                  local);

    if (replace == -1)
    {
        return 0;
    }

    if (replace == episode_index)
    {
        return 0;
    }

    memory_copy((n_byte*)&local_episodic[episode_index], (n_byte*)&local_episodic[replace], sizeof(noble_episodic));

    local_episodic[replace].event = EVENT_INTENTION + event;

    local_episodic[replace].space_time.time = time;
    local_episodic[replace].space_time.date = date;

    local_episodic[replace].first_name[BEING_MEETER] = being_gender_name(local);
    local_episodic[replace].family_name[BEING_MEETER] = being_family_name(local);

    local_episodic[replace].arg = args;

    return 1;
}
Example #5
0
/**
 * @brief Remember eating
 * @param local_sim Pointer to the simulation object
 * @param local Pointer to the being
 * @param energy Energy obtained from food
 * @param food_type The type of food
 */
void episodic_food(noble_being * local, n_int energy, n_byte food_type)
{
    episodic_store_full(local, EVENT_EAT, energy,
                        being_gender_name(local), being_family_name(local),
                        0, 0, 0, food_type);
}
Example #6
0
/**
 * @brief Updates the sex drive
 * @param local Pointer to the ape
 * @param awake whether the ape is awake
 * @param local_sim Pointer to the simulation
 */
static void drives_sex(
    noble_being * local,
    n_int awake,
    noble_simulation * local_sim)
{
    n_int i,max;
    noble_social * local_social_graph = being_social(local);
    n_int age_in_days = AGE_IN_DAYS(local);

#ifdef EPISODIC_ON
    noble_episodic * local_episodic = being_episodic(local);
#endif

    /** is the being mature */
    if (age_in_days > AGE_OF_MATURITY)
    {
        /** is the being awake and its sex drive not saturated */
        if (awake)
        {
            /** increase the sex drive */
            being_inc_drive(local, DRIVE_SEX);

            /** if sex drive is above a mate seeking threshold and
            the being has no current goal */
            if ((being_drive(local, DRIVE_SEX) > THRESHOLD_SEEK_MATE) &&
                being_check_goal(local, GOAL_NONE))
            {
                /** either search for a preferred mate, or mate randomly */
                if (GENE_MATE_SEEK(being_genetics(local))&1)
                {
                    /** look for a mate */
#ifdef EPISODIC_ON
                    if (!local_episodic) return;

                    /** does the being remember mating in the recent past */
                    for(i=0; i<EPISODIC_SIZE; i++)
                    {
                        if (local_episodic[i].event == EVENT_MATE)
                        {
                            /** not someone else's mate */

                            if (being_name_comparison(local, local_episodic[i].first_name[BEING_MEETER], local_episodic[i].family_name[BEING_MEETER]))
                            {
                                /** set a goal to seek the remembered mate */
                                
                                being_set_goal_mate(local, local_episodic[i].first_name[BEING_MET], local_episodic[i].family_name[BEING_MET]);
                                
                                /** remember seeking a mate */
                                episodic_store_memory(
                                    local_sim,
                                    local, EVENT_SEEK_MATE, AFFECT_SEEK_MATE,
                                    being_gender_name(local), being_family_name(local),
                                    local->delta.goal[1], local->delta.goal[2],0);
                                break;
                            }
                        }
                    }
#endif
                    /** if the being is not seeking a remembered mate
                        then examine the social graph for attractive prospects */
                    if (being_check_goal(local, GOAL_MATE) == 0)
                    {
                        max = 0;
                        if (!local_social_graph) return;

                        for(i=1; i<SOCIAL_SIZE_BEINGS; i++)
                        {
                            if (!SOCIAL_GRAPH_ENTRY_EMPTY(local_social_graph,i))
                            {
                                if ((local_social_graph[i].attraction) > max)
                                {
                                    
                                    /** who are we most attracted to? */
                                    max=local_social_graph[i].attraction;
                                    
                                    being_set_goal_mate(local, local_social_graph[i].first_name[BEING_MET], local_social_graph[i].family_name[BEING_MET]);
                                }
                            }
                        }
                        /** if an attractive mate was found then remember this event */
                        if (being_check_goal(local, GOAL_MATE))
                        {
                            episodic_store_memory(
                                local_sim,
                                local, EVENT_SEEK_MATE, AFFECT_SEEK_MATE,
                                being_gender_name(local), being_family_name(local),
                                local->delta.goal[1], local->delta.goal[2],0);
                        }
                    }
                }
            }
            /** during gestation reduce the sex drive */
            if (being_pregnant(local) != 0)
            {
                if (being_drive(local, DRIVE_SEX) >= GESTATION_SEX_DRIVE_DECREMENT)
                {
                    being_dec_drive(local, DRIVE_SEX);
                }
            }
        }
        else
        {
            /** while sleeping reduce sex drive */
            being_dec_drive(local, DRIVE_SEX);
        }
        /** if sex drive falls below the mate seeking threshold and the being
            is seeking a mate, then stop seeking a mate */
        if ((being_drive(local, DRIVE_SEX) < THRESHOLD_SEEK_MATE) &&
             being_check_goal(local, GOAL_MATE))
        {
            being_set_goal_none(local);
        }
    }
}