LÖVE crashes, when using a function in ipairs() - function

I was running an experiment on whether or not I am able to use autogenerating seeds in LÖVE, but I'm running into a problem. It crashes, when I try to add tiles into the game through a table using ipairs.
Can anybody see the problem with this code?:
world = {}
function world.generate()
for i = 1, 100 do
world.addTile(i, love.math.random(1, 3), 1)
end
local tempWorld = world
for i,v in ipairs(tempWorld) do
world.addTile(v.x, v.y+1, 1)
end
end
function world.addTile(x, y, id)
for i,v in ipairs(tile) do
if v.id == id then
table.insert(world, {id = id, x = x*tile.w, y = y*tile.h})
else
print("The following id was not recognised: "..id)
end
end
end
function world.draw()
for i,v in ipairs(world) do
love.graphics.draw(tile.getImage(v.id), v.x, v.y)
end
end

You have an infinite loop.
local tempWorld = world does not copy world, it just creates another reference to it. So when world has another item added by world.addTile the for loop:
for i,v in ipairs(tempWorld) do
world.addTile(v.x, v.y+1, 1)
end
has a new stopping point since ipairs has one more item to iterate. This repeats until you run out of memory. You may want to save the size of the old list instead:
local oldsize = #world
for i=1, oldsize do
local v = world[i]
world.addTile(v.x, v.y+1, 1)
end
And now it wont iterate more than oldsize times.

Related

Is it impossible to assign output argument after completion of recursive loop in the function of MATLAB?

When the below function is executed, I get the following error message "Output argument "max_idx" (and maybe others) not assigned during call to "find_node"."
I think the problem is in the fact that some output is produced after recursive loop. How can I solve this?
function max_idx = find_node(wt)
persistent all_idx_max;
node_degree=sum(wt,2);
maxval = max(node_degree);
all_nodes_with_max_val = ismember(node_degree,maxval);
idx_max = find(all_nodes_with_max_val);
if isempty(all_idx_max)
all_idx_max=1:8;
end
if size(idx_max,1)==3
max_idx=all_idx_max(idx_max(1))
elseif size(idx_max,1)>1
all_idx_max=idx_max;
find_node(wt(idx_max,idx_max)); <--problem happens in this path
else
max_idx=all_idx_max(idx_max)
end
I forgot to add output to the recursive part
function max_idx = find_node(wt)
persistent all_idx_max;
node_degree=sum(wt,2);
maxval = max(node_degree);
all_nodes_with_max_val = ismember(node_degree,maxval);
idx_max = find(all_nodes_with_max_val);
if isempty(all_idx_max)
all_idx_max=1:8;
end
if size(idx_max,1)==3
max_idx=all_idx_max(idx_max(1))
elseif size(idx_max,1)>1
all_idx_max=idx_max;
***max_idx =*** find_node(wt(idx_max,idx_max)); <--problem happens in this path
else
max_idx=all_idx_max(idx_max)
end

Better way than using `Task/produce/consume` for lazy collections express as coroutines

It is very convenient to use Tasks
to express a lazy collection / a generator.
Eg:
function fib()
Task() do
prev_prev = 0
prev = 1
produce(prev)
while true
cur = prev_prev + prev
produce(cur)
prev_prev = prev
prev = cur
end
end
end
collect(take(fib(), 10))
Output:
10-element Array{Int64,1}:
1
1
2
3
5
8
13
21
34
However, they do not follow good iterator conventions at all.
They are as badly behaved as they can be
They do not use the returned state state
start(fib()) == nothing #It has no state
So they are instead mutating the iterator object itself.
An proper iterator uses its state, rather than ever mutating itself, so they multiple callers can iterate it at once.
Creating that state with start, and advancing it during next.
Debate-ably, that state should be immutable with next returning a new state, so that can be trivially teeed. (On the other hand, allocating new memory -- though on the stack)
Further-more, the hidden state, it not advanced during next.
The following does not work:
#show ff = fib()
#show state = start(ff)
#show next(ff, state)
Output:
ff = fib() = Task (runnable) #0x00007fa544c12230
state = start(ff) = nothing
next(ff,state) = (nothing,nothing)
Instead the hidden state is advanced during done:
The following works:
#show ff = fib()
#show state = start(ff)
#show done(ff,state)
#show next(ff, state)
Output:
ff = fib() = Task (runnable) #0x00007fa544c12230
state = start(ff) = nothing
done(ff,state) = false
next(ff,state) = (1,nothing)
Advancing state during done isn't the worst thing in the world.
After all, it is often the case that it is hard to know when you are done, without going to try and find the next state. One would hope done would always be called before next.
Still it is not great, since the following happens:
ff = fib()
state = start(ff)
done(ff,state)
done(ff,state)
done(ff,state)
done(ff,state)
done(ff,state)
done(ff,state)
#show next(ff, state)
Output:
next(ff,state) = (8,nothing)
Which is really now what you expect. It is reasonably to assume that done is safe to call multiple times.
Basically Tasks make poor iterators. In many cases they are not compatible with other code that expects an iterator. (In many they are, but it is hard to tell which from which).
This is because Tasks are not really for use as iterators, in these "generator" functions. They are intended for low-level control flow.
And are optimized as such.
So what is the better way?
Writing an iterator for fib isn't too bad:
immutable Fib end
immutable FibState
prev::Int
prevprev::Int
end
Base.start(::Fib) = FibState(0,1)
Base.done(::Fib, ::FibState) = false
function Base.next(::Fib, s::FibState)
cur = s.prev + s.prevprev
ns = FibState(cur, s.prev)
cur, ns
end
Base.iteratoreltype(::Type{Fib}) = Base.HasEltype()
Base.eltype(::Type{Fib}) = Int
Base.iteratorsize(::Type{Fib}) = Base.IsInfinite()
But is is a bit less intuitive.
For more complex functions, it is much less nice.
So my question is:
What is a better way to have something that works like as Task does, as a way to buildup a iterator from a single function, but that is well behaved?
I would not be surprised if someone has already written a package with a macro to solve this.
The current iterator interface for Tasks is fairly simple:
# in share/julia/base/task.jl
275 start(t::Task) = nothing
276 function done(t::Task, val)
277 t.result = consume(t)
278 istaskdone(t)
279 end
280 next(t::Task, val) = (t.result, nothing)
Not sure why the devs chose to put the consumption step in the done function rather than the next function. This is what is producing your weird side-effect. To me it sounds much more straightforward to implement the interface like this:
import Base.start; function Base.start(t::Task) return t end
import Base.next; function Base.next(t::Task, s::Task) return consume(s), s end
import Base.done; function Base.done(t::Task, s::Task) istaskdone(s) end
Therefore, this is what I would propose as the answer to your question.
I think this simpler implementation is a lot more meaningful, fulfils your criteria above, and even has the desired outcome of outputting a meaningful state: the Task itself! (which you're allowed to "inspect" if you really want to, as long as that doesn't involve consumption :p ).
However, there are certain caveats:
Caveat 1: The task is REQUIRED to have a return value, signifying the final element in the iteration, otherwise "unexpected" behaviour might occur.
I'm assuming the devs chose the first approach to avoid exactly this kind of "unintended" output; however I believe this should have actually been the expected behaviour! A task expected to be used as an iterator should be expected to define an appropriate iteration endpoint (by means of a clear return value) by design!
Example 1: The wrong way to do it
julia> t = Task() do; for i in 1:10; produce(i); end; end;
julia> collect(t) |> show
Any[1,2,3,4,5,6,7,8,9,10,nothing] # last item is a return value of nothing
# correponding to the "return value" of the
# for loop statement, which is 'nothing'.
# Presumably not the intended output!
Example 2: Another wrong way to do it
julia> t = Task() do; produce(1); produce(2); produce(3); produce(4); end;
julia> collect(t) |> show
Any[1,2,3,4,()] # last item is the return value of the produce statement,
# which returns any items passed to it by the last
# 'consume' call; in this case an empty tuple.
# Presumably not the intended output!
Example 3: The (in my humble opinion) right way to do it!.
julia> t = Task() do; produce(1); produce(2); produce(3); return 4; end;
julia> collect(t) |> show
[1,2,3,4] # An appropriate return value ending the Task function ensures an
# appropriate final value for the iteration, as intended.
Caveat 2: The task should not be modified / consumed further inside the iteration (a common requirement with iterators in general), except in the understanding that this intentionally causes a 'skip' in the iteration (which would be a hack at best, and presumably not advisable).
Example:
julia> t = Task() do; produce(1); produce(2); produce(3); return 4; end;
julia> for i in t; show(consume(t)); end
24
More Subtle example:
julia> t = Task() do; produce(1); produce(2); produce(3); return 4; end;
julia> for i in t # collecting i is a consumption event
for j in t # collecting j is *also* a consumption event
show(j)
end
end # at the end of this loop, i = 1, and j = 4
234
Caveat 3: With this scheme it is expected behaviour that you can 'continue where you left off'. e.g.
julia> t = Task() do; produce(1); produce(2); produce(3); return 4; end;
julia> take(t, 2) |> collect |> show
[1,2]
julia> take(t, 2) |> collect |> show
[3,4]
However, if one would prefer the iterator to always start from the pre-consumption state of a task, the start function could be modified to achieve this:
import Base.start; function Base.start(t::Task) return Task(t.code) end;
import Base.next; function Base.next(t::Task, s::Task) consume(s), s end;
import Base.done; function Base.done(t::Task, s::Task) istaskdone(s) end;
julia> for i in t
for j in t
show(j)
end
end # at the end of this loop, i = 4, and j = 4 independently
1234123412341234
Interestingly, note how this variant would affect the 'inner consumption' scenario from 'caveat 2':
julia> t = Task() do; produce(1); produce(2); produce(3); return 4; end;
julia> for i in t; show(consume(t)); end
1234
julia> for i in t; show(consume(t)); end
4444
See if you can spot why this makes sense! :)
Having said all this, there is a philosophical point about whether it even matters that the way a Task behaves with the start, next, and done commands matters at all, in that, these functions are considered "an informal interface": i.e. they are supposed to be "under the hood" functions, not intended to be called manually.
Therefore, as long as they do their job and return the expected iteration values, you shouldn't care too much about how they do it under the hood, even if technically they don't quite follow the 'spec' while doing so, since you were never supposed to be calling them manually in the first place.
How about the following (uses fib defined in OP):
type NewTask
t::Task
end
import Base: start,done,next,iteratorsize,iteratoreltype
start(t::NewTask) = istaskdone(t.t)?nothing:consume(t.t)
next(t::NewTask,state) = (state==nothing || istaskdone(t.t)) ?
(state,nothing) : (state,consume(t.t))
done(t::NewTask,state) = state==nothing
iteratorsize(::Type{NewTask}) = Base.SizeUnknown()
iteratoreltype(::Type{NewTask}) = Base.EltypeUnknown()
function fib()
Task() do
prev_prev = 0
prev = 1
produce(prev)
while true
cur = prev_prev + prev
produce(cur)
prev_prev = prev
prev = cur
end
end
end
nt = NewTask(fib())
take(nt,10)|>collect
This is a good question, and is possibly better suited to the Julia list (now on Discourse platform). In any case, using defined NewTask an improved answer to a recent StackOverflow question is possible. See: https://stackoverflow.com/a/41068765/3580870

(Corona SDK) Call function once from an "enterFrame" function

I'm wondering how it would be possible to call a function once from an "enterFrame" function in Corona SDK.
Let's say i have:
local function funa()
i = i+1
funb()
end
Runtime:addEventListener("enterFrame", funa)
Besides wanting 'i' to be incremented each frame, I also want to run "funb", but only one time instead of one time for each frame, but I can't find out how to do that.
Any ideas?
Besides the simpler and more obvious solution of using a global variable to keep track of this, you can use a closure. Example:
local
function funa()
local run_already = false
local i = 0
return function()
i = i+1
if not run_already then
funb()
run_already = true
end
end
end
funa = funa()
funa()
funa()
local run_flag = false
local function funa()
i = i+1
if not run_flag then
funb()
run _flag = true
end
end
Runtime:addEventListener("enterFrame", funa)
Now i will incremented each frame , but function will be called once.

Attempting to make a random choice in Lua

This is what I have so far, but it seems that everytime I attempt to run it, it closes.
function wait(seconds)
local start = os.time()
repeat until os.time() > start + seconds
end
function random(chance)
if math.random() <= chance then
print ("yes")
elseif math.random() > chance then
print ("no")
end
random(0.5)
wait(5)
end
That is the full context.
Theres a few problems with that code, the first (as Lorenzo Donati points out) is that you've wrapped the actual invocations inside of random(), giving you a chunk that never actually does anything (woops).
The second is that you are invoking math.random() twice, giving you two separate values; this means that its perfectly possible for neither test to be true.
The third is minor: You are making two tests for an either-or choice; the first test would tell us everything we need to know:
function wait(seconds)
local start = os.time()
repeat until os.time() > start + seconds
end
function random(chance)
local r = math.random()
if r <= chance then
print ("yes")
else
print ("no")
end
end
random(0.5)
wait(5)
and just for kicks, we can replace the if-block with a conditional value, thus:
function wait(seconds)
local start = os.time()
repeat until os.time() > start + seconds
end
function random(chance)
local r = math.random()
print(r<=chance and "yes" or "no")
end
random(0.5)
wait(5)
Probably you meant to write this:
function wait(seconds)
local start = os.time()
repeat until os.time() > start + seconds
end
function random(chance)
if math.random() <= chance then
print ("yes")
elseif math.random() > chance then
print ("no")
end
end
random(0.5)
wait(5)

Tips for function inside while loop and i=i+1, Matlab

I have a problem with a function in matlab. This specific function is for filtering light signals. As you can see below I added the coding I’ve used in the function and in the while loop itself. The code is written for a NXT Lego robot.
Is there any tip how to get the count variable ( i = i + 1 ) to work in the function, so we can plot Light(i)? Because we’re getting a bunch of error messages when we try different codes to make it work.
function [light] = filter_func( i)
lightI(i) = GetLight(SENSOR_3);
if i==1
light(i)=lightI(i)
elseif i==2
light(i) = 0.55*lightI(i) + 0.45*lightI(i-1)
else
light(i) = 0.4*lightI(i) + 0.3*lightI(i-1) + 0.3*lightI(i-2);
end
end
i=1
while true
lightI(i) = GetLight(SENSOR_3); % Get’s a lightvalue between 0 and 1024.
if i>2
light =filter_func(i)
light=round(light);
else
light(i) = GetLight(SENSOR_3);;
end
i=1+i
plot(light(end-90:end), 'r-');
title('Lightvalue')
axis([0 100 0 1023]) ;
end
You probably mainly get errors because you are not allowed to mix script and functions like this in MATLAB (like you are in Python).
Your filter function is only used when i>2 so why are you doing the first 2 tests? It seems like you want lightI as a global variable, but that is not what you have done. The lightI inside the function is not the same as the one in the while loop.
Since your while loop runs forever, maybe you don't need to worry about updating the plot the first two times. In that case you can do this:
filter = [0.4 0.3 0.3]';
latest_filtered_light = nan(90,1);
lightI = [];
p = plot(latest_filtered_light, 'r-');
title('Lightvalue')
axis([0 100 0 1023]) ;
while True
lightI(end+1,1) = rand*1024; % Get’s a lightvalue between 0 and 1024.
if i>=3
new_val = lightI(end-2:end,1)'*filter;
latest_filtered_light = [latest_filtered_light(2:end);...
new_val];
set(p, 'ydata', latest_filtered_light)
drawnow
end
end
I think it is an important point to not call plot every time - at least if you are the least concerned about performance.