Disaster

author: ''
version: ''
summary: ''
description: ''
graphics: '0'
platform: '0'
puzzle: '0'
rpg: '0'
strategy: '0'
sports: '0'
casino: '0'
board: '0'
utility: '0'
misc: '0'
compatibility: bb
image: null
fileSize: '3'
fileSizeUnit: '1'

jonbush

Connect Four game with an AI. Temporarily removed.

Puzzle Strategy Board Misc

challenges:26/connect4.gif

connect4.zip

2031

author: 'Simon Alford'
description: "My take on the popular 2048 game.\n-Optimized for speed (not size)\n-Includes a high score\n-Lacks game-over detecting (for sake of speed)\n-Looks ugly because a nice GUI is too slow."
graphics: '0'
platform: '0'
puzzle: '1'
rpg: '0'
strategy: '1'
sports: '0'
casino: '0'
board: '1'
utility: '0'
misc: '0'
image: 'archives:2048/2048.jpg'
size: '1548'
unit: '1'

author: Zachatoo
description: 'Pretty standard game. Gives you range between 1-100 and you input your guess until you get it correct. Features levels up to 10,000 with a mystery level!'
graphics: '0'
platform: '0'
puzzle: '0'
rpg: '0'
strategy: '1'
sports: '0'
casino: '0'
board: '0'
utility: '0'
misc: '1'
image: '/archives:guessing-game/screen_image.PNG'
size: '843'
unit: '1'

author: 'Magnus Groß'
description: "A Snake game, written in pure Basic\nIt uses the home screen."
graphics: '0'
platform: '0'
puzzle: '0'
rpg: '0'
strategy: '0'
sports: '0'
casino: '0'
board: '0'
utility: '0'
misc: '0'
image: /home/no_image_2.png
size: '335'
unit: '1'

span.pager-no {
display: none;
}
#main-content .form-table .form-value{  display: inline; }
#main-content .form-table .row-9 .form-value{
display: inline-block;
margin-right: 7px;
}
.form-table .form-value.field-fileSize{  display: inline-block; }
#edit-page-form input[type=text],
#edit-page-form textarea,
#edit-page-form .form-table{  width: 100%; }
#edit-page-form .form-labels{  width: 150px; }
.form-table .form-labels{  vertical-align: top; }

.row-5 .form-values .form-label{
display: inline-block;
width: 80px;
}

.do-not-notify{  display: none; }

.archive_Table{  width: 100%; }
.archive_InfoElementTitle{  width: 120px; }
.showWhenFail{  display: none; }

.archive_Image{
width: 200px;
/*  vertical-align: top;  */
}
.archive_Image img{
width: 192px;
height: 128px;
}
.archive_ImageFail img{  display: none; }

border: 1px solid #F66;
background: rgba(255, 190, 190, .8);
font-size: 125%;
margin: 0 1em 1em 10px;
text-align: center;
}

.genre0, .genre1{
display: inline-block;
}
.genre0{  display: none; }


author: 'Timothy Foster'
version: '1.1'
summary: 'This is minesweeper written in pure BASIC, no assembly. It takes advantage of three difficulty levels and a custom dimension setter. It also keeps track of the high score (or low score, rather) for each difficulty. With easy controls and relatively fast loading times, this program is worth trying! '
description: "This is minesweeper written in pure BASIC, no assembly. It takes advantage of three difficulty levels and a custom dimension setter. It also keeps track of the high score (or low score, rather) for each difficulty. With easy controls and relatively fast loading times, this program is worth trying! \n\nThe code is open source and free to use without my explicit permission."
graphics: '0'
platform: '0'
puzzle: '1'
rpg: '0'
strategy: '0'
sports: '0'
casino: '0'
board: '0'
utility: '0'
misc: '0'
compatibility: cc
image: 'archiveimage:minesweeperpic/MINESWEEPERPIC.BMP'
fileSize: '2530'
fileSizeUnit: '1'

author: kdnooij
description: 'The most addictive game is now made for the TI-84 Plus Calculator with nice graphics! Enjoy playing for a while! (maybe a bit longer than that)'
graphics: '1'
platform: '0'
puzzle: '0'
rpg: '0'
strategy: '0'
sports: '0'
casino: '0'
board: '0'
utility: '0'
misc: '0'
size: '4107'
unit: '1'

Routine Summary

Calculates the day that Easter Sunday falls on any given year.

Inputs

Y - The year (any year at all)

Outputs

Ans - The day in March of Easter Sunday (plus 31 if the month is April)

Variables Used

Y, Ans

Calculator Compatibility

TI-83/84/+/SE

Author

John Horton Conway

eastercalculation.zip

:int(Y/ᴇ2
:50-30fPart((11(1+19fPart(Y/19))-Ans+int(Ans/4)+int(8(Ans+11)/25))/30
:If Ans=50 or Ans=49 and 11≤19fPart(Y/19
:Ans-1
:round(Ans+7-7fPart((int(23(3+(Ans>31))/9)+Ans-31(Ans>31)+2+Y+int(Y/4)-int(Y/ᴇ2)+int(Y/400))/7),0


This is the TI-BASIC version of an Easter Calculation algorithm by John Horton Conway (famous for creating the cellular automata "The Game of Life"). After implementation of this program, 3+(Ans>31) is the month it occurs in, and Ans-31(Ans>31) is the day.

# Date Identification

This code, as it stands right now, displays the day of March it falls on (if it's over 31, then the day in April+31).

Append the following code to display the actual day:

:ClrHome
:Disp sub("MARCHAPRIL",1+5(Ans>31),5
:Output(1,7,Ans-31(Ans>31


# Why it Works

Easter is the first Sunday strictly after the Paschal Full Moon, which is an approximation of the real full moon (the 14th day of a lunar month, specifically), although it may be off by as much as two days.

The formula is

$(April\;19=March\;50)-((11G+C)\mod30)$

except if the formula gives April 19, take April 18, and if the formula gives you April 18 and G≥12, take April 17.

Here is the value of G:

$G=(Y\mod19)+1$

Here is the value of C (with H=int(Y/100), and [H]=int(H)):

$C=-H+[H/4]+[8(H+11)/25]$

The first four lines of code implement this algorithm.

Lastly, the last line of code adjusts the date to the next Sunday using a modified version of the Day of Week routine.1

# Alternate Routine

This routine is a modified version of the Easter20Ops function on this page.

:2613+1483int(.01Y)-2225int(Y/400→A
:round(29fPart(int((66690fPart(Y/19)+319int(Ans/25))/330)/29
:56-Ans-7fPart((int(5Y/4)+A-Ans)/7


This returns the date of Easter as day-of-March, just like the previous routine. Retrieving the actual date is the exact same.

• None known.

# Related Routines

author: BatedMarlin
description: 'Allows the user to get 1, 5, 10, or unlimited guesses. Range is from 1-10, 1-100, 1-1000, or is user-specified. When unlimited guesses is selected the total number of guesses will be tracked.'
graphics: '0'
platform: '0'
puzzle: '1'
rpg: '0'
strategy: '1'
sports: '0'
casino: '0'
board: '0'
utility: '0'
misc: '0'
image: /home/no_image_2.png
size: '3'
unit: '2'

author: 'Simon Alford'
description: 'Based off of the 24 game app for the iPhone, you try to make 24 using addition, subtraction, multiplication, and division using the four numbers given. The game features a timer, high scores, undo button, and superb graphics ;)'
graphics: '1'
platform: '0'
puzzle: '1'
rpg: '0'
strategy: '0'
sports: '0'
casino: '0'
board: '0'
utility: '0'
misc: '0'
image: 'archives:24-game/24game.jpg'
size: '3523'
unit: '1'

 Nov 16 — A new routine was made to replace the dayOfWk( command on the TI-83/+/SE

Routine Summary

Calculates the day of week of a date, without using dayOfWk( (because it's only available on the 84+ and 84+SE)

Inputs

D - The day
M - The month
Y - The year (Any year at all)

Outputs

Ans - 0-6 = the day of week (Sunday - Saturday)

Variables Used

D, M, Y, Ans

Calculator Compatibility

TI-83/84/+/SE

Author

Michael Keith

weekday2.zip

:Y-(M<3
:round(7fPart((int(23M/9)+D+4+Y+int(Ans/4)-int(Ans/ᴇ2)+int(Ans/400)-2(M≥3))/7


This is the TI-BASIC version of a Day of Week formula in C by Michael Keith, found at the beginning of this page. The formula is (d+=m<3?y—:y-2,23*m/9+d+4+y/4-y/100+y/400)%7, a mere 45 characters. In comparison with the other Day of the Week routine, this handles not just the years between 1950 and 2049.1

There is also a human-readable version on the site, as follows.

dayofweek = ( [23m/9] + d + 4 + y + [z/4] - [z/100] + [z/400] - 2 (if m ≥ 3) ) mod 7

where
[x] means to truncate downward to the nearest integer, and
z = y - 1 if m < 3,
z = y otherwise.

# Why it Works

Directly from this website:

Assume for the moment that February has 30 days (we'll correct for this later). Then the number of days in each of month is 31, 30, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, which modulo 7 is 3, 2, 3, 2, 3, 2, 3, 3, 2, 3, 2, 3. Now stick a 2 before this sequence and a 2 3 2 3 3 after it, and you get (2) 3 2 3 2 3 2 3 3 2 3 2 3 (2 3 2 3 3), which is just 2,3,2,3,2,3,2,3,3 repeated twice. But - this is the key - these numbers are the first differences of the sequence [23m/9] = (2,5,7,10,12,15,17,20,23). Therefore, the term [23m/9] adds the sum (mod 7) of the total number of days in months 1 to m-1 to the day of the week, thus correctly adjusting the formula for the months that have passed prior to m.

The next term, d, simply adjusts the sum based on the day of the month. The constant term, 4, shifts the result to correctly align with the calendar.2 The next term, y, adds 1 for each passing year, since 365 = 1 mod 7. The next three terms add 1 (the leap day) for each leap year that's passed since the "base date", including this year. To complete the correct formula requires handling two exceptions:

1. If m ≥ 3 (we are later than February), then we must subtract 2 because February actually has 28 days rather than the 30 we assumed.
2. If m < 3 (the opposite case), then we must use z = y-1 rather than z = y. This causes the leap-day correction term to not include the leap day for the given year, since in this case it hasn't yet occured.

# Display Day

Just as the other formula, append the following code to display the day of the week,

:Disp sub("SUNDAY***MONDAY***TUESDAY**WEDNESDAYTHURSDAY*FRIDAY***SATURDAY*",9Ans+1,9      //replace *s with spaces


Or you can use the alternative code, which is smaller and space-pads it.
Disp sub("***SUN***MON**TUESWEDNES*THURS***FRI*SATUR",6Ans+1,6)+"DAY       //replace *s with spaces


• None known.

# Related Routines

…that you can use check max(N=L₁ to check if N is in L₁, and 1+sum(not(cumSum(N=L₁ to tell where?

…that you can store an empty string into a string variable, but you cannot perform operations on it?

This is a program to find out if any number from 1 to 999 is a happy number. Before I put the code in though, some of you may be wondering what a happy number is though.
To find a happy number:
Take X (Ex. 123)
Take each of the digits in X and square them (Ex. 1²,2²,3²)
Keep on doing this until you get either 1 or 4. If you get 1, the number is happy; if you get 4, it is not.
Here is the code. It might not be in the most convenient format, but here it is:

Lbl A
Prompt J
Goto B
Lbl B
If J>999:Goto A
If 1000>J>99:Goto C
If 100>J>9:Goto D
If 10>J>0 Goto E


Here's where things get complicated. I'll try to explain in words what the code is. The explanation is after the // on each line, so don't put it in the actual program.

Lbl C
(J/100)→K //To isolate each digit, I first divided the number by 100 (Ex. 123 becomes 1.23)
iPart(K)→T //Then, I took the integer part, which was formerly the hundreds digit. (Ex. 1.23 becomes 1)
(K-T)→O // Next, I subtracted the iPart from the full number, so that I had only 2 digits. (Ex. 1.23-1 becomes 0.23)
(O*10)→L //And then I multiplied the new number by 10 to get the next digit. (Ex. 0.23 becomes 2.3)
iPart(L)→U //(Ex. 2.3 becomes 2)
(L-U)→P //(Ex. 2.3-2 becomes 0.3)
(P*10)→V //(Ex. 0.3 becomes 3)
(T²+U²+V²)→J
Goto B //At the end, we plug the final number back into J and check for the number of digits.


The next piece of code (if J has 2 digits) works the same way.

Lbl D
(J/10)→K
iPart(K)→T
(K-T)→O
(O*10)→U
(T²+U²)→J
Goto B


The last part (if J has only 1 digit) is a bit different.

Lbl E
If J=1 or 4
Then
Goto F
Else
J²→J:Goto B
Lbl F
If J=1:Disp "HAPPY"
If J=4:Disp "NOT HAPPY"


Again, I know it isn't the most effective method, but it was the first one I came up with. Perhaps, when I am better at coding, I will find a more effective way to do this, but for now, here it is.

Have fun trying out numbers!

author: SuperJedi224
description: 'A simple battle game with single-calculator player-versus-player and player-versus-cpu modes. To install, simply ungroup it. G1P and G2P are the master programs, the other programs provide the nescessary function calls. There seems to be a bug in the ai routine (involving the block command), let me know if you manage to fix it.'
graphics: '0'
platform: '0'
puzzle: '0'
rpg: '0'
strategy: '1'
sports: '0'
casino: '0'
board: '0'
utility: '0'
misc: '0'
image: /home/no_image_2.png
size: '2576'
unit: '1'

author: Tybo10000
description: "*This update is necessary if you are using an older version*\nNew to v0.6.1: re-worked setup; updated apps; many bug fixes; lots of optimization; slightly easier navigation\n\nNew to v0.5: setup bug fix; new ans updated apps; slightly faster; misc bug fixes\n\n\ncurrent version- v0.6.0\n\nFull release of version 1.0 coming soon!!!"
graphics: '0'
platform: '0'
puzzle: '0'
rpg: '0'
strategy: '0'
sports: '0'
casino: '0'
board: '0'
utility: '1'
misc: '1'
image: archives%3Agameplayer/scr00.gif
size: '40246'
unit: '1'

author: smaldragon979
description: 'A simple addicting game about clicking on the right key before time runs out that takes advantage of the position of the functions keys relative to the screen, displaying arrows and other symbols in the bottom of the screen that point directly to the key that must be pressed. \nIncludes 3 difficulty levels, high scores and instructions on the program itself.'
graphics: '0'
platform: '0'
puzzle: '0'
rpg: '0'
strategy: '0'
sports: '0'
casino: '0'
board: '0'
utility: '0'
misc: '0'
image: 'archives:clicker/clicker.gif'
size: '2873'
unit: '1'

author: ''
description: ''
graphics: '0'
platform: '0'
puzzle: '0'
rpg: '0'
strategy: '0'
sports: '0'
casino: '0'
board: '0'
utility: '0'
misc: '0'
image: '0'
size: '0'
unit: '1'

author: theFlyingDutchman
description: 'A simple program used to solve cubic equations (AX^3+BX^2+CX+D=0)'
graphics: '0'
platform: '0'
puzzle: '0'
rpg: '0'
strategy: '0'
sports: '0'
casino: '0'
board: '0'
utility: '1'
misc: '0'
image: /home/no_image_2.png
size: '347'
unit: '1'

Routine Summary

Solves for the complex roots of a cubic equation.

Inputs

A, B, C, D - the constants in Ax3+Bx2+Cx+D=0

Outputs

The three roots (or repeated roots)

Variables Used

A, B, C, D, M, N, O, P, Q, R, U, V, W

Calculator Compatibility

TI-83/84/+/SE

Author

theFlyingDutchman

URL: United TI

cubicformula.zip

ClrHome
Disp "AX³+BX²+CX+D=0
Prompt A,B,C,D
2B³-9ABC+27A²D→R
√(Ans²-4(B²-AC)³→M
³√(0.5(R+Ans→N
³√(0.5(R-M→O
(1+i√(3))/6A→P
(1-i√(3))/6A→Q
3A→E
-B/Ans→F
Ans+(-N-O)/E→U
F+PN+QO→V
F+QN+PO→W
Disp "X1=",U
Disp "X2=",V
Disp "X3=",W


This is the complete program used to give the three roots that solve the cubic equation. If there are less than 3 roots, it will still give three answers. Because the formula used to solve cubic equations is quite big, several repeated parts are turned into variables.

author: vapaavetehinen
description: 'A tic-tac-toe game that doesn''t overwrite any variables and uses the graph screen to look good. It has three game modes; two-player, and two levels of one-player difficulty.'
graphics: '0'
platform: '0'
puzzle: '0'
rpg: '0'
strategy: '1'
sports: '0'
casino: '0'
board: '0'
utility: '0'
misc: '0'
image: 'archives:tic-tac-toe/preview.gif'
size: '3804'
unit: '1'

Imagine you're creating an RPG, and the current problem you're facing is how to display all of the data for each character on the screen. Without putting too much thought into it, the easiest approach to you seems to be to simply write out the data each time. Unfortunately, when you start implementing this approach, it soon becomes apparent that it will not work in your program.

While you've only programmed in a few of the characters and their respective data, you can already see that there is simply too much data to enter in; and then when you think about the possibility of having to go through and change all of the data again if you update the program, you're now left feeling overwhelmed and wondering if there's another way. Thankfully, there is, and its name is subprograms.

A subprogram is a program called by another program to perform a particular task or function for the program. When a task needs to be performed multiple times (such as displaying character data), you can make it into a separate subprogram. The complete program is thus made up of multiple smaller, independent subprograms that work together with the main program.

There are two different general types of subprograms available:

• External — They exist as stand-alone programs that are listed in the program menu, and can be executed just like a regular program.
• Internal — They are contained inside the program itself, so that they can be called by the program whenever needed.

There are certain advantages and disadvantages to using each type of subprogram, and consequently, situations where using one type of subprogram makes more sense than using the other. This doesn't mean you can't use whichever you like, though.

# External Subprograms

External subprograms are the simplest type of subprogram, and involve executing one program from inside another program using the prgm command. You just insert the prgm command into the program where you want the subprogram to run, and then type the subprogram's name. You can also go to the program menu, and press ENTER on whichever program you want to use to paste the program's name into the program.

:prgmPROGNAME


When creating a subprogram, you take whatever code you want from the parent program and put it in its own program (see your first program for more information), and then put a Return command whenever you want to return to the parent program. (A Return command is optional at the end of a program, and you typically leave it off as part of program optimization.)

You should try to name your subprograms Zparentn or θparentn, where parent is the name of the parent program and n is the number (if you have more than one). Because subprograms are relatively unimportant by themselves, you want them to appear at the bottom of the program menu so they don't clutter it up and interfere with the user's ability to find whatever program they're looking for.

Here's a simple example where we are storing maps for our maze game in a subprogram, and then retrieving the desired map from the subprogram as a string, so we can print it out on the home screen. (This example is somewhat contrived, but it should be enough to illustrate external subprograms).

PROGRAM:MAZE
:ClrHome
:prgmZMAZE
:Output(1,1,Ans
:Pause

PROGRAM:ZMAZE
:int(3rand→A
:"X    XX    XXXXXX    XX    XXXXXX    XX    XXXXX
:If A=1:"X X X X X X X X X X X X X X X X X X X X X X X X
:If not(A:"X              XX              XX              X


When the subprogram's name is encountered (in this case, prgmZMAZE), execution of the program will be put on hold, and program execution will transfer to the subprogram. Once the subprogram is finished running, or the Return command is executed, program execution will go back to the program, continuing right after the subprogram name. (If the Stop command is used instead of Return, however, the complete program hierarchy will stop.) See the image to the right for a graphical view of program flow using subprograms.

Although subprograms can call themselves (i.e., recursion) or other subprograms, each subprogram should return to the parent program and let it handle all the program calling. A structured program hierarchy is easier to understand and update (in fact, it's actually a code convention), and helps cut down the potential for memory leaks.

Each program call is sixteen bytes, and gets put on a stack in RAM by the calculator. This is fine as long as its size isn't larger than the free RAM available, but each additional program call takes more memory until the program Returns. Having many nested program calls can run out of memory and crash the calculator (giving you a ERR:MEMORY error).

External subprograms often are made to increase the speed of a program and decrease the size of the program overall by executing often used code at one place, where it can be called quickly. (as opposed to Labels)

To make subprograms even faster, a Return may be used in the subprogram, but only is useful in subprograms with several methods, and only after a method has been completed. The problem with using a Return in such a method is that it isn't very easy to prevent memory leaks by using a Return before an End command should have been called.

Because the same thing happens with Goto's before End commands as Returns before End commands, we can use this to our advantage, to quickly return from a subprogram. By using a Goto to a label with one or possibly more End commands, you can quickly return from a program, or quickly reset a While, Repeat, or For( loop without having to execute the rest of the code in the subprogram or loop.

Goto ST
Lbl E1
End
Lbl E0
Return
Lbl ST
[code]
If [condition]
Goto E0
[code]
If [condition]
Then
[code]
Goto E1
End
For(A,1,10
[code]
If [condition]
Goto E1
[code]
End


This can significantly increase the speed of subprograms or loops, by using Labels without worry of ERR:MEMORY.

## Passing Arguments

The main problem associated with trying to use external subprograms is that there is no built-in support for passing arguments to subprograms. This feature is important because it allows the subprogram to act differently based on what values are given to it for processing.

Fortunately, you can mimic this functionality by using variables. Because all variables are global (variables used by one program can be used by another), changing a variable in one program affects that variable everywhere else. While you can use almost any variable that you want, there are three main types of variables that you should choose from:

• Pre-Defined Variables — Includes reals, strings, matrices, built-in lists, etc. These variables are frequently used by most programs, so you don't have to worry very much about whether the user cares if your mess with them.
• User-Defined Lists — Uses the individual list elements to store different values. These variables have a certain sense of security that comes with using them because they are the only variable that you can actually create, so a program can have its own custom list to use.
• Ans — It can take on whatever value and variable you want, so the program doesn't have a specific variable hard-coded in. Its value changes whenever you store something or simply place an expression or string on a line by itself.

When using a pre-defined variable or user-defined list, you simply have to set the variable to the value that you want and then call the subprogram. The subprogram should be able to use that variable without problems, but if you don't properly setup the variable, the subprogram won't work correctly.

:{2,3,5,7,9→PRIME
:prgmZPRIME


Using the Ans variable is essentially the same, except you need to add some additional code to the subprogram. Because the value of Ans changes whenever there is a new variable storage, you should have the first line inside the subprogram save Ans to another, more stable variable.

:{2,3,5,7,9
:prgmZPRIME

PROGRAM:ZPRIME
:Ans→PRIME


This change saves some memory in the main program (in our example, we were able to get rid of the →PRIME statement), but the subprogram size is larger, since we really just shifted the variable storage code to the subprogram. However, if the subprogram is called multiple times this extra memory is only used once instead of once per call.

This does create a problem, though, because now when you store Ans to another variable, it will crash the program if Ans isn't the same type of variable. There is only one case where you can avoid crashing when the subprogram receives the wrong variable type. If the subprogram is expecting a real variable (such as A or X) and it is passed a list, it can prevent a crash by using the fact that a parenthesis ("(") has multiple functions.

PROGRAM:ZSUB
:Ans(1→A


The reason that this works is because a user-defined list doesn't need the ∟ prefixed character at the beginning when referring to the list. While you may be only asking the user to input a simple real variable, a list would also be allowed. There is nothing you can really do to fix this problem with other types, so just be careful.

The main consideration when using external subprograms is how many subprograms your program should have. While you're still putting your program together, it's good to keep it in many small, separate subprograms; but when you're done, all those subprograms become a liability and make your program unwieldy to use. This is because you have to remember all those subprograms in order to use your program.

There are two different ways to resolve this problem. The first way is to put the subprograms back in your program. This should only be done if a subprogram was only called once or twice, and putting it back in won't slow down the program. All you have to do is paste the code from the subprogram in place of the subprogram call. When you're done, you can delete the now unnecessary subprograms.

(The more detailed explanation is to go through your main program, and whenever you see a prgm call for a subprogram, clear that line and press 2nd STO. The Recall option will come up. Press the PRGM key and select the appropriate subprogram from the EXEC menu. The calculator will paste that subprogram's code into the main program.)

This is the same subprogram example from before, but now we've gotten rid of the ZMAZE subprogram and simply placed the subprogram code in the MAZE program itself:

PROGRAM:MAZE
:ClrHome
:int(3rand→A
:"X    XX    XXXXXX    XX    XXXXXX    XX    XXXXX
:If A=1:"X X X X X X X X X X X X X X X X X X X X X X X X
:If not(A:"X              XX              XX              X
:Output(1,1,Ans
:Pause


The second way to resolve the problem is by simply combining your subprograms together, so that there are fewer subprograms needed. Of course, how many subprograms you decide to use is up to you, but you should try to limit it to three or four subprograms at most, and just one subprogram ideally. This might take some effort on your part, but it will most certainly make your users happy.

When you start combining your subprograms together, you should place the subprograms one after the other, giving each subprogram a unique branching label (note that labels are local, so you can't use Goto in one program to jump to a label in another program). Instead of having to search through each individual subprogram, branching allows you to simply jump to the desired subprogram. You then just use the subprogram's variable argument to determine which subprogram to access.

:If A=e:Goto A  // jump to first subprogram
:Stop  // the subprogram was accidentally called
:Lbl A
: // subprogram code
:Return
:Lbl B
: // subprogram code
: // No Return needed here


Looking at the example, the first thing you should notice is the variable values that are used to determine which subprogram to jump to. While you could use something simple like one or two, those values have a high probability of being accidentally entered in by the user or being set by another unrelated program. What works better is to use random decimals (like .193 or 1.857) or math symbols (like e or π).

If none of the variable values for the subprograms match, then none of the subprograms will be executed; instead, program execution will go to the Stop command on the next line, which will immediately stop the entire program. The reason for adding this program protection is to prevent the user from running the subprogram separate from our main program.

This is a real concern since external subprograms are listed in the program menu, and the user most likely at some point will try to run the subprogram just out of pure curiosity. Unless the user is a competent TI-Basic programmer who knows what they are doing, however, you normally don't want to let the user mess with your subprograms. If they change something, or delete some lines of code, then your program might stop working correctly.

The second thing you should notice about the example is the Return command at the end of each subprogram. If you have lots of subprograms, and you're accessing a subprogram near the bottom, it takes a considerable amount of time for program execution to go back to the main program. This happens because program execution doesn't return to the main program until after it reaches the end of the program, or it executes a Return command. So, just remember to include the Return commands as needed.

## Using Assembly

Although using assembly programs can limit the compatibility of your program, they can be helpful in reducing the memory your program occupies, and allow for easier calling of subprograms. To use an assembly program for calling subprograms, have your subprograms named using some very simple pattern (e.g. "ZZ10", "ZZ11", "ZZ12", "ZZ13", etc). Then create a program such as the following called ZEXEC (or something similar):

:"ZZ"+Ans→StrX
://Assembly program to run program name in StrX


Then you can call this program through the line:

:"13
:prgmZEXEC


This will create a string with the contents "ZZ13" which will then run the program ZZ13. Depending on the assembly program you are using, you could have "ZZ13" archived (along with the rest of the subroutines) and when ZEXEC is called, it copies it to an unarchived program, runs the copy, and then deletes the copy, thus only one subroutine at a time is unarchived. This is useful for programs with lots of subroutines. One way of doing this is using xLIB, for which the ZEXEC code would look like this:

"ZZ"+Ans
real(10,0,0
prgmXTEMP000
real(10,1,0


In order to make this concept more efficient, a number to string routine would come in handy. If one were using such a routine one could have various actions in a program return number values. These numbers would be converted into strings and the program would run the corresponding subprogram. This would become useful with a custom menu, one could have the program return the location of the cursor, convert that into a string and run the subprogram that corresponds to that cursor location. Some assembly programs that can be used may be found on the assembly libraries page.

There are several advantages of using external subprograms. First, and foremost, they reduce program size by eliminating redundant code. Instead of having to type the code multiple times for a task that occurs more than once in a program, you just type it once and put it in a subprogram. You then call the subprogram whenever you want to perform the task in your program.

Second, external subprograms increase program speed by making programs as compact as possible. You separate conditional tasks from the program (they either happen every time or they are skipped over), and put them in a subprogram; you then call the subprogram instead. This improves program speed because the calculator doesn't have to go through all of the conditional code anymore.

Third, external subprograms make editing, debugging, and optimizing easier. Instead of going through the entire program, looking for the code you want to change, you can focus on one subprogram at a time. This makes the code more manageable, allowing you to more thoroughly look at each subprogram and to better keep track of which subprograms you have looked at. It also prevents you from accidentally changing other parts of the program.

Lastly, subprograms are reusable, allowing multiple programs to share and use the same code. Breaking a program into smaller, individual subprograms, which each do a basic function or task, allows other programs to use those subprograms. Consequently, this reduces program size.

# Internal Subprograms

Internal subprograms are the most complicated type of subprogram, and involve putting the subprograms in the main program itself. This is not the same thing as pasting the code from the subprogram in place of the subprogram call, like you do with external subprograms; rather, it is designing your main program so that it can take advantage of subprograms, but all the code is self-contained.

There are several different ways that you can make internal subprograms, but the three most common ways are:

1. Append to the beginning of the program
2. Structured loops or branching
3. Branching out of broken loops

## Append to Program Beginning

If you remember how we used external programs, then this should be very familiar. Instead of placing the subprograms in their own separate program, we are now just placing the subprograms at the beginning of our main program.

The standard way to make a subprogram is to use an If-Then conditional:

:If A=1.234:Then
: // subprogram code
:DelVar A
:Return
:End


Then to call the subprogram, you just set the variable to the desired value:

:1.234→A
:prgmPROGNAME


Of course, there are some important considerations that you need to be aware of. You can use whatever random value for the variable that you want, just as long as it isn't something that the user would typically use. This is to ensure that the subprogram isn't accidentally run when it shouldn't be, which is why you need to reset the variable's value inside the subprogram before exiting.

While you could use any variable that you want (including Ans), the best variables to use are the simple real variables (A-Z and θ). This is because they are small in size and they are constantly being used by other programs, so you don't have to really worry very much about your subprograms being accidentally run. (Ans is not a very good variable to use for the reasons listed above.)

You should always remember to include the Return command at the end of the subprogram. Once the subprogram is finished, the Return command will cause the subprogram to stop and return to the previous place in the program from where it was called. The other reason for the Return command is to prevent any memory errors that can occur if a program recursively calls itself too much.

You can have multiple subprograms at the beginning listed one after the other by simply using different values for the the variable:

:If A=1.234:Then
: // subprogram 1
:End
:If A=2.246:Then
: // subprogram 2
:End


While this works quite well when you only have three or four subprograms, with more subprograms it can actually slow down the main program. This happens because the calculator has to go through all the subprograms to get to the main program code.

You could fix this problem in a couple different ways, but the easiest way is to simply place all the subprograms in an If-Then conditional and then make that part of the subprograms. If this conditional is false, all of the subprograms will be skipped over.

A real number has an integer (accessed with the iPart( command) and fraction (accessed with the fPart( command) part, and you can use both of those for the subprograms: the integer will be the subprogram access check on the outside If-Then conditional and the fraction will be the respective subprogram we want to run.

:If 123456=iPart(A:Then  // get integer part of number
:10fPart(A  // get fraction part of number
:If Ans=1:Then
: // subprogram 1
:End
:If Ans=2:Then
: // subprogram 2
:End
: // rest of subprograms
:End


For calling the subprograms, you then just set the variable to the desired value like before:

:123456.1→A  // run subprogram 1
:prgmPROGNAME


## Structured Loops or Branching

If you don't like placing subprograms at the beginning of a program, the next approach that you can try is placing subprograms in the actual program code. While it would appear easy to simply place the subprograms wherever you feel like in your program, you can't readily do this since it would almost certainly cause your program to stop working correctly. Instead, you need to modify your program and subprograms so they can be put together.

What this modification entails is reorganizing your program so that the code works in a modular fashion as individual subprograms. This may not seem like it would be worth the effort, depending on the amount of code in your program, but modularization makes the program easier to understand and update (see planning programs for more information).

While there are several different ways you can structure the code in a modular fashion, the simplest way is to give each subprogram its own individual loop with a respective variable value as the loop condition. You can then access and exit the desired loop by simply changing the value of the variable. Of course, you have to determine which loop and variable you are going to use.

There are three different loops you can choose from (While, Repeat, and For(), but the best loop to use in this circumstance is While. This is because the condition is tested at the top of the loop, so if it's false already before the loop, then the loop will actually be skipped over (which is what allows us to use the loops as subprograms).

Once you have decided upon a particular loop, now you need to choose which variable you want to use. Like with the first way to make internal subprograms, the best variable to use is one of the real variables (A-Z and θ). This is because we just need a single value, and real variables only take up 15 bytes of memory (other variables are just as small, but they take up more memory when you're accessing them).

Now that the loop and variable have been chosen, we need to setup the system of loops to act as the subprograms. What works best is to have a main program loop and then place the subprogram loops inside of it. Putting the variable and loops together, here is what the program skeleton looks like:

:Repeat not(A  // main program loop
:1→A
:While A=1
: // subprogram 1
:2→A  // enter loop for second subprogram
:End
:While A=2
: // subprogram 2
:DelVar A  // exit main program loop
:End
: // rest of subprograms
:End


You just set the value of the variable in the loop to use the desired subprogram. Then when you are done with the subprogram, you just change the value of the variable to something different to exit the loop. You do the same thing to exit the main program loop. You can use whatever system of values for the variable that you want, but just remember to keep it simple enough so that you can come back to it later and it still makes sense to you.

The one drawback of using this approach is that the calculator has to go through all the subprograms to exit the main program loop, which can really be slow depending on the size of the subprograms. At the same time, this approach is very easy to understand and follow because the loops are organized in a straight forward manner, so it's kind of an even trade off.

Related to using structured loops, the alternative you can use is branching. While using branching by itself to structure a program is generally frowned upon (see planning programs for more information), you can actually use it quite effectively for making internal subprograms that only need to be called a few times. Here is a simple example:

:0→A:Goto A
:Lbl B
: // main program code
:1→A:Goto A
:Lbl C
: // main program code
:Stop
:Lbl A
: // subprogram code
:If A:Goto C
:Goto B


The A variable is used for determining when to stop the program: a zero value will simply cause the subprogram to jump back to the main program, but a value of one will cause the subprogram to jump to the exit of the program (the C label). Because the calculator doesn't store the label positions, there is no way to get memory leaks using this approach, which is especially important when exiting the program. However, it does get hard to follow and maintain the code the more branching there is.

## Branching out of Loops

The last way to make internal subprograms is arguably the most difficult to understand, but once you have it setup in your program, it provides an easy framework for adding additional subprograms. The best time to use these kind of subprograms is when you have a main program loop that you're running and you want to be able to jump out of it and then back into it whenever you want.

The basis of these subprograms is using branching (Goto and Lbl) with loops and conditionals (anything that uses an End command). Branching by itself allows the calculator to jump from one point in a program to another, skipping over whatever code you don't want executed. When you use branching to exit loops and conditionals, however, it has the unwanted effect of causing memory leaks.

Memory leaks happen because the calculator doesn't get to reach the End command for the associated loop or conditional, and the calculator just keeps on storing the End commands in its stack until there is eventually no free memory left. (Memory leaks can also occur with excessive program recursion.) Here is a simple example that has a memory leak:

:Lbl A
:While 1
:Goto A
:End


If you notice, when the Goto A command is executed, it jumps to the matching label A that is on the line before the loop. The While 1 loop is never allowed to finish because the End command never gets reached, and the branching occurs over and over again until the calculator finally slows down to a stop (because there is less and less free memory available) and returns a memory error.

This type of programming is common with beginners, and its use is generally frowned upon; instead you should try to use proper program structure (see planning programs for more information). However, if you know what you are doing, you can actually use these broken loops and conditionals for internal subprograms, and you won't have to worry about memory leaks or the dreaded memory error.

There are two different approaches that you can use. The first approach is to use another Goto and matching label to jump back into the loop. Because the calculator doesn't store the labels, you can freely use whatever branching in the loop that you want, and the calculator will act like it had never even left the loop:

:Repeat getKey
:Goto A
:Lbl B
:End
:Stop
:Lbl A
: // subprogram code
:Goto B


The key here is that the Goto A command jumps to the matching label A outside the loop, and then the Goto B jumps to the matching label B back inside the loop. The calculator still has the loop's associated End command on its stack, so the loop will just keep looping without problems until you eventually press a key to stop it and it executes the Stop command.

While this first approach works rather nicely in small programs, it is not very practical for use in large programs because all the branching starts to slow the program down. Unlike loops and conditionals, the calculator doesn't keep track of the label positions, so it must start from the beginning of the program to find the matching label to jump to. The further down the label is in the program code, the more time the calculator must spend looking for it.

The second approach solves this problem by using a duplicate End command for the loop or conditional. Since the calculator keeps track of the number of unfinished loops and conditionals by storing the associated End commands in its stack, we can make the calculator believe that our different End command is actually the End command that belongs to the loop. Here is a simple example to illustrate:

:Repeat getKey
:Goto A
:End
:Stop
:Lbl A
: // subprogram code
:End


Like with the first approach, when Goto A is executed the program will jump to the matching label A, and then the subprogram code will be executed. This time, however, the calculator will read the End command after the subprogram code, which it believes is the end of the loop, and then immediately jump back to the beginning of the loop. This process will be repeated over and over again until the user presses a key, at which time the Stop command will be executed and the program will stop.

The subprogram code for both approaches can be whatever you want, including other loops and conditionals. You just need to remember to close the loops and conditionals before returning to the original loop, otherwise the calculator will have the wrong End command on its stack. You also want to have a matching number of End commands for your loops and conditionals, or you will get a memory leak.

There are a couple different ways you can enhance the duplicate End subprogram approach so that you get the most use out of it. The first way is relatively simple, and just involves using a For( loop as the looping structure, instead of a While loop or Repeat loop (which is what we had in our previous examples).

A For( loop is basically a specialized form of a While loop, with the main differences being that it is executed a specific number of times and it has the variable setup and ending condition built-in. You just choose a variable, the range of values, and the increment (it is optional, with one as the default); and then the loop will start the variable at the initial value and increment it each time until it reaches the ending value.

Now when you start using the For( loop for internal subprograms, you need to make sure the For( loop executes at least twice. This is so that the End command of the For( loop gets used along with the End command of the subprogram, otherwise it will simply fall through after the first time through the loop. You can select different subprograms based on the variable's value. Here is our example from above, now using a For( loop instead:

:For(A,0,1
:If not(A:Goto A
:End
: // main program code
:Stop
:Lbl A
: // subprogram code
:End


When the For( loop is executed, the A variable is set to zero. The not(A condition is true, so the calculator executes the Goto A command and then jumps to the matching label A. The calculator then jumps back to the beginning of the For( loop and increments the A variable to one. This time, however, there is no subprogram jump taking place, and the calculator simply finishes the For( loop like normal.

The second way to enhance the duplicate End subprogram approach is by using a simple trick. Because a While loop loops only when the condition is true, when the calculator comes across a While loop with a false condition, it will simply skip over the entire loop (and everything inside the loop). The easiest way to make a false condition is to use zero, since zero will never be true (based on Boolean logic). Here is a simple example to demonstrate:

:While 0
:Lbl A
: // subprogram code
:End
: // main program code
:If getKey:Then
: // program code
:Goto A
:End


When the calculator encounters the While 0 loop, it won't execute it because 0 is false. After the calculator enters the subprogram conditional, it executes some program code and then hits the Goto A command and jumps to the matching label A inside the While 0 loop. The calculator takes the End command of the loop as the End command of the conditional, and thus no memory leak occurs.

The reason that this trick is so valuable is because it allows you to place your subprograms at the beginning of the program, and you don't ever have to worry about them being accidentally executed (they will always be skipped over). In addition, now that the labels are at the beginning of the program, there is no more speed problem to deal with, since the calculator doesn't have to search through the entire program to find the labels.

The main advantage of using internal subprograms is that there is only one program needed to make your program run. When you give someone your program, you don't have to worry about forgetting to include any subprograms; or somebody deleting your subprograms afterwards, causing your program to stop working correctly. These things are mostly out of your hands, but users will think your program is at fault.

Related to the first advantage, the other advantage is that the user's program menu doesn't get cluttered up with insignificant subprograms. This problem is relative to how many subprograms a program has, but it can become tiresome to have to sort through the program menu in order to find the program that you want. If anything, this is just a nice courtesy to the users of your programs.

# References

author: Harrison
description: "Finally play 5x5 and 8x8 picross puzzles! 4 puzzles are included with the game and a new puzzle pak is coming soon.\nVersion 1.2.0 features-\n*Smaller (compressed) program size\n*Bug fixes\n*Better stability"
graphics: '0'
platform: '0'
puzzle: '1'
rpg: '0'
strategy: '1'
sports: '0'
casino: '0'
board: '0'
utility: '0'
misc: '0'
image: /home/no_image_2.png
size: '13970'
unit: '1'

name: ''
content: "In preparation for TI-Concours, I picked up my TI-89t and tried to make a few programs with it. Among other things, I made a tilemap engine, so I thought I would share the code and explain the parts.\n\n First, let's take a look at how indirection works. If you have an argument that requires a variable name, you can indirectly refer to it with a string. For example, you can draw a picture on the graph screen named sprite0 like this:\n[[code]]\n\"sprite0\"→string\nRclPic #string,0,0\n[that example, 'string' had the variable name and we used the indirection symbol '#' to tell the program to use the string as the variable name. This will do the same thing:\n[[code]\nRclPic sprite0,0,0\n[[/code]]\n\nIf you are familiar with the string() command, then you are probably coming up with all sorts of ideas already. For example, say you had a bunch of sprites named sprite0,sprite1,sprite2,… and you wanted to draw a sprite based on an input number:\n[[code]]\n\"sprite\"&string(num)→string\nRclPic #string,0,0\n[to optimise this a little:\n[[code]\nRclPic #(\"sprite\"&string(num)),0,0\n[if 'num' holds the sprite number to draw, it will draw the appropriate sprite. Using this, we can make a tilemap engine that uses a matrix to hold the tile numbers and uses 8x8 tiles:\n[[code]\nFor a,1,8 ;8 tiles tall\nFor b,1,8 ;8 tiles wide\nRclPic #(\"sprite\"&string(tilemap[a,b])),shift(a,3),shift(b,3)\nEndFor\nEndFor\n[[/code]]\ntilemap[a,b] is used to access each matrix element and shift(a,3) basically multiplies the value of a by 8. A more memory efficient way of storing tilemaps, though, is to use strings. For example, if you start your sprite index at sprite1 instead of sprite0, you can convert your matrix to 1-byte char() strings and then add them all together. So the conversion code:\n[[code]]\n\"\"→str0\nFor a,1,8\nFor b,1,8\nstr0+char(tilemap[a,b])→str0\nEndFor\nEndFor\n[[/code]]\nThen to draw your tilemap, you can use the inverse function of char()— ord():\n[[code]]\n0→c\nFor a,1,8\nFor b,1,8\nc+1→c\nRclPic #(\"sprite\"&string(ord(mid(str0,c,1)))),shift(a,3),shift(b,3)\nEndFor\nEndFor\n[probably better:\n[[code]\nFor a,0,63\nRclPic #(\"sprite\"&string(ord(mid(str0,a+1,1)))),8*int(a/8),8*mod(a,8)\nEndFor\n[[/code]]\n\nAttached is a screenshot taken using CalcCapture. I tested it and unfortunately, the screenshot is about half the speed that it actually runs at, so keep that in mind!\n\nThis program is a little different from the code that is posted in that it uses another level of indirection. It takes two inputs for the name of the tileset and the name of the tilemap, so it is meant to be a general tilemap engine."
attachment: 'file:tilemapex0/TileMapEx0.GIF'

Command Summary

Returns a previous answer from the Home screen.

Command Syntax

ans([integer]).

2nd, ANS (the (-) key)

This command works on all calculators.

X byte(s)

Simply put, the ans() function returns an answer that the calculator has already returned. The argument specifies which answer to return, and must be an integer between 1 and 99 and may not be an expression or a variable. For example ans(1), the default, will return the last answer displayed on the home screen. ans(3), however, will return return the third most recent answer. If no argument is provided, the calculator assumes 1. Strangely, while official documentation states that the argument must be between 1 and 99, 0 may be used, which returns the same answer as if 1 were used (this is probably why ans() returns the most recent answer, even though no argument is provided).

Example home screen input to generate the Fibonacci sequence.

:1
1
:1
1
:ans(1)+ans(2)
2
:ans(1)+ans(2)
3


When entered into a program, the calculator will automatically change the ans() command into whatever value it represents at runtime, so that even if the home screen changes, the program will always return the same value of the ans() function as the first time it was run. This may be avoided by using the expr() function and putting the ans() function in quotes to make it a string. For example: expr("ans(3)"). This can be rather cumbersome, however, and generally anything that you can do with the ans() function can be accomplished equally well with a variable.

# Error Conditions

260 - Domain error happens when the argument is not in the range 1-99 or the argument is not an integer.

380 - Invalid ans() happens when that many answers haven't been stored yet.

620 - Invalid variable or function name happens when the user attempts to store a value to ans().

name: ''
content: "There are still a few weeks left to register! Currently the BASIC (z80) category has 12 contestants. 8 are from France, 3 are from the US, and 1 is from Belgium. Last year the topics were Tic-Tac-Toe, Tron, and a personal project. We won't find out what the topic is until the start of the competition, either :D\n\nIn the Axe category, there are 7 contestants, 4 from France, 2 from the US, and 1 from Belgium (yay, powers of two!). Last year the topics were making a grayscale image editor, making Snake, and a personal project.\n\nIn z80 Assembly, there are 6 competitors. 4 are from France, 1 is myself from the USA, and 1 is from Belgium. By the way, ben_g is the guy from Belgium in each of these categories so far.\n\nFor nSpire Lua, there are 4 competitors including 2 from the US, and 2 from Belgium (Jim Bauwens, the brother of Stefan Bauwens, and Nick). \n\nFinally, for TI-BASIC (68K), it still just Stefan and I D:\n\nReally, y'all should join if you can, it will be great fun. I would feel sorry for the judges, but they have been working hard to get a bunch of people to compete :D I think last year they had three NSpire CX calculators from their sponsors to give to the first place winners in each category (there were three categories) and I think there were similar prizes for the second, and third places, and some goodies for fourth and fifth. I don't know if they have this for this time around, but regardless, you get to compete with people from different countries o__o Isn't that awesome?\n\nEDIT: Also, if you have difficulty with the French stuff that they haven't translated yet, you can ask here or use Google Translate. I should theoretically understand the French >.>"
attachment: null

name: ''
content: "One small note:\n\"or\" and \"and\" can be replaced with addition and multiplication, respectively\n\nSo\nIf G=72 and Y-L+31\nbecomes\nIf (G=72)(Y-L+31\n\nand\nIf N=1 or N=93\nbecomes\nIf (N=1)+(N=93\n\nThese increase size but also offer a marginal increase in speed\n\nIf max(N={1,93 \ncan also replace\nIf N=1 or N=93\nfor the same size, though I do not know which is faster\n"
attachment: null

Member

Member

Member

Member

Member

Member

Member

Member

Member

Member

Member

Member

Member

Member

Member

Member

Member

Member

Member

Included page "lflskdafjlkdjgflv" does not exist (create it now)

The ListPages module does not work recursively.
page 1 of 14123...1314next »

name: ''
content: "Thank you so much for your optimizations. I really can't express how much this means to me; I'm ecstatic to try them out.\n\nI just realized I forgot to mention trick shots. The ball /does/ move at an angle, but you have to set it off first with a trick shot executed by moving the paddle exactly one pixel away from the ball when you hit the ball. It's kind of hard to explain but really easy to understand once you do it once. I made it this way purposefully to give skilled players an edge; once you start a trick shot ball it can't be undone until the next ball. It's also impossible to score anything in Challenge Mode without using trick shots. If you didn't know about them, you probably weren't having much fun :P"
attachment: null

name: ''
content: "Thank you so so much for your optimizations. I really can't express how much I appreciate it; I'm literally ecstatic right now. \n\nAlso, I may have forgotten to mention this, but the ball does move at an angle, but you have to \"set it off\" first by moving the paddle exactly one pixel away from the ball. This is kind of hard to explain until you do it once. I made it this way on purpose to give skilled players an edge; they'll have the precision to set off trick shots and once a trick shot is off, it can't be undone until the next ball. Haha, if you were playing without knowing that you probably weren't having a lot of fun :P"
attachment: null

name: ''
content: "I am going through and optimising some of your code and I can tell a bunch of it was well thought out :D\nThere are a handful of common optimisations that I can suggest:\n\n* Instead of using ~L+32 (I am assuming ~ is negative), you can use 32-L to save a byte\n* You can drop ending quotes and parentheses\n* To elaborate on what Silver said, DelVar is two bytes, so 0→Q is the same size as DelVar Q. However, DelVar and the other memory functions have a cool trick where you don't need to use a newline for the next command, saving a byte! For example, instead of this:\n[[code]]\n0→Q\n1→P\n-or-\nDelVar Q\n1→P\n[are the same size) You can do this:\n[[code]\nDelVar Q1→P\n[[/code]]\nWhich is one byte less and essentially does the same thing.\n* Disp has a cool trick like Text( where each additional argument is treated like a new Disp. For example:\n[[code]]\nDisp \"YOU LOSE…\"\nDisp \"YOUR SCORE:\"\n[instead be:\n[[code]\nDisp \"YOU LOSE…\",\"YOUR SCORE:\n[neat, right?\n* One random trick optimisation was with this line:\n[[code]\nIf G=72 and Y-L+32≠1\n[changed it in my head to:\n[[code]\nIf G=72 and Y-L+32-1\n[can be optimised to save two bytes:\n[[code]\nIf G=72 and Y-L+31\n[am weird, so my methods are awkward. If you want to do the more logical version of my solution:\n[[code]\nIf G=72 and Y-L+32≠1\n-use some algebra-\nIf G=72 and Y-L+32-32≠1-32\nIf G=72 and Y-L≠~31\n-get rid of that negtive sign, it is using an unnecessary byte D: -\nIf G=72 and Y-L+L≠~31+L\nIf G=72 and Y≠L-31\n[[/code]]\nYay :3 (I am in a math optimisy mood, sorry).\n* Often Repeat is more useful than While (in my opinion) because you don't need to set the variables before the loop. When I started learning TI-BASIC, I actually never learned what While did until I joined this site and saw people using it. I just found Repeat and figured out how it worked and I like it .-.\nHere is how I convoluted it:\n[[code]]\nDelVar CDelVar P\" ;6 spaces here\nMenu(Ans+\"PONG\"+Ans,\"TWO PLAYER\",2,\"PRACTICE\",P,\"CHALLENGE\",C,\"QUIT\",Q\nLbl C\n1→C\n2→U\nLbl P\n1→P\nLbl 2\nDelVar VDelVar WDelVar SDelVar T4→L\n32→O\n48→N\nDelVar EDelVar Q1→D\nStoreGDB 0\n1→Xmin\n95→Xmax\nFnOff \nAxesOff\nClrDraw\nIf C or P\nThen\nVertical 1\nVertical 2\nEnd\nHorizontal (-)10\nHorizontal 10\nFor(I,1,93,92\nFor(J,32-L,L+32,1\nPxl-On(J,I\nEnd\nEnd\nRepeat Q\ngetKey→G\nIf G\nThen\nIf G=72 and Y-L+31\nThen\nY-1→Y\nPxl-On(Y-L+32,1\nPxl-Off(Y+L+33,1\nElse\nIf G=92 and Y+L≠29\nThen\nY+1→Y\nPxl-On(Y+L+32,1\nPxl-Off(Y-L+31,1\nElse\nIf G=45\nThen\nClrHome\nDisp \"GAME PAUSED\",\"[ENTER]: RESUME\",\"[CLEAR]: QUIT\nRepeat 30=abs(Ans-75\ngetKey\nEnd\nIf Ans=45\n1→Q\nElse\nIf G=74 and T-L+31\nThen\nT-1→T\nPxl-On(T-L+32,93\nPxl-Off(T+L+33,93\nElse\nIf G=94 and T+L≠29\nThen\nT+1→T\nPxl-On(T+L+32,93\nPxl-Off(T-L+31,93\nEnd\nEnd\nEnd\nEnd\nEnd\nEnd\nN→A\nO→B\nIf N=1 or N=93\nThen\nIf not(C\nThen\nClrHome\nIf N=1\nV+1→V\nIf N=93\nW+1→W\nDisp \"LEFT SCORE:\nOutput(1,13,V\nDisp \"RIGHT SCORE:\nOutput(2,14,W\nPause \nIf V>9\nThen\nDisp \"LEFT WINS!\n1→Q\nEnd\nIf W>9\nThen\nDisp \"RIGHT WINS!\n1→Q\nEnd\n32→O\nDelVar E48→N\nElse\nClrHome\nDisp \"YOU LOSE…\",\"YOUR SCORE:\nOutput(2,13,U\nIf U>|LPONG(1\nU→|LPONG(1\nDisp \"HIGH SCORE:\nOutput(3,13,|LPONG(1\nPause \n1→Q\nEnd\nEnd\nIf pxl-Test(O,N+D\nThen\nIf C and U>2\nThen\nVertical U-1\nVertical U\nU+1→U\nEnd\n~D→D\nElse\nIf pxl-Test(O+1,N+D\nThen\n~1→E\nIf N=2 or N=92\nThen\n~D→D\nIf C\nThen\nVertical U-1\nVertical U\nU+1→U\nEnd\nEnd\nEnd\nIf pxl-Test(O-1,N+D\nThen\n1→E\nIf N=2 or N=92\n~D→D\nEnd\nEnd\nO+E→O\nN+D→N\nPxl-Off(B,A\nPxl-On(O,N\nEnd\nLbl Q\nRecallGDB 0\nClrHome\n[[/code]]\nI gave it a try and I like how you implemented the two player mode. Also, should the pixel be moving at an angle or just back and forth? If you want, I can put together a simple Pong engine so that you can compare it :D"
attachment: null

name: ''
content: 'instead of 0→(variable) try delvar variable'
attachment: null

name: ''
content: 'Oh jeez, looks like you can''t edit posts on this forum. Well, regardless, the PONG.8Xp file is attached. I didn''t mean to cross it out in the previous post.'
attachment: 'file:pong/PONG.8Xp'

name: ''
attachment: null

Command Summary

Returns the angle of expression, interpreting expression as a complex number.

Command Syntax

angle(expression)

• Press 2nd MATH to enter the MATH popup menu.
• Press 5 to enter the Complex submenu.
• Press 4 to select angle(

This command works on all calculators.

X byte(s)

The angle() command returns the angle of a complex number. The argument may be an expression, a list, or a matrix. In the case of a lists and matrices, each element is evaluated individually and the result is outputted to the corresponding element of a matrix or list of the same dimensions as the original.

:angle(2i)
pi/2
:angle({2i,3+i})
{pi/2  tan^-1(1/3)}
:angle([[2i,3+i][i+7,2i]])
[pi/2  tan^-1(1/3)]
[tan^-1(1/7)  pi/2]


name: ''
content: 'Haha, oops, sorry XD I am used to adding things to the end of Str1 instead of putting things before it x_x'
attachment: null

name: ''
content: "Oh, sorry, I misread something and thought that you wanted it at the end of the string, sorry. You could add this to the end of my code to remedy that:\n[[code]]\nsub(Ans,5B+1,int(B\n[[/code]]\nMy code assumes that the input might not be a multiple of 5 digits."
attachment: null

name: ''
content: "[[code]]\n\" → Str0\n.2length(Str1→B\nFor(A,1,B\n0\nFor(C,-4,0\n2Ans+expr(sub(Str1,5A+C,1\nEnd\nStr0+sub(\"ZYXWVUTSRQPONMLKJIHGFEDCBA\",Ans-5,1→Str0\nEnd\n[[/code]]\n\nIt stores it to Str0."
attachment: null

name: ''
content: 'Xeda Elnara''s code works, but it adds the answer to the end of the input. how could that be fixed?'
attachment: null

name: ''
content: 'yet again…above post is mine'
attachment: null

name: ''
content: "it almost works, just need to make this small change\n\n[[code]]\n\"0→Str1\nWhile A\nsub(\"0123456789ABCDEF\",1+16fPart(A/16),1)+Str1→Str1\niPart(A/16→A\nEnd\nIf Str1≠\"0\nsub(Str1,1,length(Str1)-1\n[[/code]]"
attachment: null

name: ''
content: 'Yes, I think we''ve all been there before XD'
attachment: null

name: ''
content: 'Yes, we''ve all been there before XD'
attachment: null

 Welcome to TI-Basic Developer (TI|BD), the TI-Basic information repository! If you are a first-time visitor, please check out the welcome pack to get you up to speed on using the site. We encourage you to become a member and to get involved in the community, and to come back often to see what changes have occurred. And above all else, enjoy your stay!
 The ListPages module does not work recursively.
 Recent Forum Posts Recent Forum Threads Popular Forum Threads I have looked at that page in the past for exactly this, but that is not what I want to do. I... (by Deoxal 20 Oct 2018 04:08, posts: 3) Take a look at the RandIntNoRep page (by Trenly 20 Oct 2018 00:49, posts: 3) What I want to do is to make non repeating pairs of numbers to use with the home screen and graph... (by Deoxal 19 Oct 2018 21:55, posts: 3) (Started 19 Oct 2018 21:55, Posts: 3) (Started 18 Oct 2018 21:24, Posts: 8) (Started 18 Oct 2018 19:09, Posts: 2) (Started 18 Oct 2018 16:24, Posts: 4) (Started 17 Oct 2018 18:28, Posts: 0) (Started 17 Oct 2018 18:28, Posts: 2) (Started 18 Oct 2018 21:24 , Posts: 8) (Started 15 Oct 2018 20:55 , Posts: 8) (Started 14 Oct 2018 05:31 , Posts: 7) (Started 16 Oct 2018 20:12 , Posts: 6) (Started 16 Oct 2018 13:16 , Posts: 5) (Started 10 Oct 2018 22:11 , Posts: 6) TI-83 Basic 68k TI-Basic TI-Nspire Basic TI-83 Basic is the most commonly used, because the TI-83/84 series has been heavily marketed by Texas Instruments to high school students needing a graphing calculator for math and science classes. At the same time, it is the least powerful language, lacking many of the complex commands and programming capabilities. 68k TI-Basic is much more powerful than TI-83 Basic, with support for calculus, indirection, local variables and functions, advanced picture manipulation, and several other features that make it a very rich language. However, it isn't used nearly as much as TI-83 Basic, so it doesn't have as big of a community developed around it. TI-Nspire Basic is quite similar to 68k TI-Basic, but not as programmer friendly: it has poor I/O support, rigid constraints on program execution, and documents are used instead of programs. In addition, it is still relatively unknown to the TI community, so there isn't much documentation available yet.

name: ''
content: "I believe you want a command to convert decimal to hexadecimal? You can do this, where A is the number to convert:\n[[code]]\n\"0→Str1\nWhile A\nsub(\"0123456789ABCDEF\",1+16fPart(A/16),1)+Str1→Str1\niPart(A/16→A\nEnd\nIf Str1≠\"0\nsub(Str1,2,length(Str1)-1\n[[/code]]\nHopefully that works ^^'"
attachment: null

name: ''
content: "[[code]]\n.2length(Str1→B\nFor(A,1,B\n0\nFor(C,-4,0\n2Ans+expr(sub(Str1,5A+C,1\nEnd\nStr1+sub(\"ZYXWVUTSRQPONMLKJIHGFEDCBA\",Ans-5,1→Str1\nEnd\n[[/code]]\n\nI am sure there is a faster and smaller way, but I think that works (I didn't test it)."
attachment: null

name: ''
content: 'Does anyone know how to convert from numeral to hexadecimal? I have a TI-83+ which does not have the ▶Hex command. Please help'
attachment: null

name: ''
content: "Lat's see…my best program is probably either my own version of snake or a blackjack program I wrote. I became interested in programming originally because I was lazy and did not feel like remembering all of the math and science formulas. And I'm terrible at optimizing because…I'm terrible at optimizing (my programs are all like 10x longer than they would be if they were optimized). An example of what some of my early programs were (like when I had never even heard of optimizing).\n[[code]]\nIf A=1\nthen\ndisp \"1\"\nend\nif A=2\nthen\ndisp \"2\"\nend\nif a=3\nthen\ndisp \"3\"\nif a=4\nthen\ndisp \"4\"\nend\netc.\n[[/code]]"
attachment: null

name: ''
content: "clarification:\nwhat i meant would look something like this\n\n[[code]]\n[input]\n\n[divide string into segments of 5]\n\n[compare segments of 5 to 11111 (A) all the way to 00110 (Z)]\n A:11111\n B:11110\n C:11101\n…11100,11011,11010,11001,11000,10111,10110,10101,10100,10011,10010,10001,10000,01111,01110,01101,01100,01011,01010,01001,01000,00111,00110\n\n[add new letter to existing string]\n\n[output string once done]\n[[/code]]"
attachment: null

name: ''
content: 'I''ve got CSS in two places: some on a spreadsheet somewhere and the rest on each page that the CSS is specific to. That''s why you are able to see some stuff and not see others. The spreadsheet passes through wdfiles, but the page-specific stuff does not.'
attachment: null

name: 'Boba Foxx'
content: 'Why is it that the Css for the board index and actually displaying the posts (like on this page) use different Css sheets? The board index page looks just like it should (sans avatar images), but the actual thread pages don''t load the css.'
attachment: null

name: 'Boba Foxx'
content: "Oh, that's what had me confused. Before, you said\n> θ-2x→A\nbut you meant \n> 2X-θ→A\nWhich is basically the solve() line simplified.\n\nI probably would've done that if I'd optimized it much; I'd just woken up from a move in history and was still kinda sleepy, but I was more concerned with getting it to work, rather than getting it to work quickly."
attachment: null

name: ''
content: 'It''s nice to see you again :) What got you interested in programming? Why do you say you''re terrible at optimizing?'
attachment: null

name: ''
content: 'darn… I don''t know how to go about doing this problem. They never teach us any probability at my school >:( I don''t think I''d be able to do it anyway, though.'
attachment: null

name: ''
content: "Right, which is why I said it needs to be negated; try 2X-θ→A instead of the solve line.\n\nBesides that, good work (:\n\nHere's what I came up with, where Ans is the displayed percentage:\n\n[[div class=\"werecode\"]]\n:2Ans-50.5+.01(101-2Ans)abs(Ans-50\n[[/div]]"
attachment: null

name: 'Boba Foxx'
content: "Another correction (I really should get into the habit of testing my code more since I haven't written much recently >.>\n[[code]]\n:If X<5 or X=31\n:Stop\n:Sub(\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\",X,1\n[be\n\n[[code]\n:If X<4\n:Stop\n:output(2,1,Sub(\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\",32-X,1\n[[/code]]"
attachment: null

name: 'Boba Foxx'
content: "It looks like what you're doing is inverted binary (instead of 1 being on and 0 being off, you have 1 represent off and 0 be on). \nThe code I wrote allows you to input a 5 character string of 1's and 0's and it inverts it to give the intended answer (as you said, 11111 is A)."
attachment: null

name: 'Boba Foxx'
content: "Yeah, I never tested anything below 25 (which is where the abs(A breaks for me); your code works perfectly (It should have been \":If abs(A>100)) or (A<0\")\nIf I change the solve( line, then I get way different answers than what I should (like 0 when I input 85, whereas before I got 95.35)."
attachment: null

name: ''
content: "Could the solve() line be simplified to θ-2X→A (which actually needs to be negated for the algorithm to actually work)?\n\nI don't have a calculator that operates TI-Basic anymore, so I transcribed it to C++. It seems to work for numbers greater than 50, but for numbers less than 50, it estimates low (ie. 0 outputs -50.5). I assumed that abs(A>100 was actually 100<abs(a.\n\nI can get it to work by changing:\n[[div class=\"werecode\"]]\n:If abs(A>100\n:100(A>0)→A\n[class=\"werecode\"]\n:If A>E2\n:E2→A\n:If A<0\n:DelVar A\n[[/div]]"
attachment: null

name: ''
content: 'Oops…i forgot to login. The above post is mine'
attachment: null

name: ''
content: 'could you please explain what this does? Because I do not think we are thinking of the same thing'
attachment: null

name: 'Boba Foxx'
content: "Correction:\n[[code]]\n:Delvar B\n:Input \"String?\",str1\n:if 5≠length(str1\n:stop\n:For(Z,1,5\n:B+1(sub(str1,6-Z,1)=2^(Z-1\n:end\nAns→X //not sure if needed, replace the x's on the following lines with Ans if it's not\n:If X<5 or X=31\n:Stop\n:Sub(\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\",X,1\n\n[[/code]]"
attachment: null

name: ''
content: 'Hello AriMB! Nice to see a new face around! What would you say is your best program?'
attachment: null

name: 'Boba Foxx'
content: "If it is inverted binary, then this should do it:\n[[code]]\n:Delvar B\n:Input \"String?\",str1\n:if 5≠length(str1\n:stop\nFor(Z,1,5\n:B+1(sub(str1,Z,1)=2^(Z-1\nend\n\n[[/code]]\nshould work :)"
attachment: null

name: ''
content: "Sooo…\nReverse binary?"
attachment: null

name: ''
content: "I know I'm a little late, as I have been seen lurking around the forum for a month or so, but I would like to introduce myself. AriMB is my actual name. I am 14. I am fairly decent at programming, but am terrible at optimizing. I currently know a little of Java, C++, Objective C, and a fair amount of TI BASIC. I'm not sure what else to say, so I'm gonna stop here.\n\n\nOh wait, I almost forgot…\n…hi!"
attachment: null

name: ''
content: "Wikidot community,\nI have an idea to make a program that takes a string of 1's and 0's in sets of five and translates them into letters so that A is 11111, B is 11110, C is 11101, D is 11100, all the way to Z. Then output this string of letters as a string. Please paste the text as a reply.\n\nGoodluck!"
attachment: null

name: 'Boba Foxx'
content: "I forgot about the [[/code]] >.>\nIT doesn't auto-paste in anymore, I forgot."
attachment: null

name: 'Boba Foxx'
content: "[[code]]\n:Input \"Prob? (0-100) \",X\n:Clrhome:Output(1,1,\"Working\n:For(θ,1,100\n:solve((X-(θ-A)/2),A,{-200,200}\n:Ans→A\n:If abs(A>100\n:100(A>0)→A\n:A→L₁(θ\n:Output(2,1,θ\n:End\n:100→dim(L₁\n:sum(L₁\n:Clrhome:Output(1,1,Ans\n:Output(2,1,\"/10000\n[[/code]]"
attachment: null

name: 'Boba Foxx'
content: "Hmm.. I'm tempted to just brute-force it since I'm too lazy to write an actual algortih…\nI'll see what I can do during precal."
attachment: null

name: ''
content: 'Yes. If Fire Emblem says that the chance of hitting, $p$, is 70%, what is the real chance of hitting? That''s determined by rolling two one-hundred sided dice, taking their average, and checking if that average value is less than or equal to $p$.'
attachment: null

name: 'Boba Foxx'
content: "To make sure I don't go do the wrong thing, I'd like to make sure I understand correctly first.\nBasically, we're to find the probability that we get a hit (which is defined as the the average of two d100 must be less than P) when we're given a chance P of hitting?"
attachment: null

name: ''
content: "In Fire Emblem, when you attempt to attack an enemy, a list of percentages are given indicating things such as hit chance. If the statistics say that you have a 50% chance of hitting, though, you actually have a 49.5% chance of hitting. Why is that?\n\nNormally, you would think that the game would roll a d100 die, and any roll that is less than or equal to the displayed percentage would be a hit; any roll above would be a miss. Fire Emblem games beyond FE5, however, utilize a different system which gives the player a statistical advantage. When a player rolls, two d100 dice are rolled, and the average of the rolls is compared to the percentage instead. Oddly enough, this actually affects the real probability significantly. When FE says you have an 85% chance of a hit, you actually have a 95.4% chance of a hit, which is significantly greater, and therefore you have an advantage, making the game easier and more playable.\n\nHere's the challenge: what is the real theoretical probability $p_r$ of a hit given the displayed hit percentage, $p$? Specify if you take $p$ on the interval [0, 1] or [0, 100]."
attachment: null

The ListPages module does not work recursively.

name: ''
content: 'This is amazing. Nice work!'
attachment: null

name: ''
content: 'Neat, these work :) I also like how nice your buttons look o.o'
attachment: null

name: ''
content: "Ok, so I made a flash application which emulates the buttons to the best of my ability. When you click on the button, it copies the syntax so that you can paste it. I only included the ones I thought were necessary.\n\nPersonally, I find it easier to simply learn the syntax, but this can help newcomers. Now I only need to find a way to make it obvious that you have to paste for this to work…"
attachment: null

name: ''
content: "Thanks! Hopefully I will get some more time in the near future to work on it :) I started adding in a menu, but you currently cannot select anything. It just draws the menu and you can move the selector thing. I need to add in scrolling for menus that are too large for one screen and I need to add in the ability to open sub-menus and then I can start going through the catalog and making tutorials XD\n\nAnother neat idea that I thought of doing was maybe if you are in a menu (like the Math menu) and you want to see how a command works, you can press ON and it starts the appropriate tutorial."
attachment: null

name: 'Timothy Foster'
content: "The \"Member Type\" is temporary; eventually it will say something like \"Member\" or \"Moderator\". I have yet to figure out how to effectively do that, but I've got an idea (which will unfortunately take me quite some time to do).\n\nI never really saw the karma bars as meaning anything relevant. What might be done in place of that is a site \"activity level\" which could go right under \"Member Type\". Making lots of edits or posts would put you at a higher level (a moderator would have to set it though, meaning spam doesn't count).\n\nPost-indention is very hard, and if I implemented it, it would probably look very sloppy. Additionally, nearly every forum I've seen is linear, and one of the reasons for this is so that people respond to the topic instead of the post. It makes it harder for a discussion to become off topic or branch into multiple conversations (which is something I and others have noticed on this forum).\n\nI will try to put the buttons back in. It for sure won't work exactly the same, but I'll see what I can do."
attachment: null

name: 'Boba Foxx'
content: 'Yeah, I kinda miss the post-indenting too.'
attachment: null

name: ''
content: "What I lke (so far):\nAttachments\nlarger avatar pictures \n\nWhat I dislike (so far):\n\"Member Type\" / lack of karma bars\nI really liked the syntax buttons/wizards\nNo indentation disrupts flow"
attachment: null

name: ''
content: 'That''s really cool! :D'
attachment: null

name: 'Boba Foxx'
content: "Crap, it seems that's right. Wdfiles pooped up as blocked.\nI'll see what I can do to get it unblocked."
attachment: null

name: ''
content: "I tried making it so you couldn't make an empty post, but only certain field types have that option, and unfortunately, the 'wiki' field type is not one of those.\n\nYou can \"delete\" (where delete means it still exists, but it is not listed in anything) a post; I just made it very hard to do so. You just have to add the _null tag to the post, which means typing in \"post:#/noredirect/true\" in the url and clicking on the Categorize button. Current permissions are set so that only post owners can delete a post or thread; of course, moderators and admins can do anything."
attachment: null

name: ''
content: Test
attachment: null

name: ''
content: "Let me try something… are you able to access and use this page?\n\nMy suspicion is that your filter is blocking the wdfiles domain, but not the wikidot domain, which is sort of strange. All of Wikidot's CSS runs through the wdfiles domain."
attachment: null

name: ''
content: 'Well, I don''t really advertise it, so that makes sense.'
attachment: null

name: ''
content: "That who I am…\n\nEdit: I have done some basic testing and it seems:\n* You can post a completely empty post, with no text/characters at all.\n* You can't delete a post, unless you manually delete the page\n\nIs there a way to \"fix\" these issues?"
attachment: null

name: ''
content: 'I think that works pretty well.'
attachment: null

name: 'Boba Foxx'
content: "Man, now I know what I'm missing. I though I was just missing the background and some styling.\nOnce this is finished, will the css sheets be able to be hosted on this subdomain in place of the original stuff? That would be awesome :D"
attachment: null

name: ''
content: "Wow, attached is what everyone else is seeing. You are right; every post gets its own page, so that is why the reply box is iframed; it's actually the edit box of a different page. For some reason, your computer or filter is preventing CSS stylesheets from loading up, so unfortunately there is nothing I can do to fix that.\n\nThe reply box will need to be an iframe, but I can provide an option that will allow you to reply on a separate page."
attachment: 'file:tibd-browsercheck/tibd_browserCheck.png'

name: ''
attachment: null

name: 'Boba Foxx'
content: "YES I CAN POST LINKS THANK GOD\nEventually, will the reply thing not be in an iframe? Some browsers can't scroll thos, and it gets annoying"
attachment: null

name: 'Boba Foxx'
content: "I never noticed that for some reason. \nAnyway, when I click the \"Edit\" button, it takes me to this page:\nhttp://tibasicdev.wikidot.com/post:83/edit/true/noredirect/true\nIt says I'm not the creator of that 'page' since apparently, every single post gets its own page. So apparently, that's how replies get to nest out.\nI kinda miss the old nesting thing of the old layout."
attachment: null

name: ''
content: "I have no idea what your filter is doing… somehow, you managed to make a reply to a reply instead of the thread…\n\nHave you tried using the name form yet, right about the calculator symbols?"
attachment: null

name: ''
content: "Actually, it's not editing it, it's taking me to that comment's talk page… I think. Some error about only admins can edit pages.\nAlso: \n guests cannot upload files, and when the reply box redirects to wdfiles after it uploads, it breaks (that might be my filter not allowing redirects, I'm not sure yet)."
attachment: null

name: ''
content: "Oh, the edit button shows up when I hover over a post. Silly me :3\nEdit: guests cannot upload files, and when the reply box redirects to wdfiles after it uploads, it breaks (that might be my filter not allowing redirects, I'm not sure yet)."
attachment: null

name: ''
content: "Oh, the edit button shows up when I hover over a post. Silly me :3\n"
attachment: null

name: ''
content: 'Awesome, that will be very useful for updating projects!'
attachment: null

name: Zeda
content: "Yes, I like that it is on one line :) As well, what happens if one is signed in, but enters a name in the box?\n\nEDIT: Cool, so it uses a default icon and posts basically as if you aren't logged in."
attachment: null

name: ''
content: "This is a test.\n\nYes, I was able to modify the attachment (:"
attachment: 'file:unstable-cake/unstable-cake.gif'

name: Testing
content: Test
attachment: null

name: ''
content: 'I think there are a few things that would be nice if it were possible to add, but I like it how it is :) I especially like the ability to attach files to posts. I think it will help keep things much more organised. I wonder, is it possible to edit an attachment?'
attachment: null

name: ''
content: "Welcome to TI-Basic Developer, Burr! Have you checked out our TI-BASIC Starter Kit? It has everything you need to get started and if it doesn't have something, you can always ask on the forums!\n :P\n\nActually, it took me quite a while to realise that you were the founder of this site. I think it was three years ago when I realised it, actually."
attachment: null

Besides standard math, trigonometry functions are helpful for simulating rotation and making games like Asteroids.

# Key Commands

The trigonometric commands are sin, cos and tan.
sin(θ) returns the sine of θ, which is defined as the y-value of the point of intersection of the unit circle and a line containing the origin that makes an angle θ with the positive x-axis.
cos(θ) returns the cosine of θ, which is defined as the x-value of the point of intersection of the unit circle and a line containing the origin that makes an angle θ with the positive x-axis.
tan(θ) returns the tangent of angle θ, which is defined as $\frac{\sin \theta}{\cos \theta}$
It is slightly unnecessary, as most games that use trigonometry only require sin and cos.

Let's say you are making an object firing simulation and you are keeping track of the angle θ. When you fire, you can increment the location variables X and Y with speed a and angle θ using these formulas:

X+Acos(θ→X
Y+Asin(θ→Y


# Examples

The following code illustrates and then calculates the area of a rectangle inscribed in a circle after the user presses [Enter].

Input "RADIUS: ",R
Input "ANGLE: ",θ
AxesOff
ZSquare
Rcos(θ→A
Rsin(θ→B
Circle(0,0,R
Line(0,0,A,B
Line(A,B,A,­B
Line(A,B,­A,B
Line(­A,­B,­A,B
Line(­A,­B,A,­B
Pause
4abs(AB


The following code awaits the user to input an angle to fire at, using a line to guide, and fires a projectile at that angle until the user presses [Clear]

:AxesOff
:DelVar XDelVar θDegree
:ClrDraw
:94→Xmax
:62→Ymax
:0→Ymin
:Ans→Xmin
:Repeat K=21
:Line(0,0,2cos(θ),2sin(θ
:Repeat Ans
:getKey→K
:End
:Line(0,0,2cos(θ),2sin(θ),0
:max(0,min(90,θ+(Ans=25)-(Ans=34→θ
:End
:Repeat K=45
:X+2cos(θ→X
:Y+2sin(θ→Y
:Pt-On(X,Y
:getKey→K
:End


Of course, Earth has gravity, doesn't it? We can account for that pretty easily. To simplify the problem, we'll just assume that Earth is flat and that the projectile follows a parabolic path:

:AxesOff
:DelVar XDelVar θDegree
:ClrDraw
:94→Xmax
:62→Ymax
:0→Ymin
:Ans→Xmin
:Repeat K=21
:Line(0,0,2cos(θ),2sin(θ
:Repeat Ans
:getKey→K
:End
:Line(0,0,2cos(θ),2sin(θ),0
:max(0,min(90,θ+(Ans=25)-(Ans=34→θ
:End
:2sin(θ→G
:Repeat K=45
:X+2cos(θ→X
:Y+G→Y
:G-.05→G    // :D Now it follows a parabolic path! You can change gravity by changing this number.
:Pt-On(X,Y
:getKey→K
:End


name: ''
content: 'And, it seems as if anonymous users will be able to post with a name!'
attachment: null

name: 'Timothy Foster'
content: 'Yes, I like it a lot better (: It''s less clunky.'
attachment: null

Programming is a very demanding task, and it requires a special kind of person. Most people who try their hand at programming decide that it is either too much work, too boring, or a combination thereof. Fortunately, these people are the ones you don't want to be programming, so it all works out.

Assuming you are not one of those people, there are a few key indicators that tell you whether you are cut out to be a programmer. The first indicator is your mental aptitude. Do you enjoy solving problems and puzzles — for example, a complex math problem — and do you like the more technical things? Programming at its core is about solving problems and figuring things out, so if you don't have the right mental aptitude, then programming probably isn't for you.

Related to the first indicator, the second indicator is your willingness to work through difficult problems and figure things out. This skill requires a very dedicated, almost obsessive person who is transfixed on the problem. Even if you don't know something, you need to be comfortable with that feeling, and still be able to rationally research a solution to the problem.

The third indicator is your passion for learning and growing. Do you spend hours at a time reading and researching in books and documentation? When you see high-quality programs and games, does that make you want to dissect the program to find out how it works? Passion is often what drives you to keep pushing to the next level, and without it, you will almost be guaranteed to just get tired and give up.

All three of these indicators — aptitude, persistence, and passion — are vitally important to any successful programmer. We all face challenges and difficulties, but we overcome them using those different things. If you only have two of the three indicators, you can still be a decent programmer, but you won't be as complete a programmer as you could be.

When you are coding, there are several different pitfalls that you have to be aware of. A pitfall is simply code that is syntactically correct, but does not produce the correct or desired results. This list is not meant to be exhaustive, but rather a general collection of things to look out for.

## Arrow Keys

One of the simplest pitfalls that people make is forgetting to use the proper values for the arrow keys. This is especially prevalent with beginners, since they are still learning the ins and outs of the calculator. For example, when the user is making movement, and wants to update the player position on the board, you will see something like this:

:A+(K=25)-(K=34→A  // Y coordinate
:B+(K=24)-(K=26→B  // X coordinate


While this code looks right, it actually has the arrow directions flipped around (25 should be swapped with 34, and vice versa for 24 and 26). This code will not generate any errors by the calculator, since it is syntactically correct, but figuring out the logic problem can be challenging if you don't recognize the mistake.

## Boolean Expressions

Another common pitfall that people make is messing up their Boolean expressions. A big part of this is simply people not taking the time to learn and understand how the calculator reads Boolean expressions and deals with operator precedence.

A Boolean expression is based on Boolean Logic, the principle that something can be either true or false. A true value is represented as 1 or any nonzero value, while a false value is represented as 0. In addition to the four math operators (*,/,+,-), there are six conditional operators (=,≠,>,<,≥,≤) and four logic operators (and,or,xor,not).

The operator precedence that the calculator follows is math operators are executed first, then the conditional operators and finally the logic operators. Of course, if there are parentheses, the calculator executes what's inside the parentheses first, which can include any one of the three different kinds of operators. Here is an example to illustrate:

:If B=A and CD:Disp "B=A and C*D≠0
:If 5X=2Y+(Y/X≠5:Output(2,2,"Hello


## Memory Leaks

Another pitfall to avoid is causing memory leaks with branching out of loops and conditionals and overusing subprograms. This is especially important because memory leaks not only take up more and more memory, but also slow the calculator down (depending on the size of the memory leak, it can be to a halt).

To prevent memory leaks from occurring, you should always make sure that any loops and conditionals (anything with an End command) are executed to their completion. The reason is that the calculator keeps track of the End commands for loops and conditionals, so if one of them isn't completed, the calculator isn't able to remove it from its list.

While it is possible to correct a memory leak problem in your pre-existing code, the best time to make those changes is when you are actually planning a program. This is because a properly planned program can be made to not only have no memory leaks, but also be as fast and small as possible. Of course, if you don't feel like rewriting your code again, a simple fix will suffice.

:If A=5:Then
:Disp "A=5
:Goto A
:End
should be
:If A=5:Disp "A=5
:If A=5:Goto A


## Portability

One of the most common pitfalls that people make is forgetting about program portability. With all of the Assembly libraries available, and there being several different TI-83 based calculators available, it is easy to see how portability becomes an issue.

In addition to the Assembly libraries, there are also several new commands that TI has added to the TI-Basic language for the newer TI-84+/SE calculators. While you can use these commands in your programs, they will crash your programs if somebody tries to execute the program on a TI-83/+/SE calculator.

Unfortunately, the only thing you can do if you want your program to be TI-83/+/SE compatible is to not use these libraries and commands. This means you won't be able to include that functionality in your program, which can be a big selling point of your program.

If you don't care about your program working on the TI-83/+/SE calculators, then portability isn't an issue for you and you don't have to worry about it. However, you should still tell the user at the beginning of the program that the program is designed to work on the TI-84+/SE, and in fact will crash if used on a TI-83/+/SE.

The same goes for using Archive/UnArchive if you care about portability to the TI-83 calculator. Additionally, while programs with lowercase letters will work on the TI-83, they can't be sent from a TI-83+ or higher to a TI-83 via the link cable.

## Math Errors

Because of the way the calculator is designed, it has limited precision when doing math. Any math calculations that involve extremely small or large numbers (ranging from -E99 to E99) will produce rounding errors that don't return the right number. There are a couple different ways you can deal with this problem.

The round( command will round a floating-point number so that it has the specified number of decimal digits. While you can hypothetically set it so that it has 25 digits, the calculator only allows a number to have up to 14 digits, which means the range is 0-14 digits.

Another way to deal with the problem is by multiplying the number by a smaller number. The calculator will automatically treat the number in a similar fashion to the smaller number, which allows it to make the math expression work. Truthfully, neither of these methods is fool-proof, so you should just be aware of the problem.

Productivity is all about using your TI calculator as efficiently and effectively as possible. There are several things you can do to improve your productivity when you are writing TI-Basic programs:

• Keyboard Shortcuts — In the Program editor, if you press alpha followed by up or down, you will scroll a whole page of program code. In addition, 2nd right will take you to the end of your current line, and 2nd left will take you to the beginning of that line.
• Backup Often — You never know when your calculator might crash, and you would be extremely upset if you lost all of your new work on your program that you had been working on. If you only have one program, backing up just consists of creating a new program, and recalling the program code into that program. However, if your program uses several programs and other variables, you should group it instead.
• Archive Programs — When you are not using a program, you should archive it so that it won't get erased accidentally in case of a RAM clear. This also applies to important program data, such as a highscore list. Alternatively, you can also group the program and program data together so you have both in one file. Grouping also saves more RAM than archiving the programs separately.
• Know The Commands — There are lots of commands on the calculator that people never bother using, mainly because they don't know about them. Before trying to create your own program to do something, check to see if the calculator doesn't already provide a command or function that does it, because the built-in commands are almost always faster and smaller.
• Edit On The Computer — The TI-Graph Link program that TI provides allows you to edit programs on the computer. In addition to faster scrolling and making program structure easier to visualize, the Graph Link also features the ability to type lowercase text and lock a program so it can't be edited on the calculator.
• Use CtlgHelpCtlgHelp is an Assembly application that is rather large (it is 32KB), but is a very helpful reference when trying to remember the syntax for using a command. After you have installed it, you just have to go to the Catalog menu and press the + key to see the help for that command. It can also be used in other menus, such as the MATH, LIST, and PRGM menus.1
• Write Comments — Whenever you write a complicated piece of code, you should put a comment in the code explaining what it does, and if appropriate, how it does it. If you ever need to come back to the code, you will now be able to quickly ascertain everything you need to know about the code. Comments are also useful when you don't have the time to implement something, and you want to remind yourself with a quick "To Do".
• Reuse Code — In many large programs, there are several pieces of code that get reused multiple times. Rather than writing the code over and over again, you can simply store it in its own program and have the main program call it as a subprogram. Because the subprogram is insignificant by itself, you should start its name with a Z or theta so that it appears at the bottom of the program list.
• Coding Style — When writing a program, you should follow code conventions so that it is easy to read and understand. Although each programmer has their own preferences in regards to programming code, there are some general guidelines that most people follow, which help to provide continuity across the programming community:
• Line up corresponding commands and statements vertically.
• Don't go through silly contortions to use a loop, when Goto/Lbl branching would be more practical.
• Use mnemonic label names. For example, Lbl UP would be an appropriate choice for code that moves the screen up.
• Before using custom list variables, you should use up the built-in variables.
• If you have a really complex expression, you should add some parentheses to make it easier to read.
• Be consistent throughout all your code. If you do one thing in one program, you should do it the same way in another program.
• Use subroutines, even if you only use a piece of code once, it is a lot easier to modify an independent program than it is to find that section of code in your whole code. Once you have passed the development stages, use the rcl feature to copy the subroutines into a skeleton.

# General Tips

Checking for Whole Number

The fastest way to check for a whole number is:

:not(fPart(X


Using DelVar

When using the DelVar command, you don't need to use colons (:) between the DelVars:

:Delvar ADelvar Str1...


This also holds when you are dealing with a completely different command, so

:DelVar AClrHome


is perfectly legal.

Know When to Use Variables

Many times you will have to use a number repeatedly in a program. To save memory you can assign that number to a variable at the beginning of your program and then just call that variable whenever you need it. This also works for strings that are used a lot.

Why Variables Get Messed Up

There are several things that can cause variables to get messed up:

• The Equation Solver updates any given letter variable that is solved for.
• Function graphing, and the tracing thereof, causes X and Y to be updated.
• Parametric graphing, and the tracing thereof, causes X, Y, and T to be updated.
• Polar graphing, and the tracing thereof, causes X, Y, R, and θ to be updated.
• Sequence graphing, and the tracing thereof, causes X, Y, and n to be updated.
• Generally, moving the cursor on the graph screen updates X and Y.
• All the above update R and θ as well if in PolarGC mode.
• Tangent, DrawF, and DrawInv update X and Y for each coordinate drawn.
• All Shade( functions update X and Y for each coordinate drawn.
• Y is set to zero per each refresh of the graph screen. (The only reason I can think of is that Y is involved in the calculating of the regions.)
• Generating a list through sequencing does not update letter variables (but will create them if they didn't exist)

Extra Variables

Sometimes when doing a program you might run out of variables to use. If that happens there are many different places you can go to for more variables. Some are:

• Create lists or matrices and just use/manipulate them
• Extra N—Open the catalog and press LOG and ENTER
• Window variables—Hit VARS and then ENTER
• Statistic variables—Hit VARS, 5, and scroll through the menus of variables
• Finance variables—Hit APPS and then go into the Finance application

(Note: You can also use most of them as characters.)

# List Tips

Use Custom Lists before Built-In Lists

Avoid using lists other than L1, L2,…, L6. You should only use custom lists when you need to save something.

Check if Elements are the Same

The quickest way to check if all the elements of L1 are the same is max(Δlist(L1.

Separate a List

You can use seq(L1(A),A,C,D→L2 to separate a list into two or more lists, where C is the start and D is the stop.

Favor cumSum(binomcdf( over seq(

cumSum(binomcdf(X,0 is the same as seq(I,I,1,X and is smaller and faster. See here for more information.

Angle Values in List

If you use the tangent, sine, or cosine function in programs you might notice they aren’t that fast. A better way to do it is to store the values in a list and then recall them from the list.

Store to one List Element Higher than Exists

You can store to one list element higher than exists. This even applies if the list does not exist, in which case the list would be created and the first element would be where the is stored.

:3→dim(L1
:Input A
:A→L1(4


(Note: This will create a fourth element in list 1, and then store A in the fourth element.)

Create a List without the L in Front

When you store to a custom list, usually you need the little “L” in front. However, this is not true. If you just have a letter or a number that is being stored to, it will actually store the list data to a list with the letter or number’s name.

:{1,2→LA
can be
:{1,2→A


Shuffle a List

The smallest and (almost) fastest way to shuffle a list (for instance, a deck of cards) is:

:seq(X,X,1,52→L1
:rand(52→L2
:SortA(L2,L1


This technique can, of course, be extended to lists of other lengths.

Chop Off First Element of a List

You can chop off the first element of a list by using the ∆List( and cumSum( commands together, since they are essentially exact opposites. In this example, the first element of L1 is chopped off and the list is stored back to L1:

:∆List(cumSum(L1→L1


User-Friendly Lists

I'm sure others like me want to be able to type in a list without the brackets, separating the elements with only commas. Here's how:

:Input Str1
:expr("{"+Str1→L1


This will load any list the user names:

:Repeat 5≥length(Str1
:Input "Name of List:",Str1
:End
:expr("L"+Str1→L1


# Matrix Tips

Initializing Matrices

In games where you store maps with all the same values in matrices, you need to initialize the matrices in order to use them. There are three different ways that you can do this.

The first way is to set the dimensions of a matrix and then use the Fill( command:

:{8,8→dim([A]
:Fill(0,[A]


The second way you can initialize the matrix is to actually delete it before using it, and then set its dimensions to the desired row and width. This initialization method only works when you want all the matrix elements to have a value of zero.

:DelVar [A]{8,8→dim([A]


The last way you can initialize the matrix is to use the identity( command. The identity( command is used to create an identity matrix based on the matrix that it's given, which must be a square, n-by-n matrix. Because of the identity( command, this initialization method only works when you have a square matrix and you want all the matrix elements to have a value of zero.

:0identity(8→[A]


# String Tips

Skip String►Equ( Command

If you want to put a string into one of the function variables (Y0-Y9) you don’t need to use the String►Equ( command. Instead, you can just simply store the string into the function variable.

:String►Equ(Str1,Y1
can be
:Str1→Y1


Get → and " in a String

Follow these steps to get the or " symbols in a string:

1. Type them on the home screen and press [ENTER]
2. Select 2:Quit when the ERR:SYNTAX comes up.
3. Press [Y=] to go to the equation editor.
4. Press [2nd] [ENTRY] to recall the symbols to Y1
5. Now, use Equ►String(Y1,Str1) to store the symbols to a string.

Use the expr( Command

One of the most unknown and unused commands is expr(. What this command does is allow you to store an expression to a string (includes graph equations) and then execute the string. Since you may use graph equations, you have 28 "extra" strings to use for text and data storage. But if you use graph equations to store data in a graphics-based program, remember to turn the functions off with FnOff.

:Input “Formula:”,Str1
:Disp expr(Str1


Converting a String to List

The fastest way to convert a string that contains only alphanumeric characters and spaces to a list is:

:seq(inString("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ",sub(Str1,A,1)),A,1,length(Str1→L1


Copy & Paste Function

If you store frequently used code to a string, you can recall the string into a program as a sort of "copy-and-paste" function. However you have to go through menus to get to the string, not to mention delete the quotes. So store your three most frequently used pieces of string into those variables, u, v, and w. Recalling those doesn't make quotes, and it's faster than getting it from a string. See seld-modifying code for more information.

# Ans Tips

If you want to speed up your program while doing calculations, you can use the Ans variable. To use Ans, put the calculation in a line all by itself, then it will automatically be stored into Ans saving the need for storing the calculation into a variable. (NOTE: You should only use Ans if it involves changing just one variable.)

:If 8>C
:Output(4,2,"Higher
:If 8<C
:Output(4,2,"Lower
can be
:"Higher
:If 8<C
:"Lower
:Output(4,2,Ans


Whenever you are using the pxl-Test( command and speed is a priority, you should put the command on its own line and test for Ans:

:pxl-Test(0,0
:If Ans
is faster than
:If pxl-Test(0,0


When you are using a For( loop, you can use the following if you want to store something in A without messing up Ans:

:For(A,16,0,-1
:End


Eliminate Annoying Things

If you want you to get rid of the “Done” message after you exit your program you can place some text or just a single double-quote on the last line of your program. Another option is to use the Output( command, which has the benefit of not moving the cursor to the second line.

:ClrHome
:Output(4,4,"Some Text
:"


Something to be aware of about this, however, is that because there is no Stop command, Return is implied. This is okay if your program runs independently, but be careful if your program was called by another program- it will return to the previous one instead of quitting.

Another annoying thing is the run indicator that appears in the upper right corner of the screen. You can get rid of the run indicator by using Text(-1,0,90," " or Output(1,16," " (on the home screen) in a getKey loop:

:Repeat Ans
:Text(-1,0,90," // 1 space
:getKey→K
:End


Home Screen Text on Graph Screen

To get home screen font on the graph screen (except on the regular TI-83) you should place '-1' at the beginning of the Text( command:

:Text(-1,Y,X,"Text


Digits in a Number

To find out the number of digits in a whole number (i.e., a number without decimals), use the log( function. An abs( function prevents a domain error when taking the logarithm of a negative number:

:1+int(log(abs(#


Empty Variables

You can create an empty string with "→Str1, and an empty list with the ClrList command.

Displaying Quotes and Store

Without storing them to a special string, you cannot usually display quotation marks (") and the store command (→). However, you can mimic these respectively in the Text( command by using two apostrophes (' '), and two subtract signs and a greater than sign (—>).

Right Triangle Hypotenuse

You can get the hypotenuse of a right triangle by using R►Pr(a,b), where a and b are the legs of a right triangle, or abs(a+bi, where a and b are the legs of a right triangle and i is the imaginary i.

Dividing by 100

Using the program editor, you can place the % symbol directly into the code as a replacement for dividing by 100. This saves a few bytes each time you use it.

Using the sub( command, if only one argument is given and it contains an expression that evaluates to a real, complex, or list of numbers, the argument will be divided by 100.

:sub(225
2.25


Turn the Screen Black

If your window is set up so that Xscl < ΔX and Yscl < ΔY, you can use GridOn to make the entire screen black. You should note, however, that is rather slow.
You can also use Shade( to go faster.

:Shade(Ymin,Ymax


Inputting Coordinates

Most programmers know the normal syntax for Input, but it can be used alone without any arguments. This simply displays a little "+" on the graph screen, along with the coordinates on the bottom. The plus symbol can be moved horizontally or vertically to a certain coordinate, and the command ends by pressing ENTER. The coordinates are then stored to x and y, respectively.

:Input


Faster Circles

On the TI-83+ and above, the Circle( command has an alternate syntax. When a complex list such as {i} is added as the 4th argument, "fast circle" mode will be turned on, which uses the symmetries of a circle to save on trig calculations, and draws a circle in only 30% of the time it would normally take.

:Circle(0,0,5,{i


Extra Characters

Although the extra characters are only available through an assembly program, once you have them you can store them to a string and then use the string in a program with no problems. The characters include lowercase letters and ASCII characters (such as @, &, #, \$, and international characters like ä).

Strange Control Flow

There are a few cases of strange control flow, where you can use If conditionals by themselves, or together with loops and/or DelVar, to create some interesting results. The Disp commands tell the input conditions under which they will be executed.

• The dangling else (i.e, the executed statement itself is a conditional)
:If A:If B:Disp "B or not(A)

:If A:Then
:Disp "A
:If B:Else
:Disp "not(A) or not(B)
:End

• Misusing the DelVar bug that occurs when chaining an If, Else, or End command to the end
:If A:DelVar XIf 0
:Disp "not(A)

:If A:Then
:Disp "A
:If B:DelVar XElse
:Disp "A and not(B)
:End


Running Programs from Assembly Shells

As a matter of convenience, you can run your TI-Basic program from an assembly shell. DoorsCS 6 will automatically display all programs, but you need to place a colon (":") as the first line of your program for MirageOS to recognize it. However, it should be noted that there is no guarantee that your program will work correctly when run by a shell.

Moving Setup to Program End

If you have a large program where speed is at a premium, then you want the main program loop as close to the beginning of the program as possible. Since program setup is usually the code that is at the beginning of the program, this means that you should move it to the end of the program and then jump to it using a Goto.

:99→I
:Goto 0
…
:Lbl 0
:ClrDraw
:ZStandard
:ZInteger
:Menu(" FROGGER v1.0 ","PLAY",1,"HELP",2,"EXIT",3


Extra Variables

If you are out of variables (A-Z and theta) to use in a program, there are actually 8 more that can be used in the same way as the others (although they do have functions of their own in certain situations). However, none of them appear in the memory menu. They are:

n


This can be typed using the [X,T,theta,n] button when in sequential mode, or by using the catalog and jumping to n. You can use the DelVar command on this, but you cannot call it if it is not defined like you can other variables.

ℕ, I%, PV, PMT, FV, P/Y, C/Y


These can all be typed using [Apps][Finance…][Vars]. You cannot use the DelVar command on these, however you can call them if they are not defined (they will come up as 0).

This allows for use of up to 35 variables instead of 27.

More Information on the last 7 of these can be found at the bottom of the System Variables page.

Now that you have learned the commands, design theory and game techniques, it's time to put that information to use. These project ideas are for programs that you should try to make to the given specifications, using whatever commands you need. Of course, the specifications aren't set in stone, so you don't have to include something if you don't want to.

In addition to following the specifications, try to make the programs as optimized as possible, and use good design when structuring them (i.e., don't use Goto when a loop is really what you should be using). If you can successfully make all of these programs, and have done a good job writing them, you can consider yourself a good programmer.

If you are having trouble making any of the programs, or you just want some input from other people, you can post in the forum. Before you do that, though, we encourage you to really try to create the programs and put some thought into them.

## Phone Directory

Create a phone directory with these features:

• Make a list of phone numbers, and also include the person(s) who own the phone number.
• Display the phone numbers and person(s) on the screen.
• Let the user sort through the phone numbers in ascending and descending order.
• Let the user create, delete, and update the phone numbers and person(s).

## Role-Playing Game (RPG)

Create an RPG with these features:

• Use the home screen for the interface.
• Split the map into multiple pieces, displaying each piece when needed.
• Create a theme for the RPG and base everything off of it.
• Give the player a few weapons to attack enemies with.
• Create AI enemies that the player can battle for experience points.
• Make a couple bosses that the player has to defeat to advance to the next level.
• Upgrade the player weapons when set experience points are gained.

## Snake

Create a snake game with these features:

• Make a snake character that you can move around on the screen using the arrow keys.
• Randomly display a piece of food on the screen for the snake to "eat".
• Use collision detection to check if the food was eaten or the snake went off the screen.
• If the snake goes over the screen boundaries, the snake is dead and the game is over.
• Keep a highscore based on the highest amount of food the snake has eaten at one time.

## BlackJack

Create a blackjack game with these features:

• Use a graphical interface.
• Have custom input for both players, alternating between players.
• Implement all the rules of blackjack into the game.
• Record the games won/lost by each player.

## Hangman

Create a hangman game with these features:

• Use a graphical interface.
• Use custom input for both players.
• Have one player choose a word, and the other player guess the word.
• The guessing player gets ten chances to guess the word before they lose.
• The guessing player selects a letter that they think is in the word. If the letter is there, then that letter is revealed and the player doesn't lose a chance.
• If the letter is not there, the player loses one of their chances.
• If the player guesses all the letters in the word, they win. If they run out of chances before they get the word, they lose.

## Flight Simulator

Create a flight simulator with these features:

• Use the graph screen
• Use way points and navigation
• Use multiple computing systems to determine attributes such as location, speed, angles, weather, engine condition, distance, fuel etc.
• Use auto piloting
• Include output of direction, angle relative to horizon, attributes, and system efficiency

content: 'I don''t know if you guys noticed, but I changed the TI-Basic characters above the reply box to just one line. Does that look any better?'
attachment: null

content: 'I can''t remember. I probably wanted to observe graphs dynamically like what you can do on various computer programs and the new Nspires.'
attachment: null

formOne: ''
content: "I thought I would create an intro thread as well, just like X/Zeda.\n* I am the founder of TI-Basic Developer.\n* I used to be a member of both United-TI and Cemetech.\n* I don't do any TI-Basic programming anymore, but I do enjoy the community around the site.\n\nThat is all :P"
attachment: null

formOne: ''
content: ''
attachment: null

content: 'That looks nice :) I''m curious, why did you create that?'
attachment: null

content: "I've seriously got to figure out how to make the system handle anonymous users properly.\n\nAre you able to take a screenshot of what you are seeing?\n\nAlso, are you not able to edit your posts? If you can't, then I don't know how to fix it, because theoretically, you ought to be able to…"
attachment: null

content: 'That''s displayed when you hover over the date/time.'
attachment: null

content: 'Would it be possibble to have a "n minutes ago" thing with some of the posts? Sometimes wikidot gets my time zone wrong and it''s confusing.'
attachment: null

content: "Welcome to TI-Basic Developer! Na, just kidding :D\n\nIt sounds like you are digging the new forum… Any things you would change about it?"
attachment: null

content: 'Thanks for that page, Timothy :)'
attachment: null

content: 'It looks nice :)'
attachment: null

content: "I do like the \"Goto this post\" thing, too.\nAlso, would it be possible to edit a post that's attributed to your IP?"
attachment: null

content: "This page is weird for me. CSS seems to br broken for me, according to firebug it's trying to load from the wikidot domain.\nAlso, this reply thingy is weird."
attachment: null

content: "I found this little guy sitting in my pile of things I did a long time ago:\n\n[[code]]\nClrDraw\nFnOn\nFull\nAxesOn\nDispGraph\n2→F\nRepeat Ans=45\nIf sum(Ans={92,93,94,82,83,84,72,73,74\nThen\nAns-36-5int(.1Ans\nexpr(sub(\"789 456 123\",Ans,1→F\nDelVar A\nEnd\nIf Ans=32 or Ans=33\n1+(Ans=33→A\nIf Ans=24 or Ans=26\nThen\n1-2(Ans=26\nAns(Xmax-Xmin)/(10F-1→T\nXmin-Ans→Xmin\nXmax-T→Xmax\nDelVar A\nEnd\nIf Ans=25 or Ans=34\nThen\n1-2(Ans=34\nAns(Ymax-Ymin)/(10F-1→T\nYmin+Ans→Ymin\nYmax+T→Ymax\nDelVar A\nEnd\nIf Ans=85\nThen\nXmin(F-(F-1)(A=2→Xmin\nXmax(F-(F-1)(A=2→Xmax\nYmin(F-(F-1)(A=1→Ymin\nYmax(F-(F-1)(A=1→Ymax\nDelVar A\nEnd\nIf Ans=95\nThen\nXmin/(F-(F-1)(A=2→Xmin\nXmax/(F-(F-1)(A=2→Xmax\nYmin/(F-(F-1)(A=1→Ymin\nYmax/(F-(F-1)(A=1→Ymax\nDelVar A\nEnd\nIf Ans=12\nThen\nZStandard\nDelVar A\nEnd\nDispGraph\ngetKey\nEnd\n[[/code]]\n\nSupposedly, this allows you to dynamically manipulate the graphscreen without having to input the window boundaries every time. Using the buttons below causes it to perform the respective actions.\n\nArrow Keys — Determines the direction by which the screen moves relative to the origin.\n+ — Zoom in. The axes scales become smaller.\n- — Zoom out. The axes scales become larger.\nNumber Pad — Determines the scale factor. 9 makes very large changes; 1 makes very little changes.\nX,T,θ,n — This button plus a zoom button will exclusively zoom the x-axis.\nSTAT — This button plus a zoom button will exclusively zoom the y-axis.\nWINDOW — Resets the graph screen to a window of X(-10,10) Y(-10,10).\nCLEAR — Halts program."
attachment: null

content: "One of my project ideas is something called the Chess Sandbox. Essentially, it will be a chess program which has absolutely no validation checks; everything will be based on the honor system. By doing this and making a wider variety of piece models available, users will be able to make up their own variations of chess and play them online.\n\nCurrently, my plan is to write this in Actionscript 3.0, but I have been contemplating the use of Java. One of my fears is that I won't be able to figure out online capability and whatnot. Creating live connections seems like it could be difficult; then again, it must be possible, considering Minecraft was written in Java and handles multiplayer fairly decently."
attachment: null

content: '(Just a test.)'
attachment: null

content: ''
attachment: 'file:20121204164418-0/20121204164418-0.jpg'

content: 'Actually, the rules page just says that the rules aren''t yet available. However, I read the rules on the post here.'
attachment: null

attachment: null

content: 'What happened to the different tools above the text box?'
attachment: null

content: 'This is just a test. '
attachment: null

content: "I have finished the New Forum System enough for testing. Please see how you like it!\n\nA few things you will notice:\n* You cannot preview a post. This is due to the Wikidot coding I'm using. However, sacrificing this functionality means being able to make attachments and having the integrated char box.\n* The syntax buttons do not show anymore. All of the relevant styling can be found here.\n* Everyone has the member type \"Member Type\". I still haven't quite figured out how I want to code this; it isn't easy.\n* I'm still figuring out how this is going to affect unregistered users (sorry Boba Foxx…), but I have ideas on making it work.\n\nPlease provide feedback so the system can better fit the needs of the community."
attachment: null

content: "Woah! I wanna do it! \nI tried to sign up, but it has a box that says \"I read and agree the contest rules, and the calendar in case I want to judge.\" —where can I find the contest rules?"
attachment: null

Recent Posts

The ListPages module does not work recursively.

The ListPages module does not work recursively.

attachment: null

 Feb 02 — Timothy Foster revised the forum system. Check it out!

content: "Here are some pointers on how you can embellish your posts.\n\n||~ Style||~ Code||\n||Bold|| **Bold**||\n||Italic||//Italic//||\n||Underline||__Underline__||\n||Monospace||{{Monospace}}||\n||Superscript||Super^^script^^||\n||Subscript||Sub,,script,,||\n||Internal Link||[[[home|Internal Link]]]||\n||External Link||[http://tistory.wikidot.com/ External Link]||\n\nYou can make code by encasing it in [[code]]...[[/code]] blocks:\n[[div class=\"code\"]]\n[[code]]\nYour code here!\n[can make a quote with the following syntax:\n[[code]\n> This is a quote\n[[/code]]\n\nYou can post math equations by encasing a LaTeX expression in [$]...[$] tags.\n\n[[code]]\n[$]\nx = {-b \pm \sqrt{b^2-4ac} \over 2a}\n[= {-b \pm \sqrt{b^2-4ac} \over 2a}\n[$"
attachment: null

attachment: null

content: 'For the curious, I have entered in TI-BASIC (68K and z80) and z80 Assembly. I doubt I will have time for it all, but I do like to participate and join the fun! I will have school to contend with, finishing up my last requirements for my math major among other things and trying to pass French IV :P'
attachment: null

content: "I don't know if any of you have heard of it, but TI-Concours 2013 recently opened up. Ti-Concours is an annual competition and is typically a French competition (Concours = Competition). Last year they bridged a language barrier and opened it up to the English speaking community as well. It was a success and so they have once again opened it up to everybody. This year's categories are:\n* TI-BASIC z80\n* TI-BASIC 68k\n* Axe\n* z80 Assembly\n* Nspire Lua\nThe competition has some interesting components in the final rounds including an interview in English or French, depending on your language and a three hour test to see what you can come up with in a short period of time. The rest of the competition is split up over a period of about six weeks where TI-BASIC (68k and z80) and Axe have two challenges that last one week and the other two categories have one challenge over two weeks. There is some overlap, but the schedule looks like this:\n\n\nThere is nothing to lose and the prizes are pretty nice! Last year they got surprised with being able to dole out even more prizes (I think up to fifth place in some categories). If you want to sign up before the competition starts, you can register here.\n\nI hope at least some of you can join! There are currently only 4 entrants for TI-BASIC (z80) and two for 68K BASIC!"
attachment: null

content: "Find the next number in the following sequence. To date, no one has been able to find it.\n\n[[div style=\"font-size: 120%;\"]]\n* 9, 0, 2, 6, 94, 10, 42, ?\n[[/div]]"
attachment: null

attachment: null

content: "Sometimes, optimization requires more than just squeezing out bytes. Entire sections of code can often be revised into more compact, efficient algorithms.\n\nDiscover what this program does and rewrite it for either speed or size.\n\n[[code]]\nClrHome\n\"?→Str1\nDisp \"AX²+BX+C=0\nPrompt A,B,C\nIf A<0\nThen\n‾A→A\n‾B→B\n‾C→C\nEnd\ngcd(A,abs(B\ngcd(Ans,abs(C→V\nA/Ans→A\nB/V→B\nC/V→C\nFor(D,A,1,‾1\nIf not(fPart(A/D\nThen\nFor(E,abs(C),1,‾1\nIf not(fPart(C/E\nThen\nA/D→F\nabs(C/E→G\nIf DAns+FE=B and EG=C\n\"1D1E1F1G→Str1\nIf DG-FE=B and ‾EG=C\n\"1D‾E1F1G→Str1\nIf FE‾DG=B and ‾EG=C\n\"1D1E1F‾G→Str1\nIf ‾DG-FE=B and EG=C\n\"1D‾E1F‾G→Str1\nIf DE+FG=B and EG=C\n\"1D1G1F1E→Str1\nIf DE-FG=B and ‾EG=C\n\"1D‾G1F1E→Str1\nIf FG-DE=B and ‾EG=C\n\"1D1G1F‾E→Str1\nIf ‾DE-FG=B and EG=C\n\"1D‾G1F‾E→Str1\nIf Str1≠\"?\nThen\nClrHome\nDisp \"(AX+B)(CX+D)=0\nFor(H,1,7,2\nDisp expr(sub(Str1,H,2\nEnd\nDisp \"FACTOR OUT\nOutput(7,2,V\nReturn\nEnd\nEnd\nEnd\nEnd\nEnd\nClrHome\nDisp \"PRIME\nDisp \"FACTOR OUT\nOutput(3,2,V\n[[/code]]"
attachment: null

content: "Very few people have the guts to fight giant ants.\n\nGood luck."
attachment: null

content: .
attachment: null

attachment: null

content: Pilot.
attachment: null

content: "Right I'm getting to it.\n\n\"Categorize\" is a button that allows you to add descriptive tags, such as axe, movement, arcade, etc. It's just a way of adding more description to a thread."
attachment: null

content: 'Yes, there is; I just hadn''t implemented it last night when I made this post because I was too tired XD'
attachment: null

content: 'This is needed to initialize the system.'
attachment: null

attachment: null

attachment: null

content: 'Hmm, is there a way to sticky topics? Otherwise this might get pushed to the bottom.'
attachment: null

attachment: null

content: 'This is (you guess it) a pilot thread.'
attachment: null

content: 'Okay, thanks! I can work with that. Should we then have a topic to go over all of the special things?'
attachment: null

content: "Hi, I am Zeda, also known as Xeda. I am a moderator here on TI-Basic Developer and I am sure many of y'all are familiar with me. With the new site change, I figured I would help populate the Introductions forum, though. So, about me:\n\n* I have been programming the TI-83+/84+ series for around six years, now.\n* I have a TI-84+, TI-84+SE, and a TI-89t.\n* I program in TI-BASIC and Z80 Assembly and I often help out by supplying assembly hexcodes for things that cannot be easily done in BASIC.\n* I am a moderator here and on several other sites.\n* I am in college, majoring in mathematics. I have also tutored highschoolers.\n* I am almost 21 and I am married :)\n* I was a museum tour guide for a few years. Basically, I just like teaching and helping people out.\n\nFeel free to ask me stuff! I've worked quite a bit with TI-BASIC and z80 assembly, so even if I am not the most knowledgeable, I might know something!"
attachment: null

content: 'This is a pilot thread.'
attachment: null

content: 'This is a pilot thread.'
attachment: null

content: 'This is a pilot thread.'
attachment: null

content: 'This is a pilot thread.'
attachment: null

content: 'This system is using what are called Wikidot Data Forms; that was how I was able to integrate the Char box and place an attachment option. A couple of the downsides to using data forms, though, is that you cannot preview content, and that toolbar of buttons does not appear. Essentially, it is a tradeoff between the preview/text-style buttons and the char/attachment boxes.'
attachment: null

content: "I cannot find an easy way to add to General Discussion, Programming & Design, Projects & Contests. Is this something planned? Also, I notice the \"categorize\" thing. What does that do?\n"
attachment: null

content: "Awesome, it looks great! Are we going to have the buttons for things like urls, images, [[code]] and [[math]] things? And is there some way to preview your post? It looks very nice at the moment.\n\nEDIT: Editing works :D"
attachment: null

content: 'The new forum is now up! Test it to see how it is.'
attachment: null

content: 'I think so.'
attachment: null

content: "I am liking this style :) And the attachment worked o.o\n∏(1-1/p)-s\nHave you managed to figure out a way to preview posts?"
attachment: null

content: 'This looks nice.'
attachment: null

content: 'The purpose of this section is to make posts about individual wiki pages.'
attachment: null

content: 'How is the new forum? What changes ought to made?'
attachment: null

attachment: null

attachment: null

The ListPages module does not work recursively.

content: "You are very silly.\n\nEDIT: Test edit."
attachment: null

content: "Nunc iaculis urna elementum quam. Suspendisse tristique eros quis massa. Sed iaculis, ligula at posuere tempor, lectus libero fringilla eros, a vehicula felis magna non pede. Donec ac lacus. Donec risus erat, rutrum sed, ornare at, suscipit a, nibh. Nullam posuere laoreet purus. Duis aliquet sollicitudin felis. Pellentesque ipsum. Praesent vel libero. Phasellus suscipit aliquet tortor. Fusce ornare blandit risus. Vivamus venenatis blandit pede. Nullam massa. Ut placerat fringilla neque. Nam tortor magna, imperdiet ut, volutpat in, lobortis vitae, sem. Donec in nisi ac leo fermentum eleifend.\n\n[[code]]\nPrompt A,B,C,D\n3-1(3C/A-B2/A2→P\n27-1(2B3/A3-9BC/A2+27D/A→Q\nP3/27+Q2/4→E\nIf E≥0\nThen\n3√(-Q/2+√(E→U\n3√(-Q/2-√(E→V\nU+V→I\n-(U+V)/2+i(U-V)√(3)/2→J\n-(U+V)/2-i(U-V)√(3)/2→K\nElse\ncos-1(-Q/(2√(abs(P)3/27→R\n2√(abs(P)/3)cos(R/3→I\n-2√(abs(P)/3)cos(3-1(R+π→J\n-2√(abs(P)/3)cos(3-1(R-π→K\nEnd\nB/(3A\nFix 3\nDisp I-Ans,J-Ans,K-Ans\nFloat\n[[/code]]\n\nLorem ipsum dolor sit amet, consectetuer adipiscing elit.\n\nEditing the original thread."
attachment: null

[[/row]]

content: '??????????????????????????'
attachment: null

content: 'Supposedly, this will take me to the post I just made.'
attachment: null

content: 'One more post.'
attachment: null

content: 'I am giving this post an attachment. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus arcu libero, aliquet sit amet, ornare quis, vulputate a, nibh. Aliquam sit amet lectus vitae ligula feugiat condimentum. Proin eu mauris. Suspendisse ac sem. Cras in quam in augue fringilla porttitor. Nulla facilisi. Aliquam erat volutpat.'
attachment: 'file:dragon-encode/dragon_encode.png'

attachment: null

content: 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus arcu libero, aliquet sit amet, ornare quis, vulputate a, nibh. Aliquam sit amet lectus vitae ligula feugiat condimentum. Proin eu mauris. Suspendisse ac sem. Cras in quam in augue fringilla porttitor. Nulla facilisi. Aliquam erat volutpat.'
attachment: null

content: 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus arcu libero, aliquet sit amet, ornare quis, vulputate a, nibh. Aliquam sit amet lectus vitae ligula feugiat condimentum. Proin eu mauris. Suspendisse ac sem. Cras in quam in augue fringilla porttitor. Nulla facilisi. Aliquam erat volutpat.'
attachment: null

content: 'Does this work?'
attachment: null

.