mIRC Home    About    Download    Register    News    Help

Print Thread
#225096 25/08/10 06:21 PM
Joined: Dec 2004
Posts: 33
W
Ameglian cow
OP Offline
Ameglian cow
W
Joined: Dec 2004
Posts: 33
I know what I want it to do, just not sure how to go about doing it.

Channel #Vote is invite only that accepts outside messages.
I want people to be able to /msg #Vote (A,B,C,D)
I then want to be able to !stats to see the outcome of the current votes

Past 2 hours:
A: ##, B: ##, C: ##, D: ##

Total:
A: ##, B: ##, C: ##, D: ##

Each person is allowed 1 vote but can change the vote, and the change in vote should have the time stamp to be included in the past 2 hours of votes if applicable.

I would assume Id need to create a list of users with their vote and a time stamp, then check the last 2 hours, add up the votes and display that, then add up all votes and display that.

I would also like to have a !reset that either wipes all votes or old votes based on how many hours old the vote is.

Also, there may come a time where there are additional options to vote on besides just 4, should be an easy copy/paste adding the additional choice.

WildCard #225098 25/08/10 06:45 PM
Joined: Aug 2010
Posts: 134
T
Vogon poet
Offline
Vogon poet
T
Joined: Aug 2010
Posts: 134
First, why an invite only channel, and not a PM? You might have your reasons, though.

Secondly, you say that each person is allowed 1 vote. How do you recognize a person? Nickname? Hostmask? You got to make up your mind about that.

Something like this should work from the top of my head. Haven't tested it, though.

Code:
on *:text:*:#vote: {

  ;Reset the votes.
  if $1 == !reset {
    unset -w %votetotal*
    unset -w %voteuser*
    .timervoteuser* off
    .notice $nick Votes resetted.
  }

  ;Show the votes.
  elseif $1 == !stats {
    .notice $nick There are %votetotalA votes for A.
    .notice $nick There are %votetotalB votes for B.
    .notice $nick There are %votetotalC votes for C.
    .notice $nick There are %votetotalD votes for D.
  }

  ;Check if the vote is legit.
  elseif $1 != A && $1 != B && $1 != C && $1 != D {
    .notice $nick You can only vote A, B, C or D.
  }

  ;Check if the vote changed (optional, but nice).
  elseif %voteuser [ $+ [ $site ] ] == $1 {
    .notice $nick You're already voting for $+($1, .)
    .timervoteuser $+ $site 1 7200 votetimeout $site
  }

  else {

    ;Reduce the old vote total.
    if %voteuser [ $+ [ $site ] ] {
      dec %votetotal [ $+ [ %voteuser [ $+ [ $site) ] ] ] ] 1
    }

    ;Apply the new vote.
    inc %votetotal [ $+ [ $1 ] ] 1
    set %voteuser [ $+ [ $site ] ] $1
    .notice $nick You have voted for $+($1, .)
    .timervoteuser $+ $site 1 7200 votetimeout $site
  }
}

;Remove a vote.
alias -l votetimeout {
  if %voteuser [ $+ [ $1 ] ] {
    dec %votetotal [ $+ [ %voteuser [ $+ [ $1) ] ] ] ] 1
    unset %voteuser [ $+ [ $1 ] ]
  }
}


EDIT: Fixed an array bug.

Note that by giving a specific name to the timer, each time the user votes, the old vote timer is overwritten, which means the vote resets 2 hours after the user's last vote, not 2 hours after the first vote.

Last edited by Thels; 25/08/10 06:49 PM.

Learning something new every day.
Thels #225100 25/08/10 06:59 PM
Joined: Oct 2004
Posts: 8,330
Hoopy frood
Offline
Hoopy frood
Joined: Oct 2004
Posts: 8,330
I'd really strongly recommend not to use variables for each person's vote... at least, not unless you're expecting only a dozen or so voters. And even then, I'd avoid it.

Hash tables would be the best option for something like this. Here's just a really quick example. It can definitely be improved. This only shows how to store the votes. I'll leave it to the OP or someone else to set up the score display. It'll be a matter of sorting through the table and then displaying the ones you want. Or, you can track the votes as they are taken and not worry about checking the table afterwards. That would require checking if the nick has voted already before overwriting it in the /hadd line below and then storing each of the votes in the table (or as variables since you won't have too many anyhow).

Code:
on *:text:*:#vote:{ 
  if ($1 == !reset) { ResetVote | halt }
  CreateVote
  if ($1 == !vote) {
    hadd Vote $nick $ctime $2
    hsave Vote Vote.hsh
  }
}
alias ResetVote {
  hfree Vote
  if ($exists(Vote.hsh)) { .remove Vote.hsh }
  CreateVote
}
alias CreateVote {
  if (!$hget(Vote)) {
    hmake Vote 100
    if ($exists(Vote.hsh)) { hload Vote Vote.hsh }
  }
}


Note that the table will have data stored as $ctime and then the vote. $ctime is your timestamp.


Invision Support
#Invision on irc.irchighway.net
Riamus2 #225101 25/08/10 07:14 PM
Joined: Dec 2004
Posts: 33
W
Ameglian cow
OP Offline
Ameglian cow
W
Joined: Dec 2004
Posts: 33
yeah, I'm expecting 100+ votes, and I would count them by username, seeing as people wouldn't just keep changing their nick for this, and if they did Id see it. thanks for the help, now to get a script to change a vote and output results.

WildCard #225103 25/08/10 08:07 PM
Joined: Oct 2004
Posts: 8,330
Hoopy frood
Offline
Hoopy frood
Joined: Oct 2004
Posts: 8,330
What I showed will change the vote. All you'd need is to put in an output. If you want it based on $address(), change $nick to $address($nick,##) where ## is the mask type you want to use.


Invision Support
#Invision on irc.irchighway.net
WildCard #225115 26/08/10 01:14 AM
Joined: Mar 2009
Posts: 74
K
Babel fish
Offline
Babel fish
K
Joined: Mar 2009
Posts: 74
Removed. Misunderstood what was wanted.

Last edited by KageNoOni; 26/08/10 01:25 AM.
Joined: Aug 2010
Posts: 134
T
Vogon poet
Offline
Vogon poet
T
Joined: Aug 2010
Posts: 134
Using variables or hash entries shouldn't really change the layout of your code. Hash tables are of course a lot cleaner, and I'd use a hash table myself, but I didn't want to over complicate the example.

$nick works fine if you don't expect people to change their nickname.

You should still decide for yourself if you want to track vote totals each time someone votes, or only when someone calls for their statistics.

When someone calls for the statistics will be cleaner, but requires quite a bit of calculation every time someone does !stats, hogging all the calculations made at a single point in time. Calculating the votes as they go results into more code (after all, you also got to track of people changing their vote, or votes expiring), but when someone calls for the statistics, you just have to display them the 4 sum totals, without having to first calculate them.

Also, you're sure using a +i channel is smarter than using a PM?

Last edited by Thels; 26/08/10 09:44 AM.

Learning something new every day.
Thels #225162 26/08/10 08:58 PM
Joined: Dec 2004
Posts: 33
W
Ameglian cow
OP Offline
Ameglian cow
W
Joined: Dec 2004
Posts: 33
I know that other people will want this information besides myself, keeping it in a channel rather then PM is what has been done before, just without a script. If the calculations don't take a lot of computer resources and it's quick then I'd rather just calculate when someone calls for it, mIRC is not a huge program and I don't think it would affect anything.


Link Copied to Clipboard