# Tackling the Logiker 2023 Vintage Computing Christmas Challenge – part 3

I have to admit, this year’s Logiker challenge stumped me. I had a few “clever” ideas on how to reproduce the pattern, but the code was larger than just printing out the pattern from arrays of strings.

Meanwhile, Jason Pittman kept posting revisions of his concept in the comments. In a response to part 2, he shared this:

This is the last attempt I came up with. It uses the same “-3 to 2 … ABS()” from the other example I sent on part 1. I think one potential trick here is to treat it as if you are holding a rubber stamp that stamps out three asterisks that are six spaces apart. You want to make this pattern by stamping it twice on each line. You’re keeping track of a starting position on each row (1027 + 32 for each row) and an offset to add and subtract to the starting position for each row. On the first line, the offset is zero, so you stamp it twice on top of itself at the starting position. On the next line, the offset is 1, so you stamp it twice, but one time you add -1 and the other time you add +1 to the starting position. Does this make any sense?

1 CLS:P=1027:FORC=1TO3:FORX=-3TO2:FORS=0TO12STEP6:POKEP-3+ABS(X)+S,106:POKEP+3-ABS(X)+S,106:NEXT:P=P+32:NEXT:NEXT:GOTO1

– Jason Pittman

This was an optimization of his original approach, but it had one limitation that might prevent it from solving the challenge: The CoCo’s 32×16 screen is too small to display the entire image, and POKEing characters on the screen would be limited to just 16 lines of text. He was aware of this, and his program does POKE the full image, but it is POKEing past the end of the visible screen. Would this count? RUNning the program displays the pattern over and over again (which was done to avoid having a new line with an endless loop GOTO):

POKEing past the visible screen works here because I am emulating a Disk Extended BASIC CoCo, and the memory after the text screen is reserved for four pages of PMODE high resolution graphics. But, I suspect, if I ran this on a cassette based CoCo, it might be POKEing in to memory used for the BASIC program itself.

Perhaps the CoCo 3 could help, since it has 40×25 and 80×25 text modes? Jason tried that:

I may play around with LPOKE. This should get it on the 40 column screen. I bet there is a crafty way to (a) not do the last line manually outside of the loops (b) remove one of the FOR loops (c) Shoot, there’s probably some crafty wizard way to do it in one FOR loop with logical operators, but I wouldn’t ever find it.

1 WIDTH40:FORZ=0TO12STEP6:FORX=-3TO2:FORS=0TO12STEP6:LOCATEABS(X)+S,Z+X+4:PRINT”*”;:LOCATE6-ABS(X)+S,Z+X+4:PRINT”*”;:NEXT:NEXT:NEXT:FORX=3TO15STEP6:LOCATE X,19:PRINT”*”;:NEXT

– Jason Pittman

In this version, Jason uses LOCATE(x,y) to position the cursor. That is what the CoCo 3 used instead of PRINT@ for text positioning. And it works!

It also feels better to use built-in BASIC text commands versus POKEing in to memory.

But he wasn’t done! He added this version:

10 WIDTH 40
20 FOR S = -15 TO 33 STEP 6
30 FOR X = 0 TO 18
40 IF S+X < 19 AND S+X >= 0 THEN LOCATE S+X,X:PRINT "*";
41 IF S-X >= 0 AND S-X < 19 THEN LOCATE S-X,X:PRINT "*";
50 NEXT X
60 NEXT S
70 GOTO 70

This one draws the same pattern, but in a very different way. It draws diagonal lines going down from the points at the top. Try it! It’s cool!

And, then this odd one, which creates the pattern by drawing the asterisks RANDOMLY, eventually getting them all on the screen.

0 WIDTH40
1 X=RND(3)*6:Y=RND(3)*6:RX=RND(7)-4:RY=ABS(RX)-3:D=RND(2)*2-3:LOCATE X+RX,Y+RY*D:PRINT"*";:GOTO 1

Nice job, Jason!

But it is going to make my brain hurt to understand how this works…

Meanwhile, I received a message from Rick Adams on Facebook with an implementation he was working on for a (much more limited) PDP-8 BASIC.

To be continued…

## 7 thoughts on “Tackling the Logiker 2023 Vintage Computing Christmas Challenge – part 3”

1. Jason Pittman

Thank you, and thanks for taking the time to post about this! These are fun. These days, I don’t really have the time (or attention span) to get very far into larger coco programs, but “basic” challenges like this are a great little mental workout and way to learn something new. I would bet that when the entries are posted there will be some that do this in a way I never even considered.

1. Jason Pittman

I’m going to split it into lines so it’s a little easier to see what’s going on. I’m treating it as nine diamonds, and the first thing it does is to find the center point of each of them. Line 1 sets both X a Y to RND(3)*6, so they will each be a random choice of {6,12,18}. The first center point is X=6,Y=6, the second is X=6,Y=12, etc. This example will just randomly print the nine center points of the diamonds (WIDTH 40 omitted):

1 X=RND(3)*6:Y=RND(3)*6
5 LOCATE X,Y
6 PRINT"*";:GOTO 1

Now we’ll add line 2 and set RX to RND(7)-4, which is a random value that will be in {-3,-2,-1,0,1,2,3} and add it to the X variable. Now when it does the LOCATE, it will just look like three horizatal lines, because the X value in the LOCATE will be {6,12,18} plus a random {-3 to 3}:

1 X=RND(3)*6:Y=RND(3)*6
2 RX=RND(7)-4
5 LOCATE X+RX,Y
6 PRINT"*";:GOTO 1

Now we’ll add line 3…this might be the part that is confusing. We set RY to the ABS of RX – 3, so RY will be set to {-3,-2,-1,0}, depending of what RX is. If RX=0, we are on the center point of the diamond, so we set RY to -3 and move up three rows and draw the top of the diamond. If RX=1 or -1, we set RY to -2 and draw the second row. If RX=2 or RX=-2, we set RY to -1 and move up one row. RX=3 stays on the same row and draws either the rightmost or leftmost point of the diamond. This example will draw the top half of the nine diamonds and essentially draw three “Charlie Brown shirt” patterns:

1 X=RND(3)*6:Y=RND(3)*6
2 RX=RND(7)-4
3 RY=ABS(RX)-3
5 LOCATE X+RX,Y+RY
6 PRINT"*";:GOTO 1

Finally, we need one more random variable to finish the diamond. On line 4, we set D to RND(2)*2-3, which will either be -1 or 1 and multiply the RY variable by it in the LOCATE. This way, when D lands on -1, it draws one of the characters below the center point that makes up the lower half of the diamond, But if it is a 1, it draws one of the characters above the center point (just like it did for the “Charlie Brown shirt”). D is just used to create a mirror of the top half of the diamond that lands below the X,Y midpoint of the diamond.

0 WIDTH40
1 X=RND(3)*6:Y=RND(3)*6
2 RX=RND(7)-4
3 RY=ABS(RX)-3
4 D=RND(2)*2-3
5 LOCATE X+RX,Y+RY*D
6 PRINT"*";:GOTO 1

2. Jason Pittman

On an unrelated note, a couple of years ago, Did I send you anything on the Notepad++ plugin I was working on that tokenizes basic and inserts programs directly into an emulator through window handles? It’s not the VSCODE plugin…that one worked pretty well but was too finicky to be useful. I’ve done a little more work and made a quick clip of it working with a customized version of VCC that accepts memory addresses through an unused window handle and plugs them into the emulator instantly without writing to a .dsk or doing anything other than plugging the tokenized program directly into memory. I’m WAY out of the loop these days…Does something like this already exist? My goal was to make it do things like rewrite line numbers and eventual get it to a point that you could do some form of line-by-line debugging in the emulator and see the state of each variable after each line executes, and I’ve gotten it a little closer to that. Ideally, I’d like to have a nice text editor (that isn’t Notepad++ or VSCODE) that would run on Linux and talk to Mame so I could have a fast basic coding workflow on Linux (or Rasp Pi). Not sure if I will get there (or if it already exists), but it’s good “back burner project”.

1. Allen Huffman Post author

You might have, but I most certainly don’t remember about something that could inject code directly into memory of the emulator. THAT sounds mega-appealing. Using the “save as text file, CLOAD” approach in XROAR is what I have been using. I only recently discovered about the “turbo” mode (F12 or something) that really helps speed up loading larger programs.

While I put Notepad++ on any Windows machine I touch, my home system is a Mac so I have never ran VCC or Notepad++ on it.

I like VS Code because it is cross platform — I use it on Windows at work, and my Mac at home. I use XROAR for the same reason. I really would like to use MAME, but it defaults to keys that don’t exist on the Mac or any of the PC laptops in the office (to get to the UI). One time I figured out how to remap them, and one day I’ll re-learn it and blog about it so I can search and find out what I did.

I’ll check that video. I’m very intrigued.

1. Jason Pittman

You know, I haven’t used it in so long that I didn’t even realize that XRoar supports CoCo3. I think it just became my new favorite.

I saw your video comment and I dug into this a little, and I think I almost have this working as a vscode plugin that supports XRoar and should work on Win/Mac/Linux. It uses a fresh snapshot that I saved from XRoar as a template, tokenizes the basic program, saves a new copy of the snapshot with the program inserted into the memory and launches XRoar with the “-load” flag pointed to the modified snapshot. Right now, I only have it (somewhat) working with CoCo3 Disk Extended, but if I can get a few issues worked out, it shouldn’t be a big deal to make it work on the other systems by just having an option that changes the location of the start of BASIC.

Can you post an email address where I can send you an update? I’ll probably have a little time to tinker with it this weekend (or get close enough that you can probably try it out) and it might be easier to explain in an email with some screenshots. I may just update the “CoCoTools” vscode extension I made a few years ago and make it only launch XRoar and do the BASIC renumbering and strip out all the things I had it in where I was trying to make it create disk images, etc. I can’t even figure out how to make all that work myself anymore and it might actually be useful if I update it to only do a couple of things.

This site uses Akismet to reduce spam. Learn how your comment data is processed.