Guess the Number

This is an experiment of how short could a full game be written in terms of the NOMAM's BASIC 10-liners Contest. This program fits in a non-existent PUR-10 category, and it was written in Atari BASIC for the 8-bits ATARI XL/XE. Development was done on 2023-04-03.

Description

Provide an upper limit and then guess the number the computer selected in that range.

Instructions

 Load the game and run it. Enter a number to set the difficulty. Try with any number between 1 and the selected difficulty. If the hidden number is lower than your number, the computer will show "<". If it is higher, it will show ">". Try other numbers based on the previous results. If you find the hidden number, the computer will say "=" and the game ends. The number of tries was given on each request. Enter RUN to play again.

Development of the game

During a talk with Bunsen, I said that no games could be written in 10 lines of a size of 10 bytes because the shortest Atari BASIC statement require 3 bytes, plus a colon as a fourth byte to separate statements, so a 10-bytes line could have at most two instructions that sum 8 bytes (the other two are the colon and the line number). Some demos could probably be written with such restrictions... Then I doubted, and I did an experiment. The only small game I could think at that moment was the same game that decades ago I wrote in a CASIO fx-3600P programmable calculator: Guess the number.

In a couple of minutes I wrote the whole algorithm using abbreviations:

```0N=INT(RND(0)*100)+1
1T=T+1
2?T;
3I.R
4S=SGN(N-R)
5?CHR\$(61+S)
6IFS THEN1```

Those were only 7 lines, but some of them were using more than 10 bytes in a single statement with an expression, so I had to split the expressions and use many lines to get the same result:

```0N=RND(0)
1N=N*100+1
2N=INT(N)
3T=T+1
4?T;:I.R
5D=N-R
6S=SGN(D)
7C=61+S
8?CHR\$(C)
9IFS THEN3```

I had to join two statements to keep the code in 10 lines of 10 bytes, but the guessing range was fixed and I wanted to make it variable. The result was:

```0N=RND(0)
1I.M:N=N*M
2N=INT(N)
3N=N+1:T=0
4T=T+1:?T;
5I.G:D=N-G
6S=SGN(D)
7C=61+S
8?CHR\$(C)
9IFS THEN4```

A game in 10 lines of 10 bytes.

Nice! A whole game in only 10 lines of at most 10 bytes. The T=0 initialization at line 3 is not required just after a RUN, but I put it for clarity (and because I had space).

The whole program uses less than 100 bytes, and 100 bytes is less than 120, the max line length for PUR-120 category. So, could this game be rewitten to fit just one line? Let's try...

The only Atari BASIC statement that allow loops without a GOTO is the FOR-NEXT structure, and we need it because we have to return to the middle of the line in a loop. The algorithm should be changed to something like this:

```INPUT M
N=INT(RND(0)*M)+1
T=0
FOR I=0 TO 1
T=T+1
PRINT T;
INPUT G
PRINT CHR\$(61+SGN(N-G))
I=(N=G)
NEXT I```

This FOR-NEXT loop is tricky: it starts with the index as 0 and should finish after the second iteration when the index is 1, but the last statement before the NEXT forces the index to be resetted to 0 when the condition N=G fails (and keep looping), and moved automaticaly to 1 if the end condition is satisfied in order to exit the loop even at the end of the first iteration.

The abbreviated code has only 78 bytes (or 74 if the initialization of T is omited), so we are still at PUR-80 category:

`0I.M:N=INT(RND(0)*M)+1:T=0:F.I=0TO1:T=T+1:?T;:I.G:?CHR\$(61+SGN(N-G)):I=N=G:N.I`

A game in 1 line with less than 80 bytes.

What if the code is entered in immediate mode? This is when we type instructions without a line number, like LIST or RUN. Changing the FOR to an almost infinite loop, with a NEXT that it is executed depending on the result of an IF condition, we get this:

`I.M:N=INT(RND(0)*M)+1:F.T=1TO1E9:?T;:I.G:?CHR\$(61+SGN(N-G)):IFN-G THENN.T`

A full game as a command.

Now, the game is only 73 bytes long, but it can't be SAVEd!!!! LOL...

Could this be reduced even more? Just change the 1E9 upper limit of the FOR to just 99 and a byte can be saved, but that limits the game to 99 tries. I you want to limit the game to only allow 9 tries, change that limit to 9 and another byte will be saved, and the command will have only 71 chars.

Of course, I'm sure it could be shorter if TurboBasic XL is used, but that is another story...

Get the GUESSNUM.ATR file and set it as drive 1 in a real Atari (or emulator). Turn on the computer and the game should start after loading. Don't press OPTION key as internal BASIC is required.

The code

The abbreviated BASIC code is the following:

The full and expanded BASIC listing is:

 Guess the Number (c) 2024 Víctor Parada ```0 ``` LINE 0: Initialization ```n=rnd(0) ``` Pick a random real number between 0 and 1 ```input m ``` Request for an integer limit (difficulty) ```n=n*m ``` Make the random number between 0 and the limit ```n=int(n) ``` Convert the real random number into an integer number between 0 and the limit minus one ```n=n+1 ``` Adjust the random number to the range of 1 and the upper limit ```t=0 ``` Initialize the tries counter (optional, it is autoinitialized at the RUN command) ```4 ``` LINE 4: Game loop ```t=t+1 ``` Updates the tries counter ```print t; ``` Show the current try number ```input g ``` Request for a guess ```d=n-g ``` Compute the difference between the random number and the guess ```s=sgn(d) ``` Express the difference in terms of -1=lower, 0=match and 1=higher ```c=61+s ``` Compute the ASCII number for the corresponding "<", "=" and ">" chars ```print chr\$(c) ``` Print the result ```if s then 4 ``` If there is a difference, go back to ask for a new guess