Attempting to make a random choice in Lua - function

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)

Related

Error: On Activation: Select: Type: Nothing expected, Array,String,Config entry when running specified code in Arma 3

So, my issue is whenever I run this code block within a trigger with condition any player,
private _all_freedom_units = ["B_FRD_Freedomer_Patrolman_01","B_FRD_Freedomer_Sniper_01", "B_FRD_Freedomer_Exo_1", "B_FRD_Freedomer_Warrior_01", "B_FRD_Freedomer_SEVA_01", "B_FRD_Freedomer_Gaurdian_01", "B_FRD_Freedomer_Seva_II_01"];
private _final_pos = [0,0,0];
private _position_player = [0, 0, 0];
_direction = getDir player;
if (_direction > 0 and _direction < 90) then {cardinal_direction = "North";};
if (_direction > 90 and _direction < 180) then {cardinal_direction = "South";};
if (_direction > 180 and _direction < 250) then{cardinal_direction = "South";};
if (_direction > 250 and _direction < 359) then{cardinal_direction = "North";};
_position_player = getPos player;
_position_player_x = _position_player select 0;
_position_player_y = _position_player select 1;
if (cardinal_direction == "North") then{
_random_x = [250, 500] call BIS_fnc_randomInt;
_random_y = [250, 500] call BIS_fnc_randomInt;
_final_pos set [0 , _position_player_x + 200 + _random_x];
_final_pos set [1 , _position_player_y + 200 + _random_y];
};
if (cardinal_direction == "South") then{
_random_x = [-250, -500] call BIS_fnc_randomInt;
_random_y = [-250, -500] call BIS_fnc_randomInt;
_final_pos set [0 , _position_player_x + _random_x];
_final_pos set [1 , _position_player_y + _random_y];
};
_position = _final_pos;
_group_freedom_patrol = createGroup [west, true];
hint str _final_pos select 0;
_random_number = floor random 5;
The editor returns with,
On Activation: Select: Type Nothing, expected Array,String,Config entry
I have a suspicion from similar reports that it's centered around these statements
_position_player = getPos player;
_position_player_x = _position_player select 0;
_position_player_y = _position_player select 1;
Because of the "select" aspect of the error code, but I just started Arma 3 scripting
A similar post recommended dealing with the Condition portion of the Trigger, but the fixes their didn't work. I'm not quite sure what the issue is at this point, as I'm new to Arma 3 scripted.
The big issue here is I'm 90% sure it's an issue with syntax, because if it was logic the trigger would allow me to use the code in the first place. In this case, the built in checks are barring me from running the code, and syntax errors are harder than logic for me.
The code is intended to run properly, grab the first player who enters the trigger, and using the position data and angle it should (this part of the code isn't included as I'm testing in chunks and this chunk isn't working) spawn units in front of the player, min 250 out, heading towards them,
But as I explained previously, the Arma 3 debugger is yelling at me before I can even test the code.
Take this with a grain of salt, I haven't scripted for Arma 3 for quite the time.
I think if the errors comes up in the editor, then it may be because the player may not be defined (makes sense in the editor). You should check that. Either way - to make it multiplayer compatible - you should use the the "thisList" variable to access the list of the objects which are in the trigger area. If this only triggers for players, then you can use "thisList select 0".
See the passed variables for On Activation in the documentation

How to restart a function when an if condition is met

How do I "restart" my function when an if condition is or isn't met.
In this pseudocode, if the if condition is met, I would like to stop what the function was doing and restart again.
function example()
.
.
.
for i in 1:N
for j in 1:N
if Mat[i,j] > 1
Mat[i,j] += restart? # Here the process should restart,
end
end
end
Rather than adding additional branching and complicating a function, return values offer a great ability for control flow in I.M.H.O. much cleaner fashion.
Adding a little separate function is simple
function do_thing_once!(mat)
# Returns true if successful
for i in 1:N
for j in 1:N
if mat[i,j] > 1
mat[i,j] += 123
return false
end
end
end
return true
end
function do_all_things!(mat)
success = false
while !success
success = do_thing_once!(mat)
end
end

(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.

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

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.

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.