mIRC Home    About    Download    Register    News    Help

Print Thread
#262862 14/04/18 03:41 PM
Joined: Apr 2018
Posts: 11
T
Pikka bird
OP Offline
Pikka bird
T
Joined: Apr 2018
Posts: 11
Hi, Im trying to create a voting system that opens voting for 60 seconds, closes voting, and then posts the result to that vote. I thought I could do this with variables. EG (On Text !vote, SET %varVOTE On, after 60 seconds, SET %varVOTE off, post result to %chan).

Here is what I have so far:

on 1:TEXT:!VoteDS:#: {
if ($nick isop #) {
if ((%floodVOTING) || ($($+(%,floodVOTING.,$NICK),2))) { RETURN }
SET -u60 %floodVOTING On
/hmake Voting 6
/hadd -s Voting VoteA 0
/hadd -s Voting VoteB 0
/hadd -s Voting VoteC 0
/hadd -s Voting VoteD 0
msg $chan Vote has been activated!
}
}

on 1:TEXT:!VoteA:#: {
if ((%floodVote) || ($($+(%,floodVote.,$NICK),2))) { RETURN }
/hinc -s Voting VoteA 1
set -u60 %floodVote. $+ $nick On
msg $chan $+($nick) Voted A
}

on 1:TEXT:!VoteB:#: {
if ((%floodVote) || ($($+(%,floodVote.,$NICK),2))) { RETURN }
/hinc -s Voting VoteB 1
set -u60 %floodVote. $+ $nick On
msg $chan $+($nick) Voted B
}

on 1:TEXT:!VoteC:#: {
if ((%floodVote) || ($($+(%,floodVote.,$NICK),2))) { RETURN }
/hinc -s Voting VoteC 1
set -u60 %floodVote. $+ $nick On
msg $chan $+($nick) Voted C
}

on 1:TEXT:!VoteD:#: {
if ((%floodVote) || ($($+(%,floodVote.,$NICK),2))) { RETURN }
/hinc -s Voting VoteD 1
set -u60 %floodVote. $+ $nick On
msg $chan $+($nick) Voted D
}

Hope you can help smile

Joined: Jan 2004
Posts: 2,127
Hoopy frood
Offline
Hoopy frood
Joined: Jan 2004
Posts: 2,127
you didn't say what help you're wanting. If the script has a problem, you should tell us what the problem is. If the problem is that it doesn't do anything when you type !voteDS, that's because :TEXT: only reacts to messages by not-you. It also helps your code be more readable if you use the hashtag icon to add the code symbols. It preserves the indenting, and for those who are used to seeing code in a fixed-width font, that also makes it easier to read.

Joined: Apr 2018
Posts: 11
T
Pikka bird
OP Offline
Pikka bird
T
Joined: Apr 2018
Posts: 11
"Im trying to create a voting system that opens voting for 60 seconds, closes voting, and then posts the result to that vote."

This is what Im trying to do, I just dont know how to do it. And I apologise about the format, first time posting to the forum so dont know the ins and outs.

What I posted Opens the voting and accepts votes, but isn't on a timer doesn't close and doesn't post results.

Last edited by ThorStreams; 14/04/18 08:20 PM.
Joined: Jan 2004
Posts: 2,127
Hoopy frood
Offline
Hoopy frood
Joined: Jan 2004
Posts: 2,127
The set -u60 does close the voting, because it won't do anything once that variable is unset.
What it doesn't do is display a message saying that the 60 seconds are finished. For that, you can have a "timer 1 60 alias_name" next to the set -u60, and the alias name is where you announce the voting is finished, and then tabulate your results.

Joined: Apr 2018
Posts: 11
T
Pikka bird
OP Offline
Pikka bird
T
Joined: Apr 2018
Posts: 11
Ok, I will try this in the morning and get back to you with the results and any other questions I have, thank you.

Joined: Apr 2018
Posts: 11
T
Pikka bird
OP Offline
Pikka bird
T
Joined: Apr 2018
Posts: 11
So that was a success. Now, how would I get the result of that vote?
EG:
VoteA = 7
VoteB = 14
VoteC = 2
VoteD = 23

Vote D is the winner, how can I tell mIRC to look for the highest number and then "msg $chan VoteD is the winner!"

Joined: Jul 2006
Posts: 4,145
W
Hoopy frood
Offline
Hoopy frood
W
Joined: Jul 2006
Posts: 4,145
Code:
on *:TEXT:!vote &:#: {
  if ($nick isop #) {
    if ($2 == start) {
      if ($timer(voting)) msg $chan Cancelling previous vote..
      .timervoting 1 60 votedone $unsafe($chan)
      unset %voteA %voteB %voteC %voteD
      msg $chan Vote has been activated!
      var %opok 1
    }
    elseif ($2 == stop) {
     if ($timer(voting)) msg $chan Cancelling previous vote
     unset %voteA %voteB %voteC %voteD
     var %opok 1
    }
  }
  if (!%opok) && ($timer(voting)) && ($1 isincs ABCD) && (!$istok(%voteA %voteB %voteC %voteD,$nick,32)) {
    set %vote $+ $1 $($+(%,vote,$1),2) $nick
    msg $chan nick Voted $1   
  }
}
alias votedone {
var %chan $1, %w $gettok($sorttok($+(%voteA,.A@,%voteB,.B@,%voteC,.C@,%voteD,.D),64,n),1,64)
tokenize 46 %w
msg %chan winner is $2 with $numtok($1,32) vote, participants for $2: $1
}
Untested but this is how you could go about it, i reduced all the on text event to a single event and changed the trigger to !vote start or !vote stop to start/stop it, then !vote A or !vote D etc, the code relies on the timer to know if !vote A is acceptable (the timer is used to announce winner), using hash table for this is not useful, i used simple variables. I changed the antiflood variable per nick to a single $istok check.


#mircscripting @ irc.swiftirc.net == the best mIRC help channel
Joined: Apr 2018
Posts: 11
T
Pikka bird
OP Offline
Pikka bird
T
Joined: Apr 2018
Posts: 11
Ok, I will test it out and see if it is what I want, thank you for the help.

Joined: Jan 2004
Posts: 2,127
Hoopy frood
Offline
Hoopy frood
Joined: Jan 2004
Posts: 2,127
$hfind(voting,vote*,0,w) would give the total number of vote options, which can be your counter to cycle through all the choices. If you have a lot of choices and want just the winner, you use $hget(voting,$hfind(voting,vote*,%counterdown,w)) to get each choice's total, and grab them if they're the highest so far.

If your total vote choices+votecount will be few enough to fit within mIRC's 4150 line length (which must also include the entire equation checking them), you can let sorttok do most of the work. With $base() you can pad the vote totals to all have 5 digits, then append the vote name to them. This lets you do an alphabetical sort to get them in order, after which you can grab the tokens and display them.

Assuming you're using $hfind() above to loop through your vote choices and at each of the Nth choice you've put the values into %choice_text and %choice_votes. Before looping you've used "var %results" to set that local var to $null.

var %result %result $base(%choice_votes,10,10,5) $+ x $+ %choice_text

that assumes no more than 99999 votes for each option, and creates a text label like 00012:VoteA, and adds it as a space-separated token after any similar item already added to %result, until %result is a long string containing a 'word' for each of the choices. The ':' can be anything, as long as it's not a character that would be the same as the last letter of any of the choice texts.

So after looping the contents of %result would be like 00012:VoteA 00008:VoteB etc

$sorttok(%result,32,ar) does a reverse alphabetic sort, that puts the greater text value at the front of the list, which would be your winner.

If you want to display all results, you can use $numtok(%result,32) to get the total number of options, then $gettok(%result,%count,32) to access each item. Since you padded the votes to 5 digits, you wouldn't want to display them like 00002, you could use remove the extra zeroes several ways.

if you pull the token 00012:VoteA into %xyz, then the label would be $mid(%xyz,7) and the votes would be in $left(%xyz,5). You could use $base again to translate the number to+from base 10 without using the 5 padding length, or you could take advantage of a quirk in how several functions handle text labels that begin with numbers. If you use only 1 parameter, and feed it to $calc() or $abs(), it effectively strips off anything beginning with the first non-text character. These both would do the same thing, with $abs() also stripping any "-" from the front:

//echo -a $calc(00012:voteA) $abs(00012:voteA)

Now that you've parsed the label and vote count into 2 variables, you can display 1-or-all any way you wish.

Joined: Apr 2018
Posts: 11
T
Pikka bird
OP Offline
Pikka bird
T
Joined: Apr 2018
Posts: 11
Ok, so that system starts a vote, takes in votes, and displays a winner.
What I would like is for it to be automated. So I would type !Vote start, it takes in votes for 60 seconds, it closes and displays the winner.
Also, that code doesn't output a message to the channel saying what the user voted for as a confirmation.
If I want mIRC to act upon the winner,
let's say Option A is linked with SendKey F7
Option B is linked with SendKey F8
Option C is linked with SendKey F9
Option D is linked with SendKey F10
The highest amount of votes were on Option C, so the bot sends a msg to the chan and says Option C won, then it would SendKey F9.

Joined: Apr 2018
Posts: 11
T
Pikka bird
OP Offline
Pikka bird
T
Joined: Apr 2018
Posts: 11
I will have to read through this a few times as Im quite new to mIRC and coding in general. But I will try and implement what you have said here and get back to you.

Joined: Jul 2006
Posts: 4,145
W
Hoopy frood
Offline
Hoopy frood
W
Joined: Jul 2006
Posts: 4,145
Quote:
Also, that code doesn't output a message to the channel saying what the user voted for as a confirmation.
In fact the code is there: "msg $chan nick Voted $1" but it should be '$nick', not 'nick', obviously.

For the rest, after sending the message with the winner, just add:

Code:
sendkey {F $+ $calc($findtok(A B C D,$2,32) + 6) $+ $chr(125)

and add the alias in your code accordingly:
Code:
alias sendkey .comopen a WScript.Shell | .comclose a $com(a,SendKeys,3,bstr,$1-)



#mircscripting @ irc.swiftirc.net == the best mIRC help channel
Joined: Apr 2018
Posts: 11
T
Pikka bird
OP Offline
Pikka bird
T
Joined: Apr 2018
Posts: 11
Originally Posted By: maroon
$hfind(voting,vote*,0,w) would give the total number of vote options, which can be your counter to cycle through all the choices. If you have a lot of choices and want just the winner, you use $hget(voting,$hfind(voting,vote*,%counterdown,w)) to get each choice's total, and grab them if they're the highest so far.

If your total vote choices+votecount will be few enough to fit within mIRC's 4150 line length (which must also include the entire equation checking them), you can let sorttok do most of the work. With $base() you can pad the vote totals to all have 5 digits, then append the vote name to them. This lets you do an alphabetical sort to get them in order, after which you can grab the tokens and display them.

Assuming you're using $hfind() above to loop through your vote choices and at each of the Nth choice you've put the values into %choice_text and %choice_votes. Before looping you've used "var %results" to set that local var to $null.

var %result %result $base(%choice_votes,10,10,5) $+ x $+ %choice_text

that assumes no more than 99999 votes for each option, and creates a text label like 00012:VoteA, and adds it as a space-separated token after any similar item already added to %result, until %result is a long string containing a 'word' for each of the choices. The ':' can be anything, as long as it's not a character that would be the same as the last letter of any of the choice texts.

So after looping the contents of %result would be like 00012:VoteA 00008:VoteB etc

$sorttok(%result,32,ar) does a reverse alphabetic sort, that puts the greater text value at the front of the list, which would be your winner.

If you want to display all results, you can use $numtok(%result,32) to get the total number of options, then $gettok(%result,%count,32) to access each item. Since you padded the votes to 5 digits, you wouldn't want to display them like 00002, you could use remove the extra zeroes several ways.

if you pull the token 00012:VoteA into %xyz, then the label would be $mid(%xyz,7) and the votes would be in $left(%xyz,5). You could use $base again to translate the number to+from base 10 without using the 5 padding length, or you could take advantage of a quirk in how several functions handle text labels that begin with numbers. If you use only 1 parameter, and feed it to $calc() or $abs(), it effectively strips off anything beginning with the first non-text character. These both would do the same thing, with $abs() also stripping any "-" from the front:

//echo -a $calc(00012:voteA) $abs(00012:voteA)

Now that you've parsed the label and vote count into 2 variables, you can display 1-or-all any way you wish.






Unfortunately, Im having a hard time understanding and applying this to my Code. I now have the vote automated so that it opens, accepts votes, closes and allows another vote to be opened. I would like for it to find the winner of the vote between the 4 options based on the numerical value. I found this on an old post but Im having trouble with it's accuracy. when I tell it to display the winner, it just posts an option rather than the one with the highest numerical value.

Originally Posted By: Riamus2

// Sort table in descending order into a temp file (this can also be done in a custom window)
hsave -n table file.tmp
filter -ffcuten 2 32 file.tmp file.tmp

// Get the Nth top value
echo -a $hget(table,$gettok($read(file.tmp,N),1,32)).item

Joined: Jan 2004
Posts: 2,127
Hoopy frood
Offline
Hoopy frood
Joined: Jan 2004
Posts: 2,127
/hadd -sm Voting VoteA 0

This created an "item" in your hash table. You can get the individual items like:

//echo -a $hget(voting,votea)

but if you want to count how many items there are, you can use

//var %i $hfind(voting,vote*,0,w)

Then while %i is greater than zero, $hfind(voting,vote*,%i,w) gives you the name of each vote choice that matches the vote* wildcard. Now that this gives the name of the choice, you can use HGET to get the vote totals.

while (%i > 0) {
echo -a votes for choice $hfind(voting,vote*,%i,w) total is $hget(voting,$hfind(voting,vote*,%i,w) )
dec %i
}

By padding the vote totals with zero then combining with a text label, before putting them into the %results variable, it creates a text label that $sorttok could sort alphabetically. The reverse-sort I showed causes the "greatest" label to be sorted first, which puts the top vote getter at the top.

If you have 00123:VoteA as the top vote getter, you can use $gettok() to grab the first item, and use $left to grab the leftmost 5 digits as the zero-padded vote total, and $mid starting at the 7th position grabs the label instead. And you can display either as you see fit. You can loop through the votes or show them all. You may need to do some additional logic when you decide what to do when there's a tie for first place. Since the previous example had treated these totals as text labels, whichever one is alphabetically last gets reported as being the winner, because sorting in reverse order puts 00012:VoteB before 00012:VoteA.

Joined: Apr 2018
Posts: 11
T
Pikka bird
OP Offline
Pikka bird
T
Joined: Apr 2018
Posts: 11
Ok thank you, I will try this today and get back to you with the results / any questions.

Joined: Apr 2018
Posts: 11
T
Pikka bird
OP Offline
Pikka bird
T
Joined: Apr 2018
Posts: 11
Ive tried inputting this part into my code with no prevail

var %result %result $base(%choice_votes,10,10,5) $+ x $+ %choice_text

My code currently looks like this:

Alias Table {
var %i $hfind(voting,vote*,0,w)
while (%i > 0) {
echo -a $hfind(voting,vote*,%i,w) $hget(voting,$hfind(voting,vote*,%i,w))
dec %i
}
}

This displays a table only with the numerical value and not the 5 digit code like you are wanting me to have. I read and re read through both posts and tried to make sense of it with the little knowledge I have, I apologise if Im not being the best student.

Last edited by ThorStreams; 16/04/18 12:12 PM.
Joined: Jan 2004
Posts: 2,127
Hoopy frood
Offline
Hoopy frood
Joined: Jan 2004
Posts: 2,127
I was showing an echo of the info, not doing the whole thing. I had skipped the part I mentioned in the earlier post. $base(number,from-base,to-base,padding) lets you left-zero-pad the number to a minimum width. This has the from/to being the same number base, only so we can use the padding feature.

Code:
Alias Table {
  var %i $hfind(voting,vote*,0,w)
  var %result
  var %j %i
  while (%i > 0) {
    var %result %result $base($hget(voting,$hfind(voting,vote*,%i,w)),10,10,5) $+ : $+  $hfind(voting,vote*,%i,w)
    echo -a %result
    dec %i
  }
  echo -a %result
  var %result $sorttok(%result,32,ar)
  while (%i < %j) {
    inc %i
    echo -a $gettok(%result,%i,32)
    echo -a $mid($gettok(%result,%i,32),7) $abs($gettok(%result,%i,32))
  }
}



Link Copied to Clipboard