Login [Register]
Don't have an account? Register now to chat, post, use our tools, and much more.
Homescreen Vertical Scrolling Engine

I created a nice homescreen vertical scrolling engine for the TI-83+ family. It's specifically written for the CSE, however I will comment with changes if you want to make it a monochrome engine. I intend to use this to make a CSE game of some sort, but I'll have to think.
(I know that there are some quotes left in, but that's for the formatting of the code blocks)

Uses all variables in the DelVar line at the end.

Code:
ClrHome
"XXXXXXXXXXXXXXXXXXXXXXXXXX"→Str1 ;26 Xs for the top boundary, remove 10
For(θ,1,10          ; you could change the third argument to any number (be careful though!), but for the CSE I used 10.
Str1+"X                        X"→Str1 ;24 spaces for the inside, remove 10
End
Str1+"XXXXXXXXXXXXXXXXXXXXXXXXXX"→Str1 ;same deal as the first 26 Xs.
53→A:260→B ; Change B to 8*16 or 128. Change A to ((third For( argument + 2) - maximum amount of lines on the homescreen) *26 or 16) + 1. So for this example, ((12-10)*26)+1=53.
Output(1,1,sub(Str1,A,B
12→V:9→W                       ;change W to 7
Repeat K=105:getKey→K
If K:Output(W,V," "
min(25,max(2,V+sum(DeltaList(K={24,26→V  ;change the number in min( to 15
min(9,max(2,W+sum(DeltaList(K={25,34→W  ;change the number in min( to 7
Output(W,V,"O"
If 2=Wnot(A<3) or 9=Wnot(A>51:Then:A-26(W=2)+26(W=9→A:If not(A:1→A:3(W=2)+8(W=9→W    ;change all "W=9" to W=7 (including "9=Wnot(A>51" and the -26 and +26 to -/+16
Output(1,1,sub(Str1,A,B
End
:End
DelVar ADelVar BDelVar KDelVar VDelVar WDelVar Str1
Nice work, 123outerme! Smile This could certainly be useful. I added in collision detection for walls (Or 'X's in this case), which is easily modifiable for things like collectibles or something. I imagine it could be a tad more optimized, but oh well. Smile


Code:
ClrHome
"XXXXXXXXXXXXXXXXXXXXXXXXXX"
For(X,1,10
Ans+"X                        X"
End:Ans+"XXXXXXXXXXXXXXXXXXXXXXXXXX"->Str1
53->A:12->V:9->W
Output(1,1,sub(Str1,A,260
Repeat K=105:getKey->K
If K:Then:W->C:V->D
V+(K=26)-(K=24->V
W+(K=34)-(K=25->W
If inString("X",sub(Str1,A+V+26W-27,1
Then:C->W:D->V:End
If 2=W(A>=3) or 9=W(A<=51:Then
A-26(W=2)+26(W=9
If Ans<=0:1:Ans->A
3(W=2)+8(W=9->W
Output(1,1,sub(Str1,A,B
End:Output(C,D," "
End:Output(W,V,"O"
End


The above comments also still hold. Of course, now you have to do region checking, but that is useful if you want to leave a level or something. Smile
KermMartian wrote:
Bitwise XOR/AND/OR of Two Integers

The following code was created by Weregoose (see this topic) for XORing two integers together. A and B are the arguments, and the output is returns in Ans.
Weregoose wrote:
If you want to retool this into another bitwise operation, go to the "=" and substitute it with "<" for AND, or "≤" for OR.

Code:
:int(log(2)⁻ąlog(max({A,B
:2^cumSum(binomcdf(Ans,0
:sum(Ans.5(1=abs(int(2fPart(Ans⁻ą(A+Bi


This is almost surely the smallest way to do it, but when the size of the integers is known, its speed can be improved.

At http://tibasicdev.wikidot.com/forum/t-780769/bitwise-operators
Weregoose suggests, when the integers are 32-bit, to
"Store 2^cumSum(binomcdf(31,0→listname on the side, then use the third line from [what I quoted] (substituting listname for Ans). At 32 bits, this takes 0.448 seconds to execute on a fresh TI-84+SE."
I stored it into L₁; this method takes 0.55 seconds on my 84+ to calculate 0x33333333 xor 0x55555555 (in decimal: 858993459 xor 1431655765), of course not counting precomputing of the list.

At the cost of a byte due to the necessary *, rearranging means we don't need to multiply the whole list by .5. Note that this is a rare case in which L₁⁻ą(A+Bi is faster than (A+Bi)/L₁, probably because it's real list*complex float.

Code:
//0.52 seconds
.5sum(L₁*(1=abs(int(2fPart(L₁⁻ą(A+Bi


We can also compute both .5Ans and Ans⁻ą instead—store them into L₁ and L₂ respectively. Multiplication is faster than division.

Code:
//0.42 seconds
sum(L₁*(1=abs(int(2fPart(L₂*(A+Bi


Now, since we're working on a list of 32 numbers, abs( is moderately expensive, and overhead is small. So complex numbers are unnecessary when optimizing for speed.

Code:
//0.30 seconds
sum(L₁*(.5≤fPart(AL₂) xor .5≤fPart(BL₂


Remember that X≥.5 is equal to, when 0≤X≤1, round(X,0), and also the identity A xor B = A+B-2(A and B). Now we have:

Code:
//xor (0.28 to 0.285 seconds)
A+B-2sum(L₁round(min(fPart(AL₂),fPart(BL₂)),0

//and (0.27 to 0.275 seconds)
sum(L₁round(min(fPart(AL₂),fPart(BL₂)),0

//or (0.275 to 0.280 seconds)
sum(L₁round(max(fPart(AL₂),fPart(BL₂)),0

Can anyone do better, maybe with a lookup table? I have 0.24 seconds using a 16x16 matrix as in the thread I linked to, but the code is ugly and the matrix is 2317 bytes.

EDIT: Factoring out 2^-13 from the list helps with speed. Where E=2^-13 and L₂=2^(13-cumsum(binomcdf(31,0))), this is as fast as the matrix method:

Code:
//and (0.242 seconds)
sum(L₁round(min(fPart(AEL₂),fPart(BEL₂)),0))
Insert to/pop from a list at a certain index
    Inputs:
    - L₁ = list to manipulate
    - A = Index to insert at/pop from (starts at 1)
    - B = Value to insert (if applicable)

    Outputs:
    Ans = L₁ = modified list


Code:

//POP
For(C,A+1,dim(L1
L1(C->L1(C-1
End
dim(L1)-1->dim(L1
//INSERT
For(C,1+dim(L1),A,~1
L1(C-not(not(C-1->L1(C //could also be "L1(C-(0 xor C-1->L1(C", but this saves a byte
End
B->L1(A
M. I. Wright, it's usually not a good idea to loop over lists when seq( applies. I believe this is the standard method, found at http://tibasicdev.wikidot.com/forum/t-661155/how-to-delete-single-value-in-a-list#post-1796150:

Code:
//Remove element at pos. N (by Weregoose). To get the value, just store it first.
seq(L1(X+(X≥N)),X,1,dim(L1)-1→L1
//Insert (optmized by calc84)
If N≤dim(L1 //next line would error if N=dim(L1)+1; smaller than piecewise
seq(L1(X+(X<N)),X,0,dim(L1→L1
B→L1(N


Here's another method of note: http://tibasicdev.wikidot.com/forum/t-575692/variable-problem#post-1593505

In general, a stack or list that resizes every time an element is stored or retrieved (as in http://tibasicdev.wikidot.com/stack) is very slow, so try to use a pointer instead.

Edit: Changed first formula to use list index properly.
Edit: Thanks, calc84. That works as it should.
I think the insert could be slightly more optimized like this:

Code:
//Insert
If N≤dim(L1  // Use this line only if you want to be able to insert at dim(L1)+1
seq(L1(X+(X<N)),X,0,dim(L1→L1
B→L1(N
Frequency of a certain number in a list
Store your list in L₁, and the number you want to find the frequency of in X (meaning the actual number, not where it is in L₁).
Frequency ends up in Ans.

Code:

sum(not(seq(L1(Z)(L1(Z)!=X),Z,1,dim(L1

If the number you want to find the frequency of is 0, this can be simplified to

Code:

sum(not(L1



edit: I'm a complete idiot. See lirtosiast's post below.

Code:
 sum(L1=X
Return a decimal number from a list containing a binary number
Hopefully more efficient than my last two contributions to this thread.

Takes L1 as input, being a list containing a binary number with each element of the list being a single binary digit.

Outputs a decimal number in Ans.

Code:

sum(seq(L1(dim(L1)-I)B^I,I,0,dim(L1)-1

For instance, an input of {1,1,0,1} would output 13.

This complements Weregoose's routine for converting a number (N) to base B:

Code:
int(BfPart(NB^seq(I,I,~int(ln(N)/ln(B))-1,~1

Storing 2->B and a number to N then storing this to L1 will give a list compatible with my routine.

There's probably a way to adapt mine to output to more bases, but I have school in a few minutes so I can't work that out.
This is shorter and faster for binary list evaluation:
Code:
sum(L1B^(dim (L1)-cumsum(1 or L1
I found a problem with one of the lines of code from the Change Case of a String - one of the 26's should be a 27:


Code:

Str1 + sub(sub(Str1,N,1) +sub(sub(Str2,26,26)+sub(Str2,1,26),26A+1,26),Ans+1,1)-->Str1

should be

Str1 + sub(sub(Str1,N,1) +sub(sub(Str2,27,26)+sub(Str2,1,26),26A+1,26),Ans+1,1)-->Str1

otherwise, going from uppercase to lowercase would also go back one letter (converting A to Z, B to a, C to b, etc.)
For almost the same size as the "Change Case of a String" routine in the first post of this topic, the following routine completes the same in less than half the time.

Change Case of a String

Inputs:
Str1 = string to convert,
A = (1 to convert to uppercase, 0 to convert to lowercase)
Output:
Str1 = converted string


Code:
" "+Str1+" →Str1
length(Ans→B
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz→Str2
For(N,2,B
inString(sub(Str2,1+A26,26),sub(Str1,N,1
If Ans
sub(Str1,1,N-1)+sub(Str2,Ans+not(A)26,1)+sub(Str1,N+1,B-N→Str1
End
sub(Str1,2,B-2→Str1


Edit: Number of optimizations discussed over SAX.
Here's my non-inline solution, which returns the result in Ans rather than building from the end of Str1 or replacing each character of Str1.


Code:
"ABCDEFGHIJKLMNOPQRSTUVWXYZzyxwvutsrqponmlkjihgfedcba"→Str2
"?"
For(N,1,length(Str1
If A=int((inString(Str2,sub(Str1,N,1))-1)/26
Then
Ans+sub(Str2,53-inString(Str2,sub(Str1,N,1)),1
Else
Ans+sub(Str1,N,1
End
End
sub(Ans,2,length(Ans)-1


Here is a version that creates a new string in Str0, not Ans. I estimate it to be faster:

Code:
"ABCDEFGHIJKLMNOPQRSTUVWXYZzyxwvutsrqponmlkjihgfedcba"→Str2 
For(N,1,length(Str1
sub(Str1,N,1
If A=int((inString(Str2,Ans)-1)/26
sub(Str2,53-inString(Str2,Ans),1
If N≠1
Str0+Ans
Ans→Str0
End


EDIT: optimized slightly
Shortest Heron's Formula

Takes a list of lengths of sides {a,b,c} in Ans, and gives the area of the triangle in Ans.

Code:
4⁻ą√(sum(Ansprod(sum(Ans)-2Ans

At twelve bytes, it is two bytes shorter than Weregoose's routine below.

Code:
√(sum(.5Ans)prod(sum(.5Ans)-Ans
Number to list
Input and output in Ans.

Lirtosiast came up with this short version (we had three total)--

Code:
int(10fPart(Ans10^(seq(A,A,~int(log(abs(Ans)))-1,~1

Dunno how they compare speed-wise, though, so these are the others by me and NoahK respectively:

Code:
seq(10fPart(.1iPart(Ans10^(A))),A,~int(log(abs(Ans))),0

seq(iPart(10fPart(Ans10^(A))),A,~int(log(abs(Ans)))-1,~1


where 10^( is the 2nd-LOG token.
not the most optimized, but here's a one way decimal-to-binary converter. it uses a string to keep track of the remainders which turns into the binary number. there are more optimized ones, so don't bother putting this one in the list, but I just thought I'd share:

Code:
" "->Str0   //extra quote added for color fix
Repeat not(N
N/2->N
sub("01",1+not(not(fPart(Ans))),1)+Str0->Str0
iPart(N->N
End
expr(sub(Str0,1,length(Str0)-1

where N is the decimal number you want to convert. the expr() is not necessary, but that will allow you to use the number value if need be.

it's actually super fast, even with large numbers. when you get super big numbers, it may go a bit slower obviously, and also you'll have the calculator return E(number) instead of all the 1's and 0's if the binary number is too big.
If you want to return the binary as a float with the decimal digits interpreted as binary, you can just use

Code:
int(2fPart(N/2^cumSum(binomcdf(44,0
.1sum(Ans10^(cumSum(1 or Ans
In the text-to-list routine the for loop becomes a seq command


Code:
   
:Delvar L1"ABCDEFGHIJKLMNOPQRSTUVWXYZ? .->Str1
:ClrHome
:Input "TEXT:", Str2
:seq(inString(Str,sub(Str2,A,1)),A,1,length(Str2->L1


Shortening it by 3 bytes and making it faster.


The second one is the Modulo Division - this is NOT by me, someone recently posted this Routine in the SAX but I do not remember his name. Anyways, it is awesome.


Code:

:A-BiPart(A/B


Saving two bytes and making it run faster.

EDIT: I just got corrected, the latter routine can produce rounding errors so it is incorrect.
Nik wrote:
In the text-to-list routine the for loop becomes a seq command


Code:
   
:Delvar L1"ABCDEFGHIJKLMNOPQRSTUVWXYZ? .->Str1
:ClrHome
:Input "TEXT:", Str2
:seq(inString(Str,sub(Str2,A,1)),A,1,length(Str2->L1


Shortening it by 3 bytes and making it faster.


The second one is the Modulo Division - this is NOT by me, someone recently posted this Routine in the SAX but I do not remember his name. Anyways, it is awesome.


Code:

:A-BiPart(A/B


Saving two bytes and making it run faster.

EDIT: I just got corrected, the latter routine can produce rounding errors so it is incorrect.

The first routine is already on tibasicdev on the string to list pageRazz gz for re-coming up with it tho, happens sometimes, you feel like you've created something awesome and learn that it's already been done xD
Change Case of a String
Inputs:
Str1 to convert
A (1 = lowercase, 0 = uppercase)
Output:
converted string in Str1 and Ans



Code:
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz->Str2
"
For(B,1,length(Str1
   Ans+sub(Str2,1+26A+remainder(inString(Str2,sub(Str1,B,1))-1,26),1
End
sub(Ans,2,length(Ans)-1->Str1


Only for the CSE and the CE though, due to the use of remainder()
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 11 of 13
» All times are GMT - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement