/// <summary> /// Admin command to end an existing vote. /// </summary> public void CMD_EndVote(string[] cmds, IUserMessage message) { if (!DemocracyBot.IsAdmin(message.Author)) { return; } FDSSection topicSection = VotingCommands.GetVoteTopicSection(cmds, message, out string topicName); if (topicSection == null) { return; } topicName = topicName.ToLowerFast(); Console.WriteLine($"Trying to end vote for {topicName} at {StringConversionHelper.DateTimeToString(DateTimeOffset.UtcNow, true)}"); FDSSection choicesSection = topicSection.GetSection("Choices"); Bot.ConfigFile.Set("old_topics." + StringConversionHelper.DateTimeToString(DateTimeOffset.UtcNow, true).Replace(".", "_") + "_topic_" + topicName.Replace(".", "_"), topicSection); string realKey = DemocracyBot.VoteTopicsSection.Data.Keys.First(s => s.ToLowerFast() == topicName); DemocracyBot.VoteTopicsSection.Remove(realKey); RefreshTopicData(topicName, topicSection, true); FDSSection userResultsSection = topicSection.GetSection("user_results"); tallyVotes(topicSection, choicesSection, userResultsSection, message, topicName, true); }
public void CMD_VoteStatus(string[] cmds, IUserMessage message) { if (!DemocracyBot.IsAdmin(message.Author)) { return; } FDSSection topicSection = VotingCommands.GetVoteTopicSection(cmds, message, out string topicName); if (topicSection == null) { return; } topicName = topicName.ToLowerFast(); Console.WriteLine($"Trying get vote status for {topicName} at {StringConversionHelper.DateTimeToString(DateTimeOffset.UtcNow, true)}"); FDSSection choicesSection = topicSection.GetSection("Choices"); string realKey = DemocracyBot.VoteTopicsSection.Data.Keys.First(s => s.ToLowerFast() == topicName); RefreshTopicData(topicName, topicSection, false); FDSSection userResultsSection = topicSection.GetSection("user_results"); tallyVotes(topicSection, choicesSection, userResultsSection, message, topicName, false); }
/// <summary> /// Admin command to end an existing vote. /// </summary> public void CMD_EndVote(string[] cmds, IUserMessage message) { if (!DemocracyBot.IsAdmin(message.Author)) { return; } FDSSection topicSection = VotingCommands.GetVoteTopicSection(cmds, message, out string topicName); if (topicSection == null) { return; } topicName = topicName.ToLowerFast(); Console.WriteLine($"Trying to end vote for {topicName} at {StringConversionHelper.DateTimeToString(DateTimeOffset.UtcNow, true)}"); FDSSection choicesSection = topicSection.GetSection("Choices"); Bot.ConfigFile.Set("old_topics." + StringConversionHelper.DateTimeToString(DateTimeOffset.UtcNow, true).Replace(".", "_") + "_topic_" + topicName.Replace(".", "_"), topicSection); string realKey = DemocracyBot.VoteTopicsSection.Data.Keys.First(s => s.ToLowerFast() == topicName); DemocracyBot.VoteTopicsSection.Remove(realKey); RefreshTopicData(topicName, topicSection, true); FDSSection userResultsSection = topicSection.GetSection("user_results"); if (userResultsSection == null || userResultsSection.GetRootKeys().IsEmpty()) { SendGenericNegativeMessageReply(message, $"Vote For Topic {topicName} Failed", "No votes were cast."); DemocracyBot.Save(); return; } List <List <string> > voteSets = new List <List <string> >(50); foreach (string userId in userResultsSection.GetRootKeys()) { List <string> choices = userResultsSection.GetStringList(userId); if (choices != null && !choices.IsEmpty() && !(choices.Count == 1 && choices[0] == "none")) { voteSets.Add(choices); } } if (voteSets.IsEmpty()) { SendGenericNegativeMessageReply(message, $"Vote For Topic {topicName} Failed", "No votes were cast."); DemocracyBot.Save(); return; } int usersWhoVotedTotal = voteSets.Count; Dictionary <string, int> votesTracker = new Dictionary <string, int>(128); string winner = voteSets[0][0]; string secondPlace = voteSets[0][0]; int discards = 0; bool haveWinner = false; string winnerStats = "(error: stats missing)"; string secondPlaceStats = "(error: second place missing)"; string gatherStats(string choice, string type) { int numberHadFirst = 0; int positionTotal = 0; int numberHadAtAll = 0; foreach (string userId in userResultsSection.GetRootKeys()) { List <string> choices = userResultsSection.GetStringList(userId); if (choices != null && !choices.IsEmpty()) { int index = choices.IndexOf(choice); if (index != -1) { numberHadAtAll++; positionTotal += index + 1; if (index == 0) { numberHadFirst++; } } } } return($"Options that were discarded due to low support: {discards}\n" + $"Users whose votes were discarded due to supporting only unpopular options: {usersWhoVotedTotal - voteSets.Count}\nUsers who listed the {type} first: {numberHadFirst}\n" + $"Users who listed the {type} at all: {numberHadAtAll}\nAverage ranking of the {type}: {positionTotal / (float)numberHadAtAll:0.0}"); } while (true) { votesTracker.Clear(); foreach (List <string> voteSet in voteSets) { string vote = voteSet[0]; if (!votesTracker.TryGetValue(vote, out int count)) { count = 0; } votesTracker[vote] = count + 1; } if (votesTracker.Count == 0) { Console.WriteLine("Something went funky in vote counting... tracker is empty without a clear winner!"); break; } string best = voteSets[0][0], worst = voteSets[0][0]; int bestCount = 0, worstCount = int.MaxValue; foreach (KeyValuePair <string, int> voteResult in votesTracker) { if (voteResult.Value > bestCount) { best = voteResult.Key; bestCount = voteResult.Value; } if (voteResult.Value < worstCount) { worst = voteResult.Key; worstCount = voteResult.Value; } } if (bestCount * 2 > voteSets.Count) { if (!haveWinner) { winner = best; winnerStats = gatherStats(winner, "winner"); haveWinner = true; for (int i = 0; i < voteSets.Count; i++) { if (voteSets[i].Contains(winner)) { voteSets[i].Remove(winner); if (voteSets[i].IsEmpty()) { voteSets.RemoveAt(i--); } } } worst = winner; } else { secondPlace = best; secondPlaceStats = gatherStats(secondPlace, "runner up"); break; } } for (int i = 0; i < voteSets.Count; i++) { if (voteSets[i][0] == worst) { voteSets[i].RemoveAt(0); if (voteSets[i].IsEmpty()) { voteSets.RemoveAt(i--); } } } if (!haveWinner) { discards++; } } SendGenericPositiveMessageReply(message, $"Vote Results For **{topicName}: {topicSection.GetString("Topic")}**", $"**__Winner__**: **{winner}**: `{choicesSection.GetString(winner)}`" + $"\n\n**Stats:**\nUsers who voted, in total: {usersWhoVotedTotal}\n{winnerStats}\n\n" + $"**__Runner Up__**: **{secondPlace}**: `{choicesSection.GetString(secondPlace)}`\n**Stats For Runner Up**:\n{secondPlaceStats}"); DemocracyBot.Save(); }