/// <summary> /// Checks if current organism and another organism in the vicinity are a good match to form a group. /// To be a good match: /// 1. The organism in vicinity must also be cooperative and not solo /// 2. Both organisms must have similar/close economy gene value (worker. thief, etc.) /// 3. Both organisms must have similar/close military gene value (non, passive, etc.) /// </summary> private bool AreMatched(Organism curOrganism, Organism vicinityOrganism) { if (vicinityOrganism.GetGeneValueByType(GeneEnum.Cooperation) == (int)CooperationGene.Solo) { return(false); } //todo decide how group mergers occur // return false if both organisms are already in a group if (curOrganism.IsInGroup && vicinityOrganism.IsInGroup) { return(false); } var curOrganismEconomyMatchPercentage = GetEconomyMatchPercentage(curOrganism, vicinityOrganism); var vicinityOrganismEconomyMatchPercentage = GetEconomyMatchPercentage(vicinityOrganism, curOrganism); var curOrganismMilitaryMatchPercentage = GetMilitaryMatchPercentage(curOrganism, vicinityOrganism); var vicinityOrganismMilitaryMatchPercentage = GetMilitaryMatchPercentage(vicinityOrganism, curOrganism); // If any of above are 0 then there is no joining if ((curOrganismEconomyMatchPercentage * curOrganismMilitaryMatchPercentage * vicinityOrganismEconomyMatchPercentage * vicinityOrganismMilitaryMatchPercentage).Equals(0)) { return(false); } // todo What is the weight on economy vs military match? // for now lets give equal weight to economy vs military match double economyWeight = 1; double militaryWeight = 1; double sumWeights = economyWeight + militaryWeight; double curOrganismAcceptancePercentage = (economyWeight * curOrganismEconomyMatchPercentage + militaryWeight * curOrganismMilitaryMatchPercentage) / (sumWeights * 100); double vicinityOrganismAcceptancePercentage = (economyWeight * vicinityOrganismEconomyMatchPercentage + militaryWeight * vicinityOrganismMilitaryMatchPercentage) / (sumWeights * 100); // Both parties must accept one another for the join to happen bool curOrganismAccepts = RandomHelper.StandardGeneratorInstance.NextDouble() < curOrganismAcceptancePercentage; bool vicinityOrganismAccepts = RandomHelper.StandardGeneratorInstance.NextDouble() < vicinityOrganismAcceptancePercentage; return(curOrganismAccepts && vicinityOrganismAccepts); }
/// <summary> /// Military Match Score = 0-100 /// NonMilitants and passives will join anyone but offenders. /// Actives will join anyone. /// Actives and offenders join one of their own kind and a small chance to join one another. /// For actives and passives, there is a higher chance to accept someone less offensive than yourself than more offensive. /// </summary> private double GetMilitaryMatchPercentage(Organism curOrganism, Organism vicinityOrganism) { var currentOrganismMilitary = curOrganism.IsInGroup ? curOrganism.Group.GroupMilitaryGene : (MilitaryGene)curOrganism.GetGeneValueByType(GeneEnum.Military); var vicinityOrganismMilitary = vicinityOrganism.IsInGroup ? vicinityOrganism.Group.GroupMilitaryGene : (MilitaryGene)vicinityOrganism.GetGeneValueByType(GeneEnum.Military); switch (currentOrganismMilitary) { default: return(0); case MilitaryGene.NonMilitant: switch (vicinityOrganismMilitary) { default: return(0); case MilitaryGene.NonMilitant: return(MjNonNon); case MilitaryGene.Passive: return(MjNonPassive); case MilitaryGene.Proactive: return(MjNonActive); } case MilitaryGene.Passive: switch (vicinityOrganismMilitary) { default: return(0); case MilitaryGene.NonMilitant: return(MjPassiveNon); case MilitaryGene.Passive: return(MjPassivePassive); case MilitaryGene.Proactive: return(MjPassiveActive); } case MilitaryGene.Proactive: switch (vicinityOrganismMilitary) { default: return(0); case MilitaryGene.NonMilitant: return(MjActiveNon); case MilitaryGene.Passive: return(MjActivePassive); case MilitaryGene.Proactive: return(MjActiveActive); case MilitaryGene.Offender: return(MjActiveOffensive); } case MilitaryGene.Offender: switch (vicinityOrganismMilitary) { default: return(0); case MilitaryGene.Proactive: return(MjOffensiveActive); case MilitaryGene.Offender: return(MjOffensiveOffensive); } } }
/// <summary> /// Economy Match Score = 0-100 /// Fungal types will join anyone. /// Workers and survivors will join each other. Higher rate if both organisms are identical /// Thieves only join thieves. /// All non-fungals may still accept to join fungals because of the strength in numbers. More so in case of thieves since they are stealing /// any way and greater numbers works better and hardly much resources are lost to fungals. /// </summary> private double GetEconomyMatchPercentage(Organism curOrganism, Organism vicinityOrganism) { EconomyGene currentOrganismEconomy = curOrganism.IsInGroup ? curOrganism.Group.GroupEconomyGene : (EconomyGene)curOrganism.GetGeneValueByType(GeneEnum.Economy); EconomyGene vicinityOrganismEconomy = vicinityOrganism.IsInGroup ? vicinityOrganism.Group.GroupEconomyGene : (EconomyGene)vicinityOrganism.GetGeneValueByType(GeneEnum.Economy); switch (currentOrganismEconomy) { default: return(0); case EconomyGene.Fungal: // Fungal types always want to join return(EjFungal); case EconomyGene.Worker: switch (vicinityOrganismEconomy) { default: return(0); case EconomyGene.Fungal: return(EjWorkerFungal); case EconomyGene.Worker: return(EjWorkerWorker); case EconomyGene.Survivor: return(EjWorkerSurvivor); } case EconomyGene.Survivor: switch (vicinityOrganismEconomy) { default: return(0); case EconomyGene.Fungal: return(EjSurvivorFungal); case EconomyGene.Worker: return(EjSurvivorWorker); case EconomyGene.Survivor: return(EjSurvivorSurvivor); } case EconomyGene.Thief: switch (vicinityOrganismEconomy) { default: return(0); case EconomyGene.Fungal: return(EjThiefFungal); case EconomyGene.Thief: return(EjThiefThief); } } }