Omnimaga
Calculator Community => TI Calculators => TI-BASIC => Topic started by: yunhua98 on October 27, 2010, 05:22:02 pm
-
I thought it would be good if we compiled a list of all the awesome BASIC tricks, and optimization stuff. ;)
so we'd just post, and it would be easy to find hints and other cool stiff to make a more efficient and awesome program. Also, ask if you don't understand a routine. ;)
So I'll start:
I make this myself, but I think I read this one from ztrumpet somewhere. ;)
in game subroutines:
:Goto 2
:Lbl 1
:<stuff>
:End
:Lbl 2
:While <condition>
:<stuff>
:Goto 1
:End
Greyscale-ish/Wave-ish RPG effect:
This really doesn't have that may uses, but the wave effect looks kinda cool. ;)
have Shade(-10,10) somewhere in the beginning and noting else in the graph screen, or have people download the pic, then:
:For(A,1,40
:DispGraph/RclPic 1, depending on what your doing
:Disp
:End
Thats all I've got for now, but I'm sure you guys will come up with more! ;)
-
Oho Great, thanks for the shadow info.
BTW, I wish there was a 'goto' function in all programming languages, TI Basic is cool for that :)
-
Well, Goto eats memory, whihc is probably why most languages don't have it anymore, or its just now used. ;)
but doesn't Python have Goto? or am I confused?
-
Well, Goto eats memory, whihc is probably why most languages don't have it anymore, or its just now used. ;)
but doesn't Python have Goto? or am I confused?
no, python doesn't have goto... :(
-
Pause for an amount of time
rand(X
X is a number.
-
that's what was used in that portal game in BASIC on ticalc...
basically, it works by returning a random number between 0-1 X number of times (I believe when x=40 it takes ~= 1 second on a 15 mhz calc)
-
Thats my Portal game :D And yeah, with rand(#) the # is the length of a List of random numbers to be generated. More elements means more random numbers means a lot slower :)
-
There is also that old thread containing TI-BASIC tricks, but I will not merge it with this one, because it also covers assembly and other stuff, it seems. http://ourl.ca/2627
Plus there is http://web.archive.org/web/20071023204415/omnimaga.org/index.php?showforum=7 as well, but most links might either be slow or not working.
Just thought I would add those to this thread too, in case someone wants to paste them into here or find additional tricks ;)
My favorite tricks are Circle(X,Y,Radius,{i and Text(-1,Y,X,"Stuff. They're well known among experienced coders now that they are documented on TI-BD, but not as much to newer coders, since they were never documented by TI themselves. Note that the i after the { is the imaginary i when pressing 2nd then dot. The first tricks display circles about 4 times faster than normal and the second one displays large fonts on graph screen, useful for dual-layer ASCII graphics. Text(-1 doesn't work with Omnicalc fonts, though.
-
whoa, why does the Circle one work?
An efficient way to jump without Goto:
:Delvar KRepeat K=21
:<stuff>
:Repeat K=21 or K=105
:getkey->K
:End
:End
this is useful for when you want a back and a go on option. ;) of course you can replace the keycodes and stuff though. ;)
-
The fast circles are supposedly less accurate, but I barely notice any difference and if there is, then it's not that bad considering the low 96x64 resolution. It's an undocumented TI-BASIC trick.
-
Yeah, they are pretty nice.
Honestly, I think the fast circles look better when being drawn and when fully drawn compared to the regular circle drawing method.
-
Well, Goto eats memory, whihc is probably why most languages don't have it anymore, or its just now used. ;)
There are some programs where you face the choice of either rewriting all of the code or using one goto.
-
Or you just get in the practice of writing without them. Using loops isn't all that difficult.
-
True. Using Gotos is fine in certain situations, though, but I recommend avoiding them as much as possible, especially in large programs.
-
Or you just get in the practice of writing without them. Using loops isn't all that difficult.
In the team program, there's a section of code that just can't be done efficiently without a Goto unless a memory leak is acceptable. I looked at that section half a dozen times trying to not use the Goto, but it just doesn't work. Goto occasionally has uses beyond loops.
-
whoa, why does the Circle one work?
An efficient way to jump without Goto:
:Delvar KRepeat K=21
:<stuff>
:Repeat K=21 or K=105
:getkey->K
:End
:End
this is useful for when you want a back and a go on option. ;) of course you can replace the keycodes and stuff though. ;)
This can be optimized even more by doing:
DelVar KRepeat K=21
\\code\\
Repeat 42=abs(K-63
getKey→K
End
End
-
You can also remove the Delvar K, since Repeat is a post-test loop. It's also a bad practice to put a loop control statement in the middle of a line, because it can screw with the parser if it has to skip over all this code for some reason (for example, if it is contained in a large If/Then/End block and the If condition is false)
-
What do you mean by loop control statement in the middle of a line? Could you show a good and bad code example?
-
What do you mean by loop control statement in the middle of a line? Could you show a good and bad code example?
Middle of a line:
:DelVar AIf A
:Return
Not middle of a line:
:DelVar A
:If A
:Return
Not middle of a line:
:DelVar A:If A:Return
I think the problem mainly occurs if End is placed in the middle of a line.
-
Oh ok you mean how you can omit the : character. Yeah I know about that trick, I just was used to just saying "omitting the : char" :P
-
There a couple of really handy things you can do for optimizations.
If K=1 or K=2 or K=3 or K=4 or K=5
\Do something.\
Can be...
If max(K={1,2,3,4,5
\Do something.\
(Not mine, I think I saw Nemo do it first but I don't know if it predates him doing it where I saw.)
If K=21 or K=105
\Do something.\
Can be...
If 42=abs(K-63
\Do something.\
However this one does not always work. You have to test and make sure. The basic algorithm to figure out the numbers is (Keycode #1+Keycode #2)/2 and that will give you the number to subtract by. Then you just subtract one of the keycodes by it and it will give you the number that they will equal. (Example: 105+21=126/2=63 then 105-63=42 and 21-63=-42 which |-42|=42).
(I don't take credit for this optimization. It's Ztrumpet's as far as I know.)
X+(K=26)-(K=24
Ans-(Ans=17)+not(Ans→X
Y+(K=34)-(K=25
Ans-(Ans=9)+not(Ans→Y
Can be...
min(16,max(1,X+sum(⌂List(K={24,26→X
min(8,max(1,Y+sum(⌂List(K={25,34→Y
(Not sure who I saw this from but it was a while ago but calc84maniac talked about this method a few weeks ago on HCWP.)
31(A>1)+31(A>2)+31(A>3)+31(A>4
Can be...
31sum(A>{1,2,3,4
0
For(A,1,dim(L1
Ans+(C=L1(A
End
If Ans
\Do something.\
(Note: this is untested but it's basically supposed to check a list if it holds the value of variable and if it does it will do something.)
Can be...
If max(C=L1
\Do something.\
(I don't remember who this was that showed this but I feel like it was Player...might have been Nemo though. I don't remember though.)
Well that's all for now. If I think of anymore off the top of my head I will post them.
-
If K=1 or K=2 or K=3 or K=4 or K=5
\Do something.\
Can be...
If max(K={1,2,3,4,5
\Do something.\
(Not mine, I think I saw Nemo do it first but I don't know if it predates him doing it where I saw.)
If K=21 or K=105
\Do something.\
Can be...
If 42=abs(K-63
\Do something.\
However this one does not always work. You have to test and make sure. The basic algorithm to figure out the numbers is (Keycode #1+Keycode #2)/2 and that will give you the number to subtract by. Then you just subtract one of the keycodes by it and it will give you the number that they will equal. (Example: 105+21=126/2=63 then 105-63=42 and 21-63=-42 which |-42|=42).
(I don't take credit for this optimization. It's Ztrumpet's as far as I know.)
I'm pretty sure the first one is Weregoose's and the second on is Luby's or HarrierFalcon's from UTI.
X+(K=26)-(K=24
Ans-(Ans=17)+not(Ans→X
Y+(K=34)-(K=25
Ans-(Ans=9)+not(Ans→Y
Can be...
min(16,max(1,X+sum(⌂List(K={24,26→X
min(8,max(1,Y+sum(⌂List(K={25,34→Y
(Not sure who I saw this from but it was a while ago but calc84maniac talked about this method a few weeks ago on HCWP.)
This stems from a discussion somewhere on TIBD.
-
Ah ok, I didn't know about the first one but ya, I remember the TIBD thing now. Thanks :)
-
I did a few tests today which broke some of my long held beliefs about speed.
The access time of Ans is the same as the access time for regular variables. So for instance both of these take the same time to execute:
Ans+Ans/Ans = Ans
A+A/A = A
But, this is faster: (N refers to the finance N)
N+N/N = N
This second rule holds true for any system variable so Xmin, ZXmin, TblStart, etc. are all fair game.
However, when it comes to store time:
1 is faster than 1->N which is faster than 1->A
Which means that Ans can be just as fast as the system variables as long as it is the only variable used.
These will execute in nearly the same speed: (The Ans version is like 2% faster)
1:Disp Ans |vs.| 1->N:Disp N
This is only interesting news though if you don't care about program size. N is 2 bytes while Ans is only 1. Not to mention that your code becomes nearly unreadable if you start using the ZXmin and ZYmax variables.
-
I knew that the finance variables were faster. How did you do the tests to determine which was the fastest?
-
Thank you ThePenguin! Because of you, Exodus and Elmgon will be able to progress a lot easier; I didn't know I could use the ZXmin and other variables like it. I needed more speed and more variables. ;D
-
Here is the complete testing code:
:startTmr
:Repeat startTmr=Ans+1 ;this is to ensure that the test starts exactly on a second, not halfway through
:End
:startTmr->A
:For(B,1,6000
:<Code goes here>
:End
:Disp checkTmr(A
Here are the real times:
:1 16
:1->N 19
:1->A 22
:Ans 19
:A 19
:N 16
And then the big one with 15,000 iterations:
:1
:Ans 65
:1->N
:N 67
-
Here is the complete testing code:
:startTmr
:Repeat startTmr=Ans+1 ;this is to ensure that the test starts exactly on a second, not halfway through
:End
:startTmr->A
:For(B,1,6000
:<Code goes here>
:End
:Disp checkTmr(A
That's awesome. I really like the repeat loop at the beginning. ;D
-
Wow nice tricks guys. One thing about Meishe's tricks, though: weren't those slower?
-
Wow nice tricks guys. One thing about Meishe's tricks, though: weren't those slower?
I don't know. I haven't noticed to much. If anything they are space savers though.
-
Yeah. I just heard somewhere that for the 4 directional key detection they were much slower than the larger way.
-
Ya, I think I remember that but I don't think it's that much slower, personally.
-
Well, it actually made a big difference in games like Illusiat 13, apparently (someone modified it once to check). Like under 2 FPS framerate during walking instead of over 3.
-
Is it me of is Goto sometimes faster than While/Repeat...? O.O
Make two programs, each having the following code at the very start:
1->A
While 1
rand
A+1->A
End
1->A
Lbl 1
rand
A+1->A
Goto 1
This Goto speed gain over While/Repeat only happens if the Lbl is at the very start of the program.
A For loop is even faster since I can then remove the A+1->A line, but if it's code with no variable incrementing, then For seems slightly slower than Goto (although faster than While/Repeat).
Could someone else run those tests to confirm? Although the speed gain would be negligible for large code, maybe it could be a slight speed boost in some cases (although the Title/menu code would need to be placed below the gameplay one, with a Goto at the very start of the program.
-
Another idea is to have a subprogram for the main game.
-
Convert Hex to Dec
DelVar SInput Str1
For(I,1,length(Str1
inString("0123456789ABCDEF",sub(Str1,I,1))-1 -> C
S+C16^(length(Str1))-I -> S
End
S