Voting Machine?
|
Padraig Stygian
The thin mick
Join date: 15 Aug 2004
Posts: 111
|
08-25-2004 12:17
Ok, please don't laugh at my pathetic scripting attempts... I'm trying to write a script that will take votes by voice on channel 314, figure out who got the most, and return the name of the variable with the most votes to the owner, when queried. Essentially, to use the box, a voter would "/314 1" to vote for the first candidate, etc. The part I don't have in yet would prevent ballot box stuffing, but I'd like to get it to take votes before I figure that out... This is the very broken, half-finished bit I have so far: //global variables integer Cont1 = 0; integer Cont2 = 0; integer Cont3 = 0; //thanks user for voting thanks(integer num) { key Who = llDetectedKey(num - 1); llDialog(Who,"Thank you for voting, " + llKey2Name(Who) + "!",["Ok"],115); }
default { //listen on channel 314, record votes state_entry() { llSay(0, "Ballot box initiating..."); llListen(314,"","",""); } listen(integer channel, string name, key id, string message) { if( id != llGetOwner() ) { if(message == "1") { Cont1 = Cont1 + 1; //balks on next line: "Function call mismatches type or number of arguments" thanks(); } else if(message == "2") { Cont2 = Cont2 + 1; thanks(); } else if(message == "3") { Cont3 = Cont3 + 1; thanks(); } } if(message == "winner") { list contestants = [Cont1,Cont2,Cont3]; llListSort(contestants,1,-1); string winner = llList2String(contestants,1); llSay(0, "The winner is contestant #" + winner); } else if(message == "reset") { Cont1 = 0; Cont2 = 0; Cont3 = 0; } } touch_start(integer num) { key Who = llDetectedKey(num - 1); llGiveInventory(Who,"Contestant List"); } }
Comments? Help? Anyone? =[EDIT]= Fixed #2 - 5 from Jake. =[EDIT]= Thanks Wednesday! ;> =[EDIT]= Thanks again, Wednesday! =[EDIT]= Answered my own dumb question; added the touch_start give notecard of contestant numbers.
|
Jake Cellardoor
CHM builder
Join date: 27 Mar 2003
Posts: 528
|
08-25-2004 13:03
A few things right off the bat:
--You've declared your listen() event handler inside your state_entry() handler (which isn't supposed to take a parameter). Declare event handlers separately.
--You're declaring a local variable named Cont1 instead of referencing the global variable. Remove the "integer" from the beginning of the "Cont1 = Cont1 + 1;" line.
--You're repeating Cont1 in subsequent blocks, instead of using Cont2 and Cont3.
--You need to add these global variables to the "contestants" list *after* you've tallied them. Adding something to Cont1 won't change the value that was previously entered in "contestants".
-- You're unnecessarily repeating code in your if-else blocks. You can put the common code after the last block.
|
Padraig Stygian
The thin mick
Join date: 15 Aug 2004
Posts: 111
|
08-25-2004 13:19
1. I'm having trouble figuring out how and where to use listen and llListen. 2. Thanks, fixed. 3. D'oh! Typo... Thanks, fixed. 4. Thanks, fixed. 5. Thanks, fixed... I think.
|
Wednesday Grimm
Ex Libris
Join date: 9 Jan 2003
Posts: 934
|
08-25-2004 13:34
From: someone Originally posted by Padraig Stygian 1. I'm having trouble figuring out how and where to use listen and llListen.
LSL is an event based language. Basically "something" happens, the handler you've defined is called, it's supposed to deal with the event and exit. Some events (touch, money, collision, state_entry) will be sent to your script without any extra work, you just need to define handlers for those events. For some events (listen, timer), you need to tell LSL that you're interested in hearing about them and what precisley you'd like to know. So, if you want to know about chat text on some channel. you call llListen, this tells LSL to send your script listen events, then your listen event handler is called whenever text appears on that channel. Simple eh?
_____________________
Sarcasm meter: 0 |-----------------------*-| 10 Rating: Awww Jeeze!
|
Padraig Stygian
The thin mick
Join date: 15 Aug 2004
Posts: 111
|
08-25-2004 14:12
Oh! You mean like this, then: state_entry() { llSay(0, "Ballot box initiating..."); llListen(314,"",id,""); } listen(integer channel, string name, key id, string message) { Stuff it does }
Two errors on compile: 1. Something's wrong with the way the Cont# variables are defined. It puts the cursor at the beginning of the line and balks on an undefined syntax errror. 2. My thanks() function balks on the first character of the line "thanks()"; undefined syntax error.
|
Wednesday Grimm
Ex Libris
Join date: 9 Jan 2003
Posts: 934
|
08-25-2004 14:22
You've pretty much got it.
For the Cont variables, you need to tell LSL what they are (strings, integers, floating point numbers, vectors, rotations) use:
integer Cont1 = 0;
[edit: oh, and in the listen() event, you *don't* need to say "integer Cont1..." just "Cont1..." ]
Try placing the thanks() function between the global variable section and the "default" line.
_____________________
Sarcasm meter: 0 |-----------------------*-| 10 Rating: Awww Jeeze!
|
Padraig Stygian
The thin mick
Join date: 15 Aug 2004
Posts: 111
|
08-25-2004 15:26
::coughs:: Ah, I see... I made the right edit in the wrong place.
It's still breaking on the 'reset' mention of 'contestants'. I think this has something to do with where I defined the list... but I'm not sure how to fix it, since the list has to be defined after the...
Wait... if list contestants is specific to 'winner' then reset is useless anyway, isn't it? Every time I tell it 'winner' it will remake the list, anyway. I need to make reset zero the *variables*... Hah. Answered my own question. Tell me if I'm wrong, though, please.
|
Padraig Stygian
The thin mick
Join date: 15 Aug 2004
Posts: 111
|
08-25-2004 21:40
This is a near-final version... Unfortunately, while it compiles cleanly, it doesn't work. The owner commands are just fine, but it is not counting votes, or thanking the voter, or returning error messages. I'm also still working on getting "winner" to return the name instead of the contents of a variable. If anyone's got any further glaringly obvious errors to point out, I'd be thrilled to hear about them. //global variables integer Cont1 = 0; integer Cont2 = 0; integer Cont3 = 0; //thanks user for voting thanks() { key user = llDetectedKey(1); llSay(0,"Thank you for voting, " + llKey2Name(user) + "!"); }
default { //listen on channel 314, record votes state_entry() { llSay(0, "Ballot box initiating..."); llListen(314,"",NULL_KEY,""); } listen(integer channel, string name, key id, string message) { if( id = llGetOwner() ) { if(message == "winner") { list contestants = [Cont1,Cont2,Cont3]; llListSort(contestants,1,-1); string winner = llList2String(contestants,1); llSay(0, "The winner is contestant #" + winner); } else if(message == "reset") { Cont1 = 0; Cont2 = 0; Cont3 = 0; llSay(0,"All votes erased. System ready for next election."); } } else if(message == "1") { Cont1 = Cont1 + 1; thanks(); } else if(message == "2") { Cont2 = Cont2 + 1; thanks(); } else if(message == "3") { Cont3 = Cont3 + 1; thanks(); } else { llSay(0,"Error: Command not recognised. To vote type /314 followed by the number of the contestant."); } } touch_start(integer num) { key Who = llDetectedKey(num - 1); llGiveInventory(Who,"Contestant List"); } }
=[EDIT]= Edit for typo.
|
Jake Cellardoor
CHM builder
Join date: 27 Mar 2003
Posts: 528
|
08-25-2004 21:52
In the version you've posted, the line "if( id = llGetOwner() )" should be "if( id == llGetOwner() )". Using a single = makes it an assignment statement instead of a comparison. As a result, the first conditional block is always being executed, while the others never are.
|
Padraig Stygian
The thin mick
Join date: 15 Aug 2004
Posts: 111
|
08-26-2004 08:41
Thanks, I had totally overlooked that. Unfortunately, it's still broken. Do I need a 'return' at the end of the 'llGetOwner' nest?
=[EDIT]= D'oh. Patently stupid mistake on my part. It's stopping on llGetOwner for me, so it never tests for a vote.
|
Padraig Stygian
The thin mick
Join date: 15 Aug 2004
Posts: 111
|
08-26-2004 16:55
This code is now entirely composed of dirty work-arounds, I confess... However, for a change, it finally works. If someone else wants to make a less dirty version, go right ahead; I'd just like to see it when you're done. Thanks go to all the contributors to this thread, and to the author of the visitor tracking script, for making it easier for me to understand how to create a voter list. //global variables integer Cont01 = 0; integer Cont02 = 0; integer Cont03 = 0; integer Cont04 = 0; integer Cont05 = 0; integer Cont06 = 0; integer Cont07 = 0; integer Cont08 = 0; integer Cont09 = 0; integer Cont10 = 0; list voters;
integer isNameOnList( string name ) { list single_name_list; single_name_list += name; return (-1 != llListFindList(voters, single_name_list) ); }
default { //listen on channel 314, record votes state_entry() { llSay(0, "Ballot box initiating..."); llListen(314,"",NULL_KEY,""); } listen(integer channel, string name, key id, string message) { if(isNameOnList(name) == FALSE) { if(message == "1") { Cont01 = Cont01 + 1; llSay(0, "Vote accepted, " + llKey2Name(id)); voters += name; } else if(message == "2") { Cont02 = Cont02 + 1; llSay(0, "Vote accepted, " + llKey2Name(id)); voters += name; } else if(message == "3") { Cont03 = Cont03 + 1; llSay(0, "Vote accepted, " + llKey2Name(id)); voters += name; } else if(message == "4") { Cont04 = Cont04 + 1; llSay(0, "Vote accepted, " + llKey2Name(id)); voters += name; } else if(message == "5") { Cont05 = Cont05 + 1; llSay(0, "Vote accepted, " + llKey2Name(id)); voters += name; } else if(message == "6") { Cont06 = Cont06 + 1; llSay(0, "Vote accepted, " + llKey2Name(id)); voters += name; } else if(message == "7") { Cont07 = Cont07 + 1; llSay(0, "Vote accepted, " + llKey2Name(id)); voters += name; } else if(message == "8") { Cont08 = Cont08 + 1; llSay(0, "Vote accepted, " + llKey2Name(id)); voters += name; } else if(message == "9") { Cont09 = Cont09 + 1; llSay(0, "Vote accepted, " + llKey2Name(id)); voters += name; } else if(message == "10") { Cont10 = Cont10 + 1; llSay(0, "Vote accepted, " + llKey2Name(id)); voters += name; } } else if( id == llGetOwner() ) { if(message == "winner") { list contestants = [Cont01,Cont02,Cont03,Cont04,Cont05,Cont06,Cont07,Cont08,Cont09,Cont10]; integer len = llGetListLength(contestants); integer i; for( i = 0; i < len; i++ ) { list p = [i + 1]; string q = llList2String(p,0); llSay( 0,"Contestant " + q + ":" + llList2String(contestants, i) ); } llSay( 0, "Total = " + (string)len ); contestants = llDeleteSubList(contestants,0, llGetListLength(contestants) - 1); } else if(message == "reset") { Cont01 = 0;Cont02 = 0;Cont03 = 0;Cont04 = 0;Cont05 = 0; Cont06 = 0;Cont07 = 0;Cont08 = 0;Cont09 = 0;Cont10 = 0; voters = llDeleteSubList(voters,0, llGetListLength(voters) - 1); llSay(0,"All votes erased. System ready for next election."); } else { llSay(0,"Error: Owner commands are 'winner' and 'reset'."); } } else { llSay(0,"Error: To vote type /314 followed by the number of the contestant. You can only vote once."); } } touch_start(integer num) { key Who = llDetectedKey(num - 1); llGiveInventory(Who,"Contestant List"); } }
The script, itself, is up for grabs to the community. If you want a voting machine preconfigured to your specifications, packed up, and ready to use out of the box, let me know, in game, and we'll talk prices. =[EDIT]= I type too fast for my own good...
|