In Lua, How do I call a variable using index? - indexing

local index = 1
Defining Function
local function PickGlass()
local RandomNum = math.random(0,1)
local Platform1 = game.Workspace.Tester.Platform(index)
local Platform2 = game.Workspace.Tester.Platform(index + 1)
local function Falling()
Platform1.Anchored = false
end
local function OtherFalling()
Platform2.Anchored = false
end
if RandomNum == 1 then
Platform1.Touched:Connect(Falling)
end
if RandomNum == 0 then
Platform2.Touched:Connect(OtherFalling)
end
index = index + 1
end
Running Function
while index < 4 do
PickGlass()
index += 2
end
It wont let me use index when defining Platform 1 and 2. How do I use it?

If you’re trying to index an instance using a variable, you can do either:
game.Workspace.Tester.Platform[tostring(index)]
-- or
game.Workspace.Tester.Platform:FindFirstChild(tostring(index))
You can’t do:
game.Workspace.Tester.Platform(index)
Because that is indicating that you want to call the Platform method which doesn’t exist on Tester. (Plus you’d need : to pass self first on any function call)

Related

GetMarkedReachedSignal isn't a valid member of AnimationTrack?

So I’m trying to make two functions happen upon a marker being reached in an animation, however it says:
“GetMarkedReachedSignal is not a valid member of AnimationTrack” I’m really confused.
Heres my code:
`
script.Parent.OnServerEvent:Connect(function(plr)
print("Started")
local on = true
local char = plr.Character
local fist = game.Lighting.DivergentFists:Clone()
local leftfist = game.Lighting.DivergentFists2:Clone()
local anim = script.Parent.Parent.DiverGentAnim
local weld = Instance.new("ManualWeld")
local leftweld = Instance.new("ManualWeld")
local function RightHandEmit()
fist.Parent = char.RightHand
fist.CFrame = char.RightHand.CFrame
weld.Parent = char.RightHand
weld.Part0 = char.RightHand
weld.Part1 = fist
weld.C0 = CFrame.new(0,-1,0)
local function FlameEmit()
while on == true do
fist.Attachment.BlackFlames:Emit(10)
fist.Attachment.Flames:Emit(10)
wait(.1)
end
end
local function SparksEmit()
while on == true do
fist.Attachment.Aura:Emit(10)
fist.Attachment.Main:Emit(10)
wait(.1)
end
end
spawn(SparksEmit)
spawn(FlameEmit)
end
local function LeftHandEmit()
leftfist.Parent = char.LeftHand
leftfist.CFrame = char.LeftHand.CFrame
leftweld.Parent = char.LeftHand
leftweld.Part0 = char.LeftHand
leftweld.Part1 = leftfist
leftweld.C0 = CFrame.new(0,-1,0)
local function LeftFlameEmit()
while on == true do
leftfist.Attachment.BlackFlames:Emit(10)
leftfist.Attachment.Flames:Emit(10)
wait(.1)
end
end
local function LeftSparksEmit()
while on == true do
leftfist.Attachment.Aura:Emit(10)
leftfist.Attachment.Main:Emit(10)
wait(.1)
end
end
spawn(LeftFlameEmit)
spawn(LeftSparksEmit)
end
local load = char.Humanoid.Animator:LoadAnimation(anim)
load:Play()
load:GetMarkerReachedSignal("ReachedStart"):Connect(function()
print("Reached")
spawn(LeftHandEmit)
spawn(RightHandEmit)
end)
end)
`
Any help is appreciated, thanks! (This is all on the server by the way)
I tried doing it on the client but nothing happened

How can I improve this iterative function?

I am trying to simplify this function which is similar from
Function Snake_makestep()
maincar.Location = locate(xpos, ypos)
car0.Location = locate(posx(0), posy(0))
car1.Location = locate(posx(1), posy(1))
If car2.Visible = True Then
car2.Location = locate(posx(2), posy(2))
End If
If car3.Visible = True Then
car3.Location = locate(posx(3), posy(3))
End If
If car4.Visible = True Then
car4.Location = locate(posx(4), posy(4))
End If
To
If car30.Visible = True Then
car30.Location = locate(posx(30), posy(30))
End If
End Function
I'm not sure If I can/how to use Controls.Find solution within this function. Any help?
To answer the question as asked:
For i = 2 To 30
Dim car = Controls("car" & i)
If car.Visible Then
car.Location = locate(posx(i), posy(i))
End If
Next
Visible and Location are both members of the Control class so it doesn't matter what type of control those car variables are.
Note that this assumes that all controls are on the form itself. If they are in a different parent container, you'd need to use the Controls collection of that container.
Also, I have started i at 2 there, so you'd still need the explicit code for car0 and car1. If they are always visible then you could start the loop at 0 and it would still work, saving you those two lines of code as well.

How to enable/disable button with a function

I have a problem with my university project
It's a little game, 6 buttons for each players and 2 players so 12 buttons
There is number in each buttons, if a player has his 6 buttons at 0, he can't play
I have try some Public Function and i'm actually working with a very simple one but i think this is not the problem
My function is here
And in my form, the problem is here, i've tried many things but i don't know how do to that ... I read my lesson and I'm searching on the internet, i have no idea ..
If possible is True you don't re-enable the button.
You can simplify things.
Public Function PeutJouer(ByVal joueur As Integer) As Boolean
Dim sum As Integer
Dim start As Integer = (joueur - 1) * 7
For i As Integer = start To start + 5
sum += tableau(i)
Next
Return sum <> 0
End Function
Then
Btn1P1.Enabled = PeutJouer(1)
Did you show all the relevant code? You are declaring Dim tableau(12) As Integer but the array is never filled with values. Probably tableau should be declared at the form level and not locally in this function. If you already have both, remove the local declaration, because it hides the one at form level. You also need to return the result from the function. I don't see this in your function.
Note that this
If x <> 0 Then
booleanVariable = True
Else
booleanVariable = True
End If
can be simplified to
booleanVariable = x <> 0
i.e., the condition is an expression yielding the Boolean result True or False already and you can use this value directly. When working with numeric values you don't write If x + y = 1 Then r = 1 Else If x + y = 2 Then r = 2 .... You simply write r = x + y.

Why won't the else statement run?

I am writing a function that checks to see if all elements in an array are equal, but for some reason, the else statement never seems to run, even when the if condition IS NOT TRUE. Any reason for this weird behavior? I actually displayed the result of the boolean expression a(i) = a(i + 1) and it was false. What could be going on here?
VB.NET Code:
Function EqualItems(ByVal a As Integer())
For i As Integer = 1 To a.Length - 1
If a(i) = a(i + 1) Then
If i + 1 = a.Length Then
Return True
End If
Else
Return False
End If
Next
End Function
There are more than a few things wrong here, I will explain in a bit...
First here's what I would do using Linq. Just make sure to Import System.Linq at the top of your class file...
Public Function IsEqual(ByVal a As Integer()) As Boolean
Return a IsNot Nothing AndAlso a.count > 0 AndAlso a.Distinct.Count() = 1
End Function
Breakdown of function
Make sure the array is not nothing.
We have more than one item so we can compare the other's in the array.
Finally do the compare of the items. The .Distinct.Count() = 1 will return a boolean of either True or False compare to all items that are in the array...
Note: Not good for comparing some objects this way...
Your Issue's
The first problem is this: For i As Integer = 1 To a.Length - 1. Should start at 0 for arrays. So it should look like this: For i As Integer = 0 To a.Length - 1.
The next is: If a(i) = a(i + 1) Then. This is where you would throw the IndexOutOfRange exception as because there might be not index at: a(i + 1). Solution: If Not (i + 1 = a.Length) Then check before trying to access that index...
You can declare a Boolean variable to False before everything. Then if anywhere the items are not equal return false or set the boolean to false and return that...
On a side note
Implement some Try Catch blocks to catch and handle the errors. Turn Option Strict On... If you had this on it would say something about the function may not return anything (cant remember what exactly that message is off-hand).

Parallel.for Loop - result varies for each click .. why does this happen?

Following parallel.for loop uses data of a bitarray which is 300000 bits in length. and the data is fixed not to change. So the produced results "Count_of_Found_Pattern1" must be same no matter how many times I execute the function "check"
But, the issue is the values of "Count_of_Found_Pattern1" & "Count_of_Found_Pattern2" produce different values every time I execute the function "check" .. what have I done wrong?
when I check it using small amount of bits (about 16 bits instead of 300000) it produces good results. But, when the bitarray length is lengthier, it produces a total mess.
For Example:
1st execution --> Count_of_Found_Pattern1 = 150526 , Count_of_Found_Pattern2 = 97855
2nd execution --> Count_of_Found_Pattern1 = 45855 , Count_of_Found_Pattern2 = 187562
Regards!
Private Function check()
Dim Count_of_Found_Pattern1 As Int64 = 0
Dim Count_of_Found_Pattern2 As Int64 = 0
Dim stopwatch As New Stopwatch
stopwatch.Start()
Dim Current_Position1 As Int64 = 0
Dim Current_Position2 As Int64 = 1
Parallel.For(0, lastbitarrayover2, Sub(countbits, loopstate)
If BitArray(Current_Position1) = False And BitArray(Current_Position2) = True Then
Count_of_Found_Pattern1 = Count_of_Found_Pattern1 + 1
End If
If BitArray(Current_Position1) = True And BitArray(Current_Position2) = False Then
Count_of_Found_Pattern1 = Count_of_Found_Pattern1 + 1
End If
If BitArray(Current_Position1) = True And BitArray(Current_Position2) = True Then
Count_of_Found_Pattern2 = Count_of_Found_Pattern2 + 1
End If
If BitArray(Current_Position1) = False And BitArray(Current_Position2) = False Then
Count_of_Found_Pattern2 = Count_of_Found_Pattern2 + 1
End If
Current_Position1 = Current_Position1 + 2
Current -Position2 = Current_Position2 + 2
Numer_of_Completed_Iterations = Numer_of_Completed_Iterations + 1
End Sub)
Numer_of_Completed_Iterations = 0 'reset counter to 0
stopwatch.Stop()
TextBox1.Text = stopwatch.Elapsed.ToString
End Function
When you increment Count_of_Found_Pattern1 (or Pattern2), first the value is read, then it is incremented, then it assigned. But the thread that is executing can change during those three steps.
Thread 1: Read Count_of_Found_Pattern1
Thread 2: Read Count_of_Found_Pattern1
Thread 2: Increment
Thread 2: Write to Count_of_Found_Pattern1
...
Thread 1: Increment its old value
Thread 1: Write to Count_of_Found_Pattern1
Now Count_of_Found_Pattern1 is wrong. And if Thread 2 had control of execution for more than just one iteration, it could be very wrong.
Consider doing as much as possible within PLINQ, avoiding any mutation of global state until all the threads have joined back up. The following code assumes you're interested in comparing adjacent entries in BitArray:
Dim counts = Enumerable.
Range(0, lastbitarrayover2 / 2).Select(Function(i) i * 2).
AsParallel().
Aggregate(
Function()
' We're using an object of anonymous type to hold
' the results of the calculation so far.
' Each thread calls this function, so each thread
' gets its own object for holding intermediate results
Return New With {.Pattern1 = 0, .Pattern2 = 0, .Iterations = 0}
End Function,
Function(accumulator, i)
' accumulator is this thread's intermediate-result-holder.
' i is one of the even numbers from our big set of even numbers.
' Each thread will call this function many times, building up its own accumulator object
' the four conditionals from your code reduce to this If block
If (BitArray(i) = BitArray(i + 1)) Then
accumulator.Pattern2 += 1
Else
accumulator.Pattern1 += 1
End If
accumulator.Iterations += 1
Return accumulator
End Function,
Function(acc1, acc2)
' Once each thread has built up its own accumulator object,
' this function makes a new accumulator object that
' combines the results from two threads.
' This is called repeatedly until all the threads' results
' have been combined.
Return New With {
.Pattern1 = acc1.Pattern1 + acc2.Pattern1,
.Pattern2 = acc1.Pattern2 + acc2.Pattern2,
.Iterations = acc1.Iterations + acc2.Iterations}
End Function,
Function(acc)
' The last function here is supposed to take the combined results
' and turn them into what you ultimately want to use.
' Since the combined results are already in the form we want,
' we'll just use the "identity" function here: it returns its
' argument unchanged
Return acc
End Function)
Count_of_Found_Pattern1 = counts.Pattern1
Count_of_Found_Pattern2 = counts.Pattern2
Number_of_Completed_Iterations = counts.Iterations
This might seem like a lot, but it's really not too bad. The main thing is that we are giving each thread its own set of variables to work with; that way we don't have to worry about the problems I outlined at the top of my answer. Then, we combine the work done by each thread at the end.
Have you tried System.Threading.Interlocked.Increment to make this thread safe? For example:
If BitArray(Current_Position1) = False And BitArray(Current_Position2) = True Then
Interlocked.Increment(Count_of_Found_Pattern1)
End If