Friday, 22 May 2020

RetroChallenge April/May 2020: New Mahjong

I decided to take advantage of my son Charlie's newly minted Mathematics and Computer Science BSc from Dalhousie and the fact that he is trapped in the house because of Covid-19 to attempt to fix an old game of mine.  I made Mahjong many years ago, but all it did was throw the tiles into the traditional "turtle" format at random.  This meant that winning was a very rare occurrence.  Most computer versions of the game have an algorithm to ensure that there is at least one way to solve every puzzle from the beginning.  Then when you lose, you know it is because you somehow screwed up in removing the tiles.  This provides a much more rewarding play experience because you can typically play longer before running into dead ends and you know the puzzle is solvable (in principle).

I had vague ideas about how to implement such an algorithm, but they were really vague and all involved starting with a blank sheet and then placing pairs of tiles until the 3D turtle shape was built up of the stacked tiles.  So I set Charlie to the task of thinking about how to solve the problem of finding a solution. Next morning he presents me with the idea that it would be better to play the game forwards rather than backwards.  That is to say, start with the turtle populated somehow, have the computer play the game by removing sets of tiles randomly until none were left, then using that configuration.  He had a simple method worked out for mutating the values of the positions of tiles to map their "openness" or "closedness."  You can only remove a tile if it is free on one side and not covered by a tile above.

Basically Charlie's method starts with a coding system for the original positions:
1=open left and right
2=open left or right
3=not open left and right, but open above
4=not open left or right and above
5=not open left and right and above
Then whenever you remove a tile you add one to the positions left or right and add 2 to the position below to adjust their values. Then just solve the puzzle forward using blank tiles. You randomly select two free tiles (<3 tiles) and assign them a pair of tiles (1-36), then "remove" as per above.  Repeat until you get to 0. If it runs into a block (which is relatively rare) where it can't find a final pair-- Restart. See lines 20-74 and 2000-2045:

I had done some research of my own and had come across a similar tip originally from the Stack Overflow coding site. Basically the author suggested the same idea as Charlie, but he made it clear that what you do is start with a blank set of tiles in the turtle shape. He also provided insight into the problems you will face with this method, as occasionally you can end up with an odd number of tiles that are free (i.e. 1) and you will have to restart.  His estimates for how often this happened were very helpful and encouraging.

Long story short, we got the algorithm to work and the initial version timed to just under 2 minutes for program setup and algorithm completion. Obviously, it took a little longer if the algorithm hit an uneven completion and had to restart. Just running the algorithm (no including program initialization) timed to just over a minute, but in subsequent re-writes I think I have got this down to just under a minute.

Lots of data had to be stored, including a 3 dimensional array (15X9X5) to store all the initial position data and openness data. Other info was also required such as top tile, and the current height of each stack. We made use of many 144 element long 2-dimensional arrays to store pointers to the x, y and z of the valid positions and the current tile type in those positions. 144 represents the total number of tiles (i.e. 4 of the 36 types of tile, or two sets of every tile type). Processing these 2-dimensional arrays was great for speed, but we did have some difficulties moving back and forth between references to these lists and the 3-dimensional space with the info about each tiles' openness.

So I had to really streamline and pare down my initial routines for generating the unique low res tile set I had worked out for the original game. I was able to store all the tile info in strings and then just use MID$ to get to any particular tile I needed.  This was much better than my old version which stored tile detail in data statements and then constructed the strings in string memory.

I also added an undo feature that was lacking from the original, and since everything was pretty much stored in arrays already, a game save feature using the MC-10's CSAVE* command which allows you to easily save arrays to tape. Charlie's system of coding the open tile info also really sped up the searches for possible moves for the HELP/GAME OVER feature. In my old version every search required determining whether a tile was free by consulting its neighbours, instead of just storing this info permanently (and "mutate" the array every time you remove a tile as per Charlie's method).  The help feature simply presents the open tile pairs a set at a time.  If no such tiles exist, it present the game over prompt. 

So here's a video of me playing the new version:

As I mentioned, the algorithm has been speed up even further from this initial release. Here is a video of a speed test that indicates that even with initial program initialization you can be playing in just over a minute and a half:

Enjoy!  The game can be played here. Choose the "Play Our Original Micro Color Basic Games" option, then select "MAHJONG" from the Cassette menu and type RUN:

Monday, 4 May 2020

RetroChallenge April/May 2020: Golden Flutes and Great Escapes

I've ported the code of a game for the TRS-80 Model 1/3 from the Book Golden Flutes and Great Escapes: How to Write Adventure Games by Delton T. Horn. The game "The Golden Flute" is a simple adventure game with CRPG elements. The action takes place on a 10 X 10 grid. I added a nifty title screen graphic of  some of the members of the whimsical party of adventurers in the game.

I've also been engaged in some other hi-jinks. The winner of this year's Type-in Mania cup was Darren Ottery of Australia. Darren wrote a prominent early game in the MC-10 community, "Micomania." I remember playing this game as one of my first programs obtained through the Internet. Darren played it recently and posted a video of it online, because he couldn't get my game Miner running on MCX.  So I fixed Miner to work on the MCX and then I tried Micomania again myself just for the nostalgia of it. Well, I couldn't resist trying some of my speedup techniques on it. This morphed into making a better tracking algorithm for the enemy. Finally I did a little graphic editing using SKETCH to spiff-up the title page. In the end I sent it to Darren and he made a few more edits including putting me on the title page, which led to "Micomania 2."

Finally I have worked on some programs from a book for the Dick SMith VZ-200 computer, VZ200 Giant Book of Games by Tim Hartnell. One of the games I have got running on the MC-10 and (hopefully) fully debugged is "Rural Pursuits." Another one I am working on currently is "Chairman of the Board."

Rural Pursuits
There are just so many type-in programs out there it is hard to figure out which one to work on next. Some other folks have also been getting into the Basic program business. I was made aware of the Hartnell VZ-stuff by Mike Hawkey and David Maunder, who are trying to get the programs running on the VZ-200. Fabrizio Caruso posted a completely new puzzle game (with some arcade elements) in the MC-10 Facebook called "Mines Plus."  It's for next year's 10 liner, but although a small program, it is very addictive.  Curtis F. Kaylor posted a math skills game for kids on the MC-10 called "MathCom."  Darren Ottery added to MMania with TypeAttk, which is a typing skills testing program (made even more challenging on a real MC-10 I'm sure).  I have added these folks programs to the "Programmers" directory in my distro of the VMC10 Emulator.

Chairman of the Board by Tim Hartnell

Sunday, 19 April 2020

RetroChallenge April/May 2020: Mazies & Crazies Boss Fight

Here is the (somewhat sinister) map of the game Mazies & Crazies. In this update of my hand drawn map of my last post you can really discern the coherence of the underlying structure of DaCosta's game. This structure repeats itself 3 times. The map restarts at rooms 31 and 61, which are cognates of room 1.

Since room 1 doesn't allow a return through the top door because it has a pit trap going in that direction (i.e. the door is only one way from room 90), you can only get to room 90 by traversing the 3 levels. That makes room 90 an ideal place for a final boss battle.  So I have modified the program a little to provide this.  I have renamed the "DemiLich" monster I had been using to simply "Lich".  But in room 90 this character gets renamed "Demilich" and gets a bonus on its strength.  I also made the program put its highest ranked treasure in room 90. All other treasures and monsters only get distributed to rooms 4-89.

So now, you must seek the Demilich in its lair. This makes the game somewhat like the classic D&D dungeon adventure "The Tomb of Horrors" created by the legendary Gary Gygax. In keeping with ambiance of that adventure (if not its actual limited set of monsters), I have renamed the monsters yet again.  Here's  the current list in my version of Mazies:

  1. Asp
  2. Evil Dust
  3. Live Axe
  4. Skel-eton
  5. Mum-my
  6. Gray Ooze
  7. Ogre
  8. Lich
  9. Demi-Lich
For those who don't know, a lich is an undead corpse of a powerful wizard. A demilich is the animated skull of an extremely powerful undead wizard who has gone beyond the need for the rest of his body. Great wizards usually became liches in order to continue their pursuit of magic and power beyond death. The boss of Tomb of Horrors is the Arch Demilich Acererak. He's pretty powerful, so you'll need to marshall your powers to be able to kill him in MC-10 Mazies. You'll need the shield (at least) to have a chance. Don't think the arrow will help, although it can't hurt. You might try getting the bomb and then try to lure him onto it, if you want to ensure victory.

I have also added a few more fixes and speedups to the program. The victory sound and the sound for the magic portal and pit trap have been improved. I fixed a bug that made the portal only take you to room 11. Now it will take you anywhere in dungeon except room 90.

I'm pretty sure that this program is pretty obscure, if not completely missing from the Net, by which I mean it doesn't have any playable copy available that I can find. My version of it is even more obscure again. But in case there are any hardcore fans of 8-bit BASIC RPG's out there, this is an adventure for you.

P.S. Added a listing for this game to the Wikipedia's List of role-playing video games: 1975 to 1985
P.S.S. I final read other chapters of the book, and discovered that DaCosta actually presents the map of the layout, so all my careful mapping was unnecessary.  Lesson: Don't just read the chapter about the source code.

Saturday, 18 April 2020

RetroChallenge April 2020: Mazies & Crazies Map

I have been able to clean up the map I made last night (and wrote about in my prior post). There is definately a coherent structure, which my poor sketching skills pobably obscures a little.

The other levels just repeat this basic map, with their "Room One" occuring at 31 and 61. Each of these can be looked at as different levels of the dungeon. So You could say that DaCosta has constructed a 3 level dungeon.  Room like room 30 on this first level leads back to Room One, but you cannot go back to room 90 because of the "pit trap" which prevents going that direction.

I think another line of possible improvement of the game would be to make each level's monsters harder than the prvious. Perhaps, this could be done simply by adding a number of more powerful monsters unique to succeeding levels and with a boss fight in room 90.  At the very least, I think I will add a "Lich King" to room 90.  Or perhaps I will change all the demilich's to just "lich"s and put the demilich as the final boss. This will make DaCosta's game a little more like one of the most famous dungeon campaigns (modules) of the classic game D&D, the infamous "Tomb of Horrors".


P.S. Corrected a bug today in the MC-10 version. I had used the "I" variable in the FOR/NEXT for my sound routine for the magic portal, that was also used by the portal routine for the room number of the random location you were to be sent to-- Result, you were always being sent to the same room number (the last number of the FOR/NEXT). Fixed it to use another "scratch" variable C.  Now you will be sent to a random location anywhere in the dungeon. I have uploaded a new version to all my storage locations.

Friday, 17 April 2020

RetroChallenge April 2020: Mazies & Crazies Gameplay

I've moved to real MC-10 hardware and finally started to seriously play the game now that I've got (I hope) all the bugs out. I've been trying to apply some technique to play so that I don't just end up being killed. I have managed to penetrate all the way to the "end" of the dungeon. The room layout is not completely linear and is a bit convoluted, as you can see. Don't think this is from errors on my part.  There is a basic coherence.

In brief, I think the maze consists of a basic plan of 1-30 rooms, which is repeated again 31-60 and 61 to 90.  I have made it to room 90 and returned to Room One, although I didn't explore most of the rooms in the 31-89 range.  As I noted in prior posts, I "corrected" the program so you can't go back from Room One to Room 90.  Don't know if that is another "error" introduced into the code on my part, but I don't think so, since the "pitfall" routine is called nowhere else, and its use makes the most sense in Room One.  It makes the game more exciting trying to figure out how to get to the higher numbered rooms and ultimately to Room 90. It is just silly to have room 90 accessible to Room One.

Made it to Room 90

Checking my Score

Step through bottom door and I'm back to Room 1
Perhaps DaCosta corrects the Room One-Room 90 bug somewhere in the text of the book as he discusses the program. Perhaps, he suggests that you correct it after having tested the higher levels by jumping to them directly from Room One. I don't know. I've only skimmed the chapter.  I'll go back and read it in more detail now. Perhaps, he wanted to give people a way to create a boss fight in room 90, and to be able to get there quickly for testing purposes. It's an example program afterall, so there are bound to be rough edges and opportunities designed to be filled in by the reader.

I can certainly think of some nice features to add.  Like I said, a boss fight of some kind in room 90 would be nice.  Some additional monsters from the core 8 would be nice too.  Different rooms for the levels 31-91 would be a possibility too, as there is no obvious technical reason for why they should repeat. It's certainly not to save memory, since they have their own data lines in the source code. One thing that would be really nice would be a game save feature. I think this should actually not be hard to implement since, almost everything of importance is held in one numeric array, and so should be able to be saved using CSAVE*L,"FILENAME" command of the MC-10.  Such possibilities are what I will explore next for RetroChallenge, if I have time.

I felt a little like a real pioneer exploring the Mazies maze.  It was a virtual space that possibly hasn't been explored by anyone in over 30 years.  Or maybe never, at least by anyone else than DaCosta.  If no one ever actually bothered to type the whole thing in, who knows, I might be the only one besides Da Costa, to have traversed it.

Monday, 13 April 2020

RetroChallenge April 2020: Finally Figured Out How to Win!

Get your Mazies hoard on!
Two posts back I discussed an apparent bug in the Quit/Score routine of Mazies & Crazies.

I thought line should be changed from this:
240 J=0:FORI=17TO48:IFL(I)=1THENJ=J+I

to this:
240 J=0:FORI=17TO48:IFL(I)=91THENJ=J+I

because otherwise it would not count which treasures you had in inventory, which are marked as being in Room 91 (your sac presumably) and not one of the 90 rooms.

However, given my last post about the rooms and the trick of not trying to return to room 90 after returning to Room One from there through the final door, it occured to me that DaCosta might have been expecting people to take treasures back to Room One and drop them there in order for them to be "counted" by the score routine. That way you could only receive reward for treasure that you had "brought back" from the dungeon.  If you made it all the way to Room 90, you would not have to go all the way back through the maze. Instead, you could be transported directly back to Room One, where you could drop your latest items and check your score.

If you select quit anywhere else in the game your score only represents the number and power of the monsters you had killed, and not any treasure, even treasure you were carrying. This had seemed a bit weird to me, but I now see the reason for it. The style of play is to foray from and return to Room One and to only check you score there. Additionally, you might use techniques for collecting treasures and taking them to way stations, before making return to bring them to Room One. Such an approach certainly adds complexity and nuance to the game play that wouldn't be present if your inventory was all that mattered in terms of score.

But why then not make it only possible to use the quit command in Room One?  Or at least give credit for treasure being carried if quit were chosen somewhere else?

There are advantages either way, but only counting treasure dropped in Room One could have been DaCosta's way to prompt the player to figure out that the game was a treasure hunt with a preferred "home base." This would need to be recognized if collected treasures were to register and a high score achieved. Whereas, if you count stuff in inventory and also Room One, as the following change would allow,

240 J=0:FORI=17TO48:IFL(I)=91ORL(I)=1THENJ=J+I

the player might never figure out the real goal of play.

It had struck me as odd that the player could not carry all of the 16 treasures hidden throughout the dungeon. So I had thought  that the goal was to find as many of the highest numbered treasures as possible, while dropping any lower ones and to kill as much as one wanted before choosing to "quit the game." In other words, I had presumed that someone would decide when they had had enough adventuring. But it now seems likely that Da Costa felt that one should play until one died, and that the real goal of the game and the way to "win," would be to quit while in Room One, with your treasure hoard all around you.

Presumably killing every monster and returning every treasure to Room One, without any "resurrection" restarts, would be the ultimate high score. This is because every time you die and are resurrected, you get a score penalty, but anything you are carrying is dropped in the room where you die. Also, anything you dropped previously in Room One will be left there. So there is a trade off to choosing resurrection and going back to retrieve treasures, or simply rerunning the game to start fresh.  More nuance to game play. It all makes sense.

So I'm changing the Quit/Score routine back to its original form.

But there must be some way to inform the player about this. Perhaps in the instructions...

New Instruction: Return treasures to Room One
As the old saying goes... you live, you learn.

I see on page 202 of Writing BASIC Adventure Programs for Your TRS-80 that DaCosta says "J will be used to tally the score. To evaluate the treasures, a loop counts through the location array, finding treasures that reside at home home base (room 1). For each safe treasure, points are added to score J based on the treasure number." Treasures are worth anywhere from 17 to 48 points each, which means there is a total of 1040 for treasure.

The score for creatures is killed is based on the "size of the creature," according to Da Costa. Points range from 9 to 16 points each. There are 48 creatures in 6 groups of the 8 "sizes," So a max score of 8 X 16 + 8 X 15 + 8 X 14... (totally to 800) is possible.

That means the max high score for this game is 1840 if one plays without ever dying and needing resurrection, kills everything and brings every treasure back to Room One. That doesn't sound too hard.

I made some changes to the monster names, so they will format better in the 4 character space available on the right side of the screen for messages in the MC-10 version:

1. Spider -->Rat
2. Snake  --> Bad Elf
3. Land Crab
4. Scorpion --> Were Wolf
5. Huge Bee
6. Amoeba --> Gray Ooze
7. Troll --> Ogre
8. Dragon -->Demi Lich

These form better in the 4 character 2-line message space at the top right.

RetroChallenge April 2020: Why Mazies & Crazies Went Missing

Mazies-- Now with added Pit!
Allen Huffman wrote on facebook about Mazies & Crazies:
"I am really growing fond of these BASIC games you are doing. It was a really exciting time."
I replied:
"Exciting but a little tedious at times. I'm still editing this one and just found a few more typos. I can understand why the program went missing-- No one wanted to type in 90 sixty character strings (of numbers)!"
1000 R$(1)="000602540855070301062900902714-401011125401111180418"...

I noticed something strange in the code. There was a routine for a "Pit" you could fall into, but I hadn't noticed any pits yet in my playthroughs. In looking at the code I could seed that the Pit routine was triggered when you enter Room 92. This sent me to look closely at the room data to see if a Room 92 was ever listed among the exits for any of the rooms. In the course of checking, I noticed some more typos. Mostly 8s that were interpreted by the OCR of the scan as 3s. But I couldn't find any 92s.

Then I recalled being a little baffled by the ability to leave through the top door of Room One and being taken to Room 90, which is the highest number in the dungeon.  It would seem to make more sense that part of the adventure is to work your way through the dungeon to higher and higher room numbers, with 90 being the ultimate objective. Indeed the room numbers seemed to be listed in an ever increasing crescendo, with the rooms in the high 80s finally leading to Room 90.

So it seemed weird that Room One should simply let you get to Room 90 through its top door (see line 1000 above and the screen shot above). So I changed it to 92:

1000 R$(1)="000602540855070301062900922714-401011125401111180418"

Now in Room One, if you try to leave through the top door, which the two walls in the room seem almost to point you towards, down in a pit you go!  I added a little falling sound for the MC-10 version. For the TRS-80 senior version I had to fix the pause from a "I=1 TO 20" to "I=1 TO 2000," since otherwise you couldn't even see the "You've fallen in a pit" message." Now, you must struggle to get to Room 90. When you finally get there and through the final door, your are taken back to the beginning (Room One). But don't try to backtrack and return to Room 90. If you do, down in the pit you go! This is a more fitting and somewhat ironic ending for an "epic" foray into a "mysterious dungeon."

I wonder if DaCosta had left this change in to allow allow himself the ability to get quickly to the higher levels for debugging purposes, and never changed it back before sending his book to the printer.  

I also noticed that when you eat the "magic fruit" you get some random amount of healthup to several 1000s. Since the fruit returns to the rooms in which its appears whenever you leave and return, you could just pop into and out of a room many times to bump your score way above the normal 10,000 (or the 9999 in the MC-10 version since I only have 4 characters to play with on the right side for messages, instead of 8). There were no checks to prevent you from going above "full strength," which seems weird and counter to the goal of making the game a challenge.

These bugs, along with the one I found in the Score routine (discussed in my last post), and the slowness of the TRS-80 version probably annoyed anyone who actually typed in the game and left bad taste in their mouths. So when it came to people having enough affection for the game to prompt them to make sure it was preserved somewhere on the Net there was simply too little good will out there.

By replacing INKEY$ with continuous key polling PEEK(2)ANDPEEK(17023) of the MC-10 and adding some other speedups, I think the MC-10 version is really much more playable. The smaller screen size also makes moving around much less tedious. The added sounds and the color don't hurt either. With these improvements, it really is more fun.

DaCosta put a lot of thought into its construction. Without its bugs and typos, a little more speed and an instruction screen, I think it would have been fun game to play back in the day. I could see my friends and I competing for high score, which would truly represent your ability to penetrate to the higher numbered rooms, find the highest numbered treasures and defeat the largest number of the strongest monsters. If all of this could be achieved only by carefully marshalling your strength, instead of artificially pumping it up though the magic fruit bug, a high score would be truly meaningful.

But the absence of these features probably left people cold after having engaged in the monumental task of typing in and checking 90 lines of room data. Their disappointment might have prompted some to seek (literally and figuratively) to erase the game from their memory.