/** * @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--; } } } } } }
/** * @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); } } }