Example #1
0
/**
 * @brief Update the episodic memories for a given ape.
 * This is based upon a fading memory model in which older memories
 * are replaced by newer ones.  Each memory has an associated affect
 * value indicating its emotional impact, and this fades over time.
 *
 * The rate of fading is genetically regulated, with different rates
 * for memories with positive and negative affect.
 * This facilitates optimistic/pessimistic and forgetful/memorable
 * type personalities.
 *
 * The fading memory model may not be strictly realistic, and might
 * be replaced by something else in future.
 * @param local_being pointer to the ape
 */
void episodic_cycle_no_sim(noble_being * local_being, void * data)
{
    if (local_being->delta.awake == 0) return;
    {
        n_int i;
        noble_episodic * local_episodic = being_episodic(local_being);
        n_genetics * genetics = being_genetics(local_being);

        if (!local_episodic) return;

        for (i=0; i<EPISODIC_SIZE; i++)
        {
            if (local_episodic[i].event == 0) continue;

            /** remove intentions which are outdated */
            if (local_episodic[i].event >= EVENT_INTENTION)
            {
                /** is this my intention, or someone else's? */
                if (being_name_comparison(local_being, local_episodic[i].first_name[BEING_MEETER], local_episodic[i].family_name[BEING_MEETER]))
                {
                    if (spacetime_before_now(&local_episodic[i].space_time))
                    {
                        local_episodic[i].event = 0;
                        continue;
                    }
                }
                episodic_intention_update(local_being, i);
            }

            /** fade towards EPISODIC_AFFECT_ZERO */
            if (local_episodic[i].affect < EPISODIC_AFFECT_ZERO)
            {
                /** negative memories fade */
                if (EPISODIC_AFFECT_ZERO - local_episodic[i].affect > 16)
                {
                    local_episodic[i].affect+=(1+GENE_NEGATIVE_AFFECT_FADE(genetics));
                }
                else
                {
                    local_episodic[i].affect++;
                }
            }
            else
            {
                if (local_episodic[i].affect > EPISODIC_AFFECT_ZERO)
                {
                    /** positive memories fade */
                    if (local_episodic[i].affect - EPISODIC_AFFECT_ZERO > 16)
                    {
                        local_episodic[i].affect-=(1+GENE_POSITIVE_AFFECT_FADE(genetics));
                    }
                    else
                    {
                        local_episodic[i].affect--;
                    }
                }
            }
        }
    }
}
Example #2
0
static void transfer_being(n_file * tranfer_out, noble_simulation * value, n_int being, noble_file_entry * format)
{
#ifdef USE_FIL_SOE
    n_int loop = (SOCIAL_SIZE * being);
    n_int loop_end = loop + SOCIAL_SIZE;
#endif
#ifdef USE_FIL_EPI
    n_int loop_episodic = (EPISODIC_SIZE * being);
    n_int loop_episodic_end = loop + EPISODIC_SIZE;
#endif

#ifdef USE_FIL_BEI
    io_write_buff(tranfer_out, &(value->beings[being]), format, FIL_BEI, 0L);
#endif
#ifdef USE_FIL_SOE
    while (loop < loop_end)
    {
        io_write_buff(tranfer_out, being_social(&(value->beings[being])), format, FIL_SOE, &brain_three_byte_command);
        loop++;
    }
#endif
#ifdef USE_FIL_EPI
    while (loop_episodic < loop_episodic_end)
    {
        io_write_buff(tranfer_out, being_episodic(&(value->beings[being])), format, FIL_EPI, 0L);
        loop_episodic++;
    }
#endif
}
Example #3
0
/**
 * @brief If the given episodic memory is an intention, as defined by the event type,
 * then update the learned preferences based upon the intention type.
 * For example, if the ape intends to chat then the chatting preference
 * may be increased which makes chatting more likely.
 * @param local pointer to the particular ape
 * @param episode_index array index of the episodic memory representing the intention
 */
static void episodic_intention_update(noble_being * local, n_int episode_index)
{
    noble_episodic * local_episodic = being_episodic(local);
    n_byte event;
    n_int learned_preference_index=-1;
    if (local_episodic == 0L)
    {
        return;
    }
    event = local_episodic[episode_index].event - EVENT_INTENTION;
    switch(event)
    {
    case EVENT_CHAT:
    {
        learned_preference_index = PREFERENCE_CHAT;
        break;
    }
    case EVENT_GROOM:
    {
        if ((local_episodic[episode_index].arg&2)!=0)
        {
            learned_preference_index = PREFERENCE_GROOM_MALE;
        }
        else
        {
            learned_preference_index = PREFERENCE_GROOM_FEMALE;
        }
        break;
    }
    }

    /** alter preferences */
    if (learned_preference_index>-1)
    {
        if ((local_episodic[episode_index].arg&1)!=0)
        {
            if (local->changes.learned_preference[learned_preference_index]<255)
            {
                local->changes.learned_preference[learned_preference_index]++;
            }
        }
        else
        {
            if (local->changes.learned_preference[learned_preference_index]>0)
            {
                local->changes.learned_preference[learned_preference_index]--;
            }
        }
    }
}
Example #4
0
/**
 * @brief This returns the percentage of episodic memories or intentions which are first person.
 * Some memories originate from the self and others are acquired from others via chatting.
 * @param local_sim pointer to the simulation
 * @param local pointer to the ape
 * @param intention 0=episodic memories, 1=intentions
 * @return percentage in the range 0-100
 */
n_int episodic_first_person_memories_percent(
    noble_being * local,
    n_byte intention)
{
    n_int i,hits=0,memories=0;
    noble_episodic * local_episodic = being_episodic(local);
    if (local_episodic == 0L)
    {
        return 0;
    }

    /** examine all memories */
    for (i=0; i<EPISODIC_SIZE; i++)
    {
        if (local_episodic[i].event>0)
        {
            if (intention!=0)
            {
                /** ratio of intentions to other memories */
                if (local_episodic[i].event >= EVENT_INTENTION)
                {
                    hits++;
                }
            }
            else
            {
                /** ratio of first person memories to other memories */
                if (being_name_comparison(local, local_episodic[i].first_name[BEING_MEETER], local_episodic[i].family_name[BEING_MEETER]))
                {
                    hits++;
                }
            }
            memories++;
        }
    }
    if (memories>0)
    {
        return hits*100/memories;
    }
    else
    {
        if (intention!=0)
        {
            return 0;
        }
        return 100;
    }
}
Example #5
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 #6
0
n_int	tranfer_in(n_file * input_file)
{
    n_int  ret_val;
    n_byte *temp_store = 0L;
    n_uint ape_count = 0;
    n_uint social_count = 0;
    n_uint episodic_count = 0;

    noble_simulation * local_sim = sim_sim();
    n_uint  size_buffer = io_find_size_data((noble_file_entry *)noble_file_format);

    temp_store = (n_byte *)memory_new(size_buffer);

    if (temp_store == 0L)
    {
        return SHOW_ERROR("No temporary storage memory available");
    }

    io_whitespace(input_file);

    input_file->location = 0;

    ret_val = io_read_buff(input_file, temp_store, noble_file_format);

    if(ret_val != FIL_VER) /* signature must be first */
        return SHOW_ERROR("Signature not first in file");

    {
        n_byte2	*signature = (n_byte2 *)temp_store;

        if(signature[0] != NOBLE_APE_SIGNATURE) /* not a Noble Ape file */
            return SHOW_ERROR("Not a Noble Ape File");

        if(signature[1] > VERSION_NUMBER) /* file version greater than this version */
            return SHOW_ERROR("File newer than Simulation");
    }

    do
    {
        n_byte *temp = 0L;
        ret_val = io_read_buff(input_file, temp_store, noble_file_format);
        if (ret_val == -1)
            SHOW_ERROR("Failure in file load");
        if (ret_val < FILE_EOF)
        {
            n_uint	loop_end = 0;
            switch (ret_val)
            {
            case FIL_LAN:
                temp = (n_byte*)land_ptr();
                loop_end = 11; /* Needs to be fixed */
                break;
            case FIL_BEI:
                temp = (n_byte*) &(local_sim->beings[ape_count]);
                loop_end = sizeof(noble_being);
                break;
            case FIL_SOE:
            {
                noble_social * local_social = being_social(&(local_sim->beings[ape_count]));
                temp = (n_byte*)(&local_social[social_count]);
                loop_end = sizeof(noble_social);
            }
            break;
            case FIL_EPI:
            {
                noble_episodic * local_episodic = being_episodic(&(local_sim->beings[ape_count]));
                temp = (n_byte*)(&local_episodic[episodic_count]);
                loop_end = sizeof(noble_episodic);
            }
            break;
            default:
            {
                return SHOW_ERROR("Unknown file kind"); /*unknown kind*/
            }
            break;
            }
            if(temp != 0L)
            {
                memory_copy(temp_store, temp, loop_end);
            }
            if (ret_val == FIL_BEI)
            {
                ape_count ++;
                if (ape_count == local_sim->max)
                {
                    local_sim->num = ape_count;
                    return SHOW_ERROR("Too many apes for memory");
                }
            }
            if (ret_val == FIL_SOE)
            {
                social_count ++;
                if (social_count == (local_sim->max * SOCIAL_SIZE))
                {
                    local_sim->num = ape_count;
                    return SHOW_ERROR("Too many social graph events for memory");
                }
            }
            if (ret_val == FIL_EPI)
            {
                episodic_count ++;
                if (episodic_count == (local_sim->max * EPISODIC_SIZE))
                {
                    local_sim->num = ape_count;
                    return SHOW_ERROR("Too many episodic events for memory");
                }
            }

        }

    }
    while (ret_val < FILE_EOF);

    if (ret_val == FILE_EOF)
    {
        local_sim->num = ape_count;
        return 0;
    }
    return SHOW_ERROR("Process file failed");
}
Example #7
0
/**
 * @brief Copy an episodic memory (an anecdote) from one ape to another during chat.
 * @param local_sim Pointer to the simulation
 * @param local Pointer to the ape conveying the anecdote
 * @param other Pointer to the ape to which the anecdote will be copied
 * @return Returns 1 if the copy was successful, 0 otherwise
 */
n_byte episodic_anecdote(
    noble_being * local,
    noble_being * other)
{
    noble_episodic * local_episodic = being_episodic(local);
    noble_episodic * other_episodic = being_episodic(other);
    n_int affect;
    n_byte event;
    n_int replace,mult=1;

    if (local_episodic == 0L || other_episodic == 0L || local == other)
    {
        return 0;
    }

    affect = (n_int)(local_episodic[being_attention(local,ATTENTION_EPISODE)].affect)-EPISODIC_AFFECT_ZERO;
    event = local_episodic[being_attention(local,ATTENTION_EPISODE)].event;

    /** both protagonists must be awake */
    if ((event==0) ||
            (local->delta.awake == FULLY_ASLEEP) ||
            (other->delta.awake == FULLY_ASLEEP))
    {
        return 0;
    }

    if (local->delta.awake != FULLY_AWAKE)
    {
        /** more likely to make errors while drowsy */
        mult=2;
    }

    /** mutate with some probability */
    if (being_random(local) <
            (ANECDOTE_EVENT_MUTATION_RATE+
             (local->changes.learned_preference[PREFERENCE_ANECDOTE_EVENT_MUTATION])*100)*mult)
    {
        event = (n_byte)(being_random(local) % EVENTS);
    }
    if (being_random(local) <
            (ANECDOTE_AFFECT_MUTATION_RATE+
             (local->changes.learned_preference[PREFERENCE_ANECDOTE_AFFECT_MUTATION])*100)*mult)
    {
        /** affect gets exaggerated or downplayed */
        affect = (affect * (64 + (n_int)(being_random(local) & 127))) / 128;
        /** keep affect within range */
        if (affect<-32000) affect=-32000;
        if (affect>32000) affect=32000;
    }

    /** find an index within the other episodic memory in which to insert */
    replace = noble_episodic_replace_index(
                  event,affect,
                  local_episodic[being_attention(local,ATTENTION_EPISODE)].first_name[BEING_MEETER],
                  local_episodic[being_attention(local,ATTENTION_EPISODE)].family_name[BEING_MEETER],
                  local_episodic[being_attention(local,ATTENTION_EPISODE)].first_name[BEING_MET],
                  local_episodic[being_attention(local,ATTENTION_EPISODE)].family_name[BEING_MET],
                  local);

    if (replace==-1) return 0;

    other_episodic[replace] = local_episodic[being_attention(local,ATTENTION_EPISODE)];
    other_episodic[replace].event = event;
    other_episodic[replace].affect = (n_byte2)(affect+EPISODIC_AFFECT_ZERO);

    /** other ape pays attention to the incoming anecdote */
    being_set_attention(local, ATTENTION_EPISODE, replace);

    return 1;
}
Example #8
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 #9
0
/**
 * @brief Stores an episodic memory
 * @param local Pointer to the being
 * @param event The type of event
 * @param affect Affect value associated with the event
 * @param local_sim Pointer to the simulation
 * @param name1 First name of a being participating in the event
 * @param family1 Family names of a being participating in the event
 * @param name2 First name of a second being participating in the event
 * @param family2 Family names of a second being participating in the event
 * @param arg Any additional argument
 * @param food Type of food
 */
static void episodic_store_full(
    noble_being * local,
    being_episodic_event_type event,
    n_int affect,
    n_byte2 name1, n_byte2 family1,
    n_byte2 name2, n_byte2 family2,
    n_byte2 arg,
    n_byte food)
{
    noble_episodic * local_episodic = being_episodic(local);
    n_int replace;
    n_byte  old_event;
    n_byte4 old_time;
    n_byte4 new_time;

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

    if (local->delta.awake == FULLY_ASLEEP) return;

    replace = noble_episodic_replace_index(event,affect,name1,family1,name2,family2,local);

    if (replace == -1) return;

    old_event = local_episodic[replace].event;
    old_time = local_episodic[replace].space_time.time;

    /** insert the current event into the episodic memory */
    local_episodic[replace].event       = event;
    local_episodic[replace].affect      = (n_byte2)(affect+EPISODIC_AFFECT_ZERO);

    spacetime_set(&local_episodic[replace].space_time, being_location(local));

    new_time = local_episodic[replace].space_time.time;

    local_episodic[replace].first_name[BEING_MEETER]=name1;
    local_episodic[replace].family_name[BEING_MEETER]=family1;
    local_episodic[replace].first_name[BEING_MET]=name2;
    local_episodic[replace].family_name[BEING_MET]=family2;
    local_episodic[replace].food=food;
    local_episodic[replace].arg=arg;

    if ((event == 0) || (event>=EVENTS))
    {
        (void)SHOW_ERROR("Event outside scope");
    }

    if (local_logging)
    {
        if ((old_event != event) /*|| ((old_time+10) < (new_time))*/) /**< TODO this may need to be changed */
        {
            n_string_block description = {0};
            n_string_block str = {0};
            n_string_block time = {0};
            n_string_block combination = {0};
            n_int social_event;

            social_event = episode_description(local, replace, description);

            if ((local_social == 1) && (social_event == 0))
            {
                return;
            }

            being_name_simple(local, str);
            io_time_to_string(time);
            io_three_string_combination(combination, time, str, description, 35);

            (*local_logging)(combination);
        }
    }
}
Example #10
0
/**
 * @brief Returns the index of the the episodic memory which can be overwritten with a new one.
 * @param event The type of event
 * @param affect The affect value associated with the event
 * @param name1 Name of the first ape in the memory (meeter)
 * @param family1 Family name of the first ape in the memory (meeter)
 * @param name2 Name of the second ape in the memory (met)
 * @param family2 Family name of the second ape in the memory (met)
 * @param local Pointer to the ape
 * @param local_sim Pointer to the simulation
 * @return array index of the episodic memory which can be replaced.
 */
static n_int noble_episodic_replace_index(
    being_episodic_event_type event,
    n_int affect,
    n_byte2 name1, n_byte2 family1,
    n_byte2 name2, n_byte2 family2,
    noble_being * local)
{
    /** absolute affect value */
    n_int abs_aff = affect;
    n_int i;
    n_int replace=-1;
    n_int min;
    n_byte event_exists=0;

    noble_episodic * local_episodic = being_episodic(local);

    if (!local_episodic) return -1;

    /** replace only events with an affect lower then the current */
    abs_aff = ABS(abs_aff);
    min = abs_aff;
    for (i=0; i<EPISODIC_SIZE; i++)
    {
        /** is this the same type of event */
        if (local_episodic[i].event == event)
        {
            /** is this the same being? */
            if ((local_episodic[i].first_name[BEING_MEETER]==name1) &&
                    (local_episodic[i].family_name[BEING_MEETER]==family1))
            {
                /** get absolute affect value */
                n_int aff1 = ABS((n_int)(local_episodic[i].affect)-EPISODIC_AFFECT_ZERO);
                /** does this have the least affect (most forgettable) */
                event_exists = 1;
                if (aff1 <= min)
                {
                    min = aff1;
                    replace = i;
                }
            }
        }
    }

    if (event_exists==0)
    {
        /** Use any empty memory slots */
        for (i=0; i<EPISODIC_SIZE; i++)
        {
            if (local_episodic[i].event == 0)
            {
                return i;
            }
        }

        /** no event of this type was found,
        so search for any event with the lowest affect */
        min = abs_aff;
        for (i=0; i<EPISODIC_SIZE; i++)
        {
            /** get absolute affect value */
            n_int aff1 = ABS((n_int)(local_episodic[i].affect)-EPISODIC_AFFECT_ZERO);
            /** does this have the least affect (most forgettable) */
            if (aff1 < min)
            {
                min = aff1;
                replace = i;
            }
        }
    }

    return replace;
}
Example #11
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);
        }
    }
}