public override double computeUtility(Person p, VoteOption option, List <ReasonMsg> msgs)
        {
            double u = option.getBaseUtility(p);


            if (option.index == NO_RESPONSE)
            {
                msgs.Add(new ReasonMsg("Neutral Option", 0));
            }

            if (option.index == AGENT_TO_KNIGHT)
            {
                double localU = Unit_Investigator.getSwitchUtility(p, (Unit_Investigator)option.unit, Unit_Investigator.unitState.knight);
                localU *= p.map.param.utility_swapAgentRolesMult;
                msgs.Add(new ReasonMsg("Balance of agent skills vs balance of threats", localU));
                u += localU;
            }
            if (option.index == AGENT_TO_BASIC)
            {
                double localU = Unit_Investigator.getSwitchUtility(p, (Unit_Investigator)option.unit, Unit_Investigator.unitState.basic);
                localU *= p.map.param.utility_swapAgentRolesMult;
                msgs.Add(new ReasonMsg("Balance of agent skills vs balance of threats", localU));
                u += localU;
            }

            return(u);
        }
예제 #2
0
        public override double computeUtility(Person p, VoteOption option, List <ReasonMsg> msgs)
        {
            double u = option.getBaseUtility(p);

            double concernLevel = p.threat_enshadowedNobles.threat;         //curr 0 to 200

            concernLevel += (100 * p.awareness) + (100 * p.map.worldPanic); //0 to 400
            concernLevel /= 4;
            concernLevel  = Math.Min(concernLevel, (p.map.worldPanic * 100) + 20);

            concernLevel *= (1 - p.shadow);
            if (p.state == Person.personState.enthralled || p.state == Person.personState.broken)
            {
                concernLevel = 0;
            }

            //Define the range at which this manner of response is appropriate
            double responseLevelMin = 0;
            double responseLevelMax = 0;

            if (option.index == NO_RESPONSE)
            {
                responseLevelMin = 0;
                responseLevelMax = 10;

                if (p.getGreatestThreat() != null && p.getGreatestThreat() != p.threat_enshadowedNobles)
                {
                    double localU = World.staticMap.param.utility_greatestThreatDelta * 0.5;
                    msgs.Add(new ReasonMsg("Not our greatest threat", localU));
                    u += localU;
                }
                else
                {
                    double localU = -World.staticMap.param.utility_greatestThreatDelta;
                    msgs.Add(new ReasonMsg("Enshadowed nobles are our greatest threat", localU));
                    u += localU;
                }
            }

            if (option.index == WITCH_HUNT)
            {
                responseLevelMin = 80;
                responseLevelMax = 100;

                double localU = -World.staticMap.param.utility_killSuspectRelucatance;
                msgs.Add(new ReasonMsg("Base Reluctance to Execute Noble", localU));
                u += localU;


                bool isWarlike   = false;
                bool isHonorable = false;
                bool isPacifist  = false;
                foreach (Trait t in p.traits)
                {
                    if (t is Trait_Political_Warlike)
                    {
                        isWarlike = true; break;
                    }
                    if (t is Trait_Political_Honorable)
                    {
                        isHonorable = true; break;
                    }
                    if (t is Trait_Political_Pacifist)
                    {
                        isPacifist = true; break;
                    }
                }
                if (isHonorable)
                {
                    localU = p.map.param.utility_honorableHatesWitchHunt;
                    msgs.Add(new ReasonMsg("Honorable Politician opposes executions without trials", localU));
                    u += localU;
                }
                if (isWarlike)
                {
                    localU = p.map.param.utility_warlikeLikesWitchHunt;
                    msgs.Add(new ReasonMsg("Warlike Politician supports violence", localU));
                    u += localU;
                }
                if (isPacifist)
                {
                    localU = -p.map.param.utility_warlikeLikesWitchHunt;
                    msgs.Add(new ReasonMsg("Pacifist Politician supports violence", localU));
                    u += localU;
                }

                double maxSuspicion = 0;
                foreach (Person p2 in p.society.people)
                {
                    maxSuspicion = Math.Max(maxSuspicion, p.getRelation(p2.index).suspicion);
                }
                localU = maxSuspicion;
                if (localU != 0)
                {
                    msgs.Add(new ReasonMsg("Suspicion towards other nobles", localU));
                    u += localU;
                }
            }

            if (option.index == AGENT_TO_INQUISITOR)
            {
                responseLevelMin = 0;
                responseLevelMax = 100;
                Unit_Investigator inv = (Unit_Investigator)option.unit;

                double localU = Unit_Investigator.getSwitchUtility(p, (Unit_Investigator)option.unit, Unit_Investigator.unitState.inquisitor);
                localU *= p.map.param.utility_swapAgentRolesMult;
                msgs.Add(new ReasonMsg("Balance of agent skills vs balance of threats", localU));
                u += localU;

                bool isCorrupt = false;
                foreach (Trait t in p.traits)
                {
                    if (t is Trait_Political_Corrupt)
                    {
                        isCorrupt = true; break;
                    }
                }
                if (isCorrupt)
                {
                    localU = p.map.param.utility_corruptHatesInquisitor;
                    msgs.Add(new ReasonMsg("Inquisitor may expose my political corruption", localU));
                    u += localU;
                }
            }
            if (option.index == AGENT_TO_BASIC)
            {
                responseLevelMin = 0;
                responseLevelMax = 100;

                double localU = Unit_Investigator.getSwitchUtility(p, (Unit_Investigator)option.unit, Unit_Investigator.unitState.basic);
                localU *= p.map.param.utility_swapAgentRolesMult;
                msgs.Add(new ReasonMsg("Balance of agent skills vs balance of threats", localU));
                u += localU;
            }

            if (concernLevel > responseLevelMax)
            {
                double delta = responseLevelMax - concernLevel;
                delta *= society.map.param.utility_extremeismScaling;
                double localU = delta;
                msgs.Add(new ReasonMsg("Too weak response for current concern level (" + (int)(concernLevel) + "%)", localU));
                u += localU;
            }
            if (concernLevel < responseLevelMin)
            {
                double delta = concernLevel - responseLevelMin;
                delta *= society.map.param.utility_extremeismScaling;
                double localU = delta;
                msgs.Add(new ReasonMsg("Too extreme for current concern level (" + (int)(concernLevel) + "%)", localU));
                u += localU;
            }
            return(u);
        }
예제 #3
0
        public override double computeUtility(Person p, VoteOption option, List <ReasonMsg> msgs)
        {
            double u = option.getBaseUtility(p);


            if (option.index == NO_RESPONSE)
            {
                msgs.Add(new ReasonMsg("Neutral Option", 0));
            }

            if (option.index == AGENT_TO_MEDIC)
            {
                double localU = Unit_Investigator.getSwitchUtility(p, (Unit_Investigator)option.unit, Unit_Investigator.unitState.medic);
                localU *= p.map.param.utility_swapAgentRolesMult;
                msgs.Add(new ReasonMsg("Balance of agent skills vs balance of threats", localU));
                u += localU;
            }
            if (option.index == AGENT_TO_BASIC)
            {
                double localU = Unit_Investigator.getSwitchUtility(p, (Unit_Investigator)option.unit, Unit_Investigator.unitState.basic);
                localU *= p.map.param.utility_swapAgentRolesMult;
                msgs.Add(new ReasonMsg("Balance of agent skills vs balance of threats", localU));
                u += localU;
            }
            if (option.index == QUARANTINE)
            {
                //First part is your personal utility. How much am I, personally, affected?
                double localU      = p.threat_plague.threat;
                bool   amNeighbour = false;
                bool   hasDisease  = false;
                foreach (Property p2 in p.getLocation().properties)
                {
                    if (p2.proto.isDisease)
                    {
                        hasDisease = true; break;
                    }
                }
                if (hasDisease)
                {
                    //This option doesn't help me. It's already here. If I'm corrupt, I'll naturally be angry at not being given help
                    localU = p.getSelfInterest() * p.threat_plague.threat * World.staticMap.param.utility_selfInterestFromThreat;
                    if (localU != 0)
                    {
                        msgs.Add(new ReasonMsg("Does not help me personally", localU));
                        u += localU;
                    }
                }
                else
                {
                    //I do not have the disease. Best to vote to keep it that way.
                    foreach (Location l2 in p.getLocation().getNeighbours())
                    {
                        foreach (Property p2 in l2.properties)
                        {
                            if (p2.proto.isDisease)
                            {
                                amNeighbour = true; break;
                            }
                        }
                    }
                    if (amNeighbour)
                    {
                        localU *= 1.5;
                    }
                    else
                    {
                        localU *= 0.66;
                    }
                    localU *= p.getSelfInterest() * -1 * World.staticMap.param.utility_selfInterestFromThreat; //Note this param is negative as it is petulance
                    if (localU != 0)
                    {
                        msgs.Add(new ReasonMsg("Desire to keep self safe from disease", localU));
                        u += localU;
                    }
                }

                //Second part is the benefit to the nation
                int    nNeighbours = 0;
                double nSocLocs    = 0;
                foreach (Location l2 in p.map.locations)
                {
                    if (l2.soc == p.society)
                    {
                        nSocLocs += 1;
                    }
                    else
                    {
                        continue;
                    }

                    hasDisease = false;
                    foreach (Property p2 in l2.properties)
                    {
                        if (p2.proto.isDisease)
                        {
                            hasDisease = true; break;
                        }
                    }
                    if (hasDisease)
                    {
                        foreach (Location l3 in l2.getNeighbours())
                        {
                            if (l3.soc != p.society)
                            {
                                continue;
                            }
                            bool l3HasDisease = false;
                            foreach (Property p2 in l3.properties)
                            {
                                if (p2.proto.isDisease)
                                {
                                    l3HasDisease = true; break;
                                }
                            }
                            if (!l3HasDisease)
                            {
                                //Location 3 doesn not have the disease, but l2 does. Therefore it is a spread vector
                                //Since we're taking a risk for each link, we can double-count L3s.
                                nNeighbours += 1;
                            }
                        }
                    }
                }
                localU = nNeighbours;
                if (nSocLocs > 0)
                {
                    localU /= nSocLocs;
                }                                        //Normalise for society size
                localU *= p.threat_plague.threat;
                localU *= p.map.param.utility_plagueResponseMultPerRiskItem;
                localU *= Math.Max(0, Math.Min(1, 1 - p.getSelfInterest()));//Clamp that between [0,1]
                if (localU != 0)
                {
                    msgs.Add(new ReasonMsg("Benefit to nation: Number of locations at risk", localU));
                    u += localU;
                }
            }
            if (option.index == TREATMENT)
            {
                //First part is your personal utility. How much am I, personally, affected?
                double localU     = p.threat_plague.threat;
                bool   hasDisease = false;
                foreach (Property p2 in p.getLocation().properties)
                {
                    if (p2.proto.isDisease)
                    {
                        hasDisease = true; break;
                    }
                }
                if (hasDisease)
                {
                    //I have the disease. Gotta invest in that sweet cure
                    localU *= p.getSelfInterest() * -1 * World.staticMap.param.utility_selfInterestFromThreat;//Note this param is negative as it is petulance
                    if (localU != 0)
                    {
                        msgs.Add(new ReasonMsg("Desire to save self from disease", localU));
                        u += localU;
                    }
                }
                else
                {
                    //This option doesn't help me. It's already here. If I'm corrupt, I'll naturally be angry at not being given help
                    localU = p.getSelfInterest() * p.threat_plague.threat * World.staticMap.param.utility_selfInterestFromThreat;
                    if (localU != 0)
                    {
                        msgs.Add(new ReasonMsg("Does not help me personally", localU));
                        u += localU;
                    }
                }

                //Second part is the benefit to the nation
                int    nDiseased = 0;
                double nSocLocs  = 0;
                foreach (Location l2 in p.map.locations)
                {
                    if (l2.soc == p.society)
                    {
                        nSocLocs += 1;
                    }
                    else
                    {
                        continue;
                    }

                    foreach (Property p2 in l2.properties)
                    {
                        if (p2.proto.isDisease)
                        {
                            nDiseased += 1; break;
                        }
                    }
                }
                localU = nDiseased;
                if (nSocLocs > 0)
                {
                    localU /= nSocLocs;
                }                                        //Normalise for society size
                localU *= p.threat_plague.threat;
                localU *= p.map.param.utility_plagueResponseMultPerRiskItem;
                localU *= Math.Max(0, Math.Min(1, 1 - p.getSelfInterest()));//Clamp that between [0,1]
                if (localU != 0)
                {
                    msgs.Add(new ReasonMsg("Benefit to nation: Number of locations infected", localU));
                    u += localU;
                }
            }

            return(u);
        }
        public override double computeUtility(Person p, VoteOption option, List <ReasonMsg> msgs)
        {
            double u = option.getBaseUtility(p);

            double concernLevel = p.threat_agents.threat;                   //curr 0 to 200

            concernLevel += (100 * p.awareness) + (100 * p.map.worldPanic); //0 to 400
            concernLevel /= 4;
            concernLevel  = Math.Min(concernLevel, (p.map.worldPanic * 100) + 20);

            concernLevel *= (1 - p.shadow);
            if (p.state == Person.personState.enthralled || p.state == Person.personState.broken)
            {
                concernLevel = 0;
            }

            //Define the range at which this manner of response is appropriate
            double responseLevelMin = 0;
            double responseLevelMax = 0;

            if (option.index == DEFEND_PROVINCE)
            {
                responseLevelMin = 10;
                responseLevelMax = 40;

                int evidenceFound = 0;
                foreach (Evidence ev in foundEvidence)
                {
                    if (ev.locationFound.province.index == option.province)
                    {
                        evidenceFound += 1;
                    }
                }

                double localU = World.staticMap.param.utility_defendEvidenceProvince * evidenceFound * (1 - p.shadow);
                msgs.Add(new ReasonMsg("Amount of evidence found in " + society.map.provinces[option.province].name + " province", localU));
                u += localU;

                localU = 0;
                foreach (Person person in society.people)
                {
                    if (person.getLocation() != null && person.getLocation().province.index == option.province)
                    {
                        localU += p.getRelation(person.index).getLiking() * World.staticMap.param.utility_agentDefendProvinceLikingMult;
                    }
                }
                string add = "";
                msgs.Add(new ReasonMsg("Liking for nobles in province" + add, localU));
                u += localU;

                if (p.getLocation().province.index != option.province)
                {
                    localU = p.getSelfInterest() * p.threat_agents.threat * World.staticMap.param.utility_selfInterestFromThreat;
                    if (localU != 0)
                    {
                        msgs.Add(new ReasonMsg("Does not help me personally", localU));
                        u += localU;
                    }
                }
                else
                {
                    localU = -1 * p.getSelfInterest() * p.threat_agents.threat * World.staticMap.param.utility_selfInterestFromThreat;
                    if (localU != 0)
                    {
                        msgs.Add(new ReasonMsg("Helps me personally", localU));
                        u += localU;
                    }
                }
            }
            if (option.index == NATIONWIDE_SECURITY)
            {
                responseLevelMin = 10;
                responseLevelMax = 40;

                double localU = World.staticMap.param.utility_evidenceResonseBaseline * (concernLevel / 100);
                msgs.Add(new ReasonMsg("Base Desirability", localU));
                u += localU;

                localU = p.getSelfInterest() * p.threat_agents.threat * World.staticMap.param.utility_selfInterestFromThreat / 2;
                if (localU != 0)
                {
                    msgs.Add(new ReasonMsg("Doesn't maximise my provinces' defences", localU));
                    u += localU;
                }
            }
            if (option.index == NO_RESPONSE)
            {
                responseLevelMin = 0;
                responseLevelMax = 10;

                if (p.getGreatestThreat() != null && p.getGreatestThreat() != p.threat_agents)
                {
                    double localU = World.staticMap.param.utility_greatestThreatDelta * 0.5;
                    msgs.Add(new ReasonMsg("Not our greatest threat", localU));
                    u += localU;
                }
                else
                {
                    double localU = -World.staticMap.param.utility_greatestThreatDelta;
                    msgs.Add(new ReasonMsg("Dark Agents are our greatest threat", localU));
                    u += localU;
                }
            }

            if (option.index == EXPELL_ALL_FOREIGN_AGENTS)
            {
                responseLevelMin = 75;
                responseLevelMax = 100;

                double n = 0;
                foreach (Unit unit in society.map.units)
                {
                    if (unit.society == society)
                    {
                        continue;
                    }
                    if (society.enemies.Contains(unit) == false)
                    {
                        n += 1;
                    }
                }
                if (n > 0)
                {
                    msgs.Add(new ReasonMsg("So many potential enemies!", concernLevel));
                    u += concernLevel;
                }
            }
            if (option.index == LOCKDOWN_PROVINCE)
            {
                responseLevelMin = 40;
                responseLevelMax = 100;

                int evidenceFound = 0;
                foreach (Evidence ev in foundEvidence)
                {
                    if (ev.locationFound.province.index == option.province)
                    {
                        evidenceFound += 1;
                    }
                }

                double localU = World.staticMap.param.utility_defendEvidenceProvince * evidenceFound * (1 - p.shadow);
                msgs.Add(new ReasonMsg("Amount of evidence found in " + society.map.provinces[option.province].name + " province", localU));
                u += localU;

                localU = 0;
                foreach (Person person in society.people)
                {
                    if (person.getLocation() != null && person.getLocation().province.index == option.province)
                    {
                        localU += p.getRelation(person.index).getLiking() * World.staticMap.param.utility_agentDefendProvinceLikingMult;
                    }
                }
                string add = "" + (int)(localU);
                msgs.Add(new ReasonMsg("Liking for nobles in province" + add, localU));
                u += localU;

                if (p.getLocation().province.index != option.province)
                {
                    localU = p.getSelfInterest() * p.threat_agents.threat * World.staticMap.param.utility_selfInterestFromThreat;
                    if (localU != 0)
                    {
                        msgs.Add(new ReasonMsg("Does not help me personally", localU));
                        u += localU;
                    }
                }
                else
                {
                    localU = -1 * p.getSelfInterest() * p.threat_agents.threat * World.staticMap.param.utility_selfInterestFromThreat;
                    if (localU != 0)
                    {
                        msgs.Add(new ReasonMsg("Helps me personally", localU));
                        u += localU;
                    }
                }
            }
            if (option.index == AGENT_TO_INVESTIGATOR)
            {
                responseLevelMin = 0;
                responseLevelMax = 100;
                Unit_Investigator inv = (Unit_Investigator)option.unit;

                double localU = Unit_Investigator.getSwitchUtility(p, (Unit_Investigator)option.unit, Unit_Investigator.unitState.investigator);
                localU *= p.map.param.utility_swapAgentRolesMult;
                msgs.Add(new ReasonMsg("Balance of agent skills vs balance of threats", localU));
                u += localU;
                bool hasSuspicions = false;
                foreach (RelObj rel in inv.person.relations.Values)
                {
                    if (inv.location.map.persons[rel.them] == null)
                    {
                        continue;
                    }
                    if (rel.suspicion > 0 && inv.location.map.persons[rel.them].unit != null && inv.location.map.units.Contains(inv.location.map.persons[rel.them].unit))
                    {
                        hasSuspicions = true;
                    }
                }
                if (hasSuspicions)
                {
                    localU = 12;
                    msgs.Add(new ReasonMsg("Has a suspect", localU));
                    u += localU;
                }
            }
            if (option.index == AGENT_TO_BASIC)
            {
                responseLevelMin = 0;
                responseLevelMax = 100;

                double localU = Unit_Investigator.getSwitchUtility(p, (Unit_Investigator)option.unit, Unit_Investigator.unitState.basic);
                localU *= p.map.param.utility_swapAgentRolesMult;
                msgs.Add(new ReasonMsg("Balance of agent skills vs balance of threats", localU));
                u += localU;
            }

            if (concernLevel > responseLevelMax)
            {
                double delta = responseLevelMax - concernLevel;
                delta *= society.map.param.utility_extremeismScaling;
                double localU = delta;
                msgs.Add(new ReasonMsg("Too weak response for current concern level (" + (int)(concernLevel) + "%)", localU));
                u += localU;
            }
            if (concernLevel < responseLevelMin)
            {
                double delta = concernLevel - responseLevelMin;
                delta *= society.map.param.utility_extremeismScaling;
                double localU = delta;
                msgs.Add(new ReasonMsg("Too extreme for current concern level (" + (int)(concernLevel) + "%)", localU));
                u += localU;
            }
            return(u);
        }