Friday, 30 August 2024

"Des cavernes dans le poquette" by Charles Feydy (1982) Update


"Some caverns in the pocket" is how I would translate the title of the game and article by Charles Feydy published in 1982. A while back I made and English translation from French and port of this little game from TRACE magazine Issue 2, 2nd quarter 1982, p. 62. This post is an supplement to the one I originally made on the project (https://jimgerrie.blogspot.com/2021/09/retrochallenge-2021-les-cavernes-by.html). It was prompted by a post by Jason Dyer on his "All Text Adventures" blog, who helpfully took the game for a spin.  He confirmed my vague sense at the time that the game was not functioning properly before I lost interest. I went back to look at some suspicions I had that differences in precision between Micro Color BASIC and the TRS-80 Pocket Computer 1, which was the original target machine, were not fully dealt with. In particular the exponent function's decimal precision has some wonkiness (try printing 10^7).

There is a bug/accuracy limitation in some early 80s Microsoft BASIC's exponent functions which produces erroneous decimals results rather than a whole number. For example, 10^7 on the MC-10 produces 9999999.99 instead of 10000000. Simply adding .5 and adding an INT (integer) function to any exponent function call can often clean up these possibilities. It seemed to clean up some of the weird room descriptions, but not all, and there seemed to be an inordinate number of dead ends still happening. It also improved the combat results, because the exponent function was also used in that subroutine.

I also altered some of the translation choices I made based on the comments from readers of Jason's blog. One about "trappe" being “hatch” versus an actual “trap,” as I had naively assumed, was especially helpful in clarifying an oddity I had noticed that "traps" didn't seem dangerous.

I now think the port might be functioning more-or-less correctly, and that any remaining difficulties might be inherent. The game represents an exercise in producing a simple “procedurally generated” dungeon based on the initial number you enter and the oscillating and pseudo random decimal numbers produced by the SIN function. Those numbers result in calculations that will recreate the same “dungeon” (arrangement of nodes, monsters, rings). What results is a mathematically generated series of unique interconnections that when combined with descriptive words creates a simple unique “maze".  However, this maze is not actually fully interconnected as you cannot actually reverse paths to go back the exact way you came.

Sometimes these interconnections end in dead ends–- either because you can’t pass a monster given the "rings" you have found– or because the node is simply empty (no ways out). Overall, I think this is essentially a mathematical challenge (not surprising for pocket computer owning crowd) of finding the right starting Dungeon Number and combat Level Number combo that actually has a possible solution.  Such a solution will involve being able to find a path that includes the right arrangement of rings and interconnected nodes to get all 10 of those rings, while also defeating all the monsters encountered along the way. The number of monsters defeated is counted as one's score.  So I think the ultimate goal of the game is to find the Dungeon number and path that will allow one to collect all 10 rings, with the intermediate goal being simply to get the highest monster kill rate.

I have to do some more testing, but that is the win hypothesis I am currently working on. I might be able to set my software engineer (and Math major) son onto the problem to see if gaining all 10 rings is mathematically possible. Maybe he could use a proper language and some AI techniques to find if there actually is “a solution” if my hypothesis is correct.  It is an interesting game-theory question if anyone is looking for a grad thesis.

I decided to create a completely alternate exponent subroutine to do my testing and allow me to fiddle with alternate ways of implementing the exponent function. As I noted, simply INTing the result was not enough to fully correct all the apparent errors in maze generation. In revisiting the source code and original listing I think might have also found a few bracketing errors, but not sure if they were the causes of any of the troubles I was having.

In the end I realized the problem was also a result of a slightly lower level of mathematical accuracy between the MC-10 and Pocket PC. The game relies heavily on the mathematical accuracy of the Pocket PC and its BASIC. Simply put, it needs 10 decimal digits to come out of SIN, whereas the MC-10 could only give 9. That is because the decimal is multiplied by 100 to give two hole number digits, which are used for combat calculations, plus 8 decimal numbers, which are used to store maze node information for 4 directions of moves. The Pocket PC apparently could give you a number like

90.12345678

Whereas the MC-10 can only give you

90.1234567

The 8 decimal number give 4 groups of 2 numbers which store the node information for the four directions of movement. If the first digit is 4 - 9 then you can go in that direction. If the second digit is odd and there is a monster present, then you will be blocked. If you defeat the monster then you will be allowed to move to a new room by adding one to that digit to make it an even number and then a new SIN number will be generated based on the current number. Since I was missing an 8th decimal digit I made it so that it is simply replaced by a zero.  So there will likely be differences in the maps of the original machine and the MC-10, but I don’t think it should matter that much. It is really a math nerd’s game, allowing the player to explore the interactions of a complex set of calculations “Fibonacci-style” as a dungeon maze.

Here is a vid of some early testing: https://youtu.be/N4bUl5sQNtA?si=k0mLNOnd-EH-Nu0j

Here’s a vid of a long play of the final iteration (I hope): https://youtu.be/M8UySLhMr80

The game can be played online here: https://archive.org/details/CAVERNES

As part of the testing I also did a MS Quick Basic conversion, which can be seen here:



The source for that version can be found on Github here:

https://github.com/jggames/QuickBASIC/tree/main/Cavernes

The source for the MC-10 version can be found here:

https://github.com/jggames/trs80mc10/tree/master/quicktype/Text%20Adventures/Cavernes

The last point I would like to make is about what genre this game fits into. It straddles the line between CRPG and text adventure. Since there is combat and "items" that can improve one's performance it seems like its a CRPG.  But there is no ability to define one's character or change it in any way beyond collecting the single type of item, which makes it an extremely limited form of CRPG.  But it also has all the tropes of a text adventure in terms of vocabulary: N S E W directional movement, Inventory, Look, and Get. The room descriptions are sparse but it is not really randomized in terms of the maze, as they are in many CRPGs.  There is a narrative "Get the 10 Rings" which will play out in the same environment every time, as in a text adventure.  And as in a text adventure there is a puzzle to solve-- Can the path to the 10 rings be found?  In the end I would describe this as a simple mathematical text adventure with CRPG elements.  Credit must be granted to the Feydy for being able to fit this into a machine with extremely limited memory.  He used a bunch of tricky techniques, including having the user key in all the description data by hand before every session, instead of using costly DATA statements redundantly reading their contents into separate array variables. Amazing! It is a tribute to the persistence of early computing pioneers on these extremely limited machines.

P.S.  Turned out there maybe were some precision errors in the mathematical routine to "snip out" the individual decimals in the node variable. When I printed its results they were offset at the third digit for some reason (more rounding errors?). That routine made two calls to the exponent function to do its calculations to derive a single digit from a designated location in the string of decimals. In the end I realized I could simply convert the decimal to a string and then use the MID$ function to snip the desired digit from the desired location. Then I could just use VAL to make that character back into a number. I had the luxury of memory to do this, although I think the routine was actually shorter, but it uses string handling, so I can't say for sure if it is actually more memory parsimonious.  Oh well, now the routine seems to work reliably.

Wednesday, 28 August 2024

"Softball" for BASIC 10-Liner Programming Competition (2025)

I decided to try to make another 10-Liner BASIC game for the next BASIC 10Liner Games Contest on Homputerium. It is loosely based on many computer simulation baseball games I've seen over the years, but more specifically, a game video I saw recently for the old 8-bit Japanese home computer the Sharp MZ-700:


I've been thinking for some time that it would be simple to animate a pitcher batter interaction and the plotting of the movement of runners around the 4 bases of a diamond.  I wasn't so sure whether it could all happen on the same screen though, until I saw the MZ game.  That old 8-bit machine isn't all that more functional than an MC-10 in its screen resolution. I also really liked the simple dynamic of different zones in the outfield representing different possibilities for number of bases. The original had 1 to 4 base possibilities and two "out" zones mapped along the back fence. I thought I could save some space by using the pixels of the semigraphics-4 mode of the MC-10, which gives me 1-64 units horizontally.  This is a lot better than the 1-40 units of the text "graphics" being used on the MZ game, and more than twice what I would have if I used the 1-32 horizontal text spaces of the regular MC-10 text screen. I just requires using solid colours instead of numbers.

In the end fitting in a diamond and a side bar for the pitcher and batter interaction on the right meant I could only fit in 1,2 and 4 base zones and two zones for outs. The MZ game also had four positions in the inner outfield for outs. I used Red for the zones causing an out, and then the colors corresponding to the semi-graphic 4 values 1,2,4 (offset slightly) to save my program doing some conversion between sensing the color the ball is travelling through and the number of bases achieved.

The MZ game doesn't actually recreate a baseball/softball game. There is something else going on about points for hits.  I can't really tell.  My son knows Japanese so maybe I'll try to locate the article for the type-in magazines with the game and see what he can make of it.  But I thought I could recreate the rules of a simple softball match, which I remember from school, including grad school recreational teams I played on. The balls just track within the diamond.  There are no out of bounds.  This would be too complex for a 10-Liner.

The game basically is a reaction game where you try to time your key press to activate the bat at the same time that the ball is crossing directly to the right of the player.  If you make a hit, a random trajectory from a slightly random starting point at the bottom apex of the diamond heads up screen. If the pixel track hits anything besides green, a number of bases are won, or the ball is out if it hits red.  Once I had the graphics for diamond and pitcher and batter printed, and the animation for the pitch and the swing done, then there is just some simple calculations of runs and misses until 3 outs has happened. Then a shift is made to the other team and it is all done again. Repeat until 9 innings are completed, then END with a report of the two scores.

To achieve this in 10 lines requires all the techniques I've developed over the years.  The most important are using "ON -(logical test) GOTO line num,num..." as a kind of 8-bit BASIC replacement CASE SELECT IF/ELSE commands.  The other "biggy" is using Boolean logical operators directly in calculations to help omit using IF/THEN statements for conditional calculations. Then it's just the simple techniques-- single letter variables, reusing variables/scratch variables, removing spaces, etc.

The code can be found on my Github here:

https://github.com/jggames/trs80mc10/tree/master/quicktype/Strategy%20%26%20Simulation/Softball

But I'll include the current version here:

0 J=3.5:K=1:B$="*":C$=" ":C=40+RND(10):?"ßßßßßß¿¿¿ÏÏÏ¿¿¿ßßßßßß","ßß߯¯¯¿¿¿ÏÏÏ¿¿¿¯¯¯ßßß","ŸŸŸ¯¯¯¯¯¯ŸŸŸ",

1 ?"ŸŸŸŒŸŸŸ","†Žƒ‰","߆¿¿Ž‡‹¿¿‰ß","ß߆Ž‡‹‰ßß","ßß߆Ž‡‹‰ßßß"

2 ?"ßßß߆Œ‡‹Œ‰ßßßß","ßßßßß‚ßßßßß","ßßßßß߆‰ßßßßßß",:A$(5)="ÿ":A$(6)="€ƒƒ‡":A$(7)="Ž‚":A$(8)="‹‹

3 ?"ßßßßßß߆‰ßßßßßßß ‹ÿ","ßßßßßßß߆‰ßßßßßßßß ‹€","ßßßßßßßß߆‰ßßßßßßßßß ","ßßßßßßßßß߀ßßßßßßßßßß ‡‹"

4 ?@58,"X":FORB=90TO470STEP32:?@B,B$;:FORZ=1TOC:NEXT:?@B,C$;:IFINKEY$<>""THENFORT=5TO8:?@214+T*32,A$(T)" ";:NEXT:IFB=378THEN7

5 NEXT:IFB=474THENS=S+1:SOUND1,2:IFS=3THENS=0:?@277,O+1"OUT":N=N+1:S=0:O=O+1:IFO=3THENO=0:R(W)=R(W)+R:R=0:W=-(W=0):N=0:K=0

6 FORZ=1TO2500:NEXT:N=N*-(N<10):?@480,"R"R"O"O"P"N+1"T"W+1"SC"R(W);:?@0,;:ONKGOTO0:FORT=0TO9:P(T)=0:NEXT:I=I+1:INPUTE:CLS:GOTO0

7 B=500:X=19+RND(3):H=RND(0)*SGN(RND(0)-.5):FORY=25TO0STEP-1:X=X+H:P=POINT(X,Y):RESET(X,Y):IFP=4THENB=442:Y=0:S=2:GOTO9

8 IFP>1ANDP<6THENQ=P-1:?@277,Q"BASES":Y=0:P(N)=.5:FORT=0TO9:P(T)=P(T)+Q*-(P(T)>0):R=R-(P(T)>J):P(T)=P(T)*-(P(T)<=J):NEXT:N=N+1

9 NEXT:?@480,"R"R"O"O"P"N+1"T"W+1"SC"R(W)"I"INT(I/2)+1;:FORZ=1TO2500:NEXT:ON-(E=0)GOTO5:PRINT@0,"T1:"R(0)"T2:"R(1):INPUTE:GOTO5

10 REM                                                                                             1         1         1         1

11 REM   1         2         3         4         5         6         7         8         9         0         1         2         3

12 REM78901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234

Doesn't seem like much, but it plays a whole game of softball. If your reactions are good then you will get more hits and more chances for various runs. If you miss a lot, then you'll get fewer runs.


It is working but I know as Christmas approaches and I have some more time for programming that I will want to refine it. There are possible bells and whistles I can add to make it a little more fulsome a game, possibly out of bounds hits, and maybe even adjusting the zones to include 3 base runs. I originally had the game limited to 127 characters, which is the max line length of the MC-10, but the contest only has a categories for 80, 120 and 256 line lengths. So I am definitely stuck with the 256 category.  Since there are some ways to trick the MC-10 to accept 256 character lines, I started adding features. But there is still room left.

I'll post addendums here as I go.  If you are interested, you can try playing the current version online at the Internet Archive.  Here is the link: