コード例 #1
0
ファイル: VoteCounter.cs プロジェクト: MizMahem/NetTally
        /// <summary>
        /// Wrapper for handling replace task, but without adding to merge records.
        /// </summary>
        /// <param name="vote">The vote being modified.</param>
        /// <param name="task">The new task to apply to the vote.</param>
        /// <returns>Returns true if the task replacement was successfully completed.</returns>
        private bool ReplaceTaskImplWrapper(VoteLineBlock vote, string task)
        {
            if (!VoteStorage.TryGetValue(vote, out var supporters))
            {
                return(false);
            }

            // Incoming parameter may be an entry in storage, or a copy of a vote.
            // Adjust so that we're always pointing at an actual vote.
            // If the vote isn't found in VoteStorage, just use the one provided.
            vote = VoteStorage.GetVoteMatching(vote) ?? vote;

            // Remove the version of the vote we're starting with.
            VoteStorage.Remove(vote);

            string originalTask = vote.Task;

            vote.Task = task;

            // If there's a conflict with the newly-tasked vote, we need to merge with the existing vote.
            if (VoteStorage.ContainsKey(vote))
            {
                if (VoteStorage.TryGetValue(vote, out var toSupport))
                {
                    foreach (var(supporterName, supporterVote) in supporters)
                    {
                        if (!toSupport.ContainsKey(supporterName))
                        {
                            supporterVote.Task = task;
                            toSupport.Add(supporterName, supporterVote);
                        }
                    }
                }
                else
                {
                    // Undo the attempt if we couldn't get the conflicting vote data
                    vote.Task = originalTask;

                    VoteStorage.Add(vote, supporters);

                    return(false);
                }
            }
            // If there's no conflict, update the tasks in the supporter votes and add the revised vote.
            else
            {
                foreach (var(_, supporterVote) in supporters)
                {
                    supporterVote.Task = task;
                }

                VoteStorage.Add(vote, supporters);
            }

            return(true);
        }
コード例 #2
0
        CountVotesForTask(VoteStorage taskVotes)
        {
            int[,] pairwisePreferences = GetPairwisePreferences(taskVotes);

            int[,] strongestPaths = GetStrongestPaths(pairwisePreferences, taskVotes.Count);

            int[,] winningPaths = GetWinningPaths(strongestPaths, taskVotes.Count);

            List <((int rank, double rankScore) ranking, VoteStorageEntry vote)> winningChoices =
                GetResultsInOrder(winningPaths, taskVotes);

            return(winningChoices);
        }
コード例 #3
0
ファイル: VoteCounter.cs プロジェクト: MizMahem/NetTally
        /// <summary>
        /// Reset all tracking variables.
        /// </summary>
        public void Reset()
        {
            VoteStorage.Clear();
            ReferenceOrigins.Clear();
            ReferencePlans.Clear();
            FutureReferences.Clear();
            UndoBuffer.Clear();

            VoteDefinedTasks.Clear();
            OrderedVoteTaskList.Clear();
            TaskList.Clear();

            OnPropertyChanged("VoteCounter");
            OnPropertyChanged("Tasks");
        }
コード例 #4
0
ファイル: VoteCounter.cs プロジェクト: MizMahem/NetTally
        private bool SplitImplWrapper(VoteLineBlock fromVote, List <VoteLineBlock> toVotes)
        {
            if (!VoteStorage.TryGetValue(fromVote, out var fromSupport))
            {
                return(false);
            }

            foreach (var toVote in toVotes)
            {
                if (!VoteStorage.TryGetValue(toVote, out var toSupport))
                {
                    return(false);
                }

                MergeImpl(fromVote, toVote, fromSupport, toSupport);
            }

            // But we still want to remove the from vote.
            return(VoteStorage.Remove(fromVote));
        }
コード例 #5
0
ファイル: VoteCounter.cs プロジェクト: MizMahem/NetTally
        /// <summary>
        /// Add a collection of votes to the vote counter.
        /// </summary>
        /// <param name="votePartitions">A string list of all the parts of the vote to be added.</param>
        /// <param name="voter">The voter for this vote.</param>
        /// <param name="postID">The post ID for this vote.</param>
        /// <param name="voteType">The type of vote being added.</param>
        public void AddVotes(IEnumerable <VoteLineBlock> votePartitions, Origin voter)
        {
            if (!votePartitions.Any())
            {
                return;
            }

            // Remove the voter from any existing votes
            VoteStorage.RemoveVoterFromVotes(voter);

            // Add/update all segments of the provided vote
            foreach (var partition in votePartitions)
            {
                VoteStorage.AddSupporterToVote(partition, voter);
                AddPotentialVoteTask(partition.Task);
            }

            // Cleanup any votes that no longer have any support
            VoteStorage.RemoveUnsupportedVotes();
        }
コード例 #6
0
        CountVotesForTask(VoteStorage taskVotes)
        {
            var results = from vote in taskVotes
                          let wilsonScore = RankingCalculations.LowerWilsonRankingScore(vote)
                                            select new { vote, score = wilsonScore };

            var orderedResults = results.OrderByDescending(a => a.score.score)
                                 .ThenByDescending(a => a.score.count);

            int r = 1;

            List <((int rank, double rankScore) ranking, VoteStorageEntry vote)> resultList
                = new List <((int rank, double rankScore) ranking, VoteStorageEntry vote)>();

            foreach (var res in orderedResults)
            {
                resultList.Add(((r++, res.score.score), res.vote));
            }

            return(resultList);
        }
コード例 #7
0
ファイル: VoteCounter.cs プロジェクト: MizMahem/NetTally
        /// <summary>
        /// Delete an entire vote and all associated supporters.
        /// </summary>
        /// <param name="vote">The vote to delete.</param>
        /// <returns>Returns true if successfully completed.</returns>
        public bool Delete(VoteLineBlock vote)
        {
            bool removed = false;

            if (VoteStorage.ContainsKey(vote))
            {
                UndoBuffer.Push(new UndoAction(UndoActionType.Delete, VoteStorage));

                removed = VoteStorage.Remove(vote);
            }

            if (removed)
            {
                OnPropertyChanged("Votes");
                OnPropertyChanged("Voters");
                OnPropertyChanged(nameof(HasUndoActions));
            }
            else
            {
                UndoBuffer.Pop();
            }

            return(removed);
        }
コード例 #8
0
ファイル: VoteCounter.cs プロジェクト: MizMahem/NetTally
        /// <summary>
        /// The wrapper handles the process of extracting the vote support from
        /// the storage before passing the pieces on to the implementation.
        /// </summary>
        /// <param name="fromVote">The vote being merged.</param>
        /// <param name="toVote">The vote being merged into.</param>
        /// <returns>Returns true if there was a successful merge.</returns>
        private bool MergeImplWrapper(VoteLineBlock fromVote, VoteLineBlock toVote)
        {
            if (fromVote == toVote)
            {
                return(false);
            }

            if (!VoteStorage.TryGetValue(fromVote, out var fromSupport))
            {
                return(false);
            }

            if (!VoteStorage.TryGetValue(toVote, out var toSupport))
            {
                return(false);
            }

            // Theoretically, all the supporters in the from vote could already
            // be in the to vote, in which case no merging would happen.
            MergeImpl(fromVote, toVote, fromSupport, toSupport);

            // But we still want to remove the from vote.
            return(VoteStorage.Remove(fromVote));
        }
コード例 #9
0
ファイル: VoteCounter.cs プロジェクト: MizMahem/NetTally
        public bool Join(List <Origin> voters, Origin voterToJoin)
        {
            bool joined = false;

            UndoBuffer.Push(new UndoAction(UndoActionType.Join, VoteStorage));

            foreach (var voter in voters)
            {
                joined = JoinImpl(voter, voterToJoin) || joined;
            }

            if (joined)
            {
                OnPropertyChanged("Votes");
                OnPropertyChanged("Voters");
                OnPropertyChanged(nameof(HasUndoActions));
            }
            else
            {
                UndoBuffer.Pop();
            }

            return(joined);

            /// <summary>
            /// Implement joining logic per voter.
            /// </summary>
            /// <param name="joiningVoter">The voter being moved to a new voting support set.</param>
            /// <param name="voterToJoin">The voter being joined.</param>
            /// <returns>Returns true if the join was completed.</returns>
            bool JoinImpl(Origin joiningVoter, Origin voterToJoin)
            {
                var source = GetVotesBy(joiningVoter);
                var dest   = GetVotesBy(voterToJoin);

                if (!source.Any() || !dest.Any())
                {
                    return(false);
                }

                bool joined = false;

                // Remove support from any votes where the target voter isn't also present.
                foreach (var vote in source)
                {
                    if (!VoteStorage.DoesVoterSupportVote(voterToJoin, vote))
                    {
                        VoteStorage.RemoveSupporterFromVote(vote, joiningVoter);
                    }
                }

                VoteStorage.RemoveUnsupportedVotes();

                foreach (var vote in dest)
                {
                    if (!VoteStorage.DoesVoterSupportVote(joiningVoter, vote))
                    {
                        VoteStorage.AddSupporterToVote(vote, joiningVoter);
                        joined = true;
                    }
                }

                return(joined);
            }
        }
コード例 #10
0
ファイル: VoteCounter.cs プロジェクト: MizMahem/NetTally
 /// <summary>
 /// Gets all voters that are supporting the specified vote.
 /// </summary>
 /// <param name="vote">The vote to check on.</param>
 /// <returns>Returns an IEnumerable of the voter names that are supporting the given vote.</returns>
 public IEnumerable <Origin> GetVotersFor(VoteLineBlock vote) => VoteStorage.GetVotersFor(vote);
コード例 #11
0
ファイル: VoteCounter.cs プロジェクト: MizMahem/NetTally
 /// <summary>
 /// Get a list of all known voters.
 /// </summary>
 /// <returns>Returns an IEnumerable of the registered reference voters.</returns>
 public IEnumerable <Origin> GetAllVoters() => VoteStorage.GetAllVoters();
コード例 #12
0
ファイル: VoteCounter.cs プロジェクト: MizMahem/NetTally
 /// <summary>
 /// Get a collection of all the votes that currently have supporters.
 /// </summary>
 /// <returns>Returns an IEnumerable of the currently stored vote blocks.</returns>
 public IEnumerable <VoteLineBlock> GetAllVotes() => VoteStorage.GetAllVotes();
コード例 #13
0
ファイル: VoteCounter.cs プロジェクト: MizMahem/NetTally
 /// <summary>
 /// Get a list of all vote blocks supported by a specified voter (which may be a plan name).
 /// </summary>
 /// <param name="voterName">The name of the voter or plan being requested.</param>
 /// <returns>Returns a list of all vote blocks supported by the specified voter or plan.</returns>
 public List <VoteLineBlock> GetVotesBy(Origin voter) => VoteStorage.GetVotesBy(voter);