Two things really.
The first is pretty straight-forward.
If you look at your web address and see ?cat=7 at the end, you are not getting the full picture of Pico-8 posts ! Remove that, change it to:
https://www.lexaloffle.com/bbs/ |
and reload to see more than just carts.
The 2nd is the rub. I want to create a function.
The function has 3-arguments.
First is the number entered, second is the low end number, third is the high end number.
What you want to do is return a value based upon the three where the 1st wraps neatly around the 2nd and 3rd.
So if for instance you had (-1,0,7)
The result would be 7.
If you had (8,1,6)
The result would be 2.
Now before you dive head on into this understand it is more complex than it seems. Here for instance are some people trying to solve it. But by reading it, it certainly left me in the cold.
https://stackoverflow.com/questions/707370/clean-efficient-algorithm-for-wrapping-integers-in-c
Now I THINK I could write one myself where the number of iterations would be based upon the absolute value range of the initial value from the edges, but that would be slow and cumbersome. And if you had numbers up to a thousand for instance it would be very slow indeed.
What is your perfect fast and small Pico-8 code for this tricky programming question ? And yes this would doubtless aid any other programmers who see it; full credit to you. We could all use an efficient function for this.
FWIW, I got to this post with the cat=7 at the end and it's not a cart :).
>> "We could all use an efficient function for this."
This may be true, but I have no idea what problem it solves or what is meant by "the 1st wraps neatly around the 2nd" or why blah(8,1,6) would return 2 as a result of whatever "wraps neatly" means, so I might not be part of the "all" this function is meant for :).
Hi @2bitchuck.
I saw a few posts appear that do not with the "cat=7" I think they were blog entries. In any case, if you don't wanna miss, don't filter to cat=7.
Let me see if I can explain the other - in code:
Look at that code, especially near the bottom. If you run the code you will see that if your ship goes too far left it will appear on the right and vice-versa.
While this is a relatively simple example of WRAPPING a number, they can be more complex, for instance where you want to wrap let's say -674 around 48 and 1272.
to visual it a little bit more:
y=warp(x,0,4)
x=-9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 y= 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 |
maybe not the shortest or best solution, but easy to understand:
function warp(value, low, high) range=high-low+1 while value<low do value += range end while value>high do value -= range end return value end cls() ? warp(-1,0,7) ? warp(8,1,6) |
edit:
short version would be:
function warp2(value,low,high) return (value-low)%(high-low +1)+low end |
Let's try it out ...
Great what you did here, @GPI ! Pretty fast too. I went and put a print routine inside to debug the loops and yeah those loops are spinning quite madly.
I think what the guys in C++ were doing was trying to make it a single calculation - which may be impossible - is why they couldn't agree upon the code and it just kept getting more and more tangled.
Yours does work and is excellent. The early bird gets the worm, or in the case, the credit. Nicely done ! I'm working on a simple game ATM where I want a wrap routine, credit to you, but later carts that WRAP is going to be working with some large figures indeed.
Now if you can do wrap() entirely through calculations minus the loops that would be something to see. I'm just hazarding a guess it would use MOD %
You just did this ! Checking it now.
?warp(-13,-2,4)
-14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 0 1 2 3 4 -2 -1 0 1 2 3 4 -2 -1 0 1 2 3 4 -2 -1 |
I think you've got it so ... now I'm confused. Why is it the boys at C++ were having such a nightmare with this ? I based their difficulty upon my difficulty in solving it. I even tried taking their code and converting it to Pico-8 - and - unless I miss my guess, you have solved it using none of theirs.
Some other people may want to run your code through a gauntlet to see if it stands up to robust use and won't break.
All I can say is I am pleasantly surprised you solved it so quickly, @GPI ! :)
Perhaps @zep might even add WRAP as a numeric function for future Pico-8 using your very method that few it seems have been able to solve.
The reason why in c it is a little bit more complex is simple.
in c "-1 % 2" can be "-1" or "1", in lua/pico8 "-1 % 2" is "1".
So you don't need to care about negative values any more in this kind of code.
see https://www.lua.org/manual/5.1/manual.html#2.5.1
it is defined like this:
function mod(a,b)
return a - flr(a/b)*b
end
but C++ it is more complex, see https://www.geeksforgeeks.org/modulo-operator-in-c-cpp-with-examples/
"The sign of the result for modulo operator is machine-dependent for negative operands, as the action takes as a result of underflow or overflow. "
so in C negative values are not really defined and different from compiler to compiler...
Well doesn't that take the cake, @GPI. Different modulos ?
So perhaps those geeks needed to work on writing a modulos function first and then tackle the wrap-around. :)
In any case all glory goes to you, @GPI, for seeing through the differences in programming languages and saving me a large headache trying to figure out how to wrap effectively when they could not.
Thanks so much for your help !
Reading this page ... https://www.lua.org/manual/5.1/manual.html#2.5.1
Now, @2bitchuck. Type out the following in your address bar:
https://www.lexaloffle.com/bbs/?cat=7
Then go to page 2 and look for the title, "Adventures in data compression"
It will not appear !
Remove the ?cat=7 , go to page 2, and it will appear then. So, yes, cat=7 is filtering results.
The best way to ensure you are getting the "whole picture" is to click on the animated "cube of people" icon in the top-left-hand corner at the top of every single Lexaloffle page. Confirm "?cat=7" does not appear. Your results WILL be filtered if that extra text is part of your address field.
Lexaloffle BBS > PICO-8 BBS
cat=7 == PICO-8 BBS
cat=6 == Voxatron BBS
cat=5 == Jasper's Journeys BBS
cat=4 == Chocolate Castle BBS
cat=3 == Zen Puzzle Garden BBS
cat=2 == Lexaloffle specific posts maybe?
cat=1 == User account blog posts
You can download the games in your Lexaloffle downloads page if you own the games.
@MBoffin, where can I purchase or acquire (if they are free) 3, 4, or 5 ?
They are not listed on the main page.
https://www.lexaloffle.com
No idea, sorry! They've just always been there for me. Maybe because I got the original Lexaloffle Humble Bundle like a million years ago? Not sure.
@MBoffin. You have no idea where they are. Disappointing ... in any case I'll start a new thread of their actual location - now that I know.
This past week, I actually had to solve this for the screen-wrapping in my UFO game. The formula I came up with was:
function bugged_scaled_mod(_n,_min,_max) return ((_n-_min)%(_max-_min))+_min -- EDIT: Note this has a bug! end |
Thank you for showing me that I was off by 1 @GPI !
I had actually noticed the bug for one of my callers but stupidly didn't realize my scaled_mod function itself was bugged. I simply passed in max+1 for that single caller :face_palm:
Nicely done, @merwok. I'll add NEKO PUZZLE to the list. The others unfortunately do not seem to have download or for-purchase links.
That list can be found HERE:
Just a note -- Another incredibly useful application for this type of function (besides screen wrapping) is accessing 1-indexed tables/arrays:
function table_mod(t, i, a) -- table, current iteration, increment amount if a==nil then a=1 end return t[scaled_mod(i/a,1,#t)] end |
EDIT - just be sure to use this corrected version of scaled_mod from GPI (not the one I defined above!)
function scaled_mod(_n,_min,_max) return ((_n-_min)%(_max-_min +1))+_min end |
[Please log in to post a comment]