ZX80 Boggle - by Jim Waterman 5-21 December 2021 - for CSSCGC 2022 ==================================== GAME in .O format - use this in the ZX80 emulator of your choice (I recommend EightyOne). LISTING in .B80 format - this can be opened in a text editor to examine the listing (on the grounds that the ZX80 never had access to a printer) and is a plain text file that fills in the graphics characters using the \:: notation that users of BASin for the Spectrum will be familiar with, and represents the code in the REM statement in line 1 using the same notation \XX (where XX is the hex code of that character). Introductory bumph ------------------ This was mainly inspired by Jamie Bradbury's two Boggle simulations for the Z88, the imaginatively-titled "Z88 Boggle" (https://www.rickdangerous.co.uk/csscgc2021/review024.html) and the later improvement, "Zoggle" (https://www.rickdangerous.co.uk/csscgc2021/review038.html), which I had to review during my tenure of the competition. The earlier version, submitted as a text file which can be auto-typed into the Z88's BBC BASIC mode, made me think that it was such a simple process that, surely, a ZX80 could do it... And a ZX80 *can* do it, but not without a few tricks behind the scenes! Jamie's two programs don't actually *play* Boggle - AND THIS IS NO DIFFERENT. It's a simulation of the grid of letter cubes, which also keeps a count of your score, and who has won. DO NOT FORGET THIS. What my ZX80 version adds is a marvellous Chunk-o-Vision title page, because the ZX80 is every bit as capable of using them this way as the ZX81, and a variety of AWESOME PRIZES awarded to the winner of the game. Also, this is a program that meets one of the Challenges I set for the participants of the 2021 CSSCGC. The "Blue Challenge v2.0", which nobody tackled, said: "Write a ZX80 program which uses all eight of its Integral Functions". I have done so, and there's no cheating. ABS and STR$ are the ZX80's least useful functions, and I've done something with them both that serves a purpose. Maybe some people were put off this Challenge because it necessarily involves machine code to use the USR function, but it only requires a few bytes here and there. This program is 3,885 bytes before any variables are defined - and there's a lot of them - so it has no hope of running with a 4K RAM pack. The next one up was 8K, which will be fine. If this was written for the ZX81, it would be considered a 16K game even though it'd still fit into 8K. Take your pick on what to call it. Playing the game ---------------- Type LOAD (key W, not J - and no quotes on a ZX80, remember!) and NEWLINE. Then RUN. And NEWLINE. Easy, isn't it? Enter your names. Throw the cubes into the tray, shake it around a bit, and let them settle into the grid. Or, get the ZX80 to simulate this for you. Then, up-end the egg timer and you have three minutes to write down your words that you can find in the grid. Or, get the ZX80 to simulate this for you. R T T A R T T A These two examples show | \ legal words - anything I--E T E I E--T E in a continuous line is | | OK, and the line can Qu M T L Qu M T L cross over itself - but \| letters cannot be used I O S I I O S I twice. QUIET LITTER The players then compare their list of words, and only score for those words that none of their opponents (just the one in this case) also found. Words score as follows: 3 or 4 letters = 1 point 5 letters = 2 points 6 letters = 3 points 7 letters = 5 points 8 or more letters = 11 points. The Qu cube counts as two letters. The first player to get a total of over 100 points is the WINNER! Congraturation, you sucsess. Unless, that is, both players exceed 100 points at the same time *and* are tied, in which case, there game continues until the tie is broken. No idea if that's a real Boggle rule, but if it isn't, I'll make it exclusive to this game. I've come over all American... there *has* to be a WINNER! In excruciating detail ---------------------- Jamie owns a real-life, physical Boggle to take the layout of the cubes from; it's merely a case of scrambling the 16 cubes and selecting one face from each. It's really easy to do with string arrays. But then, the ZX80 doesn't use string arrays... After Jamie sent "Z88 Boggle" in June, I found some time to experiment with ZX80 machine code. It's a hazardous process making machine code work on a ZX80 - according to Toni Baker's teach-yourself guide, you can either store it in a number array (where you must *never* type RUN) or in a REM statement (which will crash the ZX80 if CHR$(64)-CHR$(127) are ever displayed, and the opcodes in that area are mostly useful LDs). You can hide the REM statement with POKE 16403,10 - just remember not to hit HOME (curse, you, muscle memory, when I think I'm typing a close bracket on a Spectrum or GRAPHICS mode), because that'll display the line and that'll be a crash... My first experiment was a routine to shuffle the alphabet held in the same REM statement, which was easily adapted to shuffling the letters A-P in a different REM statement (which can still be visible). These represent each one of the Boggle cubes. The faces of the cubes, which Jamie assures me are correct, are held in a third REM statement, in order. The faces are: TTRELY NHNLZR LREIXD MUOCTI OWTOAT TOESIS BBAOOJ EEGNAA EEUSNI CSOAPH SPFAFK YRDVLE UNHIMQu TSTIYD ERWTHV GEWNHE From here, it was straightforward to make a mock-up of a Boggle grid. The characters in line 3 are PEEKed and their CODEs assigned to a number array C; C(0) is randomly selected from the first six characters, C(1) from the next six characters, and so on up to C(15). The PRINT routine (lines 120-235) has to PRINT each character at the right place while drawing the grid, as there's no PRINT AT to do it afterwards, and my attempts to POKE the system variable that holds the PRINT position did nothing useful. Each time a letter is to be printed, the characters in line 2 are PEEKed in succession and translated to numbers - A means PRINT C(0), all the way through to P which means PRINT C(15). The "QU" face on one of the cubes is accounted for. And then everything came to a grinding halt, because no technique I could think of, BASIC or simple machine code, would keep a picture on the screen while the three minute timer ticks down. The ZX80 doesn't even have an internal timer, but I thought I could do it with a machine code process that continuously POKEs a space somewhere on the screen. It still blacked the screen out. Help was at hand from the ZX80 experts on Sinclair ZX World, though, and it was "flicker-free graphics" legend Paul Farrow who came up trumps, with a modification of a routine originally written by Tim Hartnell before the ZX81 had launched... https://sinclairzxworld.com/viewtopic.php?p=45447#p45447 And from Paul's website: http://www.fruitcake.plus.com/Sinclair/ZX80/BookArchive4K/ComputerPublications.htm Apparently there were bugs in Tim's original code; Paul has fixed them in the download, because it worked for me straight out the box. Once I'd disassembled the code to see if there were any fixed addresses that needed to be changed (there weren't), it was POKEd into the invisible REM statement, the non-timed FRAMES was set to the right value and before I knew it, I had a reliable 20-second timer where the Boggle grid stayed visible on the screen! From there on, it was a case of finishing the actual game routine, and then adding all the extraneous junk that I add to my programs, such as the title screen, the prizes, and some way to use all the functions. For the record, ABS was useful to determine the winning margin - it doesn't matter who has the higher total, subtract one score from the other, ABS it and that cumbersome minus sign is gone. STR$ was useful for the "75p and a packet of Rolos" prize; I was going to keep it at a random two-digit number, then realised that turning a three-digit number into a string with STR$ meant it could be sliced in a ZX80-idiosyncratic way to make "250" appear as "£2.50". CODE(V$) deals with only the first character of V$, so CHR$(CODE(V$)) is effectively V$(1) on a ZX81 or Spectrum. Then that first character is removed with TL$ (unique to the ZX80 among Sinclair computers!) and the rest can be printed. Just USR, PEEK and RND to use, and this program made good use of all of those. What are you still doing here? Boggle off and play the game. Or write something for the ZX80 yourself.