Need help with Voting System using tables!

Hey people, currently I’m trying to make a Map Voting System and I’m working on the Voting System using Part.Touched as pads. Everything seems to be working fine when I step on a pad but when I step on a different pad my previous vote won’t delete. What am I doing wrong?

–CODE–

local Debounce1 = false
local Debounce2 = false
local Debounce3 = false

local function UpdateVoteNumbers()
	MapHolder1.Gui.NumOfVotes.Text = "Votes: " ..table.getn(votingForMap1)
	MapHolder2.Gui.NumOfVotes.Text = "Votes: " ..table.getn(votingForMap2)
	MapHolder3.Gui.NumOfVotes.Text = "Votes: " ..table.getn(votingForMap3)
end

MapHolder1Pad.Touched:Connect(function(Part)
		if not Debounce1 then
		Debounce1 = true
		local Parent = Part.Parent
		if game.Players:GetPlayerFromCharacter(Parent) then
			local plr = game.Players:GetPlayerFromCharacter(Parent)
			if not table.find(votingForMap1, plr.UserId) then
				print(plr.Name.. " voted for Map1")
				table.insert(votingForMap1, plr.UserId)
				UpdateVoteNumbers()
				wait(1)
				Debounce1 = false
			elseif table.find(votingForMap2, plr.UserId) and not table.find(votingForMap1, plr.UserId) then
				print(plr.Name.. " switched Map2 for Map1")
				table.remove(votingForMap2, plr.UserId)
				table.insert(votingForMap1, plr.UserId)
				UpdateVoteNumbers()
				wait(1)
				Debounce1 = false
			elseif table.find(votingForMap3, plr.UserId) and not table.find(votingForMap1, plr.UserId)then
				print(plr.Name.. " switched Map3 for Map1")
				table.remove(votingForMap3, plr.UserId)
				table.insert(votingForMap1, plr.UserId)
				UpdateVoteNumbers()
				wait(1)
				Debounce1 = false
			end	
		end 
	end
end)
MapHolder2Pad.Touched:Connect(function(Part)
	if not Debounce2 then
		Debounce2 = true
		local Parent = Part.Parent
		if game.Players:GetPlayerFromCharacter(Parent) then
			local plr = game.Players:GetPlayerFromCharacter(Parent)
			if not table.find(votingForMap2, plr.UserId) then
				print(plr.Name.. " voted for Map2")
				table.insert(votingForMap2, plr.UserId)
				UpdateVoteNumbers()
				wait(1)
				Debounce2 = false
			elseif table.find(votingForMap1, plr.UserId) and not table.find(votingForMap2, plr.UserId) then
				print(plr.Name.. " switched Map2 for Map1")
				table.remove(votingForMap1, plr.UserId)
				table.insert(votingForMap2, plr.UserId)
				UpdateVoteNumbers()
				wait(1)
				Debounce2 = false
			elseif table.find(votingForMap3, plr.UserId) and not table.find(votingForMap2, plr.UserId)then
				print(plr.Name.. " switched Map3 for Map2")
				table.remove(votingForMap3, plr.UserId)
				table.insert(votingForMap2, plr.UserId)
				UpdateVoteNumbers()
				wait(1)
				Debounce2 = false
			end
		end
	end
end)
MapHolder3Pad.Touched:Connect(function(Part)
	if not Debounce3 then
		Debounce3 = true
		local Parent = Part.Parent
		if game.Players:GetPlayerFromCharacter(Parent) then
			local plr = game.Players:GetPlayerFromCharacter(Parent)
			if not table.find(votingForMap3, plr.UserId) then
				print(plr.Name.. " voted for Map3")
				table.insert(votingForMap3, plr.UserId)
				UpdateVoteNumbers()
				wait(1)
				Debounce3 = false
			elseif table.find(votingForMap1, plr.UserId) and not table.find(votingForMap3, plr.UserId) then
				print(plr.Name.. " switched Map1 for Map3")
				table.remove(votingForMap1, plr.UserId)
				table.insert(votingForMap3, plr.UserId)
				UpdateVoteNumbers()
				wait(1)
				Debounce3 = false
			elseif table.find(votingForMap2, plr.UserId) and not table.find(votingForMap3, plr.UserId)then
				print(plr.Name.. " switched Map2 for Map3")
				table.remove(votingForMap3, plr.UserId)
				table.insert(votingForMap3, plr.UserId)
				UpdateVoteNumbers()
				wait(1)
				Debounce3 = false
			end
		end
	end
end)
2 Likes

I have not read the whole thing yet, but i already suggest making an if statement inside the first if statement, kinda of like this:

if not table.find(votingForMap1, plr.UserId) then
    --do your magic
     if table.find(Votingformap3, plr.UserId) then
          --more magic
     elseif table.find(votingformap2, plr.UserId) then
          --even more magic
     end
end

Also if you couldtell me what the output says, that would be helpful.

1 Like

I just wanna say that the way you wrote your code is very inefficient because of the repetitiveness of it. I will attempt to achieve your desired outcome while making it more efficient!

My method will also allow you to have as many voting pads as you want while making little changes!

(Please replace the things that needs to be replaced for this to work properly)

Code Sample:

--Services
local Players = game:GetService("Players")



local Pads = {
	Pad1 = workspace.Model.Pad1, --Change to the path of pad 1
	Pad2 = workspace.Model.Pad2, --Change to the path of pad 2
	Pad3 = workspace.Model.Pad3, --Change to the path of pad 3 
	
	--Add as many pads as you need (example: "Pad4 = workspace.Model.Pad4, etc")
}

local VoteLabels = {
	Pad1 = workspace.Model.VoteLabels.Gui.Pad1.NumOfVotes, --Change to the path of the pad 1 NumOfVotes label
	Pad2 = workspace.Model.VoteLabels.Gui.Pad2.NumOfVotes, --Change to the path of the pad 1 NumOfVotes label
	Pad3 = workspace.Model.VoteLabels.Gui.Pad3.NumOfVotes, --Change to the path of the pad 1 NumOfVotes label
	
	--Add as many vote labels as you need just make sure each key in the "Pads" table has its own corresponding key in this table  (example: "Pad4 = workspace.Model.VoteLabels.Gui.Pad1.NumOfVotes")
}

local Debounces = {}
local Votes = {} --Stores the votes for each pad


local function UpdateLabels() --This function updates all the labels
	for i,v in pairs(VoteLabels) do
		v.Text = "Votes: ".. #Votes[i]
	end
end


local function HandleTouchedEvent(plr:Player, Pad:string) --This function handles a player touching a pad
	if table.find(Votes[Pad], plr.Name) then return end --The player has already voted for this pad so no need!
	
	for i,v in pairs(Votes) do
		if i == Pad then 
			table.insert(v, plr.Name)
			continue 
		end


		local OccurenceIndex = table.find(v, plr.Name)
		if OccurenceIndex then
			table.remove(v, OccurenceIndex)
		end
		
	end
	
	UpdateLabels()
	
end


for key,Pad:BasePart in pairs(Pads) do
	Votes[key] = {}
	
	Pad.Touched:Connect(function(Part:BasePart)
		local plr = Players:GetPlayerFromCharacter(Part:FindFirstAncestorOfClass("Model"))
		if not plr or Debounces[plr]  then return end
		Debounces[plr] = true
		HandleTouchedEvent(plr, key)
		Debounces[plr] = nil
	end)
	
end

This worked perfectly fine for me as shown below so tell me if you experience any problems and I’ll try to get back to you once I see the notification!



2 Likes

Thank you so much, this worked best for me! However I have 2 questions.

  1. How would I make a function that clears the votes out?
  2. How can I print what pad has the most votes?

To solve your first question, you can loop through the “Votes” table and clear each table. To solve your second question, you can loop through the “Votes” table and check which table has the most elements.
Scroll to the end of the code block to see the implementation!

Code Sample:

--Services
local Players = game:GetService("Players")



local Pads = {
	Pad1 = workspace.Model.Pad1, --Change to the path of pad 1
	Pad2 = workspace.Model.Pad2, --Change to the path of pad 2
	Pad3 = workspace.Model.Pad3, --Change to the path of pad 3 
	
	--Add as many pads as you need (example: "Pad4 = workspace.Model.Pad4, etc")
}

local VoteLabels = {
	Pad1 = workspace.Model.VoteLabels.Gui.Pad1.NumOfVotes, --Change to the path of the pad 1 NumOfVotes label
	Pad2 = workspace.Model.VoteLabels.Gui.Pad2.NumOfVotes, --Change to the path of the pad 1 NumOfVotes label
	Pad3 = workspace.Model.VoteLabels.Gui.Pad3.NumOfVotes, --Change to the path of the pad 1 NumOfVotes label
	
	--Add as many vote labels as you need just make sure each key in the "Pads" table has its own corresponding key in this table  (example: "Pad4 = workspace.Model.VoteLabels.Gui.Pad1.NumOfVotes")
}

local Debounces = {}
local Votes = {} --Stores the votes for each pad


local function UpdateLabels() --This function updates all the labels
	for i,v in pairs(VoteLabels) do
		v.Text = "Votes: ".. #Votes[i]
	end
end


local function HandleTouchedEvent(plr:Player, Pad:string) --This function handles a player touching a pad
	if table.find(Votes[Pad], plr.Name) then return end --The player has already voted for this pad so no need!
	
	for i,v in pairs(Votes) do
		if i == Pad then 
			table.insert(v, plr.Name)
			continue 
		end


		local OccurenceIndex = table.find(v, plr.Name)
		if OccurenceIndex then
			table.remove(v, OccurenceIndex)
		end
		
	end
	
	UpdateLabels()
	
end


for key,Pad:BasePart in pairs(Pads) do
	Votes[key] = {}
	
	Pad.Touched:Connect(function(Part:BasePart)
		local plr = Players:GetPlayerFromCharacter(Part:FindFirstAncestorOfClass("Model"))
		if not plr or Debounces[plr]  then return end
		Debounces[plr] = true
		HandleTouchedEvent(plr, key)
		Debounces[plr] = nil
	end)
	
end



--Code sample to solve your questions
local function ClearVotes()
	for _,v in pairs(Votes)
		table.clear(v)
	end
end

local function GetMostVotedPad() --This returns the pad index not the table itself but you can index the "Votes" table with what the function returns
	local MaxAmount = -1 --This variable is to keep track of what the highest votes is currently
	local Pad

	for i,v in pairs(Votes)
		local VoteAmount = #v
		if VoteAmount > MaxAmount then
			MaxAmount = VoteAmount
			Pad = i
		end
	end
	
	return Pad
end

Tell me if that works for you!

1 Like