/// <summary> /// Merges the specified from vote into the specified to vote, assuming the votes aren't the same. /// Moves the voters from the from vote into the to vote list, and removes the from vote's key. /// </summary> /// <param name="fromVote">Vote that is being merged.</param> /// <param name="toVote">Vote that is being merged into.</param> /// <returns>Returns true if there were any changes.</returns> private bool MergeRanks(string fromVote, string toVote) { var votes = GetVotesCollection(VoteType.Rank); Dictionary <KeyValuePair <string, HashSet <string> >, string> mergedVotes = new Dictionary <KeyValuePair <string, HashSet <string> >, string>(); foreach (var vote in votes) { if (VoteString.CondenseVote(vote.Key) == fromVote) { string toContent = VoteString.GetVoteContent(toVote, VoteType.Rank); string toTask = VoteString.GetVoteTask(toVote, VoteType.Rank); string revisedKey = VoteString.ModifyVoteLine(vote.Key, task: toTask, content: toContent); mergedVotes.Add(vote, revisedKey); } } if (mergedVotes.Count > 0) { var voters = GetVotersCollection(VoteType.Rank); UndoBuffer.Push(new UndoAction(UndoActionType.Merge, VoteType.Rank, voters, mergedVotes)); foreach (var merge in mergedVotes) { Rename(merge.Key, merge.Value, VoteType.Rank); } return(true); } return(false); }
/// <summary> /// Add the list of all voters for a given winning option, along with /// the ranking they gave that option. /// </summary> /// <param name="taskName">The name of the task.</param> /// <param name="choice">The name of the choice selected.</param> private void AddRankedVoters(string taskName, string choice) { var votes = VoteCounter.Instance.GetVotesCollection(VoteType.Rank); var voters = VoteCounter.Instance.GetVotersCollection(VoteType.Rank); var whoVoted = from v in votes where Agnostic.StringComparer.Equals(VoteString.GetVoteTask(v.Key), taskName) && Agnostic.StringComparer.Equals(VoteString.GetVoteContent(v.Key), choice) select new { marker = VoteString.GetVoteMarker(v.Key), voters = v.Value }; var whoDidNotVote = from v in voters where whoVoted.Any(a => a.voters.Contains(v.Key)) == false select v.Key; using (new Spoiler(sb, "Voters", DisplayMode == DisplayMode.SpoilerVoters || DisplayMode == DisplayMode.SpoilerAll)) { foreach (var mark in whoVoted.OrderBy(a => a.marker)) { var sortedVoters = mark.voters.OrderBy(a => a); foreach (var voter in sortedVoters) { AddVoter(voter, VoteType.Rank, mark.marker); } } foreach (var nonVoter in whoDidNotVote.OrderBy(a => a)) { AddVoter(nonVoter, VoteType.Rank, "-"); } } sb.AppendLine(); }
public int Compare(object x, object y) { if (x == null) { throw new ArgumentNullException(nameof(x)); } if (y == null) { throw new ArgumentNullException(nameof(y)); } string xs = x as string; if (xs == null) { throw new ArgumentException("Parameter x is not a string."); } string ys = y as string; if (ys == null) { throw new ArgumentException("Parameter y is not a string."); } string marker = VoteString.GetVoteMarker(xs); VoteType voteType = string.IsNullOrEmpty(marker) ? VoteType.Rank : VoteType.Plan; string compX = VoteString.GetVoteTask(xs, voteType) + " " + VoteString.GetVoteContent(xs, voteType); string compY = VoteString.GetVoteTask(ys, voteType) + " " + VoteString.GetVoteContent(ys, voteType); int result = string.Compare(compX, compY, StringComparison.CurrentCultureIgnoreCase); return(result); }
public static IEnumerable <RankGroupedVoters> GroupByVoteAndRank(GroupedVotesByTask task) { var res = task.GroupBy(vote => VoteString.GetVoteContent(vote.Key), Agnostic.StringComparer) .Select(votes => new RankGroupedVoters { VoteContent = votes.Key, Ranks = from v in votes group v by VoteString.GetVoteMarker(v.Key) into vr select new RankedVoters { Rank = int.Parse(vr.Key), Voters = vr.SelectMany(a => a.Value) } }); return(res); }
public void GetCondensedVoteContentTest() { string line1 = "[x] Vote for stuff"; string line2 = "[] Vote for stuff"; string line3 = "[major] Vote for stuff"; string line4 = "[ animal] Vote for stuff"; string line5 = "[MINOR] Vote for stuff"; string line6 = "[Trade Relations] Vote for stuff"; string line7 = "[] [url=http://google.com]<image>[/url]"; Assert.AreEqual("Vote for stuff", VoteString.GetVoteContent(line1, VoteType.Rank)); Assert.AreEqual("Vote for stuff", VoteString.GetVoteContent(line2, VoteType.Rank)); Assert.AreEqual("Vote for stuff", VoteString.GetVoteContent(line3, VoteType.Rank)); Assert.AreEqual("Vote for stuff", VoteString.GetVoteContent(line4, VoteType.Rank)); Assert.AreEqual("Vote for stuff", VoteString.GetVoteContent(line5, VoteType.Rank)); Assert.AreEqual("Vote for stuff", VoteString.GetVoteContent(line6, VoteType.Rank)); Assert.AreEqual("[url=http://google.com]<image>[/url]", VoteString.GetVoteContent(line7, VoteType.Rank)); }
public static IEnumerable <VoterRankings> GroupByVoterAndRank(GroupedVotesByTask task) { var res = from vote in task from voter in vote.Value group vote by voter into voters select new VoterRankings { Voter = voters.Key, RankedVotes = (from v in voters select new RankedVote { Rank = int.Parse(VoteString.GetVoteMarker(v.Key)), Vote = VoteString.GetVoteContent(v.Key) }).ToList() }; return(res); }
/// <summary> /// Add the list of all possible voting options for this rank task. /// </summary> /// <param name="taskName">The name of the task.</param> private void AddRankedOptions(string taskName) { var votes = VoteCounter.Instance.GetVotesCollection(VoteType.Rank); var voteContents = votes. Where(v => Agnostic.StringComparer.Equals(VoteString.GetVoteTask(v.Key), taskName)). Select(v => VoteString.GetVoteContent(v.Key)); HashSet <string> uniqueOptions = new HashSet <string>(voteContents, Agnostic.StringComparer); sb.AppendLine("[b]Options:[/b]"); foreach (var option in uniqueOptions.OrderBy(a => a)) { AddVoteStringLine(option); } sb.AppendLine(); }
public void GetVoteContentTest() { string input = "[X] We 『i』did『/i』 agree to non-lethal. My most 『color=blue』powerful『/color』 stuff either knocks people out or kills them without having to fight at all. Everything else I've learned to do so far feels like a witch barrier, and I try not to use that since it freaks everyone out."; string expected = "We 『i』did『/i』 agree to non-lethal. My most 『color=blue』powerful『/color』 stuff either knocks people out or kills them without having to fight at all. Everything else I've learned to do so far feels like a witch barrier, and I try not to use that since it freaks everyone out."; Assert.AreEqual(expected, VoteString.GetVoteContent(input)); input = "[x] Vote for stuff"; expected = "Vote for stuff"; Assert.AreEqual(expected, VoteString.GetVoteContent(input)); input = "[x][major] Vote for stuff"; expected = "Vote for stuff"; Assert.AreEqual(expected, VoteString.GetVoteContent(input)); input = "-[x][ animal] Vote for stuff"; expected = "Vote for stuff"; Assert.AreEqual(expected, VoteString.GetVoteContent(input)); // Invalid line. Leading BBCode should have already been removed. input = "『color=blue』-[x] Vote for stuff『/color』"; expected = ""; Assert.AreEqual(expected, VoteString.GetVoteContent(input)); }
/// <summary> /// Gets all choices from all user votes. /// </summary> /// <param name="task">The collection of user votes.</param> /// <returns>Returns a list of all the choices in the task.</returns> public static List <string> GetAllChoices(GroupedVotesByTask task) { var res = task.GroupBy(vote => VoteString.GetVoteContent(vote.Key), Agnostic.StringComparer).Select(vg => vg.Key); return(res.ToList()); }
/// <summary> /// Takes the full vote string list of the vote and breaks it /// into base plans, regular vote lines, and ranked vote lines. /// Store in the local object properties. /// </summary> /// <param name="voteStrings">The list of all the lines in the vote post.</param> private void SeparateVoteStrings(List <string> voteStrings) { BasePlans = new List <IGrouping <string, string> >(); List <string> consolidatedLines = new List <string>(); // Group blocks based on parent vote lines (no prefix). // Key for each block is the parent vote line. var voteBlocks = voteStrings.GroupAdjacentToPreviousKey( (s) => string.IsNullOrEmpty(VoteString.GetVotePrefix(s)), (s) => s, (s) => s); bool addBasePlans = true; foreach (var block in voteBlocks) { if (addBasePlans) { if (block.Count() > 1) { string planName = VoteString.GetPlanName(block.Key, basePlan: true); if (planName != null && !VoteCounter.Instance.ReferenceVoters.Contains(planName, Agnostic.StringComparer)) { BasePlans.Add(block); continue; } } } addBasePlans = false; consolidatedLines.AddRange(block.ToList()); } RankLines = new List <string>(); VoteLines = new List <string>(); foreach (var line in consolidatedLines) { if (VoteString.IsRankedVote(line)) { RankLines.Add(line); } else { VoteLines.Add(line); } } // If we have ranked vote options, make sure we don't have duplicate entries, // or the same option voted on different ranks. if (RankLines.Count > 0) { var groupRankLinesMulti = RankLines.GroupBy(line => VoteString.GetVoteContent(line), Agnostic.StringComparer) .Where(group => group.Count() > 1); // If there are any, remove all but the top ranked option. foreach (var lineGroup in groupRankLinesMulti) { var topOption = lineGroup.MinObject(a => VoteString.GetVoteMarker(a)); var otherOptions = lineGroup.Where(a => a != topOption).ToList(); foreach (string otherOption in otherOptions) { RankLines.Remove(otherOption); } } } }