Opry99er Posted April 2, 2015 Author Share Posted April 2, 2015 Hehehe... I bet arcadeshopper could make em up and sell them on his site. Funny... 3 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted April 2, 2015 Share Posted April 2, 2015 Owen... Back in post #852 you mentioned planning to use an XB subprogram for something. You probably already know this: An excellent example of XB subprogram usage is @Willsy’s XB version of his Sprite Designer. ...lee Quote Link to comment Share on other sites More sharing options...
Opry99er Posted April 2, 2015 Author Share Posted April 2, 2015 (edited) Yes, Lee. Willsy's SPRITE designer is awesome. However, since that post, I have rediscovered TIdBiT for development. Take a look at this snippit of code. //BEGIN MENU LOOP// MainMenu: REM MENU CALL CLEAR :: CALL SCREEN(2):: CALL DELSPRITE(#1) CALL HCHAR(5,1,101,32):: CALL HCHAR(20,1,101,32):: CALL VCHAR(5,1,97,15):: CALL VCHAR(5,32,97,15) CALL HCHAR(5,1,98):: CALL HCHAR(5,32,100):: CALL HCHAR(20,1,99):: CALL HCHAR(20,32,96) MainMenu-MiddleReturn: GOSUB ClearMenu :: GOSUB ReturnString DISPLAY AT(8,1):"1) ITEMS":"2) ARMOR":"3) WEAPONS":"4) SPELLS":"5) STATUS"; MidMenu-Keyscan: GOSUB Keyscan IF K=13 THEN CALL CLEAR :: GOTO DrawScreen !**BUG FIXED HERE** Case-sensitive labels IF K>54 THEN GOTO MidMenu-Keyscan ELSE IF K<49 THEN GOTO MidMenu-Keyscan ON K-48 GOTO ItemMenu,ArmorMenu,WeaponsMenu,SpellsMenu,StatusMenu //BEGIN Item Menu// TIdBiT basically allows me to code using labels... which is just as easy as using SUBs, if not easier. I've noticed that my code is very recursive in nature these days... A product of the labels, I'm guessing. The labels, when translated, produce line numbers and all references to that label in the source immediately become associated with that line number... So GOSUB Label1 would reference the line number of Label 1 and GOSUB there. GOSUB 3000 or whatever. Truly an epiphany for me in the development of this game. More has happened in the last month than the last 3 years. Hey Lee... thanks for posting to this thread. I hope you play the game... even if you hate it, still..... play it. LOL!!! Edited April 2, 2015 by Opry99er 1 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted April 2, 2015 Share Posted April 2, 2015 ... However, since that post, I have rediscovered TIdBiT for development. Take a look at this snippit of code. ... TIdBiT basically allows me to code using labels... which is just as easy as using SUBs, if not easier. I've noticed that my code is very recursive in nature these days... A product of the labels, I'm guessing. ... Truly an epiphany for me in the development of this game. More has happened in the last month than the last 3 years. All that good stuff notwithstanding, subprograms make the resulting program easier to read. Though, the output from TIdBiT probably organizes the GOSUBs better than most of us often do when coding directly in Basic. ... Hey Lee... thanks for posting to this thread. I hope you play the game... even if you hate it, still..... play it. LOL!!! I am sure I won't hate it and I certainly will play it. Though, as you seem to remember my saying a long time ago, I would rather not spend a lot of time with games, I recognize that some of the most significant advances in computing have come from game programming. ...lee 1 Quote Link to comment Share on other sites More sharing options...
+arcadeshopper Posted April 3, 2015 Share Posted April 3, 2015 Hehehe... I bet arcadeshopper could make em up and sell them on his site. Funny... http://www.cafepress.com/TIandGeneveStuff.1553237159 1 Quote Link to comment Share on other sites More sharing options...
+arcadeshopper Posted April 3, 2015 Share Posted April 3, 2015 as far as making other disks.. just do good error control and open DSK.NAME.FILENAME and it will search your drives for that disk then the file. If it gets an error gosub a "put in the disk dude" screen and try again after they hit a key Greg Quote Link to comment Share on other sites More sharing options...
Opry99er Posted April 3, 2015 Author Share Posted April 3, 2015 (edited) That's definitely a possibility there, Greg... For sure. I think the fella was asking if there was a way to autodetect the size of a disk system... But yea, an ON ERROR GOSUB is a great way to handle that, assuming I have two versions of the game... One disk and multidisk. @The t-shirt-- I need to buy one of those from you. Edited April 3, 2015 by Opry99er Quote Link to comment Share on other sites More sharing options...
matthew180 Posted April 3, 2015 Share Posted April 3, 2015 TIdBiT basically allows me to code using labels... which is just as easy as using SUBs, if not easier. You can use labels with subroutines (which I know you are aware), but subroutines help you keep you code organized and easier to understand and maintain. You should not write off subroutines because you have labels, they are not mutually exclusive. Code organization can also help you write bigger programs in the same amount of memory by realizing that you do many similar things over and over in a program, and bundling those up into subroutines means less duplication and less wasted memory. I've noticed that my code is very recursive in nature these days... A product of the labels, I'm guessing. Technically your code is not recursive. I don't even know if you could do recursion in XB (maybe if you simulated a stack). Your code loops a lot as a function of playing the game, which is also known as a "game loop". I think you will learn a lot from this exercise of writing you game. 1 Quote Link to comment Share on other sites More sharing options...
Opry99er Posted April 3, 2015 Author Share Posted April 3, 2015 Thanks Matthew. What I meant by that is that my program GOSUBS to a GOSUB to a GOSUB and then, once an outcome is reached in the final stage, it RETURNS and updates, RETURNS and updates, RETURNS and updates and finally returns back to the top... Particularly in the menus... In the Syntax Error thread, that kind of process was referred to by someone as recursive. If that is not what it is, then forgive my misuse of the term. And yes, I am learning alot... Pretty cool to go into a project thinking you know how to do something, realizing you don't, and then actually learning what you have to do and then do it. And what I meant by SUBroutines not being needed is that I don't have to define a sub and then CALL "whatevername"... I can reference the label and it acts similarly. Thanks again for all your help, Matthew. Quote Link to comment Share on other sites More sharing options...
matthew180 Posted April 3, 2015 Share Posted April 3, 2015 A function is only recursive if it calls itself (very important distinction) and has a condition to eventually terminate and return back up through the calling chain. I was only clarifying for educational purposes. I did not read the Syntax Error thread, but it sounds like the initial comment misused the term. Ah, now I see what you were referring to with the subroutines. Keep in mind that in XB, what is typically thought of in other languages as a "function", "subroutine", "method", or whatever is implemented with GOSUB and RETURN. XB also has a way for you to define (with the DEF keyword) what they call a "function" that you then subsequently use with CALL "function name". In that case the "function" can only be an expression and it is a confusing term when compared to more prevalent languages. Quote Link to comment Share on other sites More sharing options...
Opry99er Posted April 3, 2015 Author Share Posted April 3, 2015 Thanks for the clean-up there. I'm learning, so some terminology is a bit fuzzy in the ol' head over here. User defined FUNCTION, I guess, is what I meant by SUB. I think I got confused because in XB you finish the program listing out with the defined function by using something like 1040 SUB SCRWIPE 1050 CALL CLEAR 1060 CALL SCREEN(5) 1070 SUBEND The "SUB" in there threw me a bit. I've progressed with this program to a point of absolutely needing to define and implement a series of multi-dimensional arrays for data handling... I can continue without it, but it is crushing my PROGRAM size... This will also be new for me, as I've never used variable arrays in my programming previously. I know it was discussed early on in this thread with Codex, yourself, and a few others, but until NOW, I didn't need them, so I never implemented them. Now, especially with the minute details starting to come together, they will be crucial, I believe, to handling business in a compact and controlled manner. as an example from my own code... MidItem-Keyscan: GOSUB Keyscan IF K=13 THEN GOTO MainMenu-MiddleReturn IF K>52 THEN GOTO MidItem-Keyscan ELSE IF K<49 THEN GOTO MidItem-Keyscan ON K-48 GOSUB ItemBeryl,ItemRepto,ItemMarkus,ItemSkylar GOTO ItemMenu //ACN=name, ANSP=name starting point, ANL=name length// ItemBeryl: REM BERYL GOSUB ActiveBeryl GOSUB ItemMenu2 BHP=AHP :: BMP=AMP :: RETURN ItemRepto: REM REPTO GOSUB ActiveRepto GOSUB ItemMenu2 RHP=AHP :: RMP=AMP :: RETURN ItemMarkus: REM MARKUS GOSUB ActiveMarkus GOSUB ItemMenu2 MHP=AHP :: MMP=AMP :: RETURN ItemSkylar: REM SKYLAR GOSUB ActiveSkylar GOSUB ItemMenu2 SHP=AHP:: SMP=AMP :: RETURN REM **THIS IS THE MEAT OF THE ITEM MENU CODE** ItemMenu2: GOSUB ClearMenu :: DISPLAY AT(1,ANSP):ACN$;:: CALL HCHAR(2,ANSP+2,94,ANL) GOSUB ReturnString ItemDisplay: DISPLAY AT(8,1):"1) POTION";HPO;:"2) ETHER";MPO;:"3) ELIXIR";ELI; DISPLAY AT(3,1):"HP:";AHP;"/";AMHP;:: DISPLAY AT(3,16):"MP:";AMP;"/";AMMP; MidItem2-Keyscan: GOSUB Keyscan IF K=13 THEN GOTO ItemMenu IF K>51 THEN GOTO MidItem2-Keyscan ELSE IF K<49 THEN GOTO MidItem2-Keyscan ON K-48 GOSUB HealthPotion,MagicPotion,Elixir GOSUB Flash DISPLAY AT(3,1):"HP:";AHP;"/";AMHP;:: DISPLAY AT(3,16):"MP:";AMP;"/";AMMP; DISPLAY AT(8,1):"1) POTION";HPO;:"2) ETHER";MPO;:"3) ELIXIR";ELI;:: FOR I=1 TO 400 :: NEXT I RETURN . . . .. . . . ActiveBeryl: AMHP=BMHP :: AHP=BHP :: AMMP=BMMP :: AMP=BMP :: ACN$="BERYL" :: ANSP=12 :: ANL=5 :: AMN=BMN RETURN ActiveRepto: AMHP=RMHP :: AHP=RHP :: AMMP=RMMP :: AMP=RMP :: ACN$="REPTOSLICER" :: ANSP=9 :: ANL=11 :: AMN=RMN RETURN ActiveMarkus: AMHP=MMHP :: AHP=MHP :: AMMP=MMMP :: AMP=MMP :: ACN$="MARKUS" :: ANSP=12 :: ANL=6 :: AMN=MMN RETURN ActiveSkylar: AMHP=SMHP :: AHP=SHP :: AMMP=SMMP :: AMP=SMP :: ACN$="SKYLAR" :: ANSP=12 :: ANL=6 :: AMN=SMN RETURN Quote Link to comment Share on other sites More sharing options...
Opry99er Posted April 3, 2015 Author Share Posted April 3, 2015 (edited) As you can see, I'm using a WHOLE lot of similar variables. I'm also unnecessarily loading my static variables (RHP,RMHP,RMP,RMMP) whatever into a temporary set in the ActiveBeryl, Active Repto,...,... routines-- INTO a temporary variable set known as "A".... or Active. If all this crap were handled in arrays, I could eliminate that altogether and just use the keypress from the user to DIRECTLY indicate which of the 4 I'm addressing in a HP(4,2) array. K-48 will determine which of the 4 in my first dimension will be addressed, and the program will dictate what to DO with that information onscreen. None of this extra garbage I've spent 2 weeks writing, trying to be clever... Just to find out that arrays were the answer all along. LOL! I feel dumb, but smarter all at once. Edited April 3, 2015 by Opry99er Quote Link to comment Share on other sites More sharing options...
JamesD Posted April 3, 2015 Share Posted April 3, 2015 (edited) The non-Computer Science equivalent of recursion is a mirror image of a mirror image. You see reflections of reflections of reflections...The reflection of one mirror is passed to the other which is passed to the other which... you get the idea. The image is reduced in size each time it's reflected.Ti BASIC doesn't really fully support recursion since it uses global variables for everything.Recursion depends on a language where subroutines allocate new storage space for variables each time they are called and the ability to pass parameters to the subroutine.Keeping that in mind, a recursive function calls itself from within itself.Unlike the mirrors, computer recursion is limited by available memory. An iterative (non-recursive) implementation of an algorithm requires a fixed amount of RAM where use of recursion requires allocation of RAM for new local variables with each recursive call as well as the return address If you think that is as clear as mud, look up the Wiki definition for recursion (Computer Science). A common use would be a recursive implementation of Quicksort. It might not be the best example because it might be tough to follow the logic. // Free Pascal implementation of Quicksort. Sorts an array of integers // calls itself again whenever it finds an array element out of order procedure QuickSort(var A: array of Integer; iLo, iHi: Integer) ; var Lo, Hi, Pivot, Tenp: Integer; begin // make local copies of the array indexes Lo := iLo; Hi := iHi; // get the value of the array element at the half way point between array indexes Pivot := A[(Lo + Hi) div 2]; // keep repeating until Lo index > Hi index (indexes cross) repeat // skip Lo array elements that are less than the Pivot value while A[Lo] < Pivot do Inc(Lo) ; // skip Hi array elements that are greater than the Pivot value while A[Hi] > Pivot do Dec(Hi) ; // fall through to here, check to see if it's because Lo and Hi are out of order if Lo <= Hi then // Swap array elements that are out of order begin Temp := A[Lo]; A[Lo] := A[Hi]; A[Hi] := Temp; Inc(Lo) ; Dec(Hi) ; end; until Lo > Hi; // make recursive call if we haven't traversed the entire array looking to see if array elements are out of order if Hi > iLo then QuickSort(A, iLo, Hi) ; if Lo < iHi then QuickSort(A, Lo, iHi) ; end; Edited April 3, 2015 by JamesD Quote Link to comment Share on other sites More sharing options...
Opry99er Posted April 3, 2015 Author Share Posted April 3, 2015 What about recursive backtracking for maze generators? I'm assuming these algorithms have similar traits.. Quote Link to comment Share on other sites More sharing options...
+adamantyr Posted April 3, 2015 Share Posted April 3, 2015 What about recursive backtracking for maze generators? I'm assuming these algorithms have similar traits.. Yes, you can absolutely use recursion for maze generation. I've written one before. That said, any recursive approach can also be done linearly by creating a stack structure to store whatever you're doing that is being copied. All a recursive function does is push the entire local stack of functional data onto the heap, it's easier to read in code but harder on the processor and memory. One call out, Matt said that you use DEF to create subprograms you can CALL with, this isn't quite accurate. DEF is used to create functions. An example: DEF RND(N)=INT(N+.5) This creates a new function you can call which will round a decimal value up if it's .5 or higher, otherwise round down. I've found, though, that creating custom functions is really REALLY inefficient. They seem to really impact program speed hard-core, and are best left unused for anything to do with graphics or sprites. You create subprograms by using SUB keywords, along with SUBEXIT and SUBEND to mark end points. Subprograms are nice in that they have local variables, so you don't have to worry about overriding globals. Arrays, though, are passed by reference into them, so they're trickier to use with subprograms. Quote Link to comment Share on other sites More sharing options...
matthew180 Posted April 3, 2015 Share Posted April 3, 2015 Recursion in computer science is typically not infinite, there is another term for that: infinite loop. Here is a classic example of recursion (ref: wikipedia): unsigned int factorial(unsigned int n) { if (n == 0) { return 1; } else { return n * factorial(n - 1); } } Stack-based languages help make doing recursion easier, but are not necessary. In XB you could use an array, for example, to store the variables at each iteration. Yes Owen, a recursive backtracking maze generator is a perfect example. In that case you can actually use the maze array itself as the storage space for each iteration. As for arrays, for 1D and 2D implementations just think in terms of the screen or graph paper. Each cell can hold a value of you choice. However, for a game like this it might be easier to think in terms of records. In XB is gets really clunky because the language does not help you, but you can emulate them with arrays. For example, you have stats for each character like class, HP, strength, weapon, etc. So you could have an array that stores those value for each character like this: num_players = 4 stats_per_player = 4 OPTION BASE 0 DIM stats[num_players * stats_per_player] PRINT "Player Stats:" FOR I = 0 TO num_players-1 IDX = I * num_players PRINT "Player "; I+1 PRINT " Class: "; stats[IDX+0] PRINT " HP: "; stats[IDX+1] PRINT " Strength: "; stats[IDX+2] PRINT " Weapon: "; stats[IDX+3] PRINT NEXT I Basically every "stats_per_player" subscripts in the array store the data for one character. You can as many characters as you want for the cost of the extra storage, and the code to deal with any given character will be the same. You could also have an array of weapons (or use DATA statements for information that is static and read only), so the weapon value stored in a player's stats record would be an index into the weapon array, which could be yet another "record" array of weapons and their stats. This can be somewhat of a pain in XB because the language lacks support for even simple constructs like constants, but you have to get a handle on data management or your game will come to like and kill you. Hmm, I could probably add support of constants in TidBit easy enough. As you work through you games you will start to realize that games are just data-management programs. You need to start thinking in terms of record storage vs fixed hard-coded variables. If you want an example let me know. Quote Link to comment Share on other sites More sharing options...
JamesD Posted April 3, 2015 Share Posted April 3, 2015 Recursion in computer science is typically not infinite, there is another term for that: infinite loop. Here is a classic example of recursion (ref: wikipedia): Typically? It can't be infinite, you'll run out of memory. Quote Link to comment Share on other sites More sharing options...
JamesD Posted April 3, 2015 Share Posted April 3, 2015 What about recursive backtracking for maze generators? I'm assuming these algorithms have similar traits.. Similar but not identical. What is most important is that recursive backtracking is a form of "perfect maze creation". An obvious example of a perfect vs non-perfect maze is shown on this page: http://www.mazeworks.com/mazegen/mazetut/ You can find many other approaches to perfect maze creation mentioned here: http://www.astrolog.org/labyrnth/algrithm.htm Pay attention to the table comparing maze generators. Memory may be an issue for some of them. The other issue is time. Interpreted BASIC is slow so you want something fast. 4 Algorithms require half the time of recursive backtracking. Quote Link to comment Share on other sites More sharing options...
Opry99er Posted April 3, 2015 Author Share Posted April 3, 2015 Thanks for all the good info fellas. This stuff is fascinating. Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted April 3, 2015 Share Posted April 3, 2015 (edited) ... One call out, Matt said that you use DEF to create subprograms you can CALL with, this isn't quite accurate. DEF is used to create functions. An example: ... Actually, that is what Matthew said. The part that is not quite right is “CALL”. You call a function by referencing it, not by using a CALL statement. To use your example, which, by the way cannot be named “RND” (let’s call it “ROUND”): 10 DEF ROUND(N) = INT(N+.5) 20 INPUT X ... 100 Y = ROUND(X) ... ...lee Edited April 3, 2015 by Lee Stewart Quote Link to comment Share on other sites More sharing options...
RobertLM78 Posted April 3, 2015 Share Posted April 3, 2015 Arrays are excellent - one of BASIC's strongest features IMO. Quote Link to comment Share on other sites More sharing options...
matthew180 Posted April 3, 2015 Share Posted April 3, 2015 I just did a review of DEF, CALL, and SUB. I did not realize XB has subroutines with static local variables! For some reason I had it in my head that all XB variables were global. You can even go so far as passing by reference or value. Owen, I think you should spend a little time understanding the use of SUB, although I better check that TidBit supports that keyword. Doh! Subroutines and local variables are the bread and butter of almost any language and helps make your programs modular and manageable. 2 Quote Link to comment Share on other sites More sharing options...
Opry99er Posted April 3, 2015 Author Share Posted April 3, 2015 I guess I need to post my TIdBiT source here so we can address some of this on a specific basis. I know TIdBiT supports SUB due to the SETMAP SUB that is in the code now. Quote Link to comment Share on other sites More sharing options...
+RXB Posted April 3, 2015 Share Posted April 3, 2015 Yes, you can absolutely use recursion for maze generation. I've written one before. That said, any recursive approach can also be done linearly by creating a stack structure to store whatever you're doing that is being copied. All a recursive function does is push the entire local stack of functional data onto the heap, it's easier to read in code but harder on the processor and memory. One call out, Matt said that you use DEF to create subprograms you can CALL with, this isn't quite accurate. DEF is used to create functions. An example: DEF RND(N)=INT(N+.5) This creates a new function you can call which will round a decimal value up if it's .5 or higher, otherwise round down. I've found, though, that creating custom functions is really REALLY inefficient. They seem to really impact program speed hard-core, and are best left unused for anything to do with graphics or sprites. You create subprograms by using SUB keywords, along with SUBEXIT and SUBEND to mark end points. Subprograms are nice in that they have local variables, so you don't have to worry about overriding globals. Arrays, though, are passed by reference into them, so they're trickier to use with subprograms. The reason mostly for this impact is DEF has to go back to that statement and re-allocate VDP memory then go back to that line and run the new variables into that formula. One of the main problems is it MUST do a Garbage Collection of VDP memory as it is a unknown how much memory will be used before that Formula is solved. If XB used RAM instead of VDP for Variables and Strings you would see a incredible speed increase of XB execution of programs. Every single byte access has that delay on it in every VDP byte? This is a huge cost in speed and efficiency. Quote Link to comment Share on other sites More sharing options...
matthew180 Posted April 3, 2015 Share Posted April 3, 2015 Typically? It can't be infinite, you'll run out of memory. Exactly. I was referring to your mirror analogy which is infinite (there is no stopping condition or result that unwinds the process), and simply commenting that the use of recursion with computers is typically not infinite. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.