Lua: Search key in table, increment index if not and retry - checkbox

Situation:
table = { this, that, something else, x_coord, y_coord }
table.x_coord = { 1,2,3,4,7,8,n}
table.y_coord = { 2,4,5,9,n} -- numbers aren't fix
table.check_boxes = { [12] = a function,
[14] = a function,
[15] = a function,
[24] = a function,
[29] = a function,
....(n) }
As you can see, the x/y_coords forming check_boxes. For example:
table.x_coord[1]..table.y_coord[1] ~ table.check_boxes[1]
I use this to move the cursor in the Terminal between the check_boxes.
The problem now is in my cursormovement.
Currently I got a function that's searching for the next x/y_coord to the left/right/up/down depending on the given input (arrow-keys).
With return/space I call the function behind the checkbox.
Now, that could set the Cursor on positions where no check_boxes are given. Actually that's not a big deal, because when input == space/return, an inputhandler calls the function at
table.check_boxes[table.x_coorx[x_index]..table.y_coords[y_index]]
So if the cursor doesn't point on a function, just nothing happens.
But now I want the cursor to be forced to the next check_box. What can I do?
My Idea so far:
following function either for x or y, depending on input left/right up/down:
while true do
for k, v in pairs(table.check_boxes) do
if(table.x_coord[x_index] .. table.y_coord[y_index] == k then break end
end -- break -> okay, coord is at a checkbox
x_index = x_index + 1 -- or -1
if table.x_coord[x_index] == nil then
x_index = 1
end
end
The Problem now is that the last if will not allow cases like x_coord = {1,3} because it will set x_index to 1 if 2 is reached.
Any tips?
Edit:
Now I got that one going:
function cursorTioNextBoxRight()
searc_index = x_index
search = true
while search do
search_index = search_index + 1
if search_index > #table.x_coord then
search_index = 1
end
for k, v in pairs(table.check_boxes) do
if tonumber(table.x_coord[search_index..table.y_coord[y_index] == k then
x_index = search_index -- YAAAY
search = false
break
end
end
end
I'ts damn slow.

local x_newIndex = x_index + 1 --[[ or -1 --]]
x_index = table.x_coord[x_newIndex] and x_newIndex or x_index
x_index becomes x_newIndex when x_newIndex exists in the table otherwise it stays the old x_index

function cursorTioNextBoxRight()
searc_index = x_index
search = true
while search do
search_index = search_index + 1
if search_index > #table.x_coord then
search_index = 1
end
for k, v in pairs(table.check_boxes) do
if tonumber(table.x_coord[search_index..table.y_coord[y_index] == k then
x_index = search_index -- YAAAY
search = false
break
end
end
end

Related

Lua/LOVE indexing problems

I'm getting a very irritating error whenever I do anything like this with arrays. I have code that sets up the array in the love.load() function:
function iceToolsInit()
objectArray = {} --for object handling
objectArrayLocation = 0
end
and then code that allows for the creation of an object. It basically grabs all of the info about said object and plugs it into an array.
function createObject(x, y, renderimage) --used in the load function
--objectArray is set up in the init function
objectArrayLocation = objectArrayLocation + 1
objectArray[objectArrayLocation] = {}
objectArray[objectArrayLocation]["X"] = x
objectArray[objectArrayLocation]["Y"] = y
objectArray[objectArrayLocation]["renderimage"] =
love.graphics.newImage(renderimage)
end
After this, an update function reads through the objectArray and renders the images accordingly:
function refreshObjects() --made for the update function
arrayLength = #objectArray
arraySearch = 0
while arraySearch <= arrayLength do
arraySearch = arraySearch + 1
renderX = objectArray[arraySearch]["X"]
renderY = objectArray[arraySearch]["Y"]
renderimage = objectArray[arraySearch]["renderimage"]
if movingLeft == true then --rotation for rightfacing images
renderRotation = 120
else
renderRotation = 0
end
love.graphics.draw(renderimage, renderX, renderY, renderRotation)
end
end
I of course clipped some unneeded code (just extra parameters in the array such as width and height) but you get the gist. When I set up this code to make one object and render it, I get this error:
attempt to index '?' (a nil value)
the line it points to is this line:
renderX = objectArray[arraySearch]["X"]
Does anyone know what's wrong here, and how I could prevent it in the future? I really need help with this.
It's off-by-one error:
arraySearch = 0
while arraySearch <= arrayLength do
arraySearch = arraySearch + 1
You run through the loop arrayLength+1 number of times, going through indexes 1..arrayLength+1. You want to go through the loop only arrayLength number of times with indexes 1..arrayLength. The solution is to change the condition to arraySearch < arrayLength.
Another (more Lua-ly way) is to write this as:
for arraySearch = 1, #objectArray do
Even more Lua-ly way is to use ipairs and table.field reference instead of (table["field"]):
function refreshObjects()
for _, el in ipairs(objectArray) do
love.graphics.draw(el.renderimage, el.X, el.Y, movingLeft and 120 or 0)
end
end
objectArray and movingLeft should probably be passed as parameters...

insert array using graphical interface in matlab

I want to insert an array using a graphical interface, but I don't understand why I get these errors:
Error using waitfor
Undefined function or variable 'A'.
Error using waitfor
Error while evaluating uicontrol Callback
THE CODE:
function read()
clear all
clc
n=2;
b=50;
a=300;
B = nan(n);
S.fh = figure('units','pixels',...
'position',[500 500 500 500],...
'menubar','none',...
'numbertitle','off',...
'name','Matrix',...
'resize','off');
for i=1:n
for j=1:n
A(i,j) = uicontrol('style','edit','units','pixels',...
'position',[b a 50 50],'fontsize',20,'string','',...
'Callback', 'B(A == gco) = str2double(get(gco, ''string''));');
b = b+60;
end
b = 50;
a = a-60;
end
S.bb = uicontrol('style','push',...
'units','pixels',...
'position',[300 10 75 50],...
'fontsize',14,...
'string','Done',...
'callback','close');
waitfor(S.fh)
B
Instead of using callbacks for all the edit boxes separately, I recommend a single callback that reads all the values on the button. For instance:
function read()
clear all
clc
n=2;
b=50;
a=300;
% A = zeros(n);
S.fh = figure('units','pixels',...
'position',[500 500 500 500],...
'menubar','none',...
'numbertitle','off',...
'name','Matrix',...
'resize','off');
for i=1:n
for j=1:n
A(i,j) = uicontrol('style','edit','units','pixels',...
'position',[b a 50 50],'fontsize',20,'string','');
% no callback for the edit boxes
b = b+60;
end
b = 50;
a = a-60;
end
S.bb = uicontrol('style','push',...
'units','pixels',...
'position',[300 10 75 50],...
'fontsize',14,...
'string','Done',...
'callback',#(~,~)(readvalues(A,n)));
% callback that reads all the values in one run
% (and closes the figure as you wanted)
waitfor(S.fh)
function readvalues(A,n)
B = zeros(n);
for i=1:n
for j=1:n
B(i,j) = str2double(get(A(i,j), 'String'));
end
end
disp(B)
close

Corona SDK array index is beyond array bounds, advice needed

I will try to as concise as possible with my issue.
Firstly, files are:
block.lua
base.lua
main.lua
In block.lua I create a block, add collision detection and a cleanup code.
In base.lua I create a base made up of 4 columns and 10 rows. 40 blocks in total.
In main.lua I create 4 bases made from the base.class.
All is working fine once the game begins.
I remove the bases and call them again on level 2.
They create themselves ok BUT
when the enemy is destroyed once again, and the bases are to be rebuilt, I get an:
array index 1 is beyond array bounds:1..1
-- all the way up to--
array index 800 is beyond array bounds:1..159
it will then create the bases and continue until the enemys are destroyed and do the same again starting at :
array index 800 is beyond array bounds:1..159
-- all the way up to--
array index 4000 is beyond array bounds:1..159
The terminal points me at block.lua line 23
blockGroup:insert(blockNum,self.block)
Now I cant see anything wrong in the class, I have looked and googled for hours but all to no avail.
I would really appreciate a helping hand to guide me here please.
I have tried rewriting the "cleanup" etc but no joy.
I left a few commented out bits in there and removed some of the irrelevant stuff.
I post below the relevant code:
--MAIN.LUA--
function gameOver()
Runtime:removeEventListener("enterFrame", onEnterFrame)
Runtime:removeEventListener("enterFrame", movePlayer)
layers:removeSelf()
layers = nil
enemyCount = 0
for i = 1,#allEnemys do
timer.cancel(allEnemys[i].clock)
Runtime:removeEventListener( "enterFrame", allEnemys[i] )
display.remove(allEnemys[i].image)
allEnemys[i].image=nil
end
allEnemys=nil
cleanupBlocks()
end
----------------------------------------------------------------------
-- LEVEL UP --
----------------------------------------------------------------------
function levelUp(level)
enemyCount = 0
local enemys = require("modules.enemy")
if allEnemys ~= nil then
for i = 1,#allEnemys do
timer.cancel(allEnemys[i].clock)
Runtime:removeEventListener( "enterFrame", allEnemys[i] )
display.remove(allEnemys[i].image)
allEnemys[i].image=nil
end
end
allEnemys=nil
cleanupBlocks()
levels()
end
----------------------------------------------------------------------
-- LEVELS --
----------------------------------------------------------------------
function levels(level)
function createInvader(x, y, row)
for j = 1, 2 do
for i = 1, 2 do
if allEnemys == nil then
allEnemys = {}
else
enemysCount=#allEnemys
end
allEnemys[#allEnemys + 1] = enemys:new()
allEnemys[#allEnemys ]:init(i * 60, j * 70 + 70,j)
allEnemys[#allEnemys ]:start()
end
end
end
createInvader()
--[[function createBases1()
local base = require("modules.base")
for i = 1, 4 do
base:new()
base:init(i * 180 - 130, 850)
end
end ]]--
createBases()
end
--BLOCK.LUA--
local block = {}
local block_mt = { __index = block}
local scene = scene
local blockGroup = display.newGroup()
local blockNum = 0
function block:new() -- constructor
local group = {}
return setmetatable( group, block_mt )
end
function block:init(xloc,yloc) --initializer
-- Create attributes
self.block = display.newRect( xloc,yloc,10,10)
self.block:setFillColor ( 2, 255, 14 )
blockNum = blockNum + 1
blockGroup:insert(blockNum,self.block)
local blockCollisionFilter = { categoryBits = 128, maskBits = 387}
physics.addBody( self.block, "static", {filter = blockCollisionFilter})
self.count = 1
end
function cleanupBlocks()
--[[ print(blockNum, blockGroup.numChildren)
for i=1,blockGroup.numChildren do
blockGroup[1]:removeSelf()
blockGroup[1] = nil
end ]]--
print(blockNum, blockGroup.numChildren)
while blockGroup.numChildren>0 do
display.remove(blockGroup[1])
blockGroup[1]=nil
end
end
function block:start()
--- Create Listeneres
self.block:addEventListener( "collision", self )
scene:addEventListener('base_block_event', self)
end
return block
--BASE.LUA--
local base = {}
local base_mt = { __index = base}
local scene = scene
local block = require("modules.block")
function base:new() -- constructor
local group = {}
return setmetatable( group, base_mt )
end
function base:init(xloc, yloc) --initializer
-- Create attributes
local base
for j = 1, 4 do
for i = 1, 10 do
base = block:new()
base:init(xloc+i * 10,yloc+j * 10)
base:start()
end
end
end
return base
I see you use
blockNum = blockNum + 1
blockGroup:insert(blockNum,self.block)
Try to use
blockGroup:insert(self.block)
just to see if you still get that error.

Matlab: stepping through an array and incrementing from one value to the next

I have an array:
step1 = [0,0;
0,1;
1,1;
2,3;
3,4;
3,5;
3,6;
3,7;
4,7;
5,7;
6,7;
6,6;
6,5;
6,4;
6,3;
6,2;
5,1];
I want to step through this array and create new arrays for the row and column that increment by 0.1 from one row to another. This is what I did:
z=1;
u=length(step1);
step_b4X = zeros(u,1);
step_b4Y = zeros(u,1);
while z <= length(step1)
step_b4X = step_presentX;
step_presentX(z,1) = step1(z,1);
step_b4Y = step_presentX;
step_presentY(z,1) = step1(z,2);
pathX = step_b4X:0.1:step_presentX;
pathY = step_b4Y:0.1:step_presentY;
z = z+1;
end
I get zeros.
I want pathX = 0:0.1:0....pathY = 0:0.1:1
next pathX = 0:0.1:1....pathY = 1:0.1:1... and so on
If you do
start:increment:end
where start == end, you'll get a scalar equal to start (which is logical).
If you want pathX and pathY to have the same length at each iteration, you'll have to do this:
z = 1;
while z <= length(step1)
currentX = step(z,1); nextX = step(z+1,1);
currentY = step(z,2); nextY = step(z+1,2);
pathX = currentX : 0.1 : nextX;
pathY = currentY : 0.1 : nextY;
if numel(pathX) == 1
pathX = repmat(pathX, numel(pathY),1); end
if numel(pathY) == 1
pathY = repmat(pathY, numel(pathX),1); end
z = z+1;
end
Now you'll have the right arrays at each iteration, that you'll use directly or save in a cell-array for later. If you want everything in one big array, add this to the end of the loop:
pathX_final = [pathX_final; pathX];
pathY_final = [pathY_final; pathY];
and initialize them as empty before the loop, of course.
Alternatively (much cleaner and possibly a bit faster), ditch the whole loop and use interp1:
x = step1(:,1);
y = step1(:,2);
xx = interp1(1:numel(x), x, 1:0.1:numel(x));
yy = interp1(1:numel(y), y, 1:0.1:numel(y));

how can i use checkboxes which gets value from database in a loop?

I have a table in database.In that table , there is an unknown number of rows.I want to put
checkboxes but number of checkboxes should be equal to the Number of rows. Thus i tried to do it in while loop. I found number of rows which exists in table.It's rowNumber.Then , i did a while loop.At this point , there is a serial failure. Because when i clicked any checkbox , the row below is called with last m value.
cbox[m] = checkBox.new(checkX, txtY, sendRows[m], col,
Because after exiting while loop , m equals rowNumber. And when any checkboxes is clicked , it doesn't know which row is clicked because m = rowNumber. I tried many things but i can't do it. What should i do ?? Should i give up using loop? IF i give up using it how can do it?
Here is the code which i can't fixed
local m = 1
while(m<rowNumber)
cbox[m] = checkBox.new(checkX, txtY, sendRows[m], col,
function(this)
local state = this:getCheck()
if state then
print(m .. " checked")
gonder[m] = 1
else
print(m .. " does not checked")
gonder[m] = 0
end
end
)
screen:addChild(cbox[m])
cbox[m]:setCheck(settings.getMusicState())
txtY = txtY + gap
print ("gonder[m] = " .. gonder[m])
end
If the code is written as in the below,it runs correctly:
cbox[1] = checkBox.new(checkX, txtY, sendRows[1], col,
function(this)
local state = this:getCheck()
if state then
print(1.. " checked")
gonder[1] = 1
else
print(1 .. " does not checked")
gonder[1] = 0
end
end
)
screen:addChild(cbox[1])
cbox[1]:setCheck(settings.getMusicState())
txtY = txtY + gap
cbox[2] = checkBox.new(checkX, txtY, sendRows[2], col,
function(this)
local state = this:getCheck()
if state then
print(2.. " checked")
gonder[2] = 1
else
print(2 .. " does not checked")
gonder[2] = 0
end
end
)
screen:addChild(cbox[2])
cbox[2]:setCheck(settings.getMusicState())
txtY = txtY + gap
.
.
.
.
It is solved after changing the inside of while as this:
while( m<rowNumber + 1)
do
cbox[m] = checkBox.new(checkX, txtY, sendRows[m], col,
function(this)
end
)
screen:addChild(cbox[m])
txtY = txtY + gap
m = m + 1
end
And the important point is here. Here , we are sending what we want:
submitt:addEventListener("click",
function()
local mydata={}
local i=1
while (i<rowNumber+1) do
mydata[3*i-2]=cbox[i].checked--1. Holds whether it is true or false
mydata[3*i-1]=sendRows2[i]
mydata[3*i] = sendURL[i]
i=i+1
end
sceneManager:changeScene("results", 1, SceneManager.flipWithFade, easing.outBack,mydata)
stage:removeChild(submitt)--after clicked , the button disappears
end)

Resources