This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
ewart4fun's profile picture

[lua] voting program

Started by ewart4fun, 08 November 2012 - 04:43 AM
ewart4fun #1
Posted 08 November 2012 - 05:43 AM
i'm busy with making a program that allows users on a server to vote, like who must get promoted and stuff
so i have made this really basic version of my program to test things out. but how can you make it so, that it stores the vote for each voting person. in stead of beginning at zero every time you restart computer?

Spoiler
--votes
local a = 0
local b = 0

print("please login")
input = read()
if input == "test" then
term.clear()
term.setCursorPos(1, 1)
print("do you want to vote for: ")
print("a. ")
print("b. ")
vote = read()
if vote == "a" then
a = a + 1
elseif vote == "b" then
b = b + 1
else
print("invalid vote")
end
Kingdaro #2
Posted 08 November 2012 - 06:18 AM
Instead of relying on a rebooting loop, use a while loop.

--votes
local a = 0
local b = 0

print("please login")
input = read()
if input == "test" then
	while true do
		term.clear()
		term.setCursorPos(1, 1)
	
		print("do you want to vote for: ")
		print("a. ")
		print("b. ")
	
		vote = read()
	
		if vote == "a" then
			a = a + 1
		elseif vote == "b" then
			b = b + 1
		else
			print("invalid vote")
			sleep(1) -- added the sleep here, otherwise it wouldn't show
		end
 	end
end
ewart4fun #3
Posted 08 November 2012 - 06:28 AM
i mean that if there is a server restart, of if i want to read the score, and have to end the program that it won't reset
Espen #4
Posted 08 November 2012 - 07:24 AM
i mean that if there is a server restart, of if i want to read the score, and have to end the program that it won't reset
To make values survive a reboot you could save them to a file.
In your case you could store the values to a file whenever a vote has been cast.
You then simply reload the values from the file on every program start.
remiX #5
Posted 08 November 2012 - 07:29 AM
Edit: Oh, its writeLine() haha =) This works. If you need me to make a admin pass so you can check all the votes, feel free to ask.

Spoiler

-- [[ All you need to do is to change these variables ]] --
pass = "password"
users = {"User1", "User2", "User3", "User4"}

osPullevent = os.pullEvent
os.pullEvent = os.pullEventRaw -- prevents ctrl + t

function cls(c, x, y)
    if c == 1 then term.clear() end
    term.setCursorPos(x, y)
end

function logged()
    cls(1, 1, 1)
    print("Logged in...") sleep(1)
    print("Place your vote (type the corresponding numbers): ")
    for i = 1, #users do
        print(i..". "..users[i])    -- prints all the users that u are able to vote for
    end
    vote = tonumber(read())
    if vote > #users or vote <= 0 then print("Invalid vote") sleep(1) return end
    print("Thank you for voting for "..users[vote]..". Let's hope it counts!")
    file = fs.open("VotingList.txt", "a")
    file.writeLine(users[vote])
    file.close()
    sleep(2)
end

while true do
    cls(1, 1, 1)
    write("Please login: ")
    input = read()
    if input == pass then logged() else print("nInvalid password!") sleep(1) end
end

And then you can make an admin password to check how many votes you have for each user, I can do that if it would print on each line separately :/
ewart4fun #6
Posted 08 November 2012 - 10:20 AM
thanks for the codes, i've added some things to it, so people cant vote more then 1 time and ive made more accounts, but it says that its expecting Then at line 41. what did i do wrong ?
-- these lines is so every account only can vote once to stop fraud
user1v = "false"
user2v = "false"
user3v = "false"

-- [[ All you need to do is to change these variables ]] --
pass = "password"
pass2 = "test"
pass3 = "bypass"
users = {"User1", "User2", "User3", "User4"}

osPullevent = os.pullEvent
os.pullEvent = os.pullEventRaw -- prevents ctrl + t

function cls(c, x, y)
    if c == 1 then term.clear() end
    term.setCursorPos(x, y)
end

function logged()
    cls(1, 1, 1)
    print("Logged in...") sleep(1)
    print("Place your vote (type the corresponding numbers): ")
    for i = 1, #users do
        print(i..". "..users[i])    -- prints all the users that u are able to vote for
    end
    vote = tonumber(read())
    if vote > #users or vote <= 0 then print("Invalid vote") sleep(1) return end
    print("Thank you for voting for "..users[vote]..". Let's hope it counts!")
    file = fs.open("VotingList.txt", "a")
    file.writeLine(users[vote])
    file.close()
    sleep(2)
end

while true do
    cls(1, 1, 1)
    write("Please enter username and password: ")
    user = read()
    pass = read("*")
    if user == "user1" and pass == "user1" and user1v = "false" then logged() and user1v = "true" else print("nInvalid password!") sleep(1) end
    if user == "user2" and pass == "user2" and user2v = "false" then logged() and user2v = "true" else print("nInvalid password!") sleep(1) end
    if user == "user3" and pass == "user3" and user3v = "false" then logged() and user3v = "true" else print("nInvalid password!") sleep(1) end
Espen #7
Posted 08 November 2012 - 10:53 AM
You don't use and to separate commands. Either use semicolon or better yet, just write one command after the other.
To fix your specific problem: Remove the and after logged() in all three lines at the end.
remiX #8
Posted 08 November 2012 - 11:55 AM
Yeah and insert another end at the end, you don't have an end for your while true do loop :P/>/>
ewart4fun #9
Posted 08 November 2012 - 07:40 PM
it works, but how can i let the part that every person let vote only once, survive a reboot and stuff?
Spoiler
-- these lines is so every account only can vote once to stop fraud
user1v = 0
user2v = 0
user3v = 0

-- [[ All you need to do is to change these variables ]] --
pass = "password"
pass2 = "test"
pass3 = "bypass"
users = {"User1", "User2", "User3", "User4"}

osPullevent = os.pullEvent
os.pullEvent = os.pullEventRaw -- prevents ctrl + t

function cls(c, x, y)
    if c == 1 then term.clear() end
    term.setCursorPos(x, y)
end

function logged()
    cls(1, 1, 1)
    print("Logged in...") sleep(1)
    print("Place your vote (type the corresponding numbers): ")
    for i = 1, #users do
        print(i..". "..users[i])    -- prints all the users that u are able to vote for
    end
    vote = tonumber(read())
    if vote > #users or vote <= 0 then print("Invalid vote") sleep(1) return end
    print("Thank you for voting for "..users[vote]..". Let's hope it counts!")
    file = fs.open("VotingList.txt", "a")
    file.writeLine(users[vote])
    file.close()
    sleep(2)
end

while true do
    cls(1, 1, 1)
    write("Please enter username and password: ")
    user = read()
    pass = read("*")
    if user == "user1" and pass == "user1" and user1v == 0 then logged() user1v = user1v + 1 else print("nInvalid password!") sleep(1) end
    if user == "user2" and pass == "user2" and user2v == 0 then logged() user2v = user2v + 1 else print("nInvalid password!") sleep(1) end
    if user == "user3" and pass == "user3" and user3v == 0 then logged() user3v = user3v + 1 else print("nInvalid password!") sleep(1) end
end
Espen #10
Posted 09 November 2012 - 12:40 AM
It looks like you just append each voted candidate to a file, but you never read from it again.
What I meant was, you save all of your important runtime-variables that represent the program in its latest state into a file.
Then when the program loads (like after a reboot/crash) you first make it look for such a "state-file".
If there is one then you load all the variables from there and put the program in the state it was in before the reboot/crash.

If you can't wrap your head around it, then I'll try to post an example with your voting program in mind.
But first some tea and breakfast. :P/>/>
Espen #11
Posted 09 November 2012 - 08:20 AM
Ok, sorry it took so long. To be honest I totally forgot about it while doing some other stuff. Sorry. :unsure:/>/>
To compensate I put together a more comprehensive example.
I might've gone a little overboard with it, but if you collapse the functions with an editor like e.g. Notepad++, then it should be more digestable.

Screenshots:
Spoiler

Prerequisites:
SpoilerFor the following voting progam to work you need to create 3 files:
.candidates
.votes
.passwd


The .votes file has to start out empty.
The votes for each candidate will be written to it line for line, like this:
candidate3:15
candidate1:27

The .candidates file has to contain the names of all the eligible candidates line for line, like this:
candidate1
candidate2
candidate3

The .passwd file has to contain the username, followed by a colon, followed by either a 0 or 1, followed by a colon, followed by the password, like this:
superMike:0:secret
mingebag:1:haxx0r
0 means this user is allowed to vote / has not yet voted.
1 means this user is not allowed to vote / has voted.

Program code
SpoilerProgram code for CC with Advanced Computers (supports non-advanced computers as well though):
Spoiler
Spoiler
--[[
Vote v1.0 by Espen
An example code for a voting system, inspired by ewart4fun

Thread: http://www.computercraft.info/forums2/index.php?/topic/5807-lua-voting-program/
--]]

-- [[ BEGINNING of FUNCTION DEFINITIONS ]] ---------------------------
-- Writes text centered, x- and y-axis position can be offset, and the line to be written can be cleared beforehand.
local function writeCentered( sText, nOffsetX, nOffsetY, color, bClearLine )
    local maxX, maxY = term.getSize()

    if nOffsetX == null then nOffsetX = 0 end
    local centeredX = (maxX / 2) - (string.len( sText ) / 2) + nOffsetX

    if nOffsetY == null then nOffsetY = 0 end
    local centeredY = (maxY / 2) + nOffsetY

    term.setCursorPos( centeredX, centeredY )
    if bClearLine then term.clearLine() end
    if color and term.isColor() then term.setTextColor( color ) end
    write( sText )
    if color and term.isColor() then term.setTextColor( colors.white ) end
end


--[[
    Returns:
        0 - If login is ok.
        1 - If login failed.
        2 - If user already voted.
]]
local function checkLogin( sUser, sPwd )
    --[[
        ^%a		= first char has to be a letter
        %w*		= then there can follow an arbitrary number of alphanumeric characters
        :		= then a colon follows (which is used in the passwd file to delimit the usernames from their passwords)
        [01]	= then either a 0 or a 1 follows
        :		= then another colon follows (which is used in the passwd file to delimit the usernames from their passwords)
        .*$		= finally the pattern ends with an arbitrary number of any characters, i.e. empty passwords are allowed as well (use .+$ to ignore users with empty passwords).

        ( )		= Everything we encase in brackets will be extracted and returned as a separate value.
    ]]
    local credentials_pattern = "^(%a%w*):(/>/>[01]):(/>/>.*)$" -- Example: "user123:0:secret"
    local bLoginOk = -1

    local hFile = fs.open( ".passwd", "r" )
    local line = hFile.readLine()
    while line do
        local user, hasVoted, pwd = string.match( line, credentials_pattern )
        if ( user and pwd ) and ( sUser == user ) then
            if ( sPwd == pwd ) then
                if ( hasVoted == "0" ) then
                    -- User found and password correct. Has not yet voted.
                    bLoginOk = 0
                    break
                else
                    -- User found and password correct. Has already voted.
                    bLoginOk = 1
                    break
                end
            else
                -- Password incorrect.
                --bLoginOk = -1  -- Unnecessary in the current code, as bLoginOk will not have changed from -1 when the program reaches this point.
                break
            end
        end

        -- Read the next line.
        line = hFile.readLine()
    end

    hFile:close()

    return bLoginOk
end

local function getLogin()
    local usrCurPosX, usrCurPosY, pwdCurPosX, pwdCurPosY
    local username = "", password

    while username == "" do
        writeCentered( "Username: ", -5, 0, nil, true )
        usrCurPosX, usrCurPosY = term.getCursorPos()
        writeCentered( "Password: ", -5, 1, nil, true )
        pwdCurPosX, pwdCurPosY = term.getCursorPos()

        term.setCursorPos( usrCurPosX, usrCurPosY )
        username = read()
        if username == "" then term.clear() end
    end

    term.setCursorPos( pwdCurPosX, pwdCurPosY )
    password = read("*")

    return username, password
end

-- Returns a table with candidates.
local function getCandidates()
    --[[
        [^:]+	= Each candidate name has to be comprised of at least one character, except colon.
    ]]
    local candidate_pattern = "[^:]+"
    local tCandidates = {}
    local candidate = nil


    local hFile = fs.open( ".candidates", "r" )
    local line = hFile.readLine()
    while line do
        candidate = string.match( line, candidate_pattern )

        if candidate then
            table.insert( tCandidates, candidate )
        end

        -- Read the next line.
        line = hFile.readLine()
    end

    hFile:close()
    return tCandidates
end

local function printVotingScreen( candidateList )
    term.clear()
    term.setCursorPos(1, 2)
    print( "Place your vote (type the corresponding numbers):n" )
    for index, candidate in ipairs( candidateList ) do
        print( "t("..index..") - "..candidate )
    end
    print( "nt(X) - Logout (vote later)." )
end

local function getVote( candidateList )
    while true do
        printVotingScreen( candidateList )

        local _, sChoice = os.pullEvent( "char" )
        local nChoice = tonumber( sChoice )

        -- Ask for confirmation of choice.
        if candidateList[ nChoice ] then
            write( "nYou chose: ")
            if term.isColor() then
                term.setTextColor( colors.yellow )
                print (candidateList[ nChoice ] )
                term.setTextColor( colors.white )
            else
                print (candidateList[ nChoice ] )
            end
            print( "(A)ccept or (C)ancel this choice." )
            while true do
                local _, sCommit = os.pullEvent( "char" )

                if sCommit and string.lower(sCommit) == "a" then return nChoice end
                if sCommit and string.lower(sCommit) == "c" then break end
            end
        end

        -- Logout
        if sChoice and string.lower(sChoice) == "x" then break end
    end
end

local function setHasVoted( voter )
    local users = {}
    local username, hasVoted, password
    local credentials_pattern = "^(%a%w*):(/>/>[01]):(/>/>.*)$"

    -- Read old values into table 'users'.
    local hFile = fs.open( ".passwd", "r" )
    local line = hFile.readLine()
    while line do
        username, hasVoted, password = string.match( line, credentials_pattern )
        if username and hasVoted and password then
            users[username] = { hasVoted, password }
        end
        line = hFile.readLine()
    end
    hFile.close()

    -- Write changes to file.
    local hFile = fs.open( ".passwd", "w" )
    for user, _ in pairs(users) do
        if user == voter then
            hFile.writeLine(user..":1:"..users[user][2])
        else
            hFile.writeLine(user..":"..users[user][1]..":"..users[user][2])    -- users[user][1] is hasVoted and users[user][2] is password.
        end
    end
    hFile.close()
end

local function applyVote( tCandidateList, sVoter, nCandidateNum )
    local vote = nil
    local votes = {}
    local votedCandidate
    local votes_pattern = "^([^:]+):(/>/>%d+)$" -- Example: candidate3:27

    local hFile = fs.open( ".votes", "r" )
    local line = hFile.readLine()
    while line do
        candidate, vote = string.match( line, votes_pattern )
        if candidate and vote then votes[candidate] = vote end
        line = hFile.readLine()
    end

    votedCandidate = tCandidateList[ nCandidateNum ]
    if not votedCandidate then print(tCandidateList[ 1 ]) error( "The voted candidate isn't in the list of eligible candidates. This shouldn't happen, please fix me." ) end

    -- Initialize votes for candidate in case there are not votes for him yet.
    if not votes[votedCandidate] then
        votes[votedCandidate] = 0
    end

    -- Now finally increment his votes by 1.
    votes[votedCandidate] = votes[votedCandidate] + 1

    -- Write the changes back to file.
    local hFile = fs.open( ".votes", "w" )
    for candidate, vote in pairs(votes) do
        hFile.writeLine( candidate..":"..vote )
    end
    hFile.close()

    -- Set the hasVoted flag for the voter.
    setHasVoted( sVoter )
end

local function main()
    term.clear()
    local sUser, sPassword
    local candidateList
    local vote
    local loginState
    local validLogin = false

    -- Check for valid user.
    while not validLogin do
        sUser, sPassword = getLogin()
        -- Special login which quits the program to console. Remove if unwanted.
        if sUser == "exit to" and sPassword == "console" then return false end

        loginState = checkLogin( sUser, sPassword )

        if loginState == 0 then
            writeCentered( "[ Access Granted ]n", 0, 3, colors.lime, true )
            validLogin = true
        elseif loginState == -1 then
            writeCentered( "[ Access Denied ]n", 0, 3, colors.red, true )
        elseif loginState == 1 then
            writeCentered( "[ Already Voted ]n", 0, 3, colors.purple, true )
        end

        sleep(1)    -- artificial cooldown before next try
    end

    -- Get the list of candidates and let the current user make a vote.
    candidateList = getCandidates()
    if #candidateList < 1 then
        term.clear()
        writeCentered( "No candidates to vote for." )
        writeCentered( "Please try again later.", 0, 1 )
        writeCentered( "Press ENTER to dismiss...", 0, 4 )
        local _, enter
        while enter ~= 28 do
            _, enter = os.pullEvent( "key" )
        end
        return true
    end

    -- Get a vote and apply it.
    vote = getVote( candidateList )
    if type(vote) == "number" then
        applyVote( candidateList, sUser, vote )
        term.clear()
        writeCentered( "Thank you for voting.", 0, 0, colors.yellow )
        writeCentered( "Have a nice day!", 0, 1, colors.yellow )
        sleep(3)
    end

    return true
end
-- [[ END of FUNCTION DEFINITIONS ]] ---------------------------

-- Prevent termination key-combo
nativePullEvent = os.pullEvent
os.pullEvent = os.pullEventRaw

-- Program loop
local running = true
while running do
    running = main()
end

-- Restore native os.pullEvent
os.pullEvent = nativePullEvent
Alternative Location: http://pastebin.com/5FK4z1Wu

Program code for CC without Advanced Computers (supports non-advanced computers as well though):
Spoiler
Spoiler
--[[
Vote v1.0 for CC without advanced computers by Espen
An example code for a voting system, inspired by ewart4fun

Thread: http://www.computercraft.info/forums2/index.php?/topic/5807-lua-voting-program/
--]]

-- [[ BEGINNING of FUNCTION DEFINITIONS ]] ---------------------------
-- Writes text centered, x- and y-axis position can be offset, and the line to be written can be cleared beforehand.
local function writeCentered( sText, nOffsetX, nOffsetY, color, bClearLine )
    local maxX, maxY = term.getSize()

    if nOffsetX == null then nOffsetX = 0 end
    local centeredX = (maxX / 2) - (string.len( sText ) / 2) + nOffsetX

    if nOffsetY == null then nOffsetY = 0 end
    local centeredY = (maxY / 2) + nOffsetY

    term.setCursorPos( centeredX, centeredY )
    if bClearLine then term.clearLine() end
    write( sText )
end


--[[
    Returns:
        0 - If login is ok.
        1 - If login failed.
        2 - If user already voted.
]]
local function checkLogin( sUser, sPwd )
    --[[
        ^%a		= first char has to be a letter
        %w*		= then there can follow an arbitrary number of alphanumeric characters
        :		= then a colon follows (which is used in the passwd file to delimit the usernames from their passwords)
        [01]	= then either a 0 or a 1 follows
        :		= then another colon follows (which is used in the passwd file to delimit the usernames from their passwords)
        .*$		= finally the pattern ends with an arbitrary number of any characters, i.e. empty passwords are allowed as well (use .+$ to ignore users with empty passwords).

        ( )		= Everything we encase in brackets will be extracted and returned as a separate value.
    ]]
    local credentials_pattern = "^(%a%w*):(/>/>[01]):(/>/>.*)$" -- Example: "user123:0:secret"
    local bLoginOk = -1

    local hFile = fs.open( ".passwd", "r" )
    local line = hFile.readLine()
    while line do
        local user, hasVoted, pwd = string.match( line, credentials_pattern )
        if ( user and pwd ) and ( sUser == user ) then
            if ( sPwd == pwd ) then
                if ( hasVoted == "0" ) then
                    -- User found and password correct. Has not yet voted.
                    bLoginOk = 0
                    break
                else
                    -- User found and password correct. Has already voted.
                    bLoginOk = 1
                    break
                end
            else
                -- Password incorrect.
                --bLoginOk = -1  -- Unnecessary in the current code, as bLoginOk will not have changed from -1 when the program reaches this point.
                break
            end
        end

        -- Read the next line.
        line = hFile.readLine()
    end

    hFile:close()

    return bLoginOk
end

local function getLogin()
    local usrCurPosX, usrCurPosY, pwdCurPosX, pwdCurPosY
    local username = "", password

    while username == "" do
        writeCentered( "Username: ", -5, 0, nil, true )
        usrCurPosX, usrCurPosY = term.getCursorPos()
        writeCentered( "Password: ", -5, 1, nil, true )
        pwdCurPosX, pwdCurPosY = term.getCursorPos()

        term.setCursorPos( usrCurPosX, usrCurPosY )
        username = read()
        if username == "" then term.clear() end
    end

    term.setCursorPos( pwdCurPosX, pwdCurPosY )
    password = read("*")

    return username, password
end

-- Returns a table with candidates.
local function getCandidates()
    --[[
        [^:]+	= Each candidate name has to be comprised of at least one character, except colon.
    ]]
    local candidate_pattern = "[^:]+"
    local tCandidates = {}
    local candidate = nil


    local hFile = fs.open( ".candidates", "r" )
    local line = hFile.readLine()
    while line do
        candidate = string.match( line, candidate_pattern )

        if candidate then
            table.insert( tCandidates, candidate )
        end

        -- Read the next line.
        line = hFile.readLine()
    end

    hFile:close()
    return tCandidates
end

local function printVotingScreen( candidateList )
    term.clear()
    term.setCursorPos(1, 2)
    print( "Place your vote (type the corresponding numbers):n" )
    for index, candidate in ipairs( candidateList ) do
        print( "t("..index..") - "..candidate )
    end
    print( "nt(X) - Logout (vote later)." )
end

local function getVote( candidateList )
    while true do
        printVotingScreen( candidateList )

        local _, sChoice = os.pullEvent( "char" )
        local nChoice = tonumber( sChoice )

        -- Ask for confirmation of choice.
        if candidateList[ nChoice ] then
            write( "nYou chose: ")
            print (candidateList[ nChoice ] )
            print( "(A)ccept or (C)ancel this choice." )
            while true do
                local _, sCommit = os.pullEvent( "char" )

                if sCommit and string.lower(sCommit) == "a" then return nChoice end
                if sCommit and string.lower(sCommit) == "c" then break end
            end
        end

        -- Logout
        if sChoice and string.lower(sChoice) == "x" then break end
    end
end

local function setHasVoted( voter )
    local users = {}
    local username, hasVoted, password
    local credentials_pattern = "^(%a%w*):(/>/>[01]):(/>/>.*)$"

    -- Read old values into table 'users'.
    local hFile = fs.open( ".passwd", "r" )
    local line = hFile.readLine()
    while line do
        username, hasVoted, password = string.match( line, credentials_pattern )
        if username and hasVoted and password then
            users[username] = { hasVoted, password }
        end
        line = hFile.readLine()
    end
    hFile.close()

    -- Write changes to file.
    local hFile = fs.open( ".passwd", "w" )
    for user, _ in pairs(users) do
        if user == voter then
            hFile.writeLine(user..":1:"..users[user][2])
        else
            hFile.writeLine(user..":"..users[user][1]..":"..users[user][2])    -- users[user][1] is hasVoted and users[user][2] is password.
        end
    end
    hFile.close()
end

local function applyVote( tCandidateList, sVoter, nCandidateNum )
    local vote = nil
    local votes = {}
    local votedCandidate
    local votes_pattern = "^([^:]+):(/>/>%d+)$" -- Example: candidate3:27

    local hFile = fs.open( ".votes", "r" )
    local line = hFile.readLine()
    while line do
        candidate, vote = string.match( line, votes_pattern )
        if candidate and vote then votes[candidate] = vote end
        line = hFile.readLine()
    end

    votedCandidate = tCandidateList[ nCandidateNum ]
    if not votedCandidate then print(tCandidateList[ 1 ]) error( "The voted candidate isn't in the list of eligible candidates. This shouldn't happen, please fix me." ) end

    -- Initialize votes for candidate in case there are not votes for him yet.
    if not votes[votedCandidate] then
        votes[votedCandidate] = 0
    end

    -- Now finally increment his votes by 1.
    votes[votedCandidate] = votes[votedCandidate] + 1

    -- Write the changes back to file.
    local hFile = fs.open( ".votes", "w" )
    for candidate, vote in pairs(votes) do
        hFile.writeLine( candidate..":"..vote )
    end
    hFile.close()

    -- Set the hasVoted flag for the voter.
    setHasVoted( sVoter )
end

local function main()
    term.clear()
    local sUser, sPassword
    local candidateList
    local vote
    local loginState
    local validLogin = false

    -- Check for valid user.
    while not validLogin do
        sUser, sPassword = getLogin()
        -- Special login which quits the program to console. Remove if unwanted.
        if sUser == "exit to" and sPassword == "console" then return false end

        loginState = checkLogin( sUser, sPassword )

        if loginState == 0 then
            writeCentered( "[ Access Granted ]n", 0, 3, colors.lime, true )
            validLogin = true
        elseif loginState == -1 then
            writeCentered( "[ Access Denied ]n", 0, 3, colors.red, true )
        elseif loginState == 1 then
            writeCentered( "[ Already Voted ]n", 0, 3, colors.purple, true )
        end

        sleep(1)    -- artificial cooldown before next try
    end

    -- Get the list of candidates and let the current user make a vote.
    candidateList = getCandidates()
    if #candidateList < 1 then
        term.clear()
        writeCentered( "No candidates to vote for." )
        writeCentered( "Please try again later.", 0, 1 )
        writeCentered( "Press ENTER to dismiss...", 0, 4 )
        local _, enter
        while enter ~= 28 do
            _, enter = os.pullEvent( "key" )
        end
        return true
    end

    -- Get a vote and apply it.
    vote = getVote( candidateList )
    if type(vote) == "number" then
        applyVote( candidateList, sUser, vote )
        term.clear()
        writeCentered( "Thank you for voting.", 0, 0, colors.yellow )
        writeCentered( "Have a nice day!", 0, 1, colors.yellow )
        sleep(3)
    end

    return true
end
-- [[ END of FUNCTION DEFINITIONS ]] ---------------------------

-- Prevent termination key-combo
nativePullEvent = os.pullEvent
os.pullEvent = os.pullEventRaw

-- Program loop
local running = true
while running do
    running = main()
end

-- Restore native os.pullEvent
os.pullEvent = nativePullEvent
Alternative Location: http://pastebin.com/1scDhKEv

SpoilerDon't panic if you see this huge amount of code, this is how it looks without the function bodies:
local function writeCentered( sText, nOffsetX, nOffsetY, color, bClearLine )
local function checkLogin( sUser, sPwd )
local function getLogin()
local function getCandidates()
local function printVotingScreen( candidateList )
local function getVote( candidateList )
local function setHasVoted( voter )
local function applyVote( tCandidateList, sVoter, nCandidateNum )
local function main()

-- Prevent termination key-combo
nativePullEvent = os.pullEvent
os.pullEvent = os.pullEventRaw

-- Program loop
local running = true
while running do
    running = main()
end

-- Restore native os.pullEvent
os.pullEvent = nativePullEvent

If you run this program as a startup program, then the only way to exit to console is either to boot from a disk, or to enter the following login details:
Username: exit to
Password: console
I left this in as a convenience, but remove it if you don't want users to accidentally find out about it. It's just one line.

There's some stuff I left out, like sorting or checking for files before I attempt to read from them.
I'll leave that as an excercise to the reader though, or else I'd never stop coding. There is always one more line to code, right? ^_^/>/>

I tried to comment the important parts. If I seem to have forgotten something important or if anything is still unclear, don't hesitate to ask.
Hope it helps, have fun! :)/>/>

Cheers

EDIT: Added version for CCs that have no advanced computers (i.e. should be Tekkit compatible).
Edited on 09 November 2012 - 09:39 PM
ewart4fun #12
Posted 09 November 2012 - 07:47 PM
wow thanks, you're a real pro in coding. :unsure:/>/> i wish i was that good one day.
can you please make it so that i can use it in tekkit?
Espen #13
Posted 09 November 2012 - 08:26 PM
wow thanks, you're a real pro in coding. :unsure:/>/> i wish i was that good one day.
can you please make it so that i can use it in tekkit?
Hey, no problem, glad to help. I didn't write everything in one go though, it gradually grew, while I tested every added functionality step-by-step.
If you take your time following the path of execution then I'm sure you'll understand everything.
If there's something you don't understand, you can always ask. And the rest is just practice.

But what exactly doesn't work in Tekkit? I'm not used to Tekkit so I have no idea on what ComputerCraft version the current Tekkit is.
If you can tell me the version then I'll gladly take a look at the differences and change the program accordingly.
remiX #14
Posted 09 November 2012 - 10:11 PM
But what exactly doesn't work in Tekkit? I'm not used to Tekkit so I have no idea on what ComputerCraft version the current Tekkit is.
If you can tell me the version then I'll gladly take a look at the differences and change the program accordingly.

Tekkit doesn't support text colours :unsure:/>/> Latest version that tekkit can use is CC 1.4 if I'm not mistaken
Espen #15
Posted 09 November 2012 - 10:16 PM
Tekkit doesn't support text colours ^_^/>/> Latest version that tekkit can use is CC 1.4 if I'm not mistaken

Oh, if that's the only problem, then there isn't a problem.^^
I've coded it in such a way that it checks for color support. And if it doesn't support colors, it'll just print the text as usual.

But I'm gonna take a look at the Tekkit CC version and see what other changes might produce problems.

EDIT: Hmm, yeah, I derped a little there, because if there are no advanced computers, then term.isColor() won't work either. *duh*
And the latest Tekkit comes with CC version… 1.33 !? Wow, one really misses out on CC when using Tekkit.
Ah well, will fix up a completely pre-Advanced-ComputerCraft-friendly version for the Tekkit-philes.
:unsure:/>/>
Edited on 09 November 2012 - 09:25 PM
remiX #16
Posted 09 November 2012 - 10:37 PM
Haha yes, but I think you can get CC 1.4 if you update other mods but I'm not bothered :unsure:/>/> There's not much in that code that prevents it from working, i think?
Espen #17
Posted 09 November 2012 - 10:41 PM
Indeed there shouldn't be, as far as I can tell.
I just removed everything regarding colors and updated the post to include a non-Advanced-Computers version that should work fine with Tekkit.
ewart4fun #18
Posted 09 November 2012 - 11:23 PM
jep, it works perfectly now, thanks
skydude92 #19
Posted 19 July 2013 - 01:55 AM
I like this program, but one thing. How would you make it display the Current tally of who is voted for on an attached monitor and update when a new vote is put in.