This line thorwing an Error im trying to create magic link for practice but this line throwing an error
end expected error but i cant find where to put
You have an elseif at the top of the function. Maybe that should be an if?
Sometimes the language parser gets thrown off track and an error in one spot does not surface until later in the code. Missing end statements often causes this.
I am a bit puzzled why the compiler does not choke on the elseif. Chances are that you have another error further up the file that will surface when you fix the elseif.
still the same problem occuring
Can you post the full script?
sure
go.property("timer", 0) -- Use to time events
local blocksize = 80 -- Distance between block centers
local edge = 40 -- Left and right edge.
local bottom_edge = 50 -- Bottom edge.
local boardwidth = 7 -- Number of columns
local boardheight = 9 -- Number of rows
local centeroff = vmath.vector3(8, -8, 0) -- Center offset for connector gfx since there's shadow below in the block img
local dropamount = 3 -- The number of blocks dropped on a "drop"
local colors = { hash("orange"), hash("pink"), hash("blue"), hash("yellow"), hash("green") }
--
-- filter(function, table)
-- e.g: filter(is_even, {1,2,3,4}) -> {2,4}
--
local function filter(func, tbl)
local new = {}
for i, v in pairs(tbl) do
if func(v) then
new[i] = v
end
end
return new
end
--
-- Build a list of blocks in 1 dimension for easy filtering
--
local function build_blocklist(self)
self.blocks = {}
for x, l in pairs(self.board) do
for y, b in pairs(self.board[x]) do
table.insert(self.blocks, { id = b.id, color = b.color, x = b.x, y = b.y })
end
end
end
--
-- INIT
--
function init(self)
self.board = {} -- Contains the board structure
self.blocks = {} -- List of all blocks. Used for easy filtering on selection.
self.chain = {} -- Current selection chain
self.connectors = {} -- Connector elements to mark the selection chain
self.num_magic = 3 -- Number of magic blocks on the board
self.drops = 1 -- Number of drops you have available
self.magic_blocks = {} -- Magic blocks that are lined up
self.dragging = false -- Drag touch input
msg.post(".", "acquire_input_focus")
msg.post("#", "start_level")
end
local function build_board(self)
math.randomseed(os.time())
local pos = vmath.vector3()
local c
local x = 0
local y = 0
for x = 0,boardwidth-1 do
pos.x = edge + blocksize / 2 + blocksize * x
self.board[x] = {}
for y = 0,boardheight-1 do
pos.y = bottom_edge + blocksize / 2 + blocksize * y
-- Calc z
pos.z = x * -0.1 + y * 0.01
c = colors[math.random(#colors)]-- Pick a random color
local id = factory.create("#blockfactory", pos, null, { color = c })
self.board[x][y] = { id = id, color = c, x = x, y = y }
end
end
-- Build 1d list that we can easily filter.
build_blocklist(self)
end
function on_message(self, message_id, message, sender)
if message_id == hash("start_level") then
build_board(self)
end
end
function on_input(self, action_id, action)
if action_id == hash("touch") and action.value == 1 then
-- What block was touched or dragged over?
local x = math.floor((action.x - edge) / blocksize)
local y = math.floor((action.y - bottom_edge) / blocksize)
if x < 0 or x >= boardwidth or y < 0 or y >= boardheight or self.board[x][y] == nil then
-- outside board.
return
end
if action.pressed then
-- Player started touch
msg.post(self.board[x][y].id, "make_orange")
self.dragging = true
elseif self.dragging then
-- then drag
msg.post(self.board[x][y].id, "make_green")
end
elseif action_id == hash("touch") and action.released then
-- Player released touch.
self.dragging = false
end
end
local function same_color_neighbors(self, x, y)
local f = function (v)
return (v.id ~= self.board[x][y].id) and
(v.x == x or v.x == x - 1 or v.x == x + 1) and
(v.y == y or v.y == y - 1 or v.y == y + 1) and
(v.color == self.board[x][y].color)
end
return filter(f, self.blocks)
end
local function in_blocklist(blocks, block)
for i, b in pairs(blocks) do
if b.id == block then
return true
end
end
return false
end
function on_input(self, action_id, action)
-- If trying to manipulate magic blocks, ignore.
if self.board[x][y].color == hash("magic") then
return
end
if action.pressed then
-- List of neighbors of the same color as touched block
self.neighbors = same_color_neighbors(self, x, y)
self.chain = {}
table.insert(self.chain, self.board[x][y])
p = go.get_position(self.board[x][y].id)
local id = factory.create("#connectorfactory", p + centeroff)
table.insert(self.connectors, id)
self.dragging = true
elseif self.dragging then
-- then drag
if in_blocklist(self.neighbors, self.board[x][y].id) and not in_blocklist(self.chain, self.board[x][y].id) then
-- dragging over a same-colored neighbor
table.insert(self.chain, self.board[x][y])
self.neighbors = same_color_neighbors(self, x, y)
-- Mark block.
p = go.get_position(self.board[x][y].id)
local id = factory.create("#connectorfactory", p + centeroff)
table.insert(self.connectors, id)
end
end
local function remove_chain(self)
-- Delete all chained blocks
for i, c in ipairs(self.chain) do
self.board[c.x][c.y] = hash("removing")
go.delete(c.id)
end
self.chain = {}
end
local function nilremoved(self)
for y = 0,boardheight - 1 do
for x = 0,boardwidth - 1 do
if self.board[x][y] == hash("removing") then
self.board[x][y] = nil
end
end
end
end
local function slide_board(self)
-- Slide all remaining blocks down into blank spots.
-- Going column by column makes this easy.
local dy = 0
local pos = vmath.vector3()
for x = 0,boardwidth - 1 do
dy = 0
for y = 0,boardheight - 1 do
if self.board[x][y] ~= nil then
if dy > 0 then
-- Move down dy steps
self.board[x][y - dy] = self.board[x][y]
self.board[x][y] = nil
-- Calc new position
self.board[x][y - dy].y = self.board[x][y - dy].y - dy
go.animate(self.board[x][y-dy].id, "position.y", go.PLAYBACK_ONCE_FORWARD, bottom_edge + blocksize / 2 + blocksize * (y - dy), go.EASING_OUTBOUNCE, 0.3)
-- Calc new z
go.set(self.board[x][y-dy].id, "position.z", x * -0.1 + (y-dy) * 0.01)
end
else
dy = dy + 1
end
end
end
-- blocklist needs updating
build_blocklist(self)
end
function on_input(self, action_id, action)
if action_id == hash("touch") and action.released then
-- Player released touch.
self.dragging = false
if #self.chain > 1 then
-- There is a chain of blocks. Remove it from board and slide the remaining blocks down.
remove_chain(self)
nilremoved(self)
slide_board(self)
end
for i, c in ipairs(self.connectors) do
go.delete(c)
end
self.connectors = {}
end
end
end
You have 3 on_input()functions. There should be only one. The second one is the one causing the problem since the function lacks a matching end.
can you highlight that problems in my code
Sure, see comments in the code:
function on_input(self, action_id, action)
-- If trying to manipulate magic blocks, ignore.
if self.board[x][y].color == hash("magic") then
return
end
if action.pressed then -- <--- BEGINNING OF 'if'.
-- List of neighbors of the same color as touched block
self.neighbors = same_color_neighbors(self, x, y)
self.chain = {}
table.insert(self.chain, self.board[x][y])
p = go.get_position(self.board[x][y].id)
local id = factory.create("#connectorfactory", p + centeroff)
table.insert(self.connectors, id)
self.dragging = true
elseif self.dragging then
-- then drag
if in_blocklist(self.neighbors, self.board[x][y].id) and not in_blocklist(self.chain, self.board[x][y].id) then
-- dragging over a same-colored neighbor
table.insert(self.chain, self.board[x][y])
self.neighbors = same_color_neighbors(self, x, y)
-- Mark block.
p = go.get_position(self.board[x][y].id)
local id = factory.create("#connectorfactory", p + centeroff)
table.insert(self.connectors, id)
end
end -- <--- END OF 'if'!
-- <--- Here the function ends, but there is no 'end'
local function remove_chain(self)
-- Delete all chained blocks
...
This is the syntax error. The bigger problem is that you have 3 on_input functions. You can only have 1.
okay let me try