; Kalah V1.0c (Konsolen-Version) von Helmut Neumann.  
;
;
; Anleitung siehe kalah.doc. 
;
;
;
; Bei Veränderungen bitte bedenken :
;
; - Es werden so gut wie alle freien Register verwendet um das
;   Programm möglichst kurz und schnell zu machen. Also bitte 
;   erst nachsehen welche Bedeutung das Register hat !
;
; - Die Länge einiger Texte ist fest ins Programm eingebunden,
;   wenn diese verändert werden ist auch bei der Ausgabe die
;   entsprechende Zahl anzupassen
;
; - Optimierungen ala addq statt add bringen nichts, da sie vom
;   Assembler automatisch durchgeführt werden wenn sie möglich sind.
;   Vergleiche dazu dann immer die Programmlänge des mitgelieferten
;   Kompilats
;
; - Dieses Source wird ohne Warnungen assembliert mit dem Assembler
;   von Aztec C V3.6, es sollte aber auch mit jedem anderen Assembler
;   funktionieren
;
; - Für 68000er-Kompatibilität sind möglicherweise bei Veränderungen
;   der Texte alignments auf gerade Adresse nötig durch entsprechende
;   Assembler-Kommandos (even) oder Einfügen bzw. Herausnehmen von Nullen   
;
; - Das Programm ist in erster Linie auf Performance optimiert,
;   insbesondere im Kern der die Spielsituationen durchrechnet. In den
;   anderen Teilen bei denen es nicht auf Geschwindigkeit ankommt wurde
;   primaer auf Länge des erzeugten Codes optimiert. Bei Veränderungen
;   kann der Erfolg leicht getestet werden indem man einen Eröffnungszug
;   berechnen lässt und die Zeit stoppt (bei einem dem Prozessor
;   angemessenen Schwierigkeitsgrad
;
; - Die Copyright-Notiz darf NICHT verändert oder gelöscht werden !!!
;

ExecBase   EQU  $4
FreeMem    EQU -210
AllocMem   EQU -198
Openlib    EQU -408
Write      EQU -48 
Read       EQU -42 
Open       EQU -30
Close      EQU -36
                                                                        

; Haupt-Einsprung :                
                        
Init:
   move.l  ExecBase,a6
   lea     dosname,a1       ;Adresse des Namens der Dos-Library laden 
   jsr     Openlib(a6)      ;Dos-Library öffnen
   move.l  d0,a2            ;Die Basisadresse der Dos-Library retten
   moveq   #64,d0
   asl     #8,d0
   move.l  #$00010001,d1
   move.l  ExecBase,a6      ;Basis-Adresse von Exec nach A6
   jsr     AllocMem(a6)     ;Speicher reservieren
   move.l  d0,a5            ;Adresse des Speichers nach A5 retten
   lea     16344(a5),a5     ;Addiere 20000 auf um die Adresse der
   move.l  d0,24(a5)        ;
   move.l  #$06060606,d0
   move.l  a5,a1
   move.l d0,(a1)+
   move.l d0,(a1)+
   move.l d0,(a1)+
   move.b d0,(a1)+
   clr.b  6(a5)
   clr.b  (a1)
   move.l  a2,a6            ;   
   jsr     -60(a6)          ;Window öffnen
   move.w  #200,a2
   move.l  d0,28(a5)        ;Window-Adresse retten
                            ;Speicher-Reservierung für Daten
   lea    LeseBuffer,a4


F4N:
   moveq   #0,d5
   moveq   #106,d3          ;
   lea     Frage4,a0        ;
   bsr     Print            ;Gebe "Wie schlau soll ich spielen" aus
   move.l  a4,d2            ;
   moveq   #2,d3            ;
   bsr     Input            ;Lese ein Zeichen ein
   move.b  (a4),d1          ;
   sub.b   #49,d1           ;
   bmi     F4N              ;
   cmpi.b  #9,d1            ;
   bgt     F4N              ;Wenn nicht so frage erneut
   add.b   d1,d1            ;Eine Ebene heisst zwei Rekursionen, also 
   move.b  d1,22(a5)        ;verdoppeln und speichern
   addq.b  #1,d1
   move.b  d1,14(a5)        ;verdoppeln und speichern
   move.w  #199,16(a5)
   sub.b   d1,17(a5)
        
Speicher:                   ;Reserviere den nötigen Speicher fÜr 
                            ;eine Spielsituation (Das Spielfeld)
                            ;und die Rekursionen
                            ;A5 wird nun als Spielfeld-Stack benutzt
Playfield_Init:             ;Spielfeld initialisieren
F3N:                        ;Frage ab wer anfangen soll
   moveq   #42,d3           ;
   lea     Frage3,a0        ;
   bsr     Print            ;Gebe den Text "Wer soll anfangen" aus 
   move.l  a4,d2            ;
   moveq   #2,d3            ;
   bsr     Input            ;Lese ein Zeichen ein
   move.b  (a4),d1          ;
   cmpi.b  #'i',d1          ;Wurde "i" eingegeben ?
   beq     est2             ;Wenn ja gehe nach Ich
   cmpi.b  #'c',d1          ;Wurde "c" eingegeben ?
   beq     est1             ;Wenn ja gehe nach Comp
   bra     F3N
Input:
   movem.l d0-d2,-(SP)    
   move.l  28(a5),d1            ;Window-Adresse laden
   jsr     Read(a6)             ;Zeichen von der Tastatur einlesen
   movem.l (SP)+,d0-d2   
   rts


loop:
   moveq   #13,d3           ;
   lea     Spieler1,a0      ;
   bsr     Print            ;
   move.l  a4,d2            ;Einlesen eines Spielzugs von der Tastatur
   moveq   #2,d3            ;
   bsr     Input            ;
   move.b  (a4),d0          ;
   cmpi.b  #'q',d0          ;Quit eingegeben ?
   beq     Ende             ;wenn ja  dann Spielende
   sub.b   #49,d0           ;
   bmi     loop
   cmpi.b  #5,d0
   bgt     loop
   move.l  a5,a3            ;Der Zug soll von domove ausgeführt werden
   moveq   #6,d3
   moveq   #13,d5
   moveq   #0,d1
   move.b  (a5,d0),d1       ;Lade die Steine aus der Schale nach d1
   beq     loop             ;Keine Steine da ? Illegal
   bsr     mk2
est1:
   bsr     PrintGame        ;Spielstand ausgeben
   bra     Test2            ;Gewinn-Abfrage

S2N: 
   bsr     CompPlay         ;Spielzug einlesen
est2:
   bsr     PrintGame        ;Spielstand ausgeben
   moveq   #36,d1           ;Hole den Kalah-Gewinn-Wert nach d1
   cmp.b   13(a5),d1        ;Hat die Kalah2 den nötigen Inhalt ?
   blt     Sieg2            ;Wenn ja, dann hat der Computer gewonnen
   tst.b   d5
   bmi     WLoop2
   tst.b   20(a5)
   bne     haha
   addq.w  #2,16(a5)
haha:
   tst.b   18(a5)
   bne     haha2 
   subq.b  #2,22(a5)
haha2:

Win:                        ;Diese Routine fragt ab, ob einer der Spieler
                            ;gewonnen hat und veranlasst das nötige
WLoop1:                     ;Testen, ob der Mensch noch ziehen kann
   tst.w   (a5)             ;Teste ob die Schale leer ist
   bne     loop             ;Wenn nicht, so hat der Mensch nicht verloren
   tst.l   2(a5)
   bne     loop
Sieg2:
   lea     WinTex2,a0       ;Mensch verloren, und wir müssen ihm das 
   bra     Schmu




Test2:
   moveq   #36,d1
   cmp.b   6(a5),d1         ;Hat die Kalah1 den nötigen Inhalt ?
   blt     Sieg1            ;Wenn ja, dann hat Spieler 1 gewonnen
   tst.b   d5               ;Wenn derselbe Spieler nochmal zieht so muss er
   bmi     WLoop1           ;seine eigenen Schalen testen
WLoop2:                     ;Testen ob der Computer noch ziehen kann :
   tst.b   7(a5)            ;Teste den Inhalt der Schale
   bne     S2N              ;Ist sie nicht leer, dann melde das zurück
   tst.l   8(a5)
   bne     S2N 
   tst.b   12(a5)            ;Teste den Inhalt der Schale
   bne     S2N              ;Ist sie nicht leer, dann melde das zurück
Sieg1:
   lea     WinTex1,a0       ;gewonnen, das müssen wir ihm natürlich
Schmu:
   moveq   #26,d3           ;Wenn er hier rausrutscht, so hat der Mensch 
   bsr     Print            ;auch mitteilen.
Schluss:
   move.l  a4,d2            ;
   moveq   #1,d3            ;Warte bis er sich an der Nachricht aufgegeilt
   bsr     Input            ;hat und eine Taste drückt
Ende:                       ;Hier folgen nun die nötigen Aufräumarbeiten
   moveq   #64,d0
   asl     #8,d0
   move.l  24(a5),a1        ;
   move.l  ExecBase,a6      ;
   jsr     FreeMem(a6)      ;Gebe den Speicher für die Rekursionen und die 
                            ;Spiel-Situation frei
   moveq   #0,d0
   rts

Print:
   movem.l d0-d6/a0-a6,-(SP)    ;
   move.l  28(a5),d1            ;Window-Adresse laden
   move.l  a0,d2
   jsr     Write(a6)            ;Text ausgeben
   movem.l (SP)+,d0-d6/a0-a6    ;
   rts


   
PrintGame:                      ;Spielstand ausgeben
   move.l  a5,a1                ;Datenstack-Basis nach a1 laden
   move.b  6(a1),d0             ;Kalah 1 nach d0 laden
   lea     SchreibBuffer1,a0    ;Speicher fÜr Transformierte Zahl 
   bsr     Transform            ;Wandle Zahl in einen ASCII String 
   moveq   #7,d3                ;Die Zeile hat die Länge 7
   subq.w  #1,a0                ;Adresse der Zeile laden
   bsr     Print                ;Kalah ausgeben
   addq.w  #6,a1            ;Errechne Adresse der letzten Schale
   moveq   #5,d4            ;Lade Schalen minus 1 nach d4 als 
   move.l  a4,a0            ;Die Transform-Routine soll den String nach
NextNum1:
   move.b  -(a1),d0         ;Lade Schalen-Inhalt nach D0
   bsr     Transform        ;Lesebuffer schreiben
   moveq   #4,d3            ;4 Zeichen sollen ausgegeben werden
   bsr     Print            ;Ausgabe der Zahl
   dbf     d4,NextNum1      ;nächste Schale
   moveq   #1,d3            ;Es soll 1 Zeichen ausgegeben werden
   lea     Return,a0        ;Lade die Adresse des Return-Codes
   bsr     Print            ;Gebe ein Return aus
   moveq   #6,d3                ;Füge vor der zweiten Zeile 6 Leerzeichen ein
   lea     Leerzeichen,a0       ;Lade die Adresse der Leerzeichen
   bsr     Print                ;Gebe sie aus

   addq.w  #7,a1            ;
   moveq   #5,d4            ;Lade Schalen minus 1 nach d4
   move.l  a4,a0            ;Die Transform-Routine soll den String nach
NextNum2:
   move.b  (a1)+,d0         ;Lade Schalen-Inhalt nach d0
   bsr     Transform        ;Lesebuffer schreiben
   moveq   #4,d3            ;4 Zeichen sollen ausgegeben werden
   bsr     Print            ;Ausgabe der Zahl
   dbf     d4,NextNum2      ;nächste Schale
   moveq   #2,d3                ;Füge an der Zeile zwei Leerzeichen an
   lea     Leerzeichen,a0       ;Lade die Adresse der Leerzeichen
   bsr     Print                ;Gebe sie aus
   move.b  (a1),d0              ;Kalah 2 nach d0 laden
   lea     SchreibBuffer1,a0    ;Speicher fÜr Transformierte Zahl 
   bsr     Transform            ;Wandle Zahl in einen ASCII String 
   moveq   #9,d3                ;Die Zeile hat die länge 6
   bra     Print                ;Zeile ausgeben

Transform:
   andi.l  #$000000ff,d0    ;Beschraenke auf Byte
   divu    #10,d0           ;Eingabeparameter sind:
   bne     Ziffer           ;In A0 die Adresse wo der String hin soll
   move.b  #' ',d0          ;Wenn die Zahl kleiner als 10 ist so soll
   bra     NoNum            ;sie nur eine Ziffer haben
Ziffer:                     ;
   add.b   #48,d0           ;Aus der Ziffer den ASCII-Wert errechnen
NoNum:                      ;
   move.b  d0,(a0)          ;Errechnetes Zeichen ablegen
   swap    d0               ;Zweite Ziffer holen
   add.b   #48,d0           ;Aus der Ziffer den ASCII-Wert errechnen
   move.b  d0,1(a0)         ;Die gewandelte Zahl steht jetzt ab A0
   rts



CompPlay:                   ;Diese Routine steuert die Rekursion an

   moveq   #13,d3           ;Gebe die Nachricht 'ich überlege' aus
   lea     Spieler2,a0      ;
   bsr     Print            ;
   move.b  13(a3),d2
   add.b   6(a3),d2

   cmp.b   #50,d2           ;Erhoehe das Level wenn nur noch wenig Steine
   blt     testzwo          ;übrig sind
   cmp.b   #18,14(a5)
   bge     nixtun
   addq.b  #2,14(a5)

testzwo:

   cmp.b   #45,d2
   blt     testvie
   cmp.b   #8,14(a5)
   bge     nixtun
   addq.b  #2,14(a5)

testvie:

   cmp.b   #36,d2
   blt     testdro
   cmp.b   #6,14(a5)
   bge     nixtun
   addq.b  #2,14(a5)

testdro:

   cmp.b   #20,d2
   blt     nixtun
   cmp.b   #4,14(a5)
   bge     nixtun
   addq.b  #2,14(a5)


nixtun:



   moveq   #0,d2            ;Lösche d2 , wir fangen auf Rekursions-Ebene
                            ;Null an
   moveq   #0,d5
   move.l  a5,a3            ;Sage der Rekursion, wo das Spielfeld steht
   move.w  a2,d6            ;Ist nötig, damit der Cut gut arbeitet
   moveq   #6,d3
   move.b  d3,18(a5)
   move.b  d3,20(a5)
   lea     16(a5),a1
   lea     22(a5),a0
   bsr  SL1                 ;Überlege
   move.b  -2(a5),d0        ;Gebe ihn nach d0 um dem Menschen mitzuteilen
   addq.b  #1,d0
   lea     CmpZug,a0        ;aus welcher Schale wir ziehen wollen
   bsr  Transform           ;Forme sie in einen String um
   moveq   #30,d3           ;
   lea     Zug2,a0          ;
   bsr     Print            ;Gebe ihn aus
   move.l  a5,a3            ;Der Zug soll von domove ausgeführt werden
                            ;domove erwartet in a3 den Zeiger auf 
                            ;das Spielfeld
   move.b  -2(a5),d0        ;Hole den Zug nach d0
   moveq   #6,d3
   moveq   #13,d5
   bra     tompu
   
   

SL1:                        ;Dies ist der Rekursions-Kern, er ruft sich 
                            ;solang selbst auf, bis die d2 den Wert der
                            ;Rekursionstiefe erreicht hat. Bei jedem 
                            ;Rücksprung wird d2 wieder dekrementiert
                            ;
                            ;Ubergebene Werte : 
                            ;In a3 der Zeiger auf das übergeordnete
                            ;Spielfeld
                            ;In d2 die momentane Rekursionstiefe
                            ;in d6 das Maximum/Minimum der oberen Ebene
                            ;Rückgabe Werte  :
                            ;in d0 die Wertung des besten bzw. 
                            ;schlechtesten Zuges
                            ;in d1 der beste Zug
 
   movem.w  d4-d7,-(sp)     ;
   tst.b   d5               ;Wurde ich von einem Bonus-Zug aufgerufen ?
   bmi     MVOL             ;Wenn ja dann lass den Cut-Wert stehen
   move.w  d6,d7            ;Wenn nicht dann nehm das momentane Minimum
                            ;oder Maximum des oberen Levels als Cut-Wert
MVOL:
   moveq   #0,d6            ;Wenn nein, dann Maximum gleich 1
   btst    d6,d2            ;Ist dies ein Mensch-Zug oder Comp-Zug
   beq     NotSetM          ;
   move.w  a2,d6            ;Wenn ja, dann Maximum gleich 200
NotSetM:
   moveq   #5,d4            ;Anzahl der Schalen in den akt. Zähler 
   lea     -16(a3),a3       ;Die Adresse des zu bearbeitenden Spielfelds
                            ;in a3 berechnen
SL4:
   move.l 16(a3),(a3)       ;Fertige eine Kopie des übergeordneten
   move.l 20(a3),4(a3)      ;Spielfelds an
   move.l 24(a3),8(a3)      ;
   move.w 28(a3),12(a3)     ;
   moveq   #13,d5
domove:                     ;Diese Routine führt einen Zug aus
   moveq   #0,d1            ;                   
   move.w  d4,d0            ;Lade d4 nach d0 als auszuführenden Zug
                            ;Ubergebene Werte : 
                            ;In d0 der Zug
                            ;In a3 das Spielfeld
                            ;Rückgabe Werte  :
                            ;in d5 ob der Zug möglich war
                            ;in d0 die Wertung falls er nicht ging
                            ;in d5 ob der Spieler nochmal dran ist
                            ;Wenn ja dann d5 = 1
                            ;Ab hier zieht der Computer :
   btst   d1,d2
   bne    SimHum
tompu:
   addq.b  #7,d0
   move.b  (a3,d0),d1       ;Lade die Steine aus der Schale nach d1
   beq     wahn
   subq.b  #1,d1            ;d1 wird später als Schleifen-Zähler benutzt
   clr.b   (a3,d0)          ;Leere die Schale aus
poss2:
   addq.b  #1,d0            ;d0 zeigt auf die nächste Schale
   cmp.b   d3,d0            ;Ist es die Kalah des Gegners
   beq     poss2            ;Nein, dann weiterverteilen
nich3:
   cmp.b   d5,d0            ;Ist es die eigene Kalah
   ble     nich2            ;Wenn wir schon eins weiter sind dann setze
   moveq   #0,d0            ;D0 wieder auf den Anfang des Spielfelds
nich2:
   addq.b  #1,(a3,d0)       ;Füge einen Stein zur momentanen Schale hinzu
   dbf     d1,poss2         ;Weiterverteilen
   cmp.b   d3,d0            ;War die letzte Schale eine gegnerische
   ble     HNotOwn1         ;Wenn ja, dann kein Schweinezug
   cmp.b   d5,d0            ;War die letzte Schale die eigene Kalah
   beq     NochmalZ         ;Wenn ja, dann nochmal ziehen
   cmpi.b  #1,(a3,d0)       ;Enthält die Schale einen Stein (vor der 
                            ;Verteilung also 0 Steine)
   bne     HNotOwn1         ;Wenn nicht, dann kein Schweinezug
                            ;Schweinezug :
   clr.b   (a3,d0)          ;Leere die Schale wieder
   sub.b   d3,d0            ;In d3 steht immer noch Schalen(a2)
   move.l  d3,d1            ;Errechne den Offset der gegenüberliegenden
   sub.b   d0,d1            ;Schale
   move.b  (a3,d1),d0       ;Hole deren Inhalt nach d1
   clr.b   (a3,d1)          ;Leere sie aus
   addq.b  #1,d0            ;Addiere noch den Inhalt der eigenen Schale auf
   add.b   d0,13(a3)        ;und füge die eingeheimsten Steine hinzu
   bra     HNotOwn1

wahn:
   dbf   d4,domove          ;Weiter zur nächsten Schale
   bra   Cut

NochmalZ:
   moveq   #-1,d5           ;Merke dir das derselbe Spieler nochmal zieht
   bra     Retu

SimHum:                     ;Zugvalidierungs-Routine für Spieler 1
   move.b  (a3,d0),d1       ;Lade die Steine aus der Schale nach d1
   beq     wahn
mk2:   
   subq.b  #1,d1            ;d1 wird später als Schleifen-Zähler benutzt
   clr.b   (a3,d0)          ;Leere die Schale aus
Hposs1:
   addq.b  #1,d0            ;d0 zeigt auf die nächste Schale
   cmp.b   d5,d0            ;ist es die Kalah des Gegners 
   bne     Hnich1
   moveq   #0,d0            ;Zeiger wieder auf erste Schale biegen, das heisst
Hnich1:                     ;die Kalah des Gegners nicht verändern
   addq.b  #1,(a3,d0)       ;Inhalt der Schale um eins erhöhen
   dbf     d1,Hposs1        ;Weiterverteilen
   cmp.b   d3,d0            ;War die letzte Schale eine eigene
   bgt     HNotOwn1         ;Nein ? Dann Rückkehr
   beq     NochmalZ         ;Die eigene Kalah ? Dann nochmal ziehen
   cmp.b   #1,(a3,d0)       ;Enthält die Schale einen Stein (vor der
                            ;Verteilung also 0 Steine)
   bne     HNotOwn1         ;Nein ? Dann Rückkehr
   clr.b   (a3,d0)          ;Leere die Schale wieder
   moveq   #12,d1           ;Errechne die Adresse der gegenüberliegenden
   sub.b   d0,d1            ;Schale
   move.b  (a3,d1),d0       ;Hole deren Inhalt nach d1 und
   clr.b   (a3,d1)          ;leere sie aus
   addq.b  #1,d0            ;füge den Stein von der eigenen Schale hinzu
   add.b   d0,6(a3)         ;Gebe die gesammelten Steine hinzu
HNotOwn1:
   moveq   #1,d5            ;Der Zug war möglich, also d5 = 0
Retu:
   cmp.l   a3,a5
   beq     WSamePl
   cmp.b   (a0),d2
   blt     Marke
   moveq   #36,d1           ;Hole den Kalah-Gewinn-Wert nach d1
   cmp.b   13(a3),d1        ;Hat die Kalah2 den nötigen Inhalt ?
   blt     ESieg2           ;Wenn ja, dann hat der Computer gewonnen
   cmp.b   6(a3),d1         ;Hat die Kalah1 den nötigen Inhalt ?
   blt     ESieg1           ;Wenn ja, dann hat Spieler 1 gewonnen
   btst    #0,d2            ;Wenn der Computer am Zug war, so sollen 
   bne     ETest2           ;die Schalen des Menschen getestet werden
   tst.b   d5               ;Wenn der Computer nochmal dran ist muss er 
   bmi     ELoop2           ;seine eigenen Schalen testen
ELoop1:                     ;Testen, ob der Mensch noch ziehen kann
   
   tst.w   (a3)             ;Teste ob die Schale leer ist
   bne     EOwn1            ;Wenn nicht, so hat der Mensch nicht verloren
                            ;und wir müssen die Kalah-Differenz errechnen
   tst.l   2(a3)
   bne     EOwn1
ESieg2:                     ;Computer gewinnt :
   move.w  #199,d0          ;Bewerte diesen Zug, indem du die momentane 
   sub.w   d2,d0
hoch:
   cmp.b   (a0),d2
   bne     SL3
   clr.b   18(a5)
   bra     masch

ETest2:                     ;Teste die Schale des Computers ab :
   tst.b   d5               ;Wenn der Mensch nochmal dran ist so muss
   bmi     ELoop1           ;er seine eigenen Schalen testen
ELoop2:                     ;Testen ob der Computer noch ziehen kann
   tst.l   8(a3)
   bne     EOwn1
   tst.b   12(a3)
   bne     EOwn1
   tst.b   7(a3)            ;Teste ob die Schale leer ist
   bne     EOwn1            ;Wenn nicht, so kann der Computer noch ziehen
ESieg1:                     ;Mensch gewinnt
                            ;Bewerte diesen Zug, indem du die momentane
   move.w  d2,d0            ;Rekursionsebene nimmst
   addq.w  #1,d0            ;Wegen Maximum bilden
   bra     hoch

EOwn1:                      ;Wenn keiner der beiden Spieler gewonnen hat
                            ;muss die Kalah-Differenz zur Bewertung dienen 
   moveq   #100,d0          ;100 ist die Mitte
   add.b   13(a3),d0        ;Hole den Inhalt von Kalah1 nach d0
   sub.b   6(a3),d0         ;Ziehe den Inhalt von Kalah2 von d0 ab
Marke:
   tst.b d5                 ;Kommt jetzt ein Bonuszug ?
   bmi   SamePlayer         ;Wenn ja dann nicht die Tiefe testen
SL7:  
   cmp.b 14(a5),d2          ;Testen ob die unterste Rekursionsebene
   beq   humt1              ;erreicht, ja -> Rücksprung
   addq.w #1,d2             ;neachst tiefere Ebene
SamePlayer:
   bra  SL1                 ;Nächste Reinkarnation
SL3:
   btst   #0,d2             ;Muss ich das Minimum oder Maximum bilden
   beq    masch             ;Wenn der  Menschdran ist das Minimum
humt1:
   cmp.w   d6,d0            ;Bilde das Minimum in einer Mensch-Rekursion
   bpl     wanix            ;Kein Minimum, kein Eintrag
Set2:
   move.w  d0,d6            ;Trage das neue Minimum ein
   cmp.w   d6,d7            ;Vergleiche mit dem Maximum des Aufrufers   
   bpl     Cut              ;um gegebenfalls einen Cut zu machen
wanix:
   dbf   d4,SL4             ;Weiter zur nächsten Schale
   bra   Cut

masch:
   cmp.w  d0,d6             ;Ist die momentane Wertung grösser als
   bpl    wanix             ;das Maximum bisher ?
HD4:
   move.w  d0,d6            ;Dann halte ihn als neues Maximum fest
   move.b  d4,14(a3)        ;der momentanen Spielsituation
   cmp.w   d7,d6            ;Vergleiche mit dem Minimum der oberen 
   bpl     Cut              ;Ebene und führe Cut aus, wenn ja
   cmp.w   (a1),d6
   blt     wanix            ;Ebene und führe Cut aus, wenn ja
Gut:    
   clr.b  20(a5)

Cut:    
   move.w  d6,d0            ;Hole das Maximum nach d0
   movem.w  (sp)+,d4-d7     ;
   lea     16(a3),a3        ;
   tst.b   d5               ;Schaue ob der Zug ein Bonuszug war
   bmi     Before           ;Wenn ja, dann lasse das Level unberührt 
   dbf     D2,SL3           ;DEC(D2) da wieder auf höherer Ebene
Before:
   cmp.l   a3,a5
   bne     SL3
WSamePl:
   rts                      ;Zurück zur oberen Ebene

;Hier kommen nun die Konstanten und der Platz um einige Zeiger zu speichern   
 
dosname:
      dc.b  "dos.library"
      dc.b  0,0
LeseBuffer:
      dc.b  0,0,"  "
      dc.b  10
SchreibBuffer1:
      dc.b  "       ",10,10
Leerzeichen:
      dc.b  "      "
Return:
      dc.b  10,10
Spieler1:
      dc.b  "Sie ziehen : "
Spieler2:
      dc.b  "Ich überlege"
      dc.b  10
Zug2:
      dc.b  "Ich entleere die Schale : "
CmpZug:
      dc.w  0
      dc.b  10,10
Frage3:
      dc.b  "Wer fängt an (C für Computer, I für Ich) :"
Frage4:
      dc.b  "Das Spiel Kalah V1.0c (© 1988,89,90,91,92,93 Helmut Neumann)"
      dc.b  10,10
      dc.b  "Wie schlau soll ich spielen (Zahl von 1-9) :"
WinTex1:
      dc.b  "Sie haben gewonnen    !!!"
      dc.b  10
WinTex2:
      dc.b  "Ich habe Sie besiegt  !!!"
      dc.b  10
