More voting stuff, start moving to typescript
This commit is contained in:
89
poll-master.ts
Normal file
89
poll-master.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
const polls: Map<string, Poll> = new Map<string, Poll>()
|
||||
|
||||
export function registerNewPoll(key, maxVotes, onComplete, onNoResult): void {
|
||||
polls.set(key, new Poll(maxVotes, onComplete, onNoResult))
|
||||
console.log("created poll", key)
|
||||
}
|
||||
|
||||
export function getNewPoll<T>(maxVotes: number, onComplete: (result: T, votes: Map<string, T>) => void, onNoResult: (votes: Map<string, T>) => void) {
|
||||
return new Poll<T>(maxVotes, onComplete, onNoResult)
|
||||
}
|
||||
|
||||
export function voteInPoll(key, voterId, vote): void {
|
||||
if (polls.has(key)) {
|
||||
const poll = polls.get(key)
|
||||
poll.vote(`${voterId}`, vote)
|
||||
const result = poll.isMajorityReached()
|
||||
if (result) {
|
||||
poll.onComplete(result, poll.votes)
|
||||
delete polls[key]
|
||||
console.log("vote finished", key, result)
|
||||
} else if (poll.currentVotes === poll.maxVotes) {
|
||||
poll.onNoResult(poll.votes)
|
||||
delete polls[key]
|
||||
console.log("vote inconclusive", key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isMajorityReached_dep(poll): any {
|
||||
const minimumConsensus = Math.ceil(poll.maxVotes * 0.5)
|
||||
const voteTally = {}
|
||||
for (const vote in poll.votes) {
|
||||
if (vote != null) {
|
||||
if (voteTally.hasOwnProperty(poll.votes[vote])) {
|
||||
voteTally[poll.votes[vote]]++
|
||||
} else {
|
||||
voteTally[poll.votes[vote]] = 1
|
||||
}
|
||||
}
|
||||
if (voteTally[poll.votes[vote]] >= minimumConsensus) {
|
||||
return vote
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
class Poll<T> {
|
||||
public currentVotes = 0;
|
||||
public votes = new Map<string, T>()
|
||||
constructor(public readonly maxVotes: number, public onComplete: (result: any, votes: Map<string, T>) => void, public onNoResult: (votes: Map<string, T>) => void) {
|
||||
|
||||
}
|
||||
|
||||
vote(voterId: string, vote: T): void {
|
||||
this.currentVotes++
|
||||
this.votes.set(voterId, vote)
|
||||
this.checkVotes()
|
||||
}
|
||||
|
||||
skipVote(voterId: string): void {
|
||||
this.currentVotes++
|
||||
this.checkVotes()
|
||||
}
|
||||
|
||||
private checkVotes(): void {
|
||||
const minimumConsensus = Math.ceil(this.maxVotes * 0.5)
|
||||
const voteTally = new Map<T, number>()
|
||||
this.votes.forEach((vote, voter) => {
|
||||
// Allow for null votes, can't have a null key in a map
|
||||
const normalizedVote = vote == null ? new T() : vote
|
||||
if (voteTally.has(normalizedVote)) {
|
||||
voteTally.set(normalizedVote, voteTally.get(normalizedVote) + 1)
|
||||
} else {
|
||||
voteTally.set(normalizedVote, 1)
|
||||
}
|
||||
if (voteTally.get(normalizedVote) >= minimumConsensus) {
|
||||
this.onComplete(vote, this.votes)
|
||||
}
|
||||
})
|
||||
if (this.currentVotes === this.maxVotes) {
|
||||
this.onNoResult(this.votes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
registerNewPoll,
|
||||
voteInPoll
|
||||
}
|
||||
Reference in New Issue
Block a user