Coronavirus

Copyright © 2020 by Víctor Parada

Coronavirus

This is a little game for the 2020 NOMAM's BASIC 10-liners Contest. This program fits in the "stock" PUR-80 category, and it was written using Atari BASIC for the 8-bits ATARI XL/XE. Development started on 2020-03-12, and it took 3 days. The final version's date is 2020-03-14.

UPDATE: It obtained the 57th place of 87 entries in the category.


Description

Coronavirus is spreading widely and too fast. Lead your population to a safe area within the time.


Instructions

CORONAVI start Virus is spreading and your population at the bottom of the screen is in danger.
CORONAVI move Use your joystick to lead one group at a time to the safe area at the top of the screen, once you leave the bottom area, you cannot go back.
CORONAVI next Once a group is safe, some more time is added, and you can lead another group.
CORONAVI spots You can arrive to any position in the safe area, but following groups should fill the empty spots.
CORONAVI diagonal You can move diagonally to pass through blocking viruses.
CORONAVI fail If the group you are leading becomes infected, you die.
CORONAVI time When the time is over, infection becames unstoppable and the game ends.
CORONAVI win You win only when all groups are safe!

Development of the game

While developing Wazers, one of the game dynamics I thought was to move lots of wazers from the bottom of the playfield to the top, but as I decided to do what I finally did in that game, I kept the idea for a simple game for the PUR-80 category. Later, with COVID-19 (Coronavirus) pandemia on course worldwide, I thought about using this dynamics in a game where you need to rescue and cuarantine people without being infected.

When I had time, I prototyped it using Atari BASIC. I selected graphics mode 2 (ANTIC 7) without text window because the screen size provides a 20x12 colorful text playfield. The idea was to put 20 elements in the bottom of the screen, and allow the player to select one of them and run with it to the top of the screen, going through moving enemies. There would be one virus per row, moving from side to side, but changing its direction unexpetedly. In order to force the action, a timer was included, and the initial spot would be blocked, making impossible to return to it as a safe place. An asterisk would represent the virus, and an uppercase O the player, because I was almost sure than I won't be able to fit code for new bitmaps.

In a couple of hours I got most of the dynamics working. As it felt too easy to go from one side to the other, I decided to add more viruses per line, but, in order to do not make the viruses move at half speed, I decided to sometimes do not remove the viruses when moving them, as it seems that the plague is spreading. Of course, when the virus goes over the left ones, it could remove it or left it again. Also, it becames hard to see where a virus actually is when it is moving over the left ones.

CORONAVI proto 1

1st prootype

CORONAVI proto 2

Adding difficulty

The problem was that I was using 9 of the 10 available lines of code, and two features weren't included yet: a functional timer and a way to select which of the remaining objects should be selected. I thought I could add the timer, but I had to discard the selection of the remaining objects. This feature was planned as a way to do not be blocked by the virus at the bottom, but after some simulations, never happened that I could not move the next object, because diagonal movement was allowed since the beginning. But I could not add the timer because I could not fit it in the lines where it should be.

Doing some code optimization to get more space, I removed the initial random direction of each virus, and make them all start moving to the right. Also, some cosmetics where changed to save more bytes, and I could fit the timer management in the code. But I found that the timer decreased too fast during my tests, and I had no space in the screen to store a larger number, so I decided to add more time when the player reached the top side. This made me to do more code optimization to include all the required code.

CORONAVI proto 3

Cosmetics were changed

CORONAVI proto 4

A working timer

While testing, I discovered that I forgot to continuously disable the attract mode, and a "POKE 77,0" had to be inserted somewhere in the loop. It was another challenge, because I also found a border condition when the game finishes that should be also solved. After some logics changes, I could fix all the pendings, but it took another day... Unfortunatelly, there is no sound in this game.

CORONAVI final

Final version


Download and try

Get the CORONAVI.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. A joystick in port 1 is required.


The code

The abbreviated BASIC code is the following:

The full and expanded BASIC listing is:


Symbology:
virus=202
player = 47
blocked = 130
pending = 175
saved = 111
dead = 208
0
LINE 0: Initialization
graphics 18
Enables text mode with 20x12 resolution and 5 colors (4 for text and 1 for background)
dim v(8),d(8)
Virus arrays:
V(0-8): horizontal position of virus
D(0-8): moving direction of the virus
? #6;"TIME=999{binary data}"
Prints game title
z=adr("{binary data}")
Joystick's bit table (x*4+y)
s=40580
Memory address where playfield data starts,
same as s=peek(88)+256*peek(89)+20
1
LINE 1: Sets up the playfield
poke 77,0
Disables attract mode
c=s+20
position 0,11
for i=0 to 8
Routine to build the start state of the game
  x=int(rnd(0)*18)+1
  v(i)=x
Choose a column where to put the virus
  d(i)=1
Each virus will start moving to the right
  poke c+x,202
Puts the virus
2
LINE 2:
  c=c+20
Next playfild line's memory address
  print #6;"{binary data}";
next i
Prints the first 9*2=18 groups
print #6;"{binary data}";
Prints cels 19 and 20, the last one in another (active) color
o=40799
Sets current position of active group
x=19
y=10
Sets current coordinates of active group
n=20
Sets number of total groups to save
k=0
Not killed... yet!
r=1
Groups are alive
f=0
Frecuency for the player to move
t=999
Sets timer
3
LINE 3: GAME LOOP
i=(i+1)*(i<8)
Selects next virus line (9 lines: from 0 to 8)
c=s+20+i*20
Computes memory address for the virus line
w=v(i)
Gets current virus horizontal position
h=(w=0)+(w=19)+(rnd(0)<0.1)
Decides if the direction of the virus should change
if h then d(i)=-d(i)
Changes virus direction if it was decided
4
LINE 4:
p=c+w
Gets memory address for current virus
q=p+d(i)
Gets next memory address for current virus
k=peek(q)=47
Is the player in the new position?
poke p,202*(rnd(0)<0.12)
Removes the virus from its old position, except if a random trail is left behind
poke q,202
Puts the virus in its new position
v(i)=w+d(i)
Updates current horizonta position of the virus
f=f+1
Increase player frecuency counter
5
LINE 5: Updates player's position
t=t-(t>0)
Decrease global timer
j=peek(z+stick(0))
Reads the joystick
on f<3 or j=5 or k goto 9
Skip player movement if is not time to move, joystick was not moved or the player was killed
f=0
Resets the player delay
a=int(j/4)
b=j-a*4-1
a=a-1
Computes movement deltas
6
LINE 6:
p=o
Makes old position the current one
w=x+a>=0 and x+a<20
u=y+b>=0 and y+b<10
Check for inbound new position
a=a*(not(y=10 and b+1))
Horizontal move is prohibited inside bottom line
if y=11 and b+1 then a=0
c=b*u*20
Computes new vertical movement of the player in the playfield
o=p+a*w
Updates horizontally current position in the playfield
7
LINE 7:
h=peek(o+c)<>111
Unable to move over a saved group
o=o+c*h
Updates vertically current position in the playfield
k=peek(o)=202
Is there a virus?
x=x+a*w
Updates current horizontal coordinate of the player
poke p,130*(y=10)
Removes the player from the old location, and fill space fro the bottom line
y=y+b*u*h
Updates vertical coordinate of the player
8
LINE 8: When a group reaches the top, select the next one
poke o,47+64*(y=0)
Moves the player to the new position, making it saved if it reached the top line
if y=0 then n=n-1
  x=n-1
  y=10
Saved a group, continue with next group
  r=n>0
Not last group?
  o=40779+n
  poke o,47*r
Changes color for the next active group
  t=t+47-n
Extra time
9
LINE 9: End of loops (in a loop)
position 5,0
print #6;t;"{binary data}";
Prints timer
on k=0 and t>0 and n goto 3
Game ends when killed, time is over or all groups were rescued
poke o,208*r
Kills the group (unless the player wins)
on strig(0) goto 9
Wait for the trigger to start a new game
run
Restarts the game

Return to my 10-liners page.

© 2020 by Víctor Parada - 2020-03-14 (updated: 2020-08-15)