Hoppa över logotypen.

Mina bidrag till Minigame 2002

Här är mina tre enkla bidrag till Minigame 2002. Uppgiften var att skriva ett spel för en åttabitarsdator på maximalt en (1) kilobyte. Eftersom mina försök att skriva spel i assembler misslyckades kapitalt är dessa tre bidrag alla skrivna i BASIC.

De tre program som beskrivs på denna sida är släppta enligt GNU General Public License (svensk översättning), version 2.

Jag har dessutom skrivit en artikel om tävlingen för ABC-Bladet, medlemstidningen för datorföreningen ABC-Klubben.

Till dig som använder en textbaserad vävläsare: På grund av användningen av CSS visas inte dessa sidor helt korrekt i textbaserade webbläsare. Links och W3M är de som fungerar bäst, men även i dem blir radnumren felplacerade.

Connectris

[Skärmbild från ”Connectris”]

Instruktioner

Detta är en implementation av spelet Connectris, en idé jag fick från den trevliga spelwebbplatsen It's Your Turn. Det är ett spel för två spelare vilket kombinerar det välkända Fyra på rad med det alltid lika populära Tetris.

De två spelarna, blå och röd, turas om att lägga i sina "brickor" i spelfältet. Du kan bara välja vilken kolumn du vill lägga din bricka i, den kommer alltid att hamna i den nedersta lediga raden. Spelaren som först får fyra brickor i dad, antingen horisontellt, vertikalt eller diagonalt, vinner.

Det speciella är att närhelst den nedersta raden blir helt fylld, så tas den ur spelet, och alla brickor flyttas ned ett steg!

Systemkrav

Spelet kör på Commodore C128 i 80-kolumnersläge, och är skrivet helt i BASIC 7.0.

Om det startas från 40-kolumnersläge kommer det be dig om att byta läge och vänta på att en tangent trycks. Om det startas från något annat än en C128 kommer det visa ett felmeddelande och avsluta.

Jag fick frågan varför detta spel kör i C128:s 80-kolumnersläge då det inte använder sig av ens 40 kolumner. Det finns två skäl: Dels så kan jag blanda små/stora bokstäver (dialogen med användaren) med stora bokstäver/grafik (spelbrädet), dels går spelet dubbelt så fort i 2MHz-läge som i 1MHz-läge, även om det fortfarande går på tok för långsamt... :-/ (Om man kör programmet med en SuperCPU går det dock i acceptabel hastighet...)

Programmet kan hämtas här.

Kommenterad källkodslistning
Startpunkt
1
GOTO90
Hoppa till huvudprogrammet
Välj färger och skriv titeln
2
COLOR6,6:
Grön bakgrund
COLOR5,2:
Vit text
PRINT"{clear}{ct b}{ct n} C o n n e c t r i s {130}":
RETURN
Skriv ut vilka som spelar (överst på varje skärm)
3
PRINT"{down}{light blue}{ct n}"a$" {black}vs {red}"
b$"{black}.{down}":
RETURN
Skriv ut brädet
10
PRINT"{142}{white} a b c d e f g h
Kolumnetiketter
11
FORy=.TO7:
 FORx=.TO7:
  PRINT"{black}{sh -}";:
Ram
  COLOR5,p(x,y):
Brädet innehåller färgdata
  PRINT"●";:
En rund ring
 NEXT:
 PRINT"{black}{sh -}":
NEXT
12
PRINT"{cm z}{sh asterisk}{cm e}{sh asterisk}{cm e}{sh asterisk}
{cm e}{sh asterisk}{cm e}{sh asterisk}{cm e}{sh asterisk}{cm e}
{sh asterisk}{cm e}{sh asterisk}{cm x}":
Nederkanten
RETURN
Hämta ett drag från spelaren
20
DO:
 DO:
  COLOR5,c:
C = spelarens färg
  PRINT"{down}{ct n}"c$", your move? {142}{black}";:
C$ = spelarens namn
  GETKEYx$:
  x=ASC(x$)-65:
Översätt A-H till kolumnnummer
  PRINTx$:
 LOOPWHILEx<.ORx>7:
Kolla att kolumn är giltig
LOOPWHILEp(x,.)<>6:
Kolla att det finns ledig plats (=6=grön)
PRINT"ok
21
FORy=7TO.STEP-1:
Hitta nederst lediga plats
 IFp(x,y)<>6THEN
  NEXT
22
p(x,y)=c:
Lägg i brickan
FORx=.TO7:
Är nedersta raden full?
 IFp(x,7)<>6THEN
  NEXT:
  GOSUB30:
Ja! Rensa den
  RETURN
Kan inte vinna nu
23
GOSUB40:
Kolla vinstposition
RETURN
Radera nedersta raden och flytta allting ned en rad
30
FORx=.TO7:
 FORy=7TO1STEP-1:
  p(x,y)=p(x,y-1):
 NEXT:
 p(x,.)=6:
6=grön indikerar tom plats
NEXT:
RETURN
Kolla vinstposition
40
FORy=.TO7:
 FORx=.TO4:
  IFp(x,y)+p(x+1,y)+p(x+2,y)+p(x+3,y)=c*4THEN50
Horisontell vinstposition
41
 NEXT:
NEXT:
FORx=.TO7:
 FORy=.TO4:
  IFx<5THEN
   IFp(x,y)+p(x,y+1)+p(x,y+2)+p(x,y+3)=c*4OR
     p(x,y)+p(x+1,y+1)+p(x+2,y+2)+p(x+3,y+3)=c*4THEN50
Vertikal eller diagonal vinstposition
42
  IFx>2THEN
   IFp(x,y)+p(x-1,y+1)+p(x-2,y+2)+p(x-3,y+3)=c*4THEN50
Diagonal vinstposition
43
 NEXT:
NEXT:
RETURN
Tala om vem som vann
50
GOSUB2:
Titelrad
COLOR5,c:
Spelarens färg
PRINT"{down}{ct n}You win, "c$:
PRINT:
GOSUB10:
Skriv ut brädet
GETKEYz$:
RUN
Börja om
Fråga efter namn
60
PRINT"{down}{ct n}What's your name, "n$;:
INPUT" player";c$:
RETURN
Uppstartsrutin
90
IFINT(.1+.9)<>1THEN
Testa BASIC 7
 PRINT"{reverse on} c128 mode ":
 END
92
IFRGR(0)<>5THEN
Kolla 80 kolumner
 PRINT"{reverse on} switch to 80 columns ":
 GRAPHIC5:
Byt till 80 kolumner
 GETKEYz$
100
FAST:
Dubbla hastigheten...
GOSUB2
Titelrad
120
n$="blue":
Hämta namn på blå spelare
DO:
 COLOR5,15:
 GOSUB60:
LOOPWHILEc$="":
a$=c$
130
n$="red":
Hämta namn på röd spelare
DO:
COLOR5,3:
GOSUB60:
LOOPWHILEc$=""ORc$=a$:
b$=c$
140
DIMp(7,7):
Brädet
FORx=.TO7:
Töm brädet
 FORy=.TO7:
(fyll med gröna brickor)
  p(x,y)=6:
6=grön=bakgrund=tom
 NEXT:
NEXT
Huvudslinga
200
c=3:
3=röd spelare (blå börjar)
DO:
 ONc/8+1GOSUB210,220:
Byt aktuell spelare
 GOSUB2:
Titelrad
 GOSUB3:
Vilka som spelar
 GOSUB10:
Rita brädet
 GOSUB20:
Hämta ett drag
LOOP
Välj blå som aktuell spelare
210
c=15:
c$=a$:
RETURN
Välj röd som aktuell spelare
220
c=3:
c$=b$:
RETURN

[CSDb]

Maggot

[Skärmbild från ”Maggot”]

Instruktioner

Detta är det berömda "Masken". Jag stötte först på detta spel i och med Luxors spel Masken till ABC_80. Du är en mask (eller en larv i det här fallet) och ditt uppdrag är att äta så många mål som möjligt. Närhelst du äter ett mål växer masken. Om du kör in i väggen eller dig själv är spelet slut.

Spelet styrs med siffrorna på det numeriska tangentbordet: 8 för uppåt, 4 för vänster, 6 för höger och 2 för nedåt. Alla andra tangenter får masken att stanna, vilket betyder att spelet omedelbart tar slut!

Systemkrav

Detta spel kör på Commodore C128 i 40-kolumnersläge, och är skrivet helt i BASIC 7.0.

Om spelet startas i 80-kolumnersläge kommer det automatiskt att växla över till 40-kolumnersläge åt dig.

Uppdateringar

Version 1.1 - 2002-08-13:
  • Rättade ett fel som gjorde spelet att spelet inte fungerade vid första körningen. Det verkar som om DEFinierade funktioner inte överlever den relokering som görs av GRAPHIC-kommandot.
  • Rättade ett stavfel.

Maggot är en variant på det gamla välkända Masken-temat. Jag kom först i kontakt med Masken på Luxor ABC-80, och det spelet var skrivet helt i BASIC. Nu är ABC BASIC snabb, till skillnad från Commodores BASIC, så det jag tyckte det var en intressant utmaning att skriva en variant av Masken i Commodore-BASIC, i grafikläge, som åtminstone inte var helt ospelbart långsam. Det gick väl så där.

Programmet kan hämtas här. Observera! VICE version 1.9 och 1.10 är buggiga och klarar inte av det här programmet ordentligt. Det fungerar i version 1.8.

Kommenterad källkodslistning
Startpunkt
0
GRAPHIC1,1:
Byt till grafikläge
FAST:
Snabba på initieringen (och släck skärmen)
DEFFNr(x)=INT(RND(.)*x):
Skapa heltalsslumptal i [0,X)
DEFFNn(x)=x+1+zz*(x=z):
Öka X med nollställning vid Z
GOTO10
Gå till huvudinitieringen
Förflytta masken
5
LOCATEx(h),y(h):
Flytta grafikpekaren till dit vi ska
IFRDOT(2)THEN100
Om det finns något där dör vi
6
GETa$:
Se om vi tryckt en tangent
IFa$<>""THENGOSUB9
Om vi gjort det byter vi riktning
7
DRAW1:
Förflytta masken
DRAW.,x(t),y(t):
t=FNn(t):
Räkna ut nästa index för svansen
IFti>pTHENGOSUB93
Dags att flytta målet?
8
RETURN
Byt riktning
9
r=4*((a$="4")-(a$="6")):
4=vänster, 9=höger
d=2*((a$="8")-(a$="2")):
8=uppåt, 2=nedåt
RETURN
Initiera spelet
10
COLOR0,7:
Blå bakgrund
COLOR1,4:
Cyan grafik
COLOR4,9:
Orange ram
WIDTH2
All grafik två pixlar bred
11
CIRCLE,40,40,8:
Målet är en fylld cirkel
PAINT,40,40:
SSHAPEt$,32,32,55,53:
Spara som sprite
GRAPHIC1,1:
Töm skärmen
SPRSAVt$,1
Definiera cirkeln som spritebild 1
12
FORi=1TO7STEP2:
 BOX1,i*2,i,319-i*2,189-i:
Rita ramar runt skärmen
NEXT:
COLOR1,14:
Ljusgrön färg
CHAR,0,24,"{ct n}Score: 0
Poängräknare
13
COLOR1,2:
Vit färg
CHAR,20,24,"{ct n}www.softwolves.pp.se":
Och lite reklam...
COLOR1,4
Masken är cyan
20
z=1024:
Maxlängd är 1024
zz=z+1:
Hjälpvariablen för FNN
DIMx(z),y(z):
FORi=.TO9:
 x(i)=18+i*4:
Startposition (100,18) - (100,36)
 y(i)=100:
 DRAW,x(i),100:
Rita
NEXT:
h=9:
Huvudet på index 9
t=.
Svansen på index 0
21
GOSUB93:
Förbered första målet
SLOW:
Visa skärmen
r=4:
Flyttar åt höger
d=.
Ej uppåt
Huvudslinga
30
DO:
 DO:
Slinga för höger/vänster-förflyttning
  o=h:
Minns föregående huvudindex
  h=FNn(h):
Räkna ut nästa huvudindex
  x(h)=x(o)+r:
Flytta åt höger/vänster
  IFx(h)<15ORx(h)>304THEN100
Kolla skärmkanter
31
  y(h)=y(o):
  GOSUB5
Förflytta
32
 LOOPWHILEr
40
 DO:
Slinga för upp/ned-förflyttning
  o=h:
  h=FNn(h):
  y(h)=y(o)+d:
Flytta åt uppåt/nedåt
  IFy(h)<8ORy(h)>181THEN100
41
  x(h)=x(o):
  GOSUB5
42
 LOOPWHILEd:
LOOP
Träff registrerad
90
COLLISION2:
Stäng av detekteringen
SPRITE1,1,1:
Gör målet svart för att indikera träff
s=s+BUMP(2):
Räkna upp poängen och nollställ kollisionen
COLOR1,14:
CHAR,6,24,STR$(s):
Skriv ut poängen
COLOR1,4
91
e=FNr(5)+3:
Slumpa fram hur mycket masken skall förlängas
DO:
 o=h:
 h=FNn(h):
 IFh=tTHEN
Har vi nått maxvärdet?
  h=o:
I så fall slutar vi förlänga
  EXIT:
 ELSE
  x(h)=x(o):
Annars förlänger vi masken
  y(h)=y(o):
  e=e-1:
LOOPWHILEe
92
SPRITE1,.:
Göm målet
MOVSPR1,.,.:
Flytta undan det från skärmen
p=30+FNr(60):
Slumpa tid för återkomst (0,5-1,5s)
GOTO94
Nollställ klockan
Slumpa fram ett mål
93
x=FNr(269)+42:
Slumpa fram koordinater för målet
y=FNr(156)+59:
MOVSPR1,x,y:
Flytta dit målet
COLLISION2,90:
Slå på träffdetektering
SPRITE1,1,FNr(5)+2,.,.,.,.:
Slå på spriten
p=360+FNr(360)
Slumpa tid innan målet flyttas (6-12s)
94
ti$="000000":
Nollställ klockan
RETURN
Slut på spelet
100
CHAR,18,24,"{ct n}Game over! Play again?":
Visa att spelet är slut
GETKEYz$:
IFz$="y"THENRUN
Starta om om så önskas
101
GRAPHIC.:
Återställ textläge
SPRITE1,.:
Ta bort målet
COLOR.,1:
Svart bakgrund
COLOR4,1:
Svart ram
PRINT"{clear}{ct n}{white}You caught"s"target";
Visa poängen
102
IFs<>1THENPRINT"s";
(i plural)

[CSDb]

None Shall Pass

[Skärmbild från ”None Shall Pass”]

Instruktioner

Detta är ett enkelt "undervisnings"-spel, i vilket du endast får passera det hemska trollet (som visas på skärmen som ett rätt fult huvud) om du kan svara på dess frågor korrekt. I detta fall gäller det matematiska problem.

Ange först din ålder, vilken väljer svårighetsgraden. Därefter får du de olika frågorna. Du måste svara alla frågor korrekt för att få passera!

Om frågorna är för svåra kan du testa med att ljuga om din ålder! :)

Systemkrav

Detta spel kör på valfri åttabitars Commodoremaskin med BASIC version 2 eller senare. Det anpassar automatisk sin utdata så att den passar din skärm, oavsett om det är en VIC 20 eller en C128 i 80-kolumnersläge.

Jag vet inte om jag egentligen vill klassa det här som ett spel... Jag fick idén en kväll när jag gått och lagt mig och kunde inte få den ur huvudet, så jag gick upp och skrev ned spelet på min C128. Det som fick mig att skicka in det till tävlingen var att jag anpassade programmet så att det fungerar på alla Commodoremaskiner med BASIC 2. Jag testade för säkerhets skull det på PET 3032, VIC-20, C64 och C128... Jag blev glad när jag såg att det inte kom sist... (Jag undrar vem som var, öh, snäll nog att ge det tio av tio poäng?) Idén med tre frågor för att passera en bro kommer från filmen Monthy Pythons galna värld.

Programmet kan hämtas här.

Kommenterad källkodslistning
Startpunkt
0
DEFFNr(r)=RND(.)*r+1:
Slumptalsgenerator
GOTO10
Gå till huvudprogrammet
Radbryt en text och skriv ut
1
IFLEN(z$)<=wTHEN
Får texten plats på raden?
 PRINTz$;:
I så fall skriv ut den direkt
 RETURN
2
FORi=wTO.STEP-1:
 IFMID$(z$,i,1)<>" "THENNEXT
Leta på strategiskt blanksteg
3
PRINTLEFT$(z$,i):
Skriv ut fram till blanksteget
z$=MID$(z$,i+1):
Klipp strängen
GOTO1
Och börja om
Huvudrutin
10
PRINT"{clear}{down}{left}";:
Ta reda på hur bred skärmen är
w=POS(.)
11
PRINT"{home}{reverse on} none shall pass! {down}":
Skriv ut titeln
PRINT" /\/\  {cm m}":
Avancerad grafik...
PRINT"/\/\/\ {sh @}":
PRINT"\ \/ /":
PRINT" \  /":
PRINT"  \/{down}
12
DIMa$(99):
Räkneord
FORi=1TO19:
Hämta in ord för 1-19
 READa$(i):
NEXT:
FORi=20TO90STEP10:
 READa$(i):
Hämta in tiotal
 FORj=1TO9:
  a$(i+j)=a$(i)+a$(j):
Konstruera räkneord inom varje tiotal
 NEXT:
NEXT
20
z$="none shall pass unless he answers me right. tell me your age":
GOSUB1
21
INPUTa%:
Hämta ålder, dvs. svårighetsgrad
IFa%<2ORa%>130THEN90
Kolla att svaret är rimligt
22
m=10:
Lägsta svårighetsgraden har bara ental
n=m:
IFa%>11THEN
 m=20:
Nästa svårighetsgrad har upp till
 n=12:
tolvans multiplikationstabell
  IFa%>15THEN
   m=99
Nästa grad har alla tal
23
y$="what is ":
Frågetext
IFa%<8THEN30
Lägsta svårighetsgraden har inte multiplikation
25
f1%=FNr(m):
Fråga 1
f2%=FNr(n)
26
z$=y$+a$(f1%)+" times "+a$(f2%):
Multiplikation
GOSUB1:
INPUTp:
IFp<>f1%*f2%THEN90
30
t1%=FNr(m):
Fråga 2
t2%=FNr(t1%):
IFt2%=0THEN30
Se till att vi inte subtraherar noll
31
z$=y$+a$(t2%)+" from "+a$(t1%):
Subtraktion (blir alltid positiv)
GOSUB1:
INPUTs:
IFs<>t1%-t2%THEN90
35
a1%=FNr(m):
Fråga 3
a2%=FNr(m):
IFa1%+a2%=0THEN35
36
z$="tell me the sum of "+a$(a1%)+" and "+a$(a2%):
Addition
GOSUB1:
INPUTa:
IFa<>a1%+a2%THEN90
Vinst
80
z$="you may pass!":
Grattis, du vann!
GOSUB1:
END
Förlust
90
z$="that's not correct!":
Du förlorade
GOSUB1:
END
Räkneord
100
DATAone,two,three,four,five,six,seven,eight,nine,ten,
    eleven,twelve,thirteen,fourteen,fifteen,sixteen,
    seventeen,eighteen,nineteen
101
DATAtwenty,thirty,fourty,fifty,sixty,seventy,
    eighty,ninety

[CSDb]

[HTML 4.01!] [Alla vävläsare går bra här!] $Date: 2004/03/22 20:27:04 $ | peter@softwolves.pp.se

Åter till Softwolves Commodoresida | Peters hemsida