Bei „GOBANG“ werden abwechselnd Steine auf die Kreuzungspunkte des Spielplans gesetzt. Ziel des Spiels ist es, fünf Steine in einer Reihe nebeneinander zu legen; diese Reihe kann senkrecht, waagrecht oder diagonal verlaufen. Während Computer und Spieler versuchen, eine Fünferreihe zustandezubringen, suchen sie gleichzeitig ihren Gegner zu behindern.
Wenn Sie das Programm geladen haben, fordert der Computer Sie zum Zug auf. Falls Sie nicht beginnen möchten, drücken Sie einfach auf „Farbenwechsel“. Dieses Feld wird immer dann invertiert dargestellt, wenn Sie mit den schwarzen Steinen spielen.
Am oberen Bildschirmrand wird links die vom Computer verbrauchte, rechts die von Ihnen verbrauchte Zeit angezeigt. Die Spielstarke können Sie in fünf Stufen wählen; bei „5“ spielt der Computer am stärksten.
Jedes Spiel kann mit der Option „Ein neues Spiel“ vorzeitig beendet werden. Nach dem zweiten Zug besteht die Möglichkeit, die jeweils letzten beiden Steine vom Brett zu nehmen („Rücknahme“).
Ein Druck auf das Feld „Abbruch“ kehrt nach einer Sicherheitsabfrage zum Desktop zurück. Das letzte durch die Maus zu betätigende Feld hat eine Doppelfunktion: Während des Spiels können Sie sich den letzten Zug des Computers ins Gedächtnis zurückrufen. Vor dem Spiel können Sie sich vom Computer eine Demonstration vorführen lassen. Diese Demo kann durch Druck auf die linke Maustaste beendet werden. Im letzten Feld wird die Bewertung direkt während der Rechnung angezeigt.
Bezeichnungen der Spiel- und Phantomfelder:
Das Spielbrett im Speicher des Computers besteht aus 361 (19x19) Spielfeldern und 168 „Phantomfeldern“. (F%(0) bis F%(528)) Alle Variablen sind aus Geschwindigkeitsgründen mit einem %-zeichen als Integerzahlen deklariert. Die „Phantomfelder“ rahmen das Spielfeld ein. Die Felder können drei verschiedenen Bezeichnungen annehmen:
Die Phantomfelder haben grundsätzlich die Bezeichnung „100“.
Ermittlung des besten Zuges:
Der Computer ordnet jedem der Felder einen bestimmten Wert zu. Danach ermittelt er das Feld mit dem höchsten Wert und prüft, ob weitere Felder mit dem gleichen Wert vorhanden sind. In diesem Fall entschließt er sich durch Wählen einer Zufallszahl, eines dieser Felder zu besetzen. Sind alle Felder nullwertig (zu Beginn des Spiels), wählt er ebenfalls zufällig. Allerdings meidet er während der ersten 50 Züge die äußeren beiden Reihen des Spielfeldes. Aber wie findet der Computer das höchstwertige Feld? Meine Idee zur Lösung des Problems ist folgender Algorithmus:
Die Menge der nebeneinanderliegenden gleichfarbigen Steine ist proportional zur Höhe des Wertes, der den Werten der direkt benachbarten unbesetzten Feldern zuaddiert wird.
Durch die Art und Weise des Spielbrettaufbaus kann ich in einer Schleife von 48 bis 480 das höchstwertige Feld mit nur vier Rechnungen ermitteln. Den Computer interessieren immer fünf nebeneinanderliegende Felder. Angenommen, er zieht das erste Feld Nummer 48 in Betracht und er möchte wissen, welche Bezeichnungen die 16 senkrecht, waagrecht sowie diagonal benachbarten Felder haben. Dann vollzieht er folgende Rechnungen:
Sie können diese Berechnungen auf jedem Feld vornehmen, immer werden Sie zu den richtigen Ergebnissen kommen. Hier erklärt sich auch der Sinn und Zweck der Phantomfelder: Ohne sie würde der Computer über den Rand hinaus rechnen, von anderen Problemen ganz zu schweigen. Die oben erwähnten vier Rechnungen etwa könnte man bei Feld 0-47 und Feld 314-361 überhaupt nicht durchführen.
Das nächste Problem war die Hierarchie der Feldbewertung:
Wann muß dem Wert ’0’ eines Feldes welcher Wert zuaddiert werden? Dies konnte ich erst nach langem Ausprobieren entwickeln. Man muß viele Feinheiten beachten, die sich erst im Laufe eines Spiels ergeben.
Sicher gibt es andere Algorithmen zur Lösung dieses Problems, doch dieser erschien mir am einfachsten. Da er sich von dem eines Schachcomputers stark unterscheidet, kann man bei einer höheren Spielstärke nicht damit rechnen, daß der Computer die Züge weiter vorausberechnet. Er rechnet stattdessen immer mehr Steinkombinationen durch.
Hätte ich mein Gobangspiel nach Art eines Schachcomputers mit einer rekursiv aufgerufenen Prozedur konstruiert, so müßte der Computer wegen der 361 Spielfelder (im Gegensatz zu 64 beim Schachbrett) nach meinen Schätzungen mindestens fünf Minuten pro Zug rechnen. Das wäre auf die Dauer ziemlich langweilig. Ich wünsche Ihnen viel Spaß beim „GOBANG“!
Gerd Stephan Rottwilm
a. Strings:
SPT Spielerzeit
COT Computerzeit
ANZ Anzeigesprite
BRT Sprite für die linke obere Ecke des Bildschirms
b. Integervariablen:
M Modus
FL Flag für den Spieleranzeigesprite
SPCO Farbeinstellung
FS Weiß
ZAL Zugnummer
Y Koordinaten
T Maustaste
TI Flag für die Zeit
GEW Gewinnanzeige
FC Schwarz
CW Flag für Computerdemo
DD Gleicher Stein nach Rücknahme?
SM Spielstärkemerker
SG Spielstärke
VA Für den Vergleich der Werte
Z Für Schleifen
A, B, C, D, E, F, G, H
Allgemein gebraucht
XM, YM
Koordinatenmerker für „Letzter Zug“
COM, SPI Spielstand
Q Für Schleifen
c. Arrays
A() Texte
WO Feldwerte
F() Feldbezeichnungen
Z() Zugmerker
WT() Zu addierende Werte
FR 10, FR 20, FRG() Steinkombinationsabfrage
T(), L() Addition - Subtraktion
d. Prozeduren:
I Initialisierung der Variablen und Arrays
S Spieler
C Computer
ANZ Anzeigemeldung (Wer ist am Zug, wer hat gewonnen usw.)
STK Spielstärkeeinstellung
RK Rücknahme
WSHL Farbenwechsel
COCO Computer gegen Computer bzw. Letzter Zug
NEUS Ein neues Spiel
SCHL Abbruch
FELD Ermittlung, wo der Spieler den Stein hinsetzt
RECH Bewertung der Felder
GEW Hat einer der Beiden gewonnen?
SEZ Stein auf das Brett setzen
AUS Auswertung
WCH Feldbezeichnungen und Farben wechseln
BEN Spiel schon beendet
NOC Funktion noch nicht möglich
LIN Stein vom Feld entfernen
AUFB Bildaufbau
' (c) MAXON Computer GmbH 1987
'
' +--------------------------------------------------------------------------+
' | Das Gobangspiel V 2:0 von |
' | Gerd Stephan Rottwilm |
' | |
' | ST-Computer 4/87 |
' +--------------------------------------------------------------------------+
@i
'
DO
IF m%=0
@s
ELSE
@c
ENDIF
LOOP
'
PROCEDURE s
REPEAT
DEFMOUSE 7
IF fl%=0
fl%=1
SETTIME spt$,""
spco%=fs%
INC zal%
@anz
DEFFILL 1,fs%,fs%
DEFTEXT ,4,0,13
TEXT 42,316,"Sie sind am Zug"
TEXT 80,350,a$(9)
TEXT 120,350,zal%
ENDIF
REPEAT
MOUSE x%,y%,t%
INC ti%
IF m%=0 AND gew%=0 AND ti%>100
ti%=0
spt$=TIME$
PRINT AT(20,2);MID$(spt$,4,5)
ENDIF
UNTIL t%=1
IF x%>10 AND x%<200
@stk
@rk(x%,y%)
@wshl
@coco
@neus
@schl
ENDIF
@feld(x%,y%)
IF t%=1
PRINT AT(1,1);CHR$(7)
PAUSE 1
ENDIF
UNTIL m%=1
RETURN
'
PROCEDURE c
DEFMOUSE 2
SETTIME cot$,""
spco%=fc%
DEFTEXT ,0,0,13
TEXT 16,253,a$(7)
@anz
DEFFILL 1,fc%,fc%
DEFTEXT ,4,0,13
TEXT 80,350,a$(9)
IF cw%=0
IF dd%=0 OR sm%<>sg%
TEXT 48,316,"Ich überlege..."
ELSE
TEXT 34,316,"Der gleiche Zug?!"
ENDIF
DEFTEXT ,16,0,13
TEXT 16,221,"Letzter Zug"
ELSE
IF fc%=1
TEXT 20,316,"Schwarz ist am Zug..."
ELSE
TEXT 38,316,"Weiß ist am Zug..."
ENDIF
ENDIF
INC zal%
DEFTEXT ,4,0,13
TEXT 120,350,zal%
IF zal%>1 AND (dd%=0 OR sm%<>sg%)
@rech
ENDIF
IF m%=1
IF dd%=0 OR sm%<>sg%
va%=0
FOR z%=48 TO 480
IF w%(z%)>va%
va%=w%(z%)
ENDIF
NEXT z%
IF va%<>0
d%=-1
FOR z%=48 TO 480
IF w%(z%)=va%
INC d%
w%(d%)=z%
ENDIF
NEXT z%
z%=w%(INT(RND(1)*(d%+1)))
ARRAYFILL w%(),0
ELSE
REPEAT
z%=INT(RND(1)*433+48)
UNTIL f%(z%)=0 AND (zal%>50 OR (z%>95 AND z%<433 AND (z%-2)/23<>INT((z%-2)/23)
AND (z%-3)/23<>INT((z%-3)/23) AND (z%+3)/23<>INT((z%+3)/23) AND (z%+4)/23<>INT((z%+4)/23)))
ENDIF
z%(zal%)=z%
f%(z%)=10
@gew
ELSE
z%=z%(zal%)
f%(z%)=10
dd%=0
ENDIF
x%=(z% MOD 23)*19+232
y%=8+19*(INT(z%/23)-1)
xm%=x%
ym%=y%
PRINT AT(3,16);a$(7)
PRINT AT(8,16);z%-48
PRINT AT(18,16);va%
@sez(x%,y%)
sm%=sg%
PRINT AT(1,1);CHR$(7)
PUT 5,301,anz$
IF gew%=10 OR zal%>360
@aus
m%=0
ELSE
IF cw%=1
@wch
m%=1
ELSE
m%=0
fl%=0
ENDIF
ENDIF
ENDIF
RETURN
'
PROCEDURE stk
IF y%>45 AND y%<66
IF gew%=0
IF x%<140 AND x%>10 AND sg%<5
INC sg%
PRINT AT(23,4);sg%
t%=0
PAUSE 10
ENDIF
IF x%<200 AND x%>139 AND sg%>1
DEC sg%
PRINT AT(23,4);sg%
t%=0
PAUSE 10
ENDIF
ELSE
@ben
t%=0
ENDIF
ENDIF
RETURN
'
PROCEDURE wshl
IF y%>77 AND y%<98
t%=0
IF gew%=0
IF spco%=0
DEFFILL 1,1,1
ELSE
DEFFILL 1,0,0
ENDIF
PBOX 10,77,200,98
DEFTEXT ,0,0,13
GRAPHMODE 3
TEXT 16,93,a$(2)
GRAPHMODE 1
@wch
IF zal%>0
DEC zal%
ENDIF
PUT 5,301,anz$
IF m%=0
m%=1
ELSE
m%=0
ENDIF
ELSE
@ben
ENDIF
ENDIF
RETURN
'
PROCEDURE neus
IF y%>109 AND y%<130
PAUSE 5
t%=0
IF zal%>1
IF gew%=0
ALERT 3,"Neues|Spiel?",1,"Ja|Nein",a%
IF a%=1
@brt
ENDIF
ELSE
@brt
ENDIF
ELSE
@noc
ENDIF
ENDIF
RETURN
'
PROCEDURE rk(a%,b%)
IF b%>141 AND b%<162
t%=0
IF zal%>2
IF gew%=0
PUT 5,301,anz$
FOR z%=0 TO 1
DEC zal%
@lin(z%(zal%))
NEXT z%
DEC zal%
fl%=0
PAUSE 10
ELSE
@ben
ENDIF
ELSE
@noc
ENDIF
ENDIF
RETURN
'
PROCEDURE schl
IF y%>173 AND y%<194
t%=0
PAUSE 10
ALERT 3,"Zurück|zum|Desktop?",2,"Ja|Nein",a%
IF a%=1
EDIT
ENDIF
ENDIF
RETURN
'
PROCEDURE coco
IF y%>205 AND y%<226
t%=0
IF gew%=0
IF zal%=1
DEFFILL 1,1,1
PBOX 10,205,200,226
DEFTEXT ,0,0,13
GRAPHMODE 3
TEXT 16,221,a$(6)
GRAPHMODE 1
PUT 5,301,anz$
DEC zal%
m%=1
cw%=1
ELSE
@sez(xm%,ym%)
DEFFILL 1,fs%,fs%
ENDIF
ELSE
@ben
ENDIF
ENDIF
RETURN
'
PROCEDURE anz
DEFFILL 1,1,1
PBOX 5,306,196,358
DEFFILL 1,0,0
PBOX 10,301,200,354
RETURN
'
PROCEDURE sez(a%,b%)
FOR z%=1 TO 4
DEFFILL 1,fs%,fs%
PCIRCLE a%,b%,9
DEFFILL 1,fc%,fc%
PCIRCLE a%,b%,9
NEXT z%
RETURN
'
PROCEDURE feld(a%,b%)
IF a%>261 AND a%<621 AND b%>17 AND b%<380 AND zal%>0 AND gew%=0
FOR x%=270 TO 612 STEP 19
EXIT IF a%<x%+10 AND a%>x%-10
NEXT x%
FOR y%=27 TO 369 STEP 19
EXIT IF b%<y%+10 AND b%>y%-10
NEXT y%
IF f%((x%-232)/19+(y%-27)/19*23+46)=0
t%=0
f%((x%-232)/19+(y%-27)/19*23+46)=1
PCIRCLE x%,y%,9
PUT 5,301,anz$
IF (x%-232)/19+(y%-27)/19*23+46=z%(zal%)
dd%=1
ELSE
FOR z%=zal% TO 361
z%(z%)=0
NEXT z%
dd%=0
z%(zal%)=(x%-232)/19+(y%-27)/19*23+46
@gew
ENDIF
IF gew%=1 OR zal%>360
@aus
ELSE
m%=1
ENDIF
ENDIF
ENDIF
RETURN
'
PROCEDURE wch
FOR z%=48 TO 480
IF f%(z%)<>0 AND f%(z%)<>100
IF f%(z%)=1
f%(z%)=10
ELSE
f%(z%)=1
ENDIF
ENDIF
NEXT z%
SWAP fs%,fc%
RETURN
'
PROCEDURE lin(z%)
a%=(z% MOD 23)*19+232
b%=8+19*(INT(z%/23)-1)
f%((a%-232)/19+(b%-27)/19*23+46)=0
DEFFILL 0,0,0
PCIRCLE a%,b%,9
IF z%=48
LINE a%,b%,a%+9,b%
LINE a%,b%,a%,b%+9
ELSE
IF z%=66
LINE a%,b%,a%-9,b%
LINE a%,b%,a%,b%+9
ELSE
IF z%=462
LINE a%,b%,a%,b%-9
LINE a%,b%,a%+9,b%
ELSE
IF z%=480
LINE a%,b%,a%-9,b%
LINE a%,b%,a%,b%-9
ELSE
IF z%>48 AND z%<66
LINE a%-9,b%,a%+9,b%
LINE a%,b%,a%,b%+9
ELSE
IF (z%-2)/23=INT((z%-2)/23)
LINE a%,b%,a%+9,b%
LINE a%,b%-9,a%,b%+9
ELSE
IF (z%+3)/23=INT((z%+3)/23)
LINE a%,b%-9,a%,b%+9
LINE a%-9,b%,a%,b%
ELSE
IF z%>462 AND z%<480
LINE a%-9,b%,a%+9,b%
LINE a%,b%-9,a%,b%
ELSE
LINE a%-9,b%,a%+9,b%
LINE a%,b%-9,a%,b%+9
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
DEFFILL 1,0,0
FOR c%=327 TO 555 STEP 114
FOR d%=84 TO 312 STEP 114
IF a%=c% AND b%=d%
PCIRCLE c%,d%,3
ENDIF
NEXT d%
NEXT c%
RETURN
'
PROCEDURE i
ON BREAK CONT
IF XBIOS(4)<>2
ALERT 1," Dieses Programm läuft|nur im hochauflösenden Modus!",1,"Abbruch",z%
EDIT
ENDIF
RESTORE
DIM z%(361),f%(528),w%(528),a$(9),frg%(10),wt%(10),fr_1%(4),fr_2%(4),t%(4),l%(4)
a$(0)="Co. 00:00 Sp. 00:00"
a$(1)="Spielstärke < > 1"
a$(2)="Farbenwechsel"
a$(3)="Ein neues Spiel"
a$(4)="Rücknahme"
a$(5)="Abbruch"
a$(6)="Computerdemo"
a$(7)="Feld Wert "
a$(8)="Stand Co.-Sp. 0 : 0"
a$(9)="Zug:"
@aufb
com%=0
spi%=0
FOR z%=1 TO 10
READ frg%(z%),wt%(z%)
NEXT z%
FOR z%=1 TO 4
READ fr_1%(z%),fr_2%(z%),t%(z%),l%(z%)
NEXT z%
@brt
RETURN
'
PROCEDURE aufb
DEFFILL 1,2,4
PBOX -1,-1,640,400
DEFFILL 1,1,1
PBOX 251,10,619,388
DEFFILL 1,0,0
PBOX 256,3,626,383
PBOX 259,6,623,380
PBOX 260,7,622,379
FOR z%=0 TO 360 STEP 19
LINE 270,27+z%,612,27+z%
LINE 270+z%,27,270+z%,369
NEXT z%
FOR z%=327 TO 555 STEP 114
FOR y%=84 TO 312 STEP 114
PCIRCLE z%,y%,3
NEXT y%
NEXT z%
DEFFILL 1,1,1
PBOX 260,7,622,16
DEFTEXT ,0,0,6
GRAPHMODE 3
TEXT 280,14,"Das Gobangspiel von Gerd Stephan Rottwilm"
GRAPHMODE 1
DEFTEXT ,0,0,13
FOR z%=13 TO 269 STEP 32
DEFFILL 1,1,1
PBOX 5,z%+5,196,z%+25
DEFFILL 1,0,0
PBOX 10,z%,200,z%+21
TEXT 16,z%+16,a$((z%+18)/32)
NEXT z%
GET 4,10,200,260,brt$
GET 4,300,200,358,anz$
RETURN
'
PROCEDURE brt
IF zal%>0
PUT 4,10,brt$
PUT 4,300,anz$
FOR z%=48 TO 480
IF f%(z%)<>0 AND f%(z%)<>100
@lin(z%)
ENDIF
NEXT z%
ELSE
HIDEM
ARRAYFILL f%(),0
FOR z%=0 TO 528
IF z%<48 OR z%>480 OR z%/23=INT(z%/23) OR (z%-1)/23=INT((z%-1)/23) OR (z%+1)/23=INT((z%+1)/23) OR (z%+2)/23=INT((z%+2)/23)
f%(z%)=100
ENDIF
NEXT z%
SHOWM
ENDIF
cot$="00:00:00"
spt$="00:00:00"
ARRAYFILL z%(),0
ARRAYFILL w%(),0
fl%=0
spco%=0
gew%=0
zal%=0
sg%=1
cw%=0
fc%=1
fs%=0
m%=0
RETURN
'
PROCEDURE aus
@anz
DEFTEXT ,4,0,13
PRINT AT(1,1);CHR$(7)
IF zal%>360
TEXT 81,332,"Remis!"
ELSE
IF cw%=1
IF fc%=1
TEXT 20,332,"Schwarz hat gewonnen!"
ELSE
TEXT 32,332,"Weiß hat gewonnen!"
ENDIF
ELSE
IF gew%=10
TEXT 32,332,"Ich habe gewonnen!"
INC com%
ELSE
TEXT 30,332,"Sie haben gewonnen!"
INC spi%
ENDIF
ENDIF
ENDIF
PRINT AT(18,18);com%;" : ";spi%
RETURN
'
PROCEDURE gew
LOCAL z%
IF zal%>8
FOR z%=48 TO 480
EXIT IF gew%<>0
IF (f%(z%)=1 AND spco%=fs%) OR (f%(z%)=10 AND spco%=fc%)
FOR q%=7 TO 8
FOR g%=1 TO 4
IF f%(z%-l%(g%))+f%(z%-t%(g%))+f%(z%+t%(g%))+f%(z%+l%(g%))=frg%(q%) AND f%(z%)=frg%(q%-6)
gew%=frg%(q%-6)
ENDIF
NEXT g%
NEXT q%
ENDIF
NEXT z%
ENDIF
RETURN
'
PROCEDURE rech
LOCAL a%
FOR z%=48 TO 480
EXIT IF m%=0
IF f%(z%)<>100
IF z%/48=INT(z%/48)
cot$=TIME$
PRINT AT(7,2);MID$(cot$,4,5)
ENDIF
IF f%(z%)<>0
FOR g%=1 TO 4
FOR q%=1 TO 8
IF f%(z%-t%(g%))+f%(z%-l%(g%))+f%(z%+t%(g%))+f%(z%+l%(g%))+f%(z%)=frg%(q%)
@add(z%-t%(g%),wt%(q%)+1)
@add(z%-l%(g%),wt%(q%))
@add(z%+t%(g%),wt%(q%)+1)
@add(z%+l%(g%),wt%(q%))
ENDIF
NEXT q%
NEXT g%
ELSE
IF (sg%>2 AND zal%>7) OR (sg%=2 AND z%/2=INT(z%/2) AND zal%>7) OR sg%=5 OR zal%=8
FOR g%=1 TO 4
FOR q%=9 TO 10
IF f%(z%-t%(g%))+f%(z%-l%(g%))=frg%(q%) AND f%(z%+t%(g%))+f%(z%+l%(g%))=frg%(q%)
ADD w%(z%),wt%(q%)
ENDIF
NEXT q%
IF sg%>3
FOR q%=1 TO 4
IF f%(z%-t%(g%))+f%(z%-l%(g%))=fr_1%(q%) AND f%(z%+t%(g%))+f%(z%+l%(g%))=fr_2%(q%)
ADD w%(z%),wt%(q%+2)+1
@add(z%+t%(g%),wt%(q%+2))
@add(z%+l%(g%),wt%(q%+2))
ENDIF
IF f%(z%-t%(g%))+f%(z%-l%(g%))=fr_2%(q%) AND f%(z%+t%(g%))+f%(z%+l%(g%))=fr_1%(q%)
ADD w%(z%),wt%(q%+2)+1
@add(z%-t%(g%),wt%(q%+2))
@add(z%-l%(g%),wt%(q%+2))
ENDIF
NEXT q%
IF sg%>4 AND zal%<10
FOR q%=1 TO 2
IF f%(z%-l%(g%))=frg%(q%) AND f%(z%-t%(g%))+f%(z%+t%(g%))+f%(z%+l%(g%))=0
ADD w%(z%-t%(g%)),wt%(q%)/2
ENDIF
IF f%(z%+l%(g%))=frg%(q%) AND f%(z%+t%(g%))+f%(z%-t%(g%))+f%(z%-l%(g%))=0
ADD w%(z%+t%(g%)),wt%(q%)/2
ENDIF
NEXT q%
ENDIF
ENDIF
NEXT g%
ENDIF
ENDIF
IF w%(z%)>a%
PRINT AT(8,16);z%-48
PRINT AT(18,16);w%(z%)
a%=w%(z%)
ENDIF
IF MOUSEK=1
PAUSE 10
ALERT 3,"Neues|Spiel?",1,"Ja|Nein",b%
IF b%=1
@brt
ELSE
DEFMOUSE 2
ENDIF
ENDIF
ENDIF
NEXT z%
RETURN
'
PROCEDURE ben
PAUSE 10
ALERT 1,"Das Spiel ist|bereits zuende!",1," okay ",z%
RETURN
'
PROCEDURE noc
PAUSE 10
ALERT 1,"Funktion erst nach| dem nächsten Zug| möglich!",1," okay ",z%
RETURN
'
PROCEDURE add(a%,b%)
IF f%(a%)=0
ADD w%(a%),b%
ENDIF
RETURN
'
'
DATA 1,5,10,20,2,200,20,400,3,1700,30,3500,4,12000,40,25000,20,25000,2,12000
DATA 2,0,1,2,20,0,23,46,2,1,22,44,20,10,24,48