I was looking at your code, and here's what I was able to come up with:
Code: SetUpEditor |LPASSW
ClrHome
Disp "BOOTING...
rand(450
ClrHome
Disp "SYSTEM ONLINE
rand(|E2
Disp "USER ONLINE
rand(|E2
Disp "INITIALIZING...
rand(|E2
ClrHome
Disp "MODULE READY
ClrHome
If not(dim(|LPASSW
Then
Input "NEW PASSWORD:",Str1
For(I,1,length(Str1
inString("1234567890",sub(Str1,I,1->|LPASSW(I
End
Else
"
Input "PASSWORD:",Str1
For(I,1,dim(|LPASSW
Ans+sub("1234567890",|LPASSW(I),1
End
If Str1!=sub(Ans,2,length(Ans)-1
Then
Pause "WRONG
Return
End
End
rand(|E2
Disp "GREETINGS
Disp "STATUS:NOMINAL
Pause "READY FOR INPUT
Lbl D
Menu("MAIN","PLAY GAME",B,"CHAT",E,"QUIT",C
Lbl B
ClrHome
Disp "NO GAMES YET INSTALLED","GET GAMES HERE:
Pause "CEMETECH.NET
Goto D
Lbl E
Menu("WHAT DO U WANT TO DO?","FACTS",F,"PLAY GAME VS CALC",G,"BACK",D
Lbl F
ClrHome
Pause "FACTS..\.
Goto E
Lbl G
Menu("GAMES VS CALC","COIN TOSS",J,"R.P.S.",K,"BACK",E
Lbl J
ClrHome
Pause "COIN TOSS
Pause "ITS "+sub("HEADS!TAILS!",6randInt(1,2)-5,6
Goto G
Lbl K
ClrHome
Disp "1=ROCK 2=PAPER 3=SCISSORS
Prompt A
randInt(1,3->R
Disp "YOU CHOSE "+sub("ROCK PAPER SCISSORS",8A-7,8
Disp "CALC CHOSE "+sub("ROCK PAPER SCISSORS",8Ans-7,8
A-R
If Ans
Then
sub("BOTYOU",3max(Ans={1,~2})+1,3)+" WON!
Else
"TIE!
End
Pause Ans
Goto G
Lbl C
ClrHome
You can copy/paste that into SourceCoder and send it to your calc.
That's a lot, so let's go through it piece by piece:
Code: SetUpEditor |LPASSW
SetUpEditor is a very powerful list command. It creates the list if it does not already exist, unarchives it if it is archived, and does nothing if it already exists and is RAM. So after this line, the list ʟPASSW is guaranteed to be defined and unarchived.
Code: ClrHome
Disp "BOOTING...
rand(450
ClrHome
Disp "SYSTEM ONLINE
rand(|E2
Disp "USER ONLINE
rand(|E2
Disp "INITIALIZING...
rand(|E2
ClrHome
Disp "MODULE READY
ClrHome
This part is nearly identical to yours. The main difference is that I replaced the For( loops with rand(#. This relies on the fact that it takes substantial time to generate a random list. The number in the rand command is the number of random elements the list should have, so increasing the number will make it make a longer delay. I tried to keep about the same delay as your For( loops, but you can adjust the numbers to your liking.
Code: If not(dim(|LPASSW
Then
This will determine whether or not ʟPASSW has any elements in it (evidence of a password being set).
Code: Input "NEW PASSWORD:",Str1
Prompt for a new password and store it into Str1.
Code: For(I,1,length(Str1
inString("1234567890",sub(Str1,I,1->|LPASSW(I
End
This recursively goes through Str1 and stores the number in the string into ʟPASSW. If Str1 was "1472", then ʟPASSW is now {1,4,7,2}
Code: Else
"
Input "PASSWORD:",Str1
If the password is already defined, put an string " " in Ans. Note that there must be a space in the string, otherwise it will cause an error. Next, we ask the user to enter the password.
Code: For(I,1,dim(|LPASSW
Ans+sub("1234567890",|LPASSW(I),1
End
This goes through ʟPASSW and adds the character (which is a string of 0-9) to the space character in Ans. Since this updates Ans on every loop iteration, we can simply add to the string and it will grow in length. If ʟPASSW is {1,4,7,2}, then Ans will now be " 1472". The beginning space is still present from before the For( loop.
Code: If Str1!=sub(Ans,2,length(Ans)-1
Then
Pause "WRONG
Return
End
End
The inline sub( command chops off the first character of the string in Ans, which contains the correct password. If Str1 (what the user just entered) is not equal to Ans without the first character (the space), then the password is incorrect. If it is incorrect, then it displays "WRONG", waits for the user to press enter, then quits the program.
Code: rand(|E2
Disp "GREETINGS
Disp "STATUS: NOMINAL
Pause "READY FOR INPUT
I removed an unnecessary Lbl (it was never called) and chopped off a few bytes.
Code: Lbl D
Menu("MAIN","PLAY GAME",B,"CHAT",E,"QUIT",C
Lbl B
ClrHome
Disp "NO GAMES YET INSTALLED","GET GAMES HERE:
Pause "CEMETECH.NET
Goto D
Lbl E
Menu("WHAT DO U WANT TO DO?","FACTS",F,"PLAY GAME VS CALC",G,"BACK",D
This is nearly identical to yours. I was able to save a handful of bytes here. I am quite curious how running programs will work though.
Code: Lbl F
ClrHome
Pause "FACTS..\.
Goto E
I just added this small piece of code in to stop the ERR:LBL from showing up. I would replace it with a randInt(1,[number_of_facts]), and then use different Disp commands to determine which fact to display. The rest is pretty self-explanatory.
Code: Lbl G
Menu("GAMES VS CALC","COIN TOSS",J,"R.P.S.",K,"BACK",E
I think this is the same as yours.
I was able to optimize the coin flip pretty heavily. Here's how it works:
Code: Lbl J
The label to jump to, obviously.
Code: ClrHome
Pause "COIN TOSS
Clear the screen and display the text.
Code: Pause "ITS "+sub("HEADS!TAILS!",6randInt(1,2)-5,6
Add the string "ITS" with the result of the sub( command. Sub( returns a substring of larger string, starting at the second argument and continuing for the third argument's characters. In other words, sub("HELLO",2,3) would return "ELL". Here, we begin at a random number (either 1 or 2 since that's the number of possibilities) multiplied by 6 (the length of each possible result ("HEADS!" or "TAILS")) minus 5, bringing us to the beginning of the string. Therefore, depending on the randInt, it will either begin at 1 or 7. It will then continue for 6 characters, the lengths of both "HEADS!" and "TAILS!". It will display the result and wait for the user to press enter.
Code: Goto G
Jump back to the menu.
I was also able to optimize a whole lot out of the Rock, paper, scissors game. Let's go through that too.
Code: Lbl K
ClrHome
The label to jump to, then clear the home screen.
Code: Disp "1=ROCK 2=PAPER 3=SCISSORS
Prompt A
Tell the user what each number uses which object, and allows them to type in a number 1-3. Both the user and the bot will have their object encoded as a 1, 2, or 3 (rock, paper, and scissors respectively).
Code: randInt(1,3->R
The "bot" picks a random action, represented by 1-3.
Code: Disp "YOU CHOSE "+sub("ROCK PAPER SCISSORS",8A-7,8
Disp "CALC CHOSE "+sub("ROCK PAPER SCISSORS",8Ans-7,8
This displays the string "YOU CHOSE" with a sub( command determining the text version of which object they chose. I won't re-explain how sub( works, but each weapon is increased with spaces to occupy 8 character spaces because they must all be the same length, and "SCISSORS" is 8 letters long. The second line is nearly the same as the first, but is dependent on the bot's choice (Ans) instead of the user's (A).
Code: A-R
I hope you can figure this one out...
It uses an algorithm I actually discovered while I was making this today. If you subtract the bot's choice from the user's choice, it will return a number from -2 to 2 inclusive. The result actually indicates who won, with -2 or 1 being a win for the user, -1 or 2 being a win for the bot, and 0 being a tie.
Code: If Ans
Then
If the aforementioned result is non-zero, or not a tie...
Code: sub("BOTYOU",3max(Ans={1,~2})+1,3)+" WON!
Return either "BOT" or "YOU" in another sub( command. max(Ans=(1,~2} is basically a fancy way of saying Ans=1 or Ans=-2. If Ans=1 or -2, then it will return "YOU" and if not, it will display "BOT", then tack " WON!" onto the end.
Code: Else
"TIE!
End
If A-R is 0 and a tie has occurred, simply put "TIE!" in Ans.
Code: Pause Ans
Goto G
Display whatever is in Ans (either "BOT/YOU WON!" or "TIE!"), wait for the user to press enter, and return to the game menu.
Code: Lbl C
ClrHome
This is the label to jump to when exiting the program.
There might be a few more bytes that can be saved through optimizations, but that's the best I could do.
Now, I'll just add a few useful tips:
• You never need closing parenthesis, brackets, braces, or quotes if they are at the end of a line or immediately before a → variable assignment. For example,
Code: Disp "TEXT"
can be
Disp "TEXT
{1,2,3}→ʟLIST
can be
{1,2,3→ʟLIST
5(A+2)→A
can be
5(A+2→A
• You can display a string and pause on a single line. For example,
Code: Disp "TEXT"
Pause
can be
Pause "TEXT"
The only disadvantage that I can think of with this is that it also puts "TEXT" in Ans, but that's often unimportant.
• Making a delay with a For( loop is inefficient. You can instead use rand(# for a delay while using many fewer bytes.
• The sub( command is extremely useful when displaying different strings. For more information on it, look here.
• Ans is great when saving bytes. It always contains the most recent result of an evaluation, which can be updated by simply having something on a line by itself, a variable store, or displaying something at a Pause.
That's all I can think of right now. I would recommend looking at http://tibasicdev.wikidot.com/ if you haven't already; it has documentation on every TI-Basic command, useful reference pages, code routines, optimization and code structure help, example programs, and tons of other useful things to learn from.
I hope my advice and optimized code was useful! If you're confused by anything about my code, feel free to ask. I hope you continue to work on your project, but it's okay if you just want to focus on a plain chatbot. Regardless of what you work on, good luck and I hope to see it on my own calculator sometime!