public void VoteForTeam(Player player, bool approve) { if (Votes.Select(v=>v.Player).ToList().Contains(player)) throw new Exception("Player has already voted.."); Votes.Add(new Vote { Player = player, Approve = approve }); }
public void SubmitQuest(Player player, bool success) { if (Quests.Select(v => v.Player).ToList().Contains(player)) throw new Exception("Player has already submitted their quest card.."); Quests.Add(new Quest { Player = player, Success = success }); }
public TeamModel(Player player, Core.VoteTrack team, int totalPlayers, int teamNumber) { if (team.Leader != null) { Leader = team.Leader.Name; TeamSummary = string.Format("Team {0}, as proposed by {1}", teamNumber.ToWords(), Leader); } if (team.Excalibur != null) { ExcaliburUsedBy = team.Excalibur.Holder.Name; ExcaliburUsedOn = team.Excalibur.UsedOn != null ? team.Excalibur.UsedOn.Player.Name : "No One"; if (player == team.Excalibur.Holder) { ExcaliburResult = team.Excalibur.OriginalMissionWasSuccess.HasValue ? (team.Excalibur.OriginalMissionWasSuccess.Value ? "questsuccess" : "questfail") : ""; } else { ExcaliburResult = "quest"; } } TeamMembers = team.Players.Select(p => new TeamMemberModel { Player = p.Name, HasExcalibur = team.Excalibur != null && p.Name == ExcaliburUsedBy }).ToList(); Vote = team.Votes.OrderBy(v=>v.Player.Name).Select(v => new VoteModel(v, team.Votes.Count != totalPlayers)).ToList(); var hidden = team.QuestCards.Count != TeamMembers.Count; if (team.Excalibur != null && team.Excalibur.UsedOn == null && !team.Excalibur.Skipped) hidden = true; QuestCards = team.QuestCards.OrderBy(q=> q.Success).Select(q => new QuestCardModel(q.Success, hidden)).ToList(); Messages = team.Messages.Select(m => new MessageModel(m.Player.Name, m.Message)).ToList(); }
public Team(Player leader) { Leader = leader; TeamMembers = new List<Player>(); Votes = new List<Vote>(); Quests = new List<Quest>(); }
public VoteTrack(Player leader, int size, int requiredFails) { Leader = leader; QuestSize = size; RequiredFails = requiredFails; Players = new List<Player>(); Votes = new List<VoteToken>(); QuestCards = new List<QuestCard>(); Messages = new List<PlayerMessage>(); }
public void AddToTeam(Player player, Player proposedPlayer) { if (TeamMembers.Contains(proposedPlayer)) throw new Exception("Player is already on team.."); if (player != Leader) throw new Exception("Hax. Player is not the leader of this team"); TeamMembers.Add(proposedPlayer); }
public Quest(Player ladyOfTheLakeHolder, int teamSize, int requiredFails) { QuestSize = teamSize; RequiredFails = requiredFails; if (ladyOfTheLakeHolder != null) { LadyOfTheLake = new LadyOfTheLakeUse { Holder = ladyOfTheLakeHolder }; } VoteTracks = new List<VoteTrack>(); }
public LadyOfTheLakeUseModel(LadyOfTheLakeUse use, Player player) { UsedBy = use.Holder.Name; UsedOn = use.Target == null ? string.Empty : use.Target.Name; if (player == use.Holder) { Result = use.IsEvil ? "evil" : "good"; } else { Result = "allegiance"; } }
public ExcaliburUseModel(ExcaliburUse use, Player player) { UsedBy = use.Holder.Name; UsedOn = use.UsedOn != null ? use.UsedOn.Player.Name : "No One"; if (player == use.Holder) { Result = use.OriginalMissionWasSuccess.HasValue ? (use.OriginalMissionWasSuccess.Value ? "evil" : "good") : ""; } else { Result = "allegiance"; } }
void UseExcalibur(Player player, Player proposedPlayer) { if (proposedPlayer!=null) { CurrentVoteTrack.Excalibur.UsedOn = CurrentVoteTrack.QuestCards.First(p => p.Player == proposedPlayer); CurrentVoteTrack.Excalibur.OriginalMissionWasSuccess = CurrentVoteTrack.Excalibur.UsedOn.Success; CurrentVoteTrack.Excalibur.UsedOn.Success = !CurrentVoteTrack.Excalibur.UsedOn.Success; } else { CurrentVoteTrack.Excalibur.Skipped = true; } QuestFinished(); }
void UseLadyOfTheLake(Player target) { CurrentQuest.LadyOfTheLake.Target = target; CurrentQuest.LadyOfTheLake.IsEvil = IsCharacterEvil(target.Character, CurrentLancelotAllegianceSwitched); CurrentHolderOfLadyOfTheLake = target; QuestFinished(); }
private void RemoveFromTeam(Player target) { CurrentVoteTrack.Players.Remove(target); }
void SubmitQuest(Player player, bool success) { CurrentVoteTrack.QuestCards.Add(new QuestCard { Player = player, Success = success }); if (CurrentVoteTrack.QuestCards.Count == CurrentVoteTrack.QuestSize) { if (CurrentVoteTrack.Excalibur != null) { GameState = State.UsingExcalibur; } else { QuestFinished(); } } }
public void SubmitQuest(Player player, bool success) { CurrentTeam.SubmitQuest(player, success); }
void NextQuest(Player leader) { if (RoundTables.Count == 0) return; var roundTable = RoundTables[Quests.Count]; var quest = new Quest(CurrentHolderOfLadyOfTheLake, roundTable.TeamSize, roundTable.RequiredFails); var team = new VoteTrack(leader, roundTable.TeamSize, roundTable.RequiredFails); quest.VoteTracks.Add(team); Quests.Add(quest); GameState = State.ChoosingTeam; }
public static ComputerPlayer Factory(Player.Type type, Guid playerGuid) { switch (type) { case Player.Type.TrustBot: default: return new TrustBot(playerGuid); } }
private double ProbabilityOfEvil(Player player) { var knowledge = _game.PlayerKnowledge(_player, player); if (knowledge == Knowledge.Evil || (knowledge == Knowledge.EvilLancelot && !_game.CurrentLancelotAllegianceSwitched) || (knowledge == Knowledge.Lancelot && _game.CurrentLancelotAllegianceSwitched)) { return 100; } if (knowledge == Knowledge.Good || (knowledge == Knowledge.EvilLancelot && _game.CurrentLancelotAllegianceSwitched) || (knowledge == Knowledge.Lancelot && !_game.CurrentLancelotAllegianceSwitched)) { return 0; } double evilProbability = 0; var evilCharactersInGame = _game.CharacterCards.Count(c => _game.IsCharacterEvil(c, false)); if (_IAmEvil) { evilCharactersInGame--; } evilProbability = (double)evilCharactersInGame / (double)(_game.Players.Count - 1); int correctVotes = 0, votesCounted = 0; //nothing confirmed, look at quest behaviour foreach (var round in _game.Quests) { var onTeam = round.VoteTracks.Last().Players.Contains(player); if (onTeam) { var fails = round.VoteTracks.Last().QuestCards.Count(q => !q.Success); var size = round.VoteTracks.Last().Players.Count(); if (round.VoteTracks.Last().Players.Contains(_player)) { if (_IAmEvil) { fails = fails - 1; } size = size - 1; } int roundEvilProbability = (int)(((double)fails / (double)size) * 100.0); if (roundEvilProbability > evilProbability) { evilProbability = roundEvilProbability; } } if(round.VoteTracks.Count() < 5) { //ignore last round as everyone votes accept if (round.CurrentVoteTrack.Votes.Count == _game.Players.Count) { var vote = round.VoteTracks.Last().Votes.FirstOrDefault(v => v.Player == player); if (vote.Approve == round.IsSuccess.Value) correctVotes++; votesCounted++; } } } //if they vote correctly each round they're probably merlin. //todo handle off by a couple //also check known evils instead of just outcome if (correctVotes == votesCounted && votesCounted > 1) { evilProbability = 0; } return evilProbability; }
void AddToTeam(Player proposedPlayer) { CurrentVoteTrack.Players.Add(proposedPlayer); if (CurrentVoteTrack.Players.Count == CurrentVoteTrack.QuestSize) { if (Rules != null && Rules.Contains(Rule.ExcaliburExists)) { GameState = State.AssigningExcalibur; } else { GameState = State.VotingForTeam; } } }
void VoteForTeam(Player player, bool approve) { CurrentVoteTrack.Votes.Add(new VoteToken { Approve = approve, Player = player }); if (CurrentVoteTrack.Votes.Count < Players.Count) return; //on the last vote, if it fails, create the next quest var rejects = CurrentVoteTrack.Votes.Count(v => !v.Approve); if (rejects >= Math.Ceiling(Players.Count / 2.0)) { if (CurrentQuest.VoteTracks.Count == 5) { GameState = State.EternalChaos; Winners = Players.Where(p => IsCharacterEvil(p.Character, CurrentLancelotAllegianceSwitched)).ToList(); } else { CurrentQuest.VoteTracks.Add(new VoteTrack(Players.Next(CurrentVoteTrack.Leader), CurrentQuest.QuestSize, CurrentQuest.RequiredFails)); GameState = State.ChoosingTeam; } } else { GameState = State.Questing; } }
public Knowledge PlayerKnowledge(Player myself, Player someoneelse) { if (myself == null) return Knowledge.Player; //lancelots can know each other if (Rules.Contains(Rule.LancelotsKnowEachOther)) { if ((myself.Character == Character.Lancelot || myself.Character == Character.EvilLancelot) && (someoneelse.Character == Character.Lancelot)) { return Knowledge.Lancelot; } if ((myself.Character == Character.Lancelot || myself.Character == Character.EvilLancelot) && (someoneelse.Character == Character.EvilLancelot)) { return Knowledge.EvilLancelot; } } //minions know each other (except oberon) if (myself.Character == Character.Assassin || myself.Character == Character.Morgana || myself.Character == Character.MinionOfMordred || myself.Character == Character.Mordred) { if (someoneelse.Character == Character.Assassin || someoneelse.Character == Character.Morgana || someoneelse.Character == Character.MinionOfMordred || someoneelse.Character == Character.Mordred || someoneelse.Character == Character.EvilLancelot) { return Knowledge.Evil; } } //merlin knows minions (except mordred) if (myself.Character == Character.Merlin) { if (someoneelse.Character == Character.Assassin || someoneelse.Character == Character.Morgana || someoneelse.Character == Character.MinionOfMordred || someoneelse.Character == Character.Oberon || someoneelse.Character == Character.EvilLancelot) { return Knowledge.Evil; } } //percy knows merlin and morgana if (myself.Character == Character.Percival) { if (someoneelse.Character == Character.Merlin || someoneelse.Character == Character.Morgana) { return Knowledge.Magical; } } return Knowledge.Player; }
public List<AvailableAction> AvailableActions(Player player) { var actions = new List<AvailableAction>(); switch (GameState) { case State.Lobby: if (player == null && Players.Count < 10) { actions.Add(AvailableAction.FreeText(Action.Type.Join)); } else { if (player == Players.First()) { actions.Add(AvailableAction.FreeText(Action.Type.SetGameName)); actions.Add(AvailableAction.FreeText(Action.Type.AddBot)); actions.Add(AvailableAction.Items(Action.Type.AddCharacterCard, Enum.GetNames(typeof(Character)).ToList())); if (CharacterCards.Count > 0) { actions.Add(AvailableAction.Items(Action.Type.RemoveCharacterCard, CharacterCards.Select(t => t.ToString()).ToList())); } var otherRules = Enum.GetValues(typeof(Rule)).Cast<Rule>().ToList().Except(Rules).Select(r=>r.ToString()).ToList(); if (otherRules.Count>0) { actions.Add(AvailableAction.Items(Action.Type.AddRule, otherRules)); } if (Rules.Count > 0) { actions.Add(AvailableAction.Items(Action.Type.RemoveRule, Rules.Select(r=>r.ToString()).ToList())); } if (IsValid()) { actions.Add(AvailableAction.FreeText(Action.Type.Start)); } } } return actions; case State.ChoosingTeam: if (CurrentVoteTrack != null && player == CurrentVoteTrack.Leader) { actions.Add(AvailableAction.Items(Action.Type.AddToTeam, Players.Except(CurrentVoteTrack.Players).Select(p=>p.Name).ToList())); } if (CurrentVoteTrack != null && player == CurrentVoteTrack.Leader && CurrentVoteTrack.Players.Any()) { actions.Add(AvailableAction.Items(Action.Type.RemoveFromTeam, CurrentVoteTrack.Players.Select(p => p.Name).ToList())); } break; case State.AssigningExcalibur: if (player == CurrentVoteTrack.Leader) { actions.Add(AvailableAction.Items(Action.Type.AssignExcalibur, CurrentVoteTrack.Players.Where(p=>p!=CurrentVoteTrack.Leader).Select(p => p.Name).ToList())); } break; case State.VotingForTeam: if (player!=null && !CurrentVoteTrack.Votes.Any(v => v.Player == player)) { actions.Add(AvailableAction.Action(Action.Type.VoteApprove)); actions.Add(AvailableAction.Action(Action.Type.VoteReject)); } break; case State.Questing: if (CurrentVoteTrack.Players.Contains(player) && !CurrentVoteTrack.QuestCards.Any(q => q.Player == player)) { //good must always vote success if (Rules.Contains(Rule.GoodMustAlwaysSucceedQuests) && !IsCharacterEvil(player.Character, CurrentLancelotAllegianceSwitched)) { actions.Add(AvailableAction.Action(Action.Type.SucceedQuest)); } else { //lancelot fanatasism if (Rules.Contains(Rule.LancelotsMustVoteFanatically) && (player.Character == Character.Lancelot || player.Character == Character.EvilLancelot)) { if (IsCharacterEvil(player.Character, CurrentLancelotAllegianceSwitched)) { actions.Add(AvailableAction.Action(Action.Type.FailQuest)); } else { actions.Add(AvailableAction.Action(Action.Type.SucceedQuest)); } } else { actions.Add(AvailableAction.Action(Action.Type.SucceedQuest)); actions.Add(AvailableAction.Action(Action.Type.FailQuest)); } } } break; case State.UsingExcalibur: if (CurrentVoteTrack.Excalibur.Holder == player) { actions.Add(AvailableAction.Items(Action.Type.UseExcalibur, CurrentVoteTrack.Players.Where(p => p != player).Select(p => p.Name).ToList())); actions.Last().ActionItems.Insert(0, ""); } break; case State.LadyOfTheLake: if (Rules.Contains(Rule.LadyOfTheLakeExists) && CurrentQuest.LadyOfTheLake != null && CurrentQuest.LadyOfTheLake.Holder == player && CurrentQuest.LadyOfTheLake.Target == null) { var list = Players.Except(Players.Where(p => Quests.Any(r => r.LadyOfTheLake != null && r.LadyOfTheLake.Holder == p))).Select(p => p.Name).ToList(); actions.Add(AvailableAction.Items(Action.Type.UseTheLadyOfTheLake, list)); } break; case Game.State.GuessingMerlin: if (player != null && player.Character == Character.Assassin) { actions.Add(AvailableAction.Items(Action.Type.GuessMerlin, Players.Where(p => p != player).Select(p => p.Name).ToList())); } break; } if (player != null) { actions.Add(AvailableAction.FreeText(Action.Type.Message)); } return actions; }
private bool IKnowTheyAreEvil(Player player, Game game) { var knowledge = game.PlayerKnowledge(_player, player); if (knowledge == Knowledge.Evil || (knowledge == Knowledge.EvilLancelot && !game.CurrentLancelotAllegianceSwitched) || (knowledge == Knowledge.Lancelot && game.CurrentLancelotAllegianceSwitched)) { return true; } return false; }
public void AddToTeam(Player player, Player proposedPlayer) { CurrentTeam.AddToTeam(player, proposedPlayer); }
public void VoteForTeam(Player player, bool approve) { CurrentTeam.VoteForTeam(player, approve); //on the last vote, if it fails, create the next quest if (CurrentTeam.Votes.Count == TotalPlayers) { var rejects = CurrentTeam.Votes.Where(v => !v.Approve).Count(); if (rejects >= Math.Ceiling(TotalPlayers / 2.0)) { _currentPlayer = NextPlayer; Teams.Add(new Team(_players[_currentPlayer])); } } }
public List<Action> DoSomething(Game game) { var actions = new List<Action>(); _game = game; _player = _game.Players.First(p => p.Guid == PlayerGuid); _IAmEvil = _game.IsCharacterEvil(_player.Character, false); var availableActions = _game.AvailableActions(_player); if (availableActions.Count == 0) return null; if (availableActions.Any(a=>a.ActionType==ResistanceOnline.Core.Action.Type.VoteApprove)) { actions.Add(new Action(PlayerGuid, TeamVote() ? Action.Type.VoteApprove : Action.Type.VoteReject)); } if (availableActions.Any(a => a.ActionType == ResistanceOnline.Core.Action.Type.AssignExcalibur)) { actions.Add( new Action(PlayerGuid, Action.Type.AssignExcalibur, AssignExcalibur().Name)); } if (availableActions.Any(a => a.ActionType == ResistanceOnline.Core.Action.Type.UseExcalibur)) { var target = UseExcalibur(); var name = target==null? string.Empty : target.Name; actions.Add( new Action(PlayerGuid, Action.Type.UseExcalibur, name)); } if (availableActions.Any(a => a.ActionType == ResistanceOnline.Core.Action.Type.FailQuest) || availableActions.Any(a => a.ActionType == ResistanceOnline.Core.Action.Type.SucceedQuest)) { actions.Add( new Action(PlayerGuid, Quest() ? Action.Type.SucceedQuest : Action.Type.FailQuest)); } if (availableActions.Any(a => a.ActionType == ResistanceOnline.Core.Action.Type.AddToTeam)) { actions.Add( new Action(PlayerGuid, Action.Type.AddToTeam, ChooseTeamPlayer().Name)); } if (availableActions.Any(a => a.ActionType == ResistanceOnline.Core.Action.Type.GuessMerlin)) { actions.Add( new Action(PlayerGuid, Action.Type.GuessMerlin, GuessMerlin().Name)); } if (availableActions.Any(a => a.ActionType == ResistanceOnline.Core.Action.Type.UseTheLadyOfTheLake)) { actions.Add( new Action(PlayerGuid, Action.Type.UseTheLadyOfTheLake, LadyOfTheLakeTarget().Name)); } if (availableActions.Any(a => a.ActionType == ResistanceOnline.Core.Action.Type.Message) && _thingsIWantToSay.Count > 0) { actions.AddRange(_thingsIWantToSay.Select(s => new Action(PlayerGuid, Action.Type.Message, s)).ToList()); } return actions; }
void GuessMerlin(Player guess) { AssassinsGuessAtMerlin = guess; if (guess.Character == Character.Merlin) { GameState = State.EvilTriumphs; Winners = Players.Where(p => IsCharacterEvil(p.Character, CurrentLancelotAllegianceSwitched)).ToList(); } else { Winners = Players.Where(p => !IsCharacterEvil(p.Character, CurrentLancelotAllegianceSwitched)).ToList(); GameState = State.GoodPrevails; } }
private bool IsProbablyEvil(Player player) { var trust = ProbabilityOfEvil(player); return (new Random().Next(100) < trust); }
void JoinGame(string playerName, Guid playerGuid, Player.Type playerType = Player.Type.Human) { if (Players.Select(p => p.Guid).Contains(playerGuid)) throw new InvalidOperationException("It's really not fair if you play as more than one player and you want the game to be fair don't you?"); if (String.IsNullOrWhiteSpace(playerName)) playerName = String.Empty; playerName = playerName.Uniquify(Players.Select(p => p.Name)); Players.Add(new Player() { Name = playerName, Guid = playerGuid, PlayerType = playerType }); RoundTables = StandardQuestSizes(Players.Count); }
void AssignExcalibur(Player proposedPlayer) { CurrentVoteTrack.Excalibur = new ExcaliburUse { Holder = proposedPlayer }; GameState = State.VotingForTeam; }
void Message(Player player, string message) { CurrentQuest.CurrentVoteTrack.Messages.Add(new PlayerMessage { Player = player, Message = message }); }