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

Multiple and/or statements

Started by KingofGamesYami, 01 July 2014 - 01:22 PM
KingofGamesYami #1
Posted 01 July 2014 - 03:22 PM
So, I'm making a map function, and in part of it it has a large amount of comparing, in which I need several or statements… What is the best way of comparing this? Do I need to write out a bunch more elsif statements, or is there an easier way? I don't think I can use multiple or statements, but maybe there is another way.

if l == tbl.y - 1 and line:sub( tbl.x, tbl.x ) == "#" then  --#I want to compare the character to #, U, or D.  But I really dont want to write out 12 more statements.
 --turtle should move forward
 return function() orient( "up" ) return turtle.forward() end, {x = tbl.x, y = tbl.y - 1, z = tbl.z}
elseif l == tbl.y and line:sub( tbl.x - 1, tbl.x - 1 ) == "#" then
 --turtle should move "left"
 return function() orient( "left" ) return turtle.forward() end, {x = tbl.x - 1, y = tbl.y, z = tbl.z}
elseif l == tbl.y and line:sub( tbl.x + 1, tbl.x + 1 ) == "#" then
 --turtle should move "right"
 return function() orient( "right" ) return turtle.forward() end, {x = tbl.x + 1, y = tbl.y, z = tbl.z}
elseif l == tbl.y + 1 and line:sub( tbl.x, tbl.x ) == "#" then
 --turtle should move back
 return function() orient( "down" ) return turtle.forward() end, {x = tbl.x, y = tbl.y + 1, z = tbl.z}
elseif oldChar:upper() == "U" then
 --turtle should move up
 return function() return turtle.up() end, {x = tbl.x, y = tbl.y, z = tbl.z + 1}
elseif oldChar:upper() == "D" then
 --turtle should move down
 return function() return turtle.down() end, {x = tbl.x, y = tbl.y, z = tbl.z - 1}
end
Bomb Bloke #2
Posted 01 July 2014 - 03:34 PM
Are you going for something along these lines?:

local compareTo = {"#","U","D"}

for i=1,#compareTo do
  if l == tbl.y - 1 and line:sub( tbl.x, tbl.x ) == compareTo[i] then
    .
    .
    .
  end
end

Or maybe something like this?:

local compareTo = {"#","U","D"}

-- Returns the index of a given value if it exists in a given table, or nil if it does not.
local function whereIn(targetTable, targetValue) for i=1,#targetTable do if targetTable[i] == targetValue then return i end end end

if l == tbl.y - 1 and whereIn(compareTo, line:sub( tbl.x, tbl.x )) then
.
.
.
KingofGamesYami #3
Posted 01 July 2014 - 08:59 PM
I could write a function to compare it yes,

local function compare( value )
 if value == "#" then
  return true
 elseif value:upper() == "D" then
  return true
 elseif value:upper() == "U" then
  return true
 else
  return false
 end
end
if l == tbl.y - 1 and compare( line:sub( tbl.x, tbl.x ) ) then

Edit: To give you an idea of how I'm using it, heres the rest of the code
Spoiler

function path( tMaps, _yield )
	--Find start
	local function findStart()
		for k, sMap in ipairs( tMaps ) do
			local l = 1
			for line in sMap:gmatch( '[^\r\n]+' ) do
				for i = 1, #line do
					if line:sub( i, i ):upper() == "X" then
						return {x = i, y = l, z = k}
					end
				end
				l = l + 1
			end
		end
	end
	--update removes already used path bits
	local function update( tbl )
		local l = 1
		local newString = {}
		local oldChar
		for line in tMaps[ tbl.z ]:gmatch( '[^\r\n]+' ) do
			if l == tbl.y then
				newString[l] = line:sub( 1, tbl.x - 1 ).." "..line:sub( tbl.x + 1, #line )
				oldChar = line:sub( tbl.x, tbl.x )
			else
				newString[l] = line
			end
			l = l + 1
		end
		return table.concat( newString, "\n" ), oldChar
	end
	--orient function
	local face = "up"
	local function orient( direction )
		if face == "up" and direction == "up" then
			return
		elseif face == "up" and direction == "right" then
			turtle.turnRight()
			face = "right"
		elseif face == "up" and direction == "left" then
			turtle.turnLeft()
			face = "left"
		elseif face == "up" and direction == "down" then
			turtle.turnRight()
			turtle.turnRight()
			face = "down"
		elseif face == "right" and direction == "up" then
			turtle.turnLeft()
			face = "up"
		elseif face == "right" and direction == "right" then
			return
		elseif face == "right" and direction == "left" then
			turtle.turnLeft()
			turtle.turnLeft()
			face = "left"
		elseif face == "right" and direction == "down" then
			turtle.turnRight()
			face = "down"
		elseif face == "left" and direction == "up" then
			turtle.turnRight()
			face = "up"
		elseif face == "left" and direction == "right" then
			turtle.turnRight()
			turtle.turnRight()
			face = "right"
		elseif face == "left" and direction == "left" then
			return
		elseif face == "left" and direction == "down" then
			turtle.turnLeft()
			face = "down"
		elseif face == "down" and direction == "up" then
			turtle.turnLeft()
			turtle.turnLeft()
			face = "up"
		elseif face == "down" and direction == "right" then
			turtle.turnLeft()
			face = "right"
		elseif face == "down" and direction == "left" then
			turtle.turnRight()
			face = "left"
		elseif face == "down" and direction == "down" then
			return
		end
	end
	--Find next position
	local function findNext( tbl )
		local oldChar
		tMaps[ tbl.z ], oldChar = update( tbl )
		local l = 1
		local function compare( value )
			if value == "#" then
				return true
			elseif value:upper() == "D" or value:upper() == "U" then
				return true
			end
		end
		--Check current level
		for line in tMaps[ tbl.z ]:gmatch( '[^\r\n]+' ) do
			if l == tbl.y - 1 and compare( line:sub( tbl.x, tbl.x ) ) then
				--turtle should move "up"
				return function() orient( "up" ) return turtle.forward() end, {x = tbl.x, y = tbl.y - 1, z = tbl.z}
			elseif l == tbl.y and compare( line:sub( tbl.x - 1, tbl.x - 1 ) ) then
				--turtle should move "left"
				return function() orient( "left" ) return turtle.forward() end, {x = tbl.x - 1, y = tbl.y, z = tbl.z}
			elseif l == tbl.y and compare( line:sub( tbl.x + 1, tbl.x + 1 ) ) then
				--turtle should move "right"
				return function() orient( "right" ) return turtle.forward() end, {x = tbl.x + 1, y = tbl.y, z = tbl.z}
			elseif l == tbl.y + 1 and compare( line:sub( tbl.x, tbl.x ) ) then
				--turtle should move "down"
				return function() orient( "down" ) return turtle.forward() end, {x = tbl.x, y = tbl.y + 1, z = tbl.z}
			elseif oldChar:upper() == "U" then
				return function() return turtle.up() end, {x = tbl.x, y = tbl.y, z = tbl.z + 1}
			elseif oldChar:upper() == "D" then
				return function() return turtle.down() end, {x = tbl.x, y = tbl.y, z = tbl.z - 1}
			end
			l = l + 1
		end		
	end
	local place = findStart()
	local path = {}
	while place do
		path[#path + 1], place = findNext( place )
	end
	path.x = 1
	path.yield = _yield
	local mt = {
	__call = function()
		if path[ path.x ] and path.yield then
			local success = path[ path.x ]()
			path.x = path.x + 1
			return success
		elseif path[ path.x ] then
			repeat
				path[ path.x ]()
				path.x = path.x + 1
			until not path[ path.x ]
		else
			return false
		end
	end,
	}
	setmetatable( path, mt )
	return path
end
Edited on 01 July 2014 - 07:04 PM
theoriginalbit #4
Posted 02 July 2014 - 02:34 AM
why not make a lookup table with anonymous functions?
KingofGamesYami #5
Posted 02 July 2014 - 02:43 PM
I actually just thought of something that (might) be slightly better

local compare = {
 ["#"] = true, --#like this?
 D = true,
 U = true,
 d = true,
 u = true,
}
if <statement> and compare[ value ] then
</statement>
Edited on 02 July 2014 - 01:00 PM
theoriginalbit #6
Posted 02 July 2014 - 02:51 PM
except you'd need to put that # into a string, otherwise Lua will complain.