public void ProcessComms(CommsEvent comm, bool isReprocess) { if (comm.Speaker == Me) { return; } // start mistrusting at suspicion > 0.5 var trust = TrustThisTurn(comm.Speaker.Id); var whom = comm.Whom; var where = comm.Where; var subject = comm.Speaker; switch (comm.EventType) { case CommsTypeEnum.IWasBitten: // first, process public effect if (Me.IsInJail) { SuspicionAgainstMeThisTurn -= trust * .5; // assume others have similar mistrust } // next process private conclusions if (LastNightAction.Whom == comm.Speaker.Id && LastNightAction.Action == NightActionEnum.Bite) { // (irrelevant if we did the biting! except maybe lie about it) // don't try and accuse if we're already more under suspicion than the bite-ee bool theyTrustMe = Relation(comm.Speaker.Id).DarkSideSuspicion + r.NextDouble() * 2 - r.NextDouble() * 3 > SuspicionAgainstMe; // don't try and accuse if there was another observer who'd know that we can't possibly know if (!isReprocess && theyTrustMe && !LastNightMet.Any() && r.NextDouble() > .5) { if (Me.Strategy == StrategyEnum.AI) { var falseAccuse = new CommsEvent(Me, CommsTypeEnum.LiedAboutBeingBitten, true, subject); Me.Game.Hub.AnnounceComms(Me.Game, falseAccuse, true, comm.Whom.NameSpan + " lied! No possible suspects!"); } } return; } var worstSuspect = ProcessBiteInfo(comm.Speaker.Id, trust, comm); Trace(true, "Worst suspect divisor: " + worstSuspect.ToString("0.00")); // no more cryWolf at approx worst suspect = .7 var cryWolfSusp = 3 / (worstSuspect + .8) - 2; if (cryWolfSusp < -.2) { cryWolfSusp = -.2; } Relation(comm.Speaker.Id).DarkSideSuspicion += cryWolfSusp; Trace(true, "Cry-wolf addSusp: " + cryWolfSusp.ToString("0.00")); break; case CommsTypeEnum.Slept: if (LastNightMet != null && LastNightMet.Contains(comm.Whom.Id)) { ProcessLie(comm.Speaker.Id, CommsTypeEnum.GenericLie, comm.Whom + " went out!", comm); } else if (comm.Whom.Id != Me.Id) { Relation(comm.Speaker.Id).SuspicionThisTurn -= .1; // trust for not-contradicted information Relation(comm.Whom.Id).SuspicionThisTurn -= trust * .2; } else if (comm.Whom.Id == Me.Id) { if (LastNightAction.Action != NightActionEnum.Sleep) { ProcessLie(comm.Speaker.Id, CommsTypeEnum.GenericLie, "I slept last night", comm); // todo: one-per-turn negative enmity } else { Relation(subject.Id).SuspicionThisTurn -= .15; // trust for correct information } } else if (LastNightKnownSlept.Contains(comm.Whom.Id)) { ProcessTruth(comm); } break; case CommsTypeEnum.WentOut: if (comm.Whom.Id != Me.Id) { // if contrary evidence, don't trust the report var trustThisReport = trust; // ???? - MIstrustToMult(0 - LastNightWentOutProbability[comm.Speaker.Id]) + .5; if (LastNightKnownSlept.Contains(comm.Whom.Id)) { ProcessLie(comm.Speaker.Id, CommsTypeEnum.GenericLie, comm.Whom.NameSpan + " slept all night!", comm); } else if (LastNightMet.Contains(whom.Id) && where != null) { // we have hard evidence if (LastNightAction.Whom == where.Id) { // truth ProcessTruth(comm); } else { // lie ProcessLie(subject.Id, CommsTypeEnum.GenericLie, subject.NameSpan + " lied! " + whom.NameSpan + " was at " + where.NameSpan + "'s", comm); } } else if (LastNightAnnouncedSleep.Contains(whom.Id)) { var accusedTrust = MIstrustToMult(Relation(whom.Id).DarkSideSuspicion); // this is insetad of using CommsTypeEnum.LiedAboutSleeping: LastNightWentOutProbability[whom.Id] += MIstrustToMult(Relation(subject.Id).DarkSideSuspicion - Relation(whom.Id).DarkSideSuspicion * .5) * .5; Relation(whom.Id).SuspicionThisTurn += trustThisReport - .1; var accuserAddSusp = accusedTrust * .75 * (MIstrustToMult(LastNightWentOutProbability[whom.Id])); Relation(subject.Id).SuspicionThisTurn += accuserAddSusp; Trace(true, "Accused of sleep/went-out lying addSusp:" + (trustThisReport - .1).ToString("0.00")); Trace(true, "Accuser of sleep/went-out lying addSusp:" + accuserAddSusp.ToString("0.00")); } else { Relation(subject.Id).SuspicionThisTurn -= .1; // trust for not-yet-contradicted information LastNightWentOutProbability[whom.Id] += trust * .5; var whomAddSusp = trustThisReport * .2; Relation(whom.Id).SuspicionThisTurn += whomAddSusp; Trace(true, "Heard went-out addSusp:" + whomAddSusp.ToString("0.00")); } } else { // claimed that I went out if (LastNightAction.Action == NightActionEnum.Sleep) { ProcessLie(subject.Id, CommsTypeEnum.GenericLie, "I slept all night!", comm); } else { Relation(subject.Id).SuspicionThisTurn -= .15; // trust for correct information } } break; case CommsTypeEnum.WillSleep: Relation(subject.Id).SuspicionThisTurn -= .1; // trust for not-yet-contracted information LastNightAnnouncedSleep.Add(subject.Id); break; case CommsTypeEnum.LiedAboutSleeping: // processed elsewhere break; case CommsTypeEnum.LiedAboutBeingBitten: ProcessAccusation(subject.Id, whom.Id); break; case CommsTypeEnum.GenericLie: ProcessAccusation(subject.Id, whom.Id); break; } }
private double ProcessBiteInfo(string whom, double probabilityIsBite, CommsEvent comms) { if (probabilityIsBite > 1) { probabilityIsBite = 1; } // got here if someone was bitten (including self) and self didn't do the biting bool reprocess = probabilityIsBite < 1; Trace(reprocess, "Someone bitten (" + probabilityIsBite.ToString("0.00") + "):"); Relation(whom).GuessedBitesThisTurn += probabilityIsBite; var innocents = LastNightKnownSlept; if (Me.Game.JailedPlayer != null) { innocents.Add(Me.Game.JailedPlayer.Id); } innocents.Add(Me.Id); innocents.Add(whom); var suspects = Relations.Where(x => !innocents.Contains(x.PlayerId)); if (LastNightAction.Whom == whom) { if (LastNightMet != null && LastNightMet.Any()) { suspects = Relations.Where(x => LastNightMet.Contains(x.PlayerId)); } } else { if (LastNightMet != null && LastNightMet.Any()) { suspects = suspects.Where(x => !LastNightMet.Contains(x.PlayerId)); } } if (suspects.Any()) { var mostSuspectSuspect = 0d; var totalNewSuspicion = 0d; foreach (var rel in suspects) { // can be slightly negative, if we have multiple trusted reports of stay-homeness totalling > .5... that's ok: totalNewSuspicion += MIstrustToMult(0 - LastNightWentOutProbability[rel.PlayerId] * 3); var thisSuspect = 1 - MIstrustToMult(LastNightWentOutProbability[rel.PlayerId] * 3 + .3) - MIstrustToMult(rel.DarkSideSuspicion + .3); if (thisSuspect > mostSuspectSuspect) { mostSuspectSuspect = thisSuspect; } } if (probabilityIsBite < 1) { probabilityIsBite = probabilityIsBite * mostSuspectSuspect; } Trace(reprocess, "probabilityIsBite reduce to: " + probabilityIsBite.ToString("0.00")); foreach (var rel in suspects) { var amountSuspicion = MIstrustToMult(0 - LastNightWentOutProbability[rel.PlayerId] * 3) / totalNewSuspicion; var addSusp = 3 * amountSuspicion * probabilityIsBite; if (reprocess) { rel.SuspicionThisTurn += addSusp; } else { rel.DarkSideSuspicion += addSusp; } Trace(reprocess, "LastNightWentOut: " + LastNightWentOutProbability[rel.PlayerId] + " addSusp:" + addSusp.ToString("0.00")); } return(mostSuspectSuspect); } else { // if no possible suspects, and self didn't do the biting, then we know somebody lied ProcessLie(whom, CommsTypeEnum.LiedAboutBeingBitten, "No possible suspects!", comms); return(-10); } }