I started programming on a TI-83+ (calculator, so no copy and paste) today, during TA. I’m writing a text-based game, and I have a fairly simple layout right now. You choose a character (elf, witch, or barbarian) and go to the Badlands. You fight creatures, and eventually I’m going to figure out how to make this game have a point.
Since I’m going to have a lot of scenarios that are almost the same, and a fair amount of scenarios that are pretty much exactly the same, I’d like to find a way of making a shortcut so I don’t have to write a whole new subroutine for barb vs. worm, witch vs. worm, elf vs. bear, etc. Is there any way to put in a program for a command and alter it slightly without having to make a new program and recopy all the code or alter every instance of the original program’s use?
In other words, is there any way for me not to have to write out all the possibilities for combat in order to have a workable game? I really don’t want to…
I have no idea how a TI-83 operates, so this might do you no good at all, but I would suggest looking in the manual for subroutines and/or functions. It might be possible to write a “fight worm” subroutine which accepts a variable loaded with the value “elf,” “witch,” or “barbarian” and returns the variable for the “elf,” “witch,” or “barbarian” modified by the damage or glory that the variable garnered. (Functions work in a similar way, but they simply return an independent value rather than the modified value you supplied to them.)
YMMV, obviously.
Have all of the creatures descend from a common base class and use The Wonders Of Polymorphism ™ to write a single function that handles combat based on the classes?
Never mind. I’ll walk away quietly now.
Jeezus. This is a TI-83 we’re talking about here, not Java.
OTOH, 'twould be quite an impressive hack to build a fully operational OOP environment on a calculator.
:: thinks :: Naaaah.
Here’s a useful tip for you people working in languages with C-derived syntax:
When comparing a variable against a constant for equality, put the constant on the left. e.g.:
if (0 == x) {
...
That way, if you’re in a caffeine-adled brainfart at 4AM, and you accidentally use an assignment operator instead of a comparitive operator, you get a far more useful compiler error instead of a bizarre mysterious “hmm, this isn’t working right” error.
If I was writing this in C I’d probably have a fight() function that took a couple of parameters specifying what creatures are slugging it out:
hold all combatants in an array, probably of structs. This would hold the type of person/monster and its current strength etc.
in a call to fight() hand in pointers to the combatants
fight(combatants[0],combatants[4]);
inside fight() do a lookup from the array to find the strengths of the combatants to figure out who wins.
That’s all well and good, folks, but IIRC, the TI-83 uses a form of TI-BASIC, not C. Some kind of BASIC, anyway. So no structs. And no functions either. Actually, you can have functions, but basically it’s you write another program and call it. It’s not so bad, but it looks like the OP wants to avoid that. Just use a GOTO or two and you can put it all in one program. And, just in case your “that’s not the way I’m used to programming!” meter hasn’t totally pegged out, you only have 27 variables, A-Z and Theta. (You can have more if you use lists or matrices or some other trick, but when do you need more than 27?)
Now, as to the question in the OP, you may be able to do something that lets you not copy all the code over. How easy this is totally depends on what you want to do! You say you want different things to happen based on the identities of the two combatants, but how different? If your combat rules are as simple as, say, bear beats rabbit, rabbit beats carrot, carrot beats witch, and witch beats bear, then I would put the possible outcomes into a matrix (say 0 if the first combatant loses, and 1 if they win) and just look up the element you need. However, I suspect you want something more complicated than that.
Good grief no functions, no structs…
Why not go the whole hog and write it in Brainf*ck?
With shades of the old barometer question:
You find the guy running the computer lab. You tell him, “I’ll give you this TI-83 if you give me an account on a linux box”. You write the program in Python.
</cries over the time he wasted as a kid trying to make BASIC work how he wanted.>
Come on. Think outside the box! It’s not something I’d want to do professionally, but it can be fun to think in unorthodox and creative ways to get stuff done. Programming on a calculator is a weird environment, because you don’t have a lot of the basic stuff - like pointers and input/output files - but a lot of the high-level math - like matrix inversion and numerical integration - is built in.
I guess it was six years ago I was trying to write a space adventure game on the TI-83. I only got as far as the intro sequence and drawing the first screen, but I learned a bit. My single biggest tip is: Easy on the text! The darn thing only has what, 28k of memory? A few screens full of text and this gets eaten up pretty quickly.
Alright, as someone who has done a lot of programming on the TI-83+, I’ll give you a HUGE hint:
Get the cable that connects it to the computer.
You want this for a few reasons:
- You can back up your programs. This is essential, since the calculator’s memory is not the most stable thing on the planet.
- You can type in programs with a keyboard. It is somewhere between frustrating and impossible to type in long strings on a TI-83(+).
- You can download cool games.
- You can cut and paste.
If you’re going to do some serious programming on the TI-83, you need one of the cables. Before, they were called the TI Graph Link, now they’re TI connectivity kit, or somesuch. You can usually find them at a Staples.
As for subroutines to call the fighting, you’re out of luck, or you can do what I did in QBasic before I had any idea what a subroutine was, and use a lot of goto commands. Be careful in TI-Basic, though, as a variable can’t have the same name as a label.
dwalin, you might recall that I am a (not so ex) geek. Perhaps nobody reminded you that I used to program T-8Xs for fun.
IIRC, what you will want to do is something like this (command lines in quotes so as to avoid some confusion):
“rand(AX,0)->Y:goto 4”
where rand is the “make me a random number” function, 0 is the number of decimal places you want, A is the number of possible enemies that can spawn at a given place (for example, if you’re planning out multiple levels for this, you might have some worms that don’t spawn in a tower, and bats that don’t spawn in a swamp, etc), and Y is the resulting number that tells you what baddie you’ve just fought. Goto4 (hypothetical number; you could use anything, really, although I’d suggest not using variables unless absolutely necessary; goto commands can have two-digit numbers at least) might tell the prog to go to an area where the following command lines would be:
"For Y=1:progWORM:goto 5
For Y=2:progSPIDER: goto 5
For Y=3:progGOBLIN: goto 5
For y=4:progHANGNAIL: goto 5:
etc., where 5 is simply returning to some other area of the program unless you want this game to just be your character getting into endless fights (how you’ll recover HP is an interesting dilemna if you decide to do that).
The AI for fighting will obviously depend on how you want to conduct the fight. Do you have a timer for hitting (IOW, is this a turn-based game or a realtime game? Based on the fact that you soon get sore fingers typing a lot on a TI-8X, you might want to make it turn-based, ESPECIALLY during fights), or is it turn based? If it’s turn-based it’s a simple calculation, based again on what sort of system you want to use (D&D has one, but you can easily make your own). The to/hit vs. defense vs. whatever else will be a subprogram, and IIRC you can have subprograms in TI-8X programming, or at least I and several friends were able to accomplish this.
The limiting agent will most likely be variables, since you can only have 26 numerical (as opposed to matrix) variables. The next limiting agent will probably be memory; the TI-8X simply isn’t designed for the type of game you’re envisioning.
From what I can recall on subprograms, they run exactly the same as any other program, and the real distinction is that a subprogram occurs within another program. You can have, for example, a prog called “math functions”, where the basic bits of that prog are “choose which function you want”, and if you choose 1 you go to calc the area of a triangle (separate prog), 2 goes to area of a square (separate prog), etc. I don’t specifically recall the command for it, but you should find it if you RTFM:)
Higher AI (eg better coding) would probably have monsters spawn in clumps, something I personally don’t know how to write short of having a command equal something like “if we spawn one monster, let’s have a 75% chance of spawning 2, a 45% of 3, a 20% of 2, etc”. Or you could just have another random number drawn to tell you how many (out of a possible other number) of a particular creature spawned. If you got particularly creative you could have two or more different monsters spawned. And then you’ll want to figure out how to make the monsters tougher as your character grows, once you’ve figured out how to make him level. Oh, and saving your game, too, unless you’re okay restarting every time you play the game. You might want to have your most important variables be things you won’t otherwise use, or possibly save some of your numbers to a matrix/list. It’s not had to do … I could probably figure it out again given some time, though given the geek factor on this MB I’d hope someone’s done it more capably and recently than I have. Matrix algebra was not my idea of a good time.
The key to this REALLY is to get as much of the coding into tight, importable bundles. Otherwise you’re just writing the same thing over and over again, and from my failed attempt at PacMan, trust me you don’t want that.
Gwar. Thought I’d forgotten something:
-
The first bit of my post makes more sense once you know that dwalin is my younger brother.
-
The
in my post should be
Well, it’s good to know that the old bold/unbold trick no longer works. The smilies in my post should be
do lots of things like
x= rand()*3
if x == 1 enemy = “horse”
if x == 2 enemy = “monster”
if x == 3 enemy = “zoidberg”
output 1,1, "you see a "
output 1,10, enemy
(is there a way to concatinate strings on a ti-83? I’m not sure… thats why I did it that way)
Yeah, I’d do something like that too. On the TI-83, one-line conditionals are instead two-line conditionals, and you can only store strings in one of 10 special string variables Str0-Str9. So it would look something like this:
:randInt(1,3)->X
:If X=1
:"HORSE"->Str1
:If X=2
:"MONSTER"->Str1
:If X=3
:"ZOIDBERG"->Str1
:Output(1,1,"YOU SEE A:")
:Output(1,2,Str1)
You can indeed concatenate strings, but I wouldn’t recommend it in this case, because the screen is only 16 characters wide, so “YOU SEE A ZOIDBERG” would get cut off and wrap to the next line. But if you wanted to do it, you’d do it like this:
:Disp "YOU SEE A"+Str1
What’s good is then you can have simple actions based on the value of X, like how much damage the creature does. Say, early in the program you can say:
:{3,10,0}->L[sub]1[/sub]
And then when it’s time for an attack:
:L[sub]1[/sub](X)->D
:Disp "THE "+Str1+" HITS"
:Disp "YOU, DOING"
:Disp D,"HP OF DAMAGE"
:H-D->H
:If H<1
:Disp "YOU'RE DEAD"
You’re looking at a TI-BASIC programming veteran. Why, back in my day, I had a program on the TI-82 that drew the ship from StarFox in wireframe rotating around at .2 frames per second. (Coincidentally, I just made a program today using an unofficial GBA devkit that does the same thing on a Gameboy Advace…only at closer to 15 frames per second this time. :D)
What I would suggest is, make a generic “fight” function, and use variables for the enemy stats, like Archernar said. What I would do is use the Lists for stuff like HP, weaknesses and other crucial numbers you’d need for an enemy. For instance, let’s say you want three enemies, called Foo, Boo, and Moo (very creative, I know.) Foo has 100 HP, Boo has 200, and Moo has 300. If I were doing it, I’d write something like this:
Put this at the beginning of the program.
:L[sub]1[/sub]={100,200,300}
Then I’d put this code, possibly in a different program:
:N=randInt(1,3)
:If N=1
:Str1="Foo"
:If N=2
:Str1="Boo"
:If N=3
:Str1="Moo"
:H=L[sub]1[/sub][N]
Where “N” is the enemy number, “H” is the HP, and “Str1” is the enemy name. You do this whenever you start a fight, and then use those variables to keep track of stuff. I’m not sure if I’m doing the notation correctly, since it’s been a while since I’ve programmed on a calculator. As I recall, multi-line “If” statements have to be in “:If ~~~ Then :Line1 :Line2 :EndIf” format, but you can do a single line “If” if you leave out the “Then.”
Since you only have 27 variables (other than the lists) I would recommend keeping a piece of paper with notes on what letter does what, so you don’t accidentally use a variable for two different things. That always came in handy for me when I was working on huge calculator projects.
If you want to run a “subroutine” from within a program, the command is just “prgm” and then the program name. So if your game was called RPG, you could make each fight a separate program called RPGFIGHT, and then you’d call the command
:prgmRPGFIGHT
Every time you needed to use that “function.” (To get to the “prgm” command, I think you have to press the PRGM button while editing, then go to “EXEC” from the menu to select the program name.) You can return out of functions using the “Return” command (Note: The “Stop” command exits the program completely no matter where it is in the “stack” so it’s not the same as “Return”) but you cannot actually return a value from a function. If you need to do that, the best way to do it would be to assign some variable, say, theta, to act as the return value for your “function.”
Another thing: It is possible to copy and paste text on the TI-8x, but it’s a bit complicated. What you need to do is, create a new program called, say, TEMP. Start editing TEMP, then press the “RCL” button (maybe it says “Recall” I don’t remember) and then press the “PRGM” button and select the program you want to paste into TEMP. This will copy the entire content of that program into prgmTEMP. Then you can just delete every line except what you want to copy, or, optionally, you can skip that step and just write TEMP from scratch. But anyway, when you want to paste TEMP into your original source file, you open up the program in the editor and use the RCL command again, and “Rcl prgmTEMP.” This will append the contents of prgmTEMP into your original program from wherever the cursor is.
Or you could get a GraphLink and learn how to make your game in assembly. (I always wanted to do that, and I even had a GraphLink, but I never got the hang of using asm, and now I have no idea where the GraphLink is. Come to think of it, I don’t even know where my old calculator is.)
Well, I’d go more for an “Interactive Progress Quest” motiv given the platform.
Just use a random number for what happens next, and a bunch of lines of code for the text that gets spit out when it does. Like for 0-100, say, you might have:
0 - Instantly win (find the super secret magic portal or whatever) and get a neat graphic display.
1-9 - Some NPC shows up and gives a useless, but intriguing clue
10-19 - Some easily beaten monster shows up and gets trounced
20-29 - Some harder to beat monster, hurts you a bit (1/20 chance of death)
30-39 - Some really tough monster, which you cleverly trick/elude
40-49 - Some insanely vicious monster, which has 1/2 chance of killing you.
50-59 - Hear a strange noise, find orc blood, broken helmet, or whatever (interesting but useless)
60-69 - Sing a song, fart, adjust your sword buckle, think of the shire, whatever
70-79 - Gain health/points somehow
80-89 - Find some treasure
90-99 - Time passes (use some neat prose here)
100 - Some kind of sudden horrible death
At every loop, you have the option of keep playing or quit. Same outcomes as a much more sophisticated game, but much easier to program.
For those that haven’t seen the hilarious Progress Quest game, here:
I haven’t played regular D&D type games since, it tops them all!
Thank you all! You were very helpful (Ah, typing on a real keyboard…). I have deleted my first game because it became a mess, and until I get better at programming, I’m not going to try again. I have started a new game which involves picking a career path and getting 100 prestige points, and I think I can do most of it except for setting points to change after a task is completed or failed. Once I attempt a game like my first one again, I think I’ll go with Thrasymachus’ idea.
Oh, I have done so much coding today… Nothing to compare with professional programmers, but a lot for me.
Good Sir Knight, how precisely do you plan to become better at this sort of programming unless you work at it?
Well, first I’m going to finish the game I’m working on now, all several stages of it, then I think I’ll probably do Thrasymachus’ PQ-esque game, and then I’ll try that game again. There’s a difference between trying new things, which is what I’m doing now, and getting in over your head, which I did with my first game. Once I finish those two, I should be well equipped to rewrite that game.
(Of course, it really didn’t help that, at the time, all I knew how to do was Display, Prompt, If-Then-Else-End, and (maybe) Goto and Label…)
Right now I have each of my variables changing every time I run the program, and I want them to be reset to original values every time the program ends. I was thinking of having an option “End Game” and have that go to the end of the program, which resets my variables to their original values. That would mean that I wouldn’t have this terminal glitch, and also that you could quit in the middle of the game if you needed to for whatever reason.