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

[Ask A Pro] Too Good To Be True?

Started by JustIan12, 09 July 2016 - 07:33 AM
JustIan12 #1
Posted 09 July 2016 - 09:33 AM
So, I wrote this code and It works. But I would like if you could go over it maybe and tell me if I am doing anything incorrectly or if I could do anything better? Also how would I check the range of the sensor on this turtle. the reason why I am asking is because I think the table has saved and is not updating live so no matter how far I am it will suck the item in front of it.

-- Intro
term.clear()
term.setCursorPos(1,1)
term.setTextColor(colors.blue)
print("ME Defence System")
term.setTextColor(colors.white)
term.setCursorPos(1,2)
sensor = peripheral.wrap("left")
-- Variables
rsSide = "bottom"
-- Sensor Input
pUnscramble = textutils.serialise(sensor.getPlayers())

-- Main
function mainLoop()

local tPlayerLookup = {
["JustIan122"] = true,
}
if tPlayerLookup[ "JustIan122" ] then
  sleep(0.1)
else
  turtle.suck()
end
end
sleep(4)
while true do
mainLoop()

end
Exerro #2
Posted 09 July 2016 - 10:03 AM
I've commented the code below (and broken it up a bit for ease of reading)


term.clear()
term.setCursorPos(1,1)
term.setTextColor(colors.blue)
print("ME Defence System")
term.setTextColor(colors.white)
term.setCursorPos(1,2) -- print() puts the cursor on the next line for you, so you don't need to do this
sensor = peripheral.wrap("left") -- use local! (shouldn't this be in the 'Variables' section anyway?)

-- Variables
rsSide = "bottom" -- this is never used, and use local!

-- Sensor Input
pUnscramble = textutils.serialise(sensor.getPlayers()) -- this is also never used, and use local!

function mainLoop() -- use local!
	local tPlayerLookup = { JustIan122 = true }

	if tPlayerLookup[ "JustIan122" ] then -- this will always eval to true
		sleep(0.1) -- so this will always happen
	else
		turtle.suck() -- and this will never happen
	end
end

sleep(4) -- this waits 4 seconds before starting the loop, is that wanted?

while true do
	mainLoop() -- why not just put the code in the while loop instead of the function?
end

The 'use local!' comments are there just because locals are generally considered good practise. They won't change how your code runs in this case. The main issue is the tPlayerLookup index which will always evaluate to true, so that if statement isn't really necessary…? Not sure what you're trying to do there though, so I'm not sure how to change it.
Edited on 09 July 2016 - 08:04 AM
The Crazy Phoenix #3
Posted 09 July 2016 - 10:33 AM
It's not just that locals are considered good practice, it's that if you use globals, the variables will still be around after the program terminates. Preserving them inside the local scope means that when you leave that scope (exiting the current program), the variables will no longer exist.
JustIan12 #4
Posted 09 July 2016 - 04:09 PM
So, I have brushed up the code and now what I need to ask is…

term.clear()
term.setCursorPos(1,1)
term.setTextColor(colors.blue)
print("ME Defence System")
term.setTextColor(colors.white)
-- Variables
local sensor = peripheral.wrap("left")
-- Main
while true do
local tPlayerLookup = {
  ["JustIan122"] = true,
}
if tPlayerLookup[ "JustIan122" ] then
  sleep(0.1)
else
  turtle.suck()
end
end

Opps ignore that :/
Bomb Bloke #5
Posted 10 July 2016 - 02:54 AM
There is a bit of a problem, in all the versions you've posted:

local tPlayerLookup = {["JustIan122"] = true}  -- Set key in table to true
if tPlayerLookup[ "JustIan122" ] then          -- Check if the key you just set to true is true

This in no way relies on sensor output! You need to check if the names the sensor detects are in your lookup table.

As to how to do that, the first step is to figure out how the results of sensor.getPlayers() are formatted…
TheRockettek #6
Posted 10 July 2016 - 07:04 AM
the title is such clickbate XD
JustIan12 #7
Posted 10 July 2016 - 11:33 AM
Yeah

XD

I am going to look into this so I can try and fix it because after I tested it with multiple people It only works relative to me.
Edited on 10 July 2016 - 09:38 AM
JustIan12 #8
Posted 10 July 2016 - 12:42 PM
sensor.getPlayers() is formatted in a table. I use the following command to read the table

sensor = peripheral.wrap("top")
pU = textutils.serialise(sensor.getPlayers())
write(pU)

I then get this written

{
   {
	 uuid = "755f4c9d-7c22-4dbf-beb2-d53a276df87",
	 name = "JustIan122",
    },
}

Essentially what I was trying to go for was table of white listed names. that the code would compare to the players that are being detected by the sensor if the player is not in the white list then the turtle will do something. As of now all the code as said above does not rely on sensor input it just relies on the value that I give so how would I convert this table to something I could compare to please

Thanks

- Light
Edited on 10 July 2016 - 10:42 AM
The Crazy Phoenix #9
Posted 10 July 2016 - 01:23 PM
If you're looking to programmatically read a table, textutils.serialize is the worst you could do…
Instead, try indexing the table using table[key], or using enhanced for loops (pairs or ipairs).
JustIan12 #10
Posted 10 July 2016 - 02:34 PM
ok

thank you
JustIan12 #11
Posted 10 July 2016 - 02:56 PM
Guys I don't get it…

term.clear()
term.setCursorPos(1,1)
term.setTextColor(colors.blue)
print("ME Defence System")
term.setTextColor(colors.white)
-- Database
local whitelist = {1 = "JustIan122"}
-- Variables
local sensor = peripheral.wrap("left")
-- Main
while true do
sensor.getPlayers()
if sensor.getPlayers() = table[1] then
  sleep(0.1)
else
  turtle.suckDown(10)
  turtle.dropUp(10)
end
end

I just get the error.

bios:14: [string "startup"]: '}'
expected

Even though there is clearly a } there.
Edited on 10 July 2016 - 12:56 PM
Bomb Bloke #12
Posted 10 July 2016 - 03:23 PM
You don't get the error because } is missing, so much as because something unexpected was encountered. In this case it's the number 1. You meant to do:

local whitelist = {[1] = "JustIan122"}  -- Note the additional square brackets

… but really you were better off with your earlier ["JustIan122"] = true structure.

As for dealing with your sensor data, the structure you indicated up here tells us that we can get the name of each player found by a given scan via this sort of code:

local players = sensor.getPlayers()

for i = 1, #players do    -- For each entry in the players table,
  print(players[i].name)  -- print the name found in the sub-table.
end

Now you need to consider how you want your system to act in response to the sensor's data. There are four scenarios to consider:
  • No players are detected.
  • A player on the whitelist is detected.
  • A player not on the whitelist is detected.
  • A player on the whitelist AND a player not on the whitelist are detected at the same time.
What actions do you intend to take in response to each of these four situations?
KingofGamesYami #13
Posted 10 July 2016 - 03:25 PM
You can't assign something in a table like that. You'd have to use square brackets, like this:

{[1] = JustIan122"}
Of course, this does the same thing:

{"JustIan122"}
However, I don't know why you're trying to change this. Your table before was much better for the intended purpose.
In addition, there are many things incorrect in your code. I will add my comments in-line.

term.clear()
term.setCursorPos(1,1)
term.setTextColor(colors.blue)
print("ME Defence System")
term.setTextColor(colors.white)
-- Database
local whitelist = {1 = "JustIan122"} --#as stated earlier, this is an invalid way to create a table.
-- Variables
local sensor = peripheral.wrap("left")
-- Main
while true do
  sensor.getPlayers() --#well, calling this and **not storing the result** is rather useless...
  if sensor.getPlayers() = table[1] then --# this will never be equal, as a table is *never* equal to a string
    sleep(0.1)
  else
    turtle.suckDown(10) --#not really sure why you're supplying 10, but presumably this works
    turtle.dropUp(10)
  end
end
I would recommend using a generic for loop to inspect each result from the sensor.
This would look something like this:

for i, result in ipairs( sensor.getPlayers() ) do --#this loops though the first layer of the table, "result" being something like {uuid = "755f4c9d-7c22-4dbf-beb2-d53a276df87", name = "JustIan122"}
  if result.name == "JustIan122" then --# this is assuming the serialized table you posted earlier is accurate. It shows a table of tables, in which are stored the name and UUID of the players found.
    print( "You're here!" )
  else
    print( "Someone else is here" )
  end
end
This code uses your name directly and does not support any additional players.

Edit: Removed double post
Edited on 10 July 2016 - 01:26 PM
The Crazy Phoenix #14
Posted 10 July 2016 - 04:12 PM
I wasn't clear enough in my previous post.

Inside a table, each key is mapped to a value. Assuming your table is called "whitelist", you can access the value stored under the key "Justlan122" by using the indexing operator, square brackets. For example, whitelist["Justlan122"] will retrieve the value under that key inside the whitelist table. You can also use variables. If you have a player name stored under the variable "player" then you could retrieve their value inside the table using whitelist[player] (notice the absence of quotes).

You can use this to your advantage by getting the player name and checking the value mapped to their username in the table. If there is no value mapped to it, you'll get nil.
JustIan12 #15
Posted 10 July 2016 - 05:10 PM
Ok, I shall now compile all this info into my code :P/>

thanks for helping :)/>