Mosaic (Compute's Gazette)

Mosaic is a strategy game you can play against the computer or against a friend. Your goal is to place numbered tiles in order before your opponent. Although the rules are easy to learn, you won't find it easy to win. The wizards and accountants have created a truly ruthless machine.
The article for this game can be found on page 44 of Compute's Gazette Issue 56 (February 1988)

Why TAS This Game?

The continuation of TASing games from my all-time favorite magazine, Compute's Gazette. This makes my 106th TAS from this series.
Never played this game, because I missed purchasing the issue. This was after my subscription ran out and I had to resort to buying issues from "Reid-A-Book" in Anderson, SC. I would have loved this game, as it is an excellent puzzle game.

Game Difficulty and Ending

There is no difficulty selection; however, there are 4 different ways to play this game.
  • Player vs. Player
  • Player vs. Computer
  • P'layer vs. Player vs. Computer
  • Player vs. Computer vs. Computer
Here, I avoid playing the 1st and 3rd modes, since I want to play one person against the computer only.

Effort In TASing (Not BOTed)

This was the very first game I found in the series that used the RND function (Commodore 64's B.A.S.I.C. RNG algorithmn) against the timer control:
RND(-TI)
For those of you who understand the Commodore architecture, the variable TI is predefined and indicates a running time from the moment the computer is turned on. What this does is give more a "true" random behavior. Some games use RND(-#), which can be replicated over and over...if you turn the computer off and start all over again. At first, I had no idea what was going on, until I examined the code to find this usage. So, I had to change the way I approached this and eventually came up with a method that gave me the results that I feel was the best starting "seed". I was trying to get this game submitted in 2024, but I couldn't figure some things out. In fact, my initial "run-through" was terrible and I could never beat the game. Until recently, I finally figured out what was going on. The sequence of numbers, dealt to the computer, was unbeatable. So after I figured out how to control RNG in this game, I was finally able to find a sequence that gave me the advantage.
So in this run, I play all the modes that use one player against the computer. (The 2nd and 4th selections from above)

Human Comparison

Couldn't fine one.

DrD2k9: Claiming for judging.
DrD2k9: While the forum discussion concerning RNG manipulation is interesting, the theoretical potential that other seeds might be faster than the one used cannot be used as a reason to reject this otherwise well executed run.
While I understand the suggested approach of breaking the game execution after the first round to reseed RNG before returning to the game, I feel it is unnecessary. That said, I can't claim that it wouldn't be an acceptable approach.
Regarding splitting the two rounds into two separate runs: I feel this is a valid option, but not critically necessary. While it can be argued that they are different game modes and should be publisehd as separate branches, it can be just as easily eargued be argued that it's akin to including all episodes of an episodic game together in one submission. It can also be considered similarly to playing easiest to hardest difficulty.
Other thoughts:
  • I think there is also potential to add game 3 into the mix. The two 'human' players could theoretically 'work together' to beat the CPU as quickly as possible.
  • While it wouldn't be drastically different, I think one could make the argument that playing with the CPU tiles hidden would be more interesting.
Accepting.

r3gamerz: Processing...


TASVideoAgent
They/Them
Moderator
Location: 127.0.0.1
Joined: 8/3/2004
Posts: 17504
Location: 127.0.0.1
This topic is for the purpose of discussing #10389: nymx's C64 Mosaic in 02:21.427
Post subject: TI Seeding RNG
Joined: 7/7/2017
Posts: 41
There are two related BASIC variables, TI$ (string) and TI (number). Normally, TI counts up approximately every 1/60 second ("1 jiffy") and TI$ shows the jiffy count as HHMMSS. (1/60 second nominal regardless of PAL/NTSC) TI is not settable, but TI$ is. TI$ is in "HHMMSS" format. Setting TI$="000001" will give TI=60, then TI=61 a short time later, then TI=62, and so on. Consider this BASIC program:
10 FOR I = 0 to 20
20 TI$="000001":X=RND(-RND(-TI))
30 PRINT RND(1),RND(1)
40 NEXT
It will usually produce the sequence starting with .395... .0380... but will occasionally produce .538... .377... -- I think this depends on how many times the jiffy counter increments between setting TI$ and evaluating TI in the X= expression. Changing it to TI$="000002" gives a different most common outcome, etc. Under TAS conditions, of course, the result should be predictable. I think your attempted seeding method, printing RND(-3), is NOT directly controlling the random seed, it's just adding some particular delay to run the line of BASIC code which changes TI as a side-effect. Printing RND(-4) might give different results just because it takes more or less time to print the value(?) but I don't think you get access to a wide range of seeds that way. OTOH, running TI$="######" should let you access to at least 86400 seeds. If you also consider delaying a variable number of frames between setting TI and the RUN command you could access 59 more seeds for each of those 86400 distinct TI$ values. It's not impossible (but not guaranteed) that there is a shorter game among all possible seeds. Helpful references: https://www.c64-wiki.com/wiki/TIME$ https://www.c64-wiki.com/wiki/TIME
Joined: 7/7/2017
Posts: 41
Assuming you can force the value of TI used in the program at line 70, it's not hard to show all the draws that will occur using a simple BASIC program...
10 R=RND(-RND(-60)):REM assume forced TI=60
20 FORR=1TO64:DK$=DK$+CHR$(R):NEXT
30 D=64

290 REM DEAL HANDS
310 FOR I=0TO40:GOSUB 1030:PRINTT;:NEXT

999 END
1010 REM DRAW NEXT TILE
1030 X=RND(1)*D+1:DK$=LEFT$(DK$,X-1)+MID$(DK$,X+1)+MID$(DK$,X,1)
1040 T=ASC(RIGHT$(DK$,1)):D=D-1:RETURN
Here I've forced the seed to 60 and you can see that the initial draws match what is printed by the program: That said, evaluating a seed requires looking at what the CPU will do, not just having the move sequence available. FWIW I think the watch location for the TI(ME) value is A0/A1/A2 (24 bits): https://www.pagetable.com/c64ref/c64mem/#TIME
nymx
He/Him
Editor, Judge, Expert player (3094)
Location: Under the Weather
Joined: 11/14/2014
Posts: 1073
Location: Under the Weather
jeff_town wrote:
There are two related BASIC variables, TI$ (string) and TI (number). Normally, TI counts up approximately every 1/60 second ("1 jiffy") and TI$ shows the jiffy count as HHMMSS. (1/60 second nominal regardless of PAL/NTSC) TI is not settable, but TI$ is. TI$ is in "HHMMSS" format. Setting TI$="000001" will give TI=60, then TI=61 a short time later, then TI=62, and so on. Consider this BASIC program:
10 FOR I = 0 to 20
20 TI$="000001":X=RND(-RND(-TI))
30 PRINT RND(1),RND(1)
40 NEXT
It will usually produce the sequence starting with .395... .0380... but will occasionally produce .538... .377... -- I think this depends on how many times the jiffy counter increments between setting TI$ and evaluating TI in the X= expression. Changing it to TI$="000002" gives a different most common outcome, etc. Under TAS conditions, of course, the result should be predictable. I think your attempted seeding method, printing RND(-3), is NOT directly controlling the random seed, it's just adding some particular delay to run the line of BASIC code which changes TI as a side-effect. Printing RND(-4) might give different results just because it takes more or less time to print the value(?) but I don't think you get access to a wide range of seeds that way. OTOH, running TI$="######" should let you access to at least 86400 seeds. If you also consider delaying a variable number of frames between setting TI and the RUN command you could access 59 more seeds for each of those 86400 distinct TI$ values. It's not impossible (but not guaranteed) that there is a shorter game among all possible seeds. Helpful references: https://www.c64-wiki.com/wiki/TIME$ https://www.c64-wiki.com/wiki/TIME
Actually, because of "TI", you can push out the frame (which yeah, your method is better and you probably already know that) that I initiate that command. I had originally gone through about 100 to 150 frames of delay...before I realized that I got a decent result early on. Because the second mode of play had radically different layouts, I started to realize that the balance between the two modes was going to be hard to control. I finally realized that my earlier seed was one that I could accept. The use of that RND(-3) was an effort to use the two in combination to see if I can trick it, only to see that this effort was so much different than other games where I have controlled RNG. When i found my best result, It was a little too late for me to go back and try and sync that up...so a few frames were lost using that technique. You are right, I didn't test all the seeds...because it would just take too long; however, if a better seed existed...it probably would have taken too long to make any difference. I had considered BOTing this, but the emulation is way too slow and I would have had to play the first mode in order to test the second mode. Good to know that someone else in this community knows their C64 stuff!
I recently discovered that if you haven't reached a level of frustration with TASing any game, then you haven't done your due diligence. ---- SOYZA: Are you playing a game? NYMX: I'm not playing a game, I'm TASing. SOYZA: Oh...so its not a game...Its for real? ---- Anybody got a Quantum computer I can borrow for 20 minutes? Nevermind...eien's 64 core machine will do. :) ---- BOTing will be the end of all games. --NYMX
nymx
He/Him
Editor, Judge, Expert player (3094)
Location: Under the Weather
Joined: 11/14/2014
Posts: 1073
Location: Under the Weather
jeff_town wrote:
Assuming you can force the value of TI used in the program at line 70, it's not hard to show all the draws that will occur using a simple BASIC program...
10 R=RND(-RND(-60)):REM assume forced TI=60
20 FORR=1TO64:DK$=DK$+CHR$(R):NEXT
30 D=64

290 REM DEAL HANDS
310 FOR I=0TO40:GOSUB 1030:PRINTT;:NEXT

999 END
1010 REM DRAW NEXT TILE
1030 X=RND(1)*D+1:DK$=LEFT$(DK$,X-1)+MID$(DK$,X+1)+MID$(DK$,X,1)
1040 T=ASC(RIGHT$(DK$,1)):D=D-1:RETURN
Here I've forced the seed to 60 and you can see that the initial draws match what is printed by the program: That said, evaluating a seed requires looking at what the CPU will do, not just having the move sequence available. FWIW I think the watch location for the TI(ME) value is A0/A1/A2 (24 bits): https://www.pagetable.com/c64ref/c64mem/#TIME
Thanks. It has been a while, since I've actually wrote any C64/Vic20 code. I will remember this next time. Oh, something that you might find interesting. With all the games I've TAS for the C64, here is a list of RNG alterations that I've run up against: *Random Inputs: Most RNG can be controlled by hitting random keys or joystick directions; thus, affecting the values picked by the Kernal's (Commodore's spelling) instruction. (Almost all Machine Language games for the Gazette; however, many commerical games don't respond this way) *Custom RNG: Most commerical games have their own method of RNG, which random inputs don't normally affect. It is more related to circumstances and calculations based on them. *B.A.S.I.C. RNG: Every game, until Mosaic, was easily controlled by using RND(-###). Games written in BASIC, make use of the command to determine RNG. Using this method, I can set a seed with one command. *TI Based RNG: This method is related more to when a request is made, making it act like other consoles that I've TASed. This was very common with games like Super Metroid, where shooting on a different frame would cause drops to be different. With Mosaic, it was done once...which was disappointing, because the 2nd mode would have been much easier to manage, by delaying frames on selecting the second part.
I recently discovered that if you haven't reached a level of frustration with TASing any game, then you haven't done your due diligence. ---- SOYZA: Are you playing a game? NYMX: I'm not playing a game, I'm TASing. SOYZA: Oh...so its not a game...Its for real? ---- Anybody got a Quantum computer I can borrow for 20 minutes? Nevermind...eien's 64 core machine will do. :) ---- BOTing will be the end of all games. --NYMX
Joined: 7/7/2017
Posts: 41
Instead of finding 1 seed for both games, For the 3-player version you could hit run-stop, re-seed the RNG, and run again, e.g., type TI$="xxxxxx";RUN: followed by the enter key. Waiting through the game animations is kinda irritating for TASing. You could modify the game to remove the tile movement animation. For instance, this gets rid of the "slide chosen tile into place" animation: .. then once you find a seed, just resync with the unmodified version. I notice there's an option to keep the computer's tiles hidden. This might speed up the game, but there's certainly an entertainment trade-off there.
nymx
He/Him
Editor, Judge, Expert player (3094)
Location: Under the Weather
Joined: 11/14/2014
Posts: 1073
Location: Under the Weather
jeff_town wrote:
Instead of finding 1 seed for both games, For the 3-player version you could hit run-stop, re-seed the RNG, and run again, e.g., type TI$="xxxxxx";RUN: followed by the enter key. Waiting through the game animations is kinda irritating for TASing. You could modify the game to remove the tile movement animation. For instance, this gets rid of the "slide chosen tile into place" animation: .. then once you find a seed, just resync with the unmodified version. I notice there's an option to keep the computer's tiles hidden. This might speed up the game, but there's certainly an entertainment trade-off there.
That is an interesting thought. I never thought to break the game's code from running to do that again. Let me think about that. Thanks.
I recently discovered that if you haven't reached a level of frustration with TASing any game, then you haven't done your due diligence. ---- SOYZA: Are you playing a game? NYMX: I'm not playing a game, I'm TASing. SOYZA: Oh...so its not a game...Its for real? ---- Anybody got a Quantum computer I can borrow for 20 minutes? Nevermind...eien's 64 core machine will do. :) ---- BOTing will be the end of all games. --NYMX
nymx
He/Him
Editor, Judge, Expert player (3094)
Location: Under the Weather
Joined: 11/14/2014
Posts: 1073
Location: Under the Weather
I've thought about the use of "Run/Stop" and I'm not so inclined to doing that. I would much rather have two submission, denoting each "Mode" played. My reasoning for this is that it makes the run "unclean". For example, when can we say is a good moment to break out of the code? Should I do it the frame after the last input was made to complete the round? or the moment the message comes up, stating the results of the round? For me, the game needs to run and give clear indication of what is going on. Basically, I believe that when code starts...it shouldn't be interrupted. With Mosaic, navigation is possible back to the menu, which seems a necessary part of keeping things congruent. With consoles, things can be quite different when the reset is used. When i think about F-Zero...should I be trying to reset the game after I cross the finish line to start the next league? In that situation, I let the game run without interruption. With NES Metroid, resets are done to cut massive time for back-tracking. I may not have a good explanation, but it just doesn't feel right to do so in this case. Maybe I'm just OCD about it. Honestly, this is the first time I've seen this problem. I would prefer two submissions; however, I don't like bloating the site with similar looking runs.
I recently discovered that if you haven't reached a level of frustration with TASing any game, then you haven't done your due diligence. ---- SOYZA: Are you playing a game? NYMX: I'm not playing a game, I'm TASing. SOYZA: Oh...so its not a game...Its for real? ---- Anybody got a Quantum computer I can borrow for 20 minutes? Nevermind...eien's 64 core machine will do. :) ---- BOTing will be the end of all games. --NYMX
Post subject: Movie published
TASVideoAgent
They/Them
Moderator
Location: 127.0.0.1
Joined: 8/3/2004
Posts: 17504
Location: 127.0.0.1
This movie has been published. The posts before this message apply to the submission, and posts after this message apply to the published movie. ---- [7132] C64 Mosaic by nymx in 02:21.427

1779104469