title REVERSI fuer SOL name ('REVERSI') include solvdm.lib ; Das Spiel REVERSI fuer den SOL-Computer ; Disassemblierte Version fuer CP/M ; ; Wegen der Disassemblierung sind die Kommentare vielleicht ; nicht immer richtig! ; ; ######################################################### ; # Angepasst an den JOYCE, Werner Cirsovius, Januar 2003 # ; ######################################################### extrn SOLon,SOLOS,VDMclr extrn CONin,vidoff,vidon _COMP equ _bcr _HUMAN equ _hpi _OK equ 0fh _EOT equ 04h ; Anzeige fuer Ende der Zeile _NL equ 18h ; Anzeige fuer neue Zeile _UL equ 1*maxcol+18 ; Obere Zeile _DL equ 9*maxcol+ 0 ; Untere Zeile _SC equ 11*maxcol+ 0 ; Spielstand _CS equ 11*maxcol+28 ; Status des Computers _HS equ 11*maxcol+44 ; Status des Spielers _ST equ 12*maxcol+ 0 ; Status _XY equ 12*maxcol+53 ; Eingabe-Koordinaten _MS equ 13*maxcol+ 0 ; Koordinaten fuer Text _AS equ 14*maxcol+ 0 ; Koordinaten fuer Text ; jp StartRev ; $HELP: db 25 db 'R'+MSB,' E ','V'+MSB,' E ','R'+MSB,' S ','I'+MSB,_NL db 24 db 'Von Ray G. White',_NL db 0 db 'Reversi ist ein Spiel, das dein Geschick gegen den Rechner',_NL db 0 db 'herausfordert. Es wird gespielt auf einem 8 X 8 "Spielfeld", auf',_NL db 0 db 'denen die "Steine" angeordnet sind. In diesem Spiel bist du der',_NL db 0 db 'wei',_sz,'e(',_HUMAN,') und der Rechner der schwarze(',_COMP,') Spieler. Ein (.) zeigt',_NL db 0 db 'eine freie Stelle auf dem Spielfeld an. Am Anfang des Spieles',_NL db 0 db 'sind die vier mittleren Felder mit Steinen belegt. Wenn du am',_NL db 0 db 'Zug bist, mu',_sz,' dieser so gef',_ue,'hrt werden, da',_sz,' mindestens ein',_NL db 0 db 'Rechnerstein zwischen einem deiner Steine und dem neu gesetzten',_NL db 0 db 'Stein liegt. Alle Rechner-Steine, die so liegen, werden in deine',_NL db 0 db 'Steine umgetauscht. Das Spiel endet, wenn das Spielfeld voll',_NL db 0 db 'ist. Gewinner ist, wer die meisten Steine besitzt.',_NL db 0,_NL db 20 db '*Leerzeichen f',_ue,'r Spielstart*' db _NL,_EOT $SCORE: db 16 db 'Mein Stand: Dein Stand:' db _NL,_EOT $TIE: db 27 db 'Unentschieden!' db _NL,_EOT $COMWIN: db 18 db 'Du hast verloren!!!' db _NL,_EOT $HUMWIN: db 19 db 'Du hast gewonnen!!!' db _NL,_EOT $NOMOVE: db 16 db 'Beide Spieler k',_oe,'nnen nicht ziehen' db _NL,_EOT $INVINP: db 20 db 'Ung',_ue,'ltig - nochmal' db _NL,_EOT $YOUR: db 14 db 'Gib deinen Zug ein (X,Y), (E f',_ue,'r Ende):' db _NL,_EOT $ICANOT: db 17 db 'Der Rechner kann nicht mehr ziehen' db _NL,_EOT $UCANOT: db 21 db 'Du hast keinen Zug mehr' db _NL,_EOT $FIRST: db 20 db 'Willst du anfangen?' db _NL,_EOT $LINE: db 21 db '1 2 3 4 5 6 7 8' db _NL,_EOT $BOARD: db '........' ; Zeile 1 db '........' ; Zeile 2 db '........' ; Zeile 3 db '...',_HUMAN,_COMP,'...' ; Zeile 4 db '...',_COMP,_HUMAN,'...' ; Zeile 5 db '........' ; Zeile 6 db '........' ; Zeile 7 db '........' ; Zeile 8 $CPBOARD: ds 8*8 ; ds 15 HumRow: db 0 HumCol: db 0 ColSav: db 0,0 ComCol: db 0 ComRow: db 0 ComMod1: db 0 ComMod2: db 0 ComXY: db 0,0 ModSav1: db 0 ModSav2: db 0 CouPart: db 0 ; Gegenstueck BoardPtr: db 0 ; Adresse auf das Spielfeld BoardCol: db 0 ; Spalte des Spielfelds BoardRow: db 0 ; Reihe des Spielfelds BoardAdr: dw 0 ; Spielfeld-Adresse ; ; Ausgabe eines inversen Textes in ^DE mit Video-Adresse in ^BC ; strgVIDon: call vidon ; Invers an call strgVID ; Text ausgeben call vidoff ; Invers aus ret ; ; Ausgabe eines Textes in ^DE mit Video-Adresse in ^BC ; ; Der Text ist organisiert als: ; ; DB COL ; Startspalte ; ; DB ; Text ; DB _NL ; Anzeige neue Zeile ; ; .... mehr Text ; ; DB _EOT ; Anzeige des Endes ; strgVID: ld h,b ; Adresse kopieren ld l,c ld a,(de) ; Byte holen cp _EOT ; Ende testen ret z ; Ja add a,l ; Adresse setzen jr nc,skpInc ; In gleicher Zeile inc h ; Zeile justieren skpInc: ld l,a ; Spalte setzen outVID: inc de ld a,(de) ; Zeichen holen cp _NL ; Test ob beue Zeile jr nz,unpVID ; Nein inc de ld a,c ; Spalte holen add a,maxcol ; Auf naechste Zeile jr nc,skpAdv inc b ; Uebertrag nicht vergessen skpAdv: ld c,a jr strgVID ; Naechste Ausgabe unpVID: ld_hl_a ; Zeichen in den Video-Speicher inc hl jr outVID ; Ende testen ; ; Spielfeld ausgeben ; outBoard: call VDMclr ; Spielfeld loeschen ld bc,SOLvid ; Zeiger auf Video-Speicher ld de,$LINE call strgVID ; Obere Spalte ausgeben ld b,'1' ; Linke Ziffer initialisieren ld hl,SOLvid+_UL ; Adresse setzen ld de,$BOARD ; Zeiger auf Spielfeld outOuter: ld_hl_b ; Nummer links eintragen ld c,1 ; Spalte initialisieren outInner: inc hl inc hl inc hl ld a,(de) ; Zeilen umlopieren ld_hl_a inc de inc c ; Spalte erhoehen ld a,8+1 ; Test ob fertig sub c jr nz,outInner ; Nein inc hl inc hl inc hl ld_hl_b ; Nummer rechts eintragen inc b ; Zeile erhoehen ld a,'8'+1 ; Test ob fertig sub b jr z,outDone ; Ja ld a,l add a,maxcol-8*3-3 ld l,a ; Zeiger auf naechste Zeile ld a,h adc a,0 ld h,a jr outOuter outDone: ld bc,SOLvid+_DL ld de,$LINE ; Untere Spalte ausgeben call strgVID ret ; ; Test ob ein Platz auf dem Spielfeld frei ist ; TestFree: ld hl,$BOARD ; Zeiger auf Spielfeld ld b,8*8 ; Laenge setzen TstFLoop: ld a,(hl) ; Spielstein holen cp '.' ; Test ob leer ret z ; Ja inc hl djnz TstFLoop ; ; Das Spielfeld ist voll ; call outBoard ; Spielfeld ausgeben ld bc,SOLvid+_SC ld de,$SCORE call strgVID ; Spielstand anzeigen CountPieces: ld b,0 ; Zaehler des Spielers loeschen ld c,0 ; Und des Computers ld hl,$BOARD ; Zeiger auf Spielfeld ld e,8*8 ; Laenge setzen CountLoop: ld a,(hl) ; Speilstein holen cp _COMP ; Test ob Computer jr z,CountComp ; Ja cp '.' ; Test ob Spieler jr z,NoCount ; Nein inc b ; Spielerstand erhoehen jr NoCount CountComp: inc c ; Computerstand erhoehen NoCount: inc hl ; Naechste Adresse dec e ; Test ob fertig jr nz,CountLoop ; ; Feststellen, wer gewonnen hat ; ld hl,SOLvid+_CS ld d,c ; Computerstand holen call CnvDtH ; Und anzeigen ld hl,SOLvid+_HS ld d,b ; Spielerstand holen call CnvDtH ; Und anzeigen ld a,b ; Gewinner bestimmen sub c ld de,$TIE ; Unentschieden jr z,WinnMess ld de,$COMWIN ; Spieler verliert jp m,WinnMess ; Computer gewinnt ld de,$HUMWIN ; Spieler gewinnt WinnMess: ld bc,SOLvid+_MS call strgVID ; Gewinner anzeigen ld de,$FIRST ld bc,SOLvid+_AS call strgVID ; Frage, wer beginnen soll ld hl,$BOARD ; Zeiger auf Spielfeld ld b,8*8 ; Laenge laden ResBoard: ld (hl),'.' ; Spielfeld neu setzen inc hl djnz ResBoard ld hl,$BOARD+3*8+3 ld (hl),_HUMAN ; Spieler setzen inc hl ld (hl),_COMP ; Und Computer ld hl,$BOARD+4*8+3 ld (hl),_COMP ; Umgedreht fuer naechste Zeile inc hl ld (hl),_HUMAN jr Restart ; ; Ausgabe einer Zahl (zwei Stellen) in Register D als ASCII in ^HL ; CnvDtH: ld_hl_8 '0' ; Nummer initialisiern dec hl ld_hl_8 '0' ; Auch die zweite Stelle inc hl ld a,d ; Test ob Zaehler Null ist or a ret z ; Ja, das war's CnvDtHLoop: ld_a_hl inc a ; Zaehler erhoehen ld_hl_a cp '9'+1 ; Test ob Ueberlauf jr nz,CnvDtHNxt ld_hl_8 '0' ; Stelle loeschen dec hl ld_a_hl inc a ; Zehner erhoehen ld_hl_a inc hl CnvDtHNxt: dec d ; Runterzaehlen jr nz,CnvDtHLoop ret ; ; ################## ; # Spiel beginnen # ; ################## ; StartRev: ld sp,LocStk ; Lokalen Stack laden call SOLon ; SOL einschalten ld bc,SOLvid ; Zeiger auf Video-Speicher ld de,$HELP call strgVID ; Spielregeln ausgeben WaitSpc: call CONin ; Zeichen lesen cp ' ' ; Auf Leerzeichen warten jr nz,WaitSpc call outBoard ; Spielfeld ausgeben ld bc,SOLvid+_ST ld de,$FIRST call strgVID ; Frage, wer anfangen soll Restart: call CONin ; Zeichen lesen cp 'E' ; Test, ob Ende jp z,SOLOS cp 'N' ; Test 'N'ein jp z,CompMove cp 'J' ; Test 'J'a jr nz,Restart ; Warten auf gueltige Eingabe jp HumMove ; ; Test ob Richtung ok ; EIN Register B haelt Spalte ; Register C haelt Zeile ; Register D haelt Gegenstueck ; Register E haelt Startspalte ; AUS Register D haelt Resultat - _OK zeigt Erfolg an ; CheckDir: ld hl,$BOARD ld a,e ld (BoardPtr),a ; Basiszeiger speichern ld a,d ld (CouPart),a ; Gegenstueck speichern ld d,0 ; Resultat initialisieren ld a,c ld (BoardRow),a ; Zeile speichern ld a,b ld (BoardCol),a ; Spalte speichern ld l,e ; Startspalte setzen ld a,l ; Und laden add a,b ; Spalte addieren CDLoop: dec c ; Zeile runterzaehlen jr z,CDgot ; Fertig add a,8 ; Zeiger auf naechste Zeile jr CDLoop CDgot: ld l,a ; Zeiger setzen ld a,(hl) ; Speilstein laden sub '.' ; Test ob frei ret nz ; Nein ld (BoardAdr),hl ; Zeiger retten ; ; Test ob die Richtung ok - Register D haelt das Resultat ; call LoadPXY ; Adresse und Koordinaten laden ld d,0 ; Hoch einstellen ld e,2 call MoveThru ; Durch das Spielfeld gehen ld a,d sub _OK ret z call LoadPXY ; Adresse und Koordinaten laden ld d,1 ; Rechts hoch einstellen ld e,2 call MoveThru ; Durch das Spielfeld gehen ld a,d sub _OK ret z call LoadPXY ; Adresse und Koordinaten laden ld d,1 ; Rechts einstellen ld e,0 call MoveThru ; Durch das Spielfeld gehen ld a,d sub _OK ret z call LoadPXY ; Adresse und Koordinaten laden ld d,1 ; Rechts unten einstellen ld e,1 call MoveThru ; Durch das Spielfeld gehen ld a,d sub _OK ret z call LoadPXY ; Adresse und Koordinaten laden ld d,0 ; Unten einstellen ld e,1 call MoveThru ; Durch das Spielfeld gehen ld a,d sub _OK ret z call LoadPXY ; Adresse und Koordinaten laden ld d,2 ; Links unten einstellen ld e,1 call MoveThru ; Durch das Spielfeld gehen ld a,d sub _OK ret z call LoadPXY ; Adresse und Koordinaten laden ld d,2 ; Links einstellen ld e,0 call MoveThru ; Durch das Spielfeld gehen ld a,d sub _OK ret z call LoadPXY ; Adresse und Koordinaten laden ld d,2 ; Links hoch einstellen ld e,2 call MoveThru ; Durch das Spielfeld gehen ld a,d sub _OK ret z ld d,0 ; Kein Treffer ret ; ; Adresse und Koordinaten laden ; LoadPXY: ld hl,(BoardCol) ; Laden der .. ld b,l ; .. Spalte ld c,h ; .. Zeile ld hl,(BoardAdr) ; .. Feldadresse ret ; ; Durch das Spielfeld gehen ; EIN Register B haelt Spalte ; Register C haelt Zeile ; Register D haelt horizontale Richtung 0 0 1 1 1 2 2 2 ; Register E haelt vertikale Richtung 1 2 0 1 2 0 1 2 ; (0 bedeutet keine Bewegung, 1 rechts oder hoch, 2 links oder runter) ; Register HL zeigt auf freies Spielfeld ; AUS Register D haelt Resultat - _OK zeigt Treffer ; MoveThru: ld a,d ; Richtung holen sub 2 ; Links testen jr nz,MTrig ; Nein dec l ; Voriges Feld einstellen dec b ; Vorige Spalte einstellen ret z ; Ende wenn linke Ecke jr MTlef MTrig: ld a,l ; Zeiger laden add a,d ; 0 oder 1 addieren ld l,a ld a,b ; Spalte laden add a,d ; 0 oder 1 addieren ld b,a sub 8+1 ; Rechte Ecke testen ret z ; Ende wenn es so ist MTlef: ld a,e ; Richtung holen sub 2 ; Test runter jr nz,MTup ; Nein dec c ; Vorige Zeile berechnen ret z ; Ende bei oberster Zeile ld a,l sub 8 ; Zeiger auf vorige Zeile ld l,a jr MThit MTup: ld a,e ; Verikale Richtung holen or a ; Test ob Bewegung jr z,MThit ; Nein, Ende inc c ; Naechste Zeile einstellen ld a,l add a,8 ; Zeiger auf naechste Zeile ld l,a ld a,c ; Zeile holen sub 8+1 ; Ende bei unterster Zeile ret z ; ; An diesem Punkt haben wir einen danebenliegenden Zeiger ; MThit: ld a,(CouPart) ; Gegenstueck holen sub (hl) ; Test Uebereinstimmung ret nz ; Nein ; ; Schleife zum Aufspueren benachbarter Steine ; MTmloop: ld a,d ; Richtung holen sub 2 ; Links testen jr nz,MTmrig ; Nein dec l ; Voriges Feld einstellen dec b ; Vorige Spalte einstellen ret z ; Ende wenn linke Ecke jr MTmlef MTmrig: ld a,l ; Zeiger laden add a,d ; 0 oder 1 addieren ld l,a ld a,b ; Spalte laden add a,d ; 0 oder 1 addieren ld b,a sub 8+1 ; Rechte Ecke testen ret z ; Ende wenn es so ist MTmlef: ld a,e ; Richtung holen sub 2 ; Test runter jr nz,MTmup ; Nein dec c ; Vorige Zeile berechnen ret z ; Ende bei oberster Zeile ld a,l sub 8 ; Zeiger auf vorige Zeile ld l,a jr MTmtest MTmup: ld a,e ; Verikale Richtung holen or a ; Test ob Bewegung jr z,MTmtest ; Nein, Ende inc c ; Naechste Zeile einstellen ld a,l add a,8 ; Zeiger auf naechste Zeile ld l,a ld a,c ; Zeile holen sub 8+1 ; Ende bei unterster Zeile ret z ; ; An diesem Punkt haben wir den naechsten danebenliegenden Zeiger ; MTmtest: ld a,(hl) ; Spielstein holen sub '.' ; Test ob frei ret z ; Ja ld a,(CouPart) ; Gegenstueck holen sub (hl) ; Test Uebereinstimmung jr z,MTmloop ; Ja ld d,_OK ; Eigenen Stein gefunden ret ; ; Spieler zieht ; HumMove: call TestFree ; Freien Platz testen call outBoard ; Spielfeld ausgeben HMstart: ld a,1 ; Initialisieren der .. ld (HumRow),a ; .. Zeile ld (HumCol),a ; .. Spalte HMloop: ld de,$BOARD-1 ld d,_COMP ld bc,(HumRow) call CheckDir ; Test ob Richtung ok ld a,d sub _OK ; Ueberpruefung jr z,HMinput ; Gut ld hl,HumRow inc (hl) ; Zeile erhoehen ld a,(hl) sub 8+1 ; Test ob fertig jr nz,HMloop ; Nein ld (hl),1 ; Zeile ruecksetzen inc hl inc (hl) ; Spalte erhoehen ld a,(hl) sub 8+1 ; Test ob fertig jr nz,HMloop ; Nein ld a,1 ; Initialisieren der .. ld (HumRow),a ; .. Zeile ld (HumCol),a ; .. Spalte HMsrcfree: ld de,$BOARD-1 ld d,_HUMAN ld bc,(HumRow) call CheckDir ; Test ob Richtung ok ld a,d sub _OK ; Ueberpruefung jr nz,HMnext ; Nicht gut ld bc,SOLvid+_ST jr HMnomove ; Wir koennen nicht ziehen HMnext: ld hl,HumRow inc (hl) ; Zeile erhoehen ld a,(hl) sub 8+1 ; Test ob fertig jr nz,HMsrcfree ; Nein ld (hl),1 ; Zeile ruecksetzen inc hl inc (hl) ; Spalte erhoehen ld a,(hl) sub 8+1 ; Test ob fertig jr nz,HMsrcfree ; Nein call outBoard ; Spielfeld ausgeben ld bc,SOLvid+_SC ld de,$SCORE call strgVID ; Spielstand ausgeben ld bc,SOLvid+_ST ld de,$NOMOVE call strgVIDon ; Zug unmoeglich ausgeben jp CountPieces HMnomove: ld de,$UCANOT call strgVID ; Spielerzug unmoeglich ausgeben jp CompMove ; Computer zieht ; ; Zug eingeben ; HMinput: ld bc,SOLvid+_ST ld de,$YOUR call strgVID ; Aufforderung ausgeben HMinagain: ld hl,SOLvid+_XY-1 ; Zeiger initialisieren call CharIn ; X-Koordinate holen ld_hl_a ; Abspeichern ld b,a sub '1' ; Bereich ueberpruefen jr nc,HMtstval ; Ok HMillin: ld bc,SOLvid+_MS ld de,$INVINP call strgVIDon ; Anzeige ungueltige Eingabe ld hl,SOLvid+_XY ld_hl_8 ' ' ; Ziffern loeschen inc hl ld_hl_8 ' ' inc hl ld_hl_8 ' ' jr HMinagain ; Neuer Versuch HMtstval: sub 7+1 ; Bereich ueberpruefen jr nc,HMillin ; Fehler ld a,b ; Ziffer holen sub '0' ; In binaeren Wert wandeln ld b,a call CharIn ; Trennzeichen holen ld_hl_a ; Abspeichern sub ',' jr nz,HMillin call CharIn ; Y-Koordinate holen ld_hl_a ; Abspeichern ld c,a sub '1' ; Bereich ueberpruefen jr c,HMillin sub 7+1 jr nc,HMillin ld a,c ; Ziffer holen sub '0' ; In binaeren Wert wandeln ld c,a ld l,b ld h,c ld (ColSav),hl ; Zeile und Spalte speichern ld de,$BOARD-1 ld d,_COMP call CheckDir ; Test ob Richtung ok ld a,d sub _OK ; Ueberpruefung jr nz,HMillin ; Nicht gut ld hl,(ColSav) ; Zeile und Spalte laden ld b,l ld c,h ld (BoardCol),hl ; Spalte und Zeile speichern ld hl,$BOARD-1 ; Feld initialisieren ld a,l add a,b ; Spalte addieren HMincrow: dec c jr z,HMgotrow add a,8 ; Zeile addieren jr HMincrow HMgotrow: ld l,a ld (BoardAdr),hl ; Zeiger auf Spielfeld sichern ld (hl),_HUMAN ; Spielerstein setzen ; ; Steine in Farbe des Spielers wechseln ; call LoadPXY ; Adresse und Koordinaten laden ld d,0 ; Nach oben ld e,2 call MoveThru ; Durch das Spielfeld gehen ld a,d sub _OK jr nz,HMmov1 ld hl,(BoardAdr) ; Zeiger auf Spielfeld laden ld d,2*8+8 ld e,_COMP call FlipPieces ; Nach oben bewegen HMmov1: call LoadPXY ; Adresse und Koordinaten laden ld d,1 ; Rechts hoch einstellen ld e,2 call MoveThru ; Durch das Spielfeld gehen ld a,d sub _OK jr nz,HMmov2 ld hl,(BoardAdr) ; Zeiger auf Spielfeld laden ld d,2*8+7 ld e,_COMP call FlipPieces ; Nach oben rechts bewegen HMmov2: call LoadPXY ; Adresse und Koordinaten laden ld d,1 ; Rechts einstellen ld e,0 call MoveThru ; Durch das Spielfeld gehen ld a,d sub _OK jr nz,HMmov3 ld hl,(BoardAdr) ; Zeiger auf Spielfeld laden ld d,1 ld e,_COMP call FlipPieces ; Nach rechts bewegen HMmov3: call LoadPXY ; Adresse und Koordinaten laden ld d,1 ; Rechts unten einstellen ld e,1 call MoveThru ; Durch das Spielfeld gehen ld a,d sub _OK jr nz,HMmov4 ld hl,(BoardAdr) ; Zeiger auf Spielfeld laden ld d,8+1 ld e,_COMP call FlipPieces ; Nach rechts unten bewegen HMmov4: call LoadPXY ; Adresse und Koordinaten laden ld d,0 ; Unten einstellen ld e,1 call MoveThru ; Durch das Spielfeld gehen ld a,d sub _OK jr nz,HMmov5 ld hl,(BoardAdr) ; Zeiger auf Spielfeld laden ld d,8 ld e,_COMP call FlipPieces ; Nach unten bewegen HMmov5: call LoadPXY ; Adresse und Koordinaten laden ld d,2 ; Links unten einstellen ld e,1 call MoveThru ; Durch das Spielfeld gehen ld a,d sub _OK jr nz,HMmov6 ld hl,(BoardAdr) ; Zeiger auf Spielfeld laden ld d,8-1 ld e,_COMP call FlipPieces ; Nach links unten bewegen HMmov6: call LoadPXY ; Adresse und Koordinaten laden ld d,2 ; Links einstellen ld e,0 call MoveThru ; Durch das Spielfeld gehen ld a,d sub _OK jr nz,HMmov7 ld hl,(BoardAdr) ; Zeiger auf Spielfeld laden ld d,2*8+1 ld e,_COMP call FlipPieces ; Nach links bewegen HMmov7: call LoadPXY ; Adresse und Koordinaten laden ld d,2 ; Links hoch einstellen ld e,2 call MoveThru ; Durch das Spielfeld gehen ld a,d sub _OK jr nz,HMmov8 ld hl,(BoardAdr) ; Zeiger auf Spielfeld laden ld d,2*8+9 ld e,_COMP call FlipPieces ; Nach links oben bewegen HMmov8: call TestFree ; Test freien Platz jr CompMove ; Computer zieht ; ; Spielsteine wechseln ; EIN Register HL haelt Spielfeldzeiger ; Register D haelt Richtung ; Register E haelt Gegenstueck ; FlipPieces: ld a,d ; Richtung holen sub 2*8 ; Bereich ueberpruefen jp m,FlipRight ; Naechste rechte Richtung ld a,l add a,2*8 ; Einstellen fuer links sub d jr FlipGo FlipRight: ld a,l add a,d FlipGo: ld l,a ; Zeiger setzen ld a,(hl) ; Spielstein holen sub e ; Gegenstueck testen ret nz ; Nein ld a,e ; Test wer wir sind sub _COMP jr z,FlipHuman ld (hl),_COMP ; Computer setzen jr FlipPieces FlipHuman: ld (hl),_HUMAN ; Spielerstein setzen jr FlipPieces ; ; Eingabe eines Zeichens fuer Spielerzug - Abbruch bei 'E'nde ; CharIn: inc hl ld_hl_8 ' '+MSB ; Cursor setzen call CONin ; Zeichen lesen ld c,a cp 'E' ; Test 'E'nde ret nz jp SOLOS ; Ja ; ; Computer zieht ; CompMove: ld b,1 ld c,1 ld de,$BOARD-1 ld d,_HUMAN call CheckDir ; Test ob Richtung ok ld a,d sub _OK ; Ueberpruefung jr z,CMexe1 ; Ok ld b,1 ld c,8 ld de,$BOARD-1 ld d,_HUMAN call CheckDir ; Test ob Richtung ok ld a,d sub _OK ; Ueberpruefung jr z,CMexe1 ; Ok ld b,8 ld c,1 ld de,$BOARD-1 ld d,_HUMAN call CheckDir ; Test ob Richtung ok ld a,d sub _OK ; Ueberpruefung jr z,CMexe1 ; Ok ld b,8 ld c,8 ld de,$BOARD-1 ld d,_HUMAN call CheckDir ; Test ob Richtung ok ld a,d sub _OK ; Ueberpruefung jr z,CMexe1 ; Ok ld hl,1*256+1 ld (ComCol),hl ; Zeile und Spalte initialisieren ld hl,2 ld (ComMod1),hl jr CMchkgo CMexe1: ld hl,(BoardCol) ; Zeile und Spalte laden ld a,h ld h,l ld l,a ld (ComXY),hl jp CMtstmov CMchkgo: ld hl,(ComCol) ; Zeile und Spalte laden ld b,h ld c,l ld de,$BOARD-1 ld d,_HUMAN call CheckDir ; Test ob Richtung ok ld a,d sub _OK ; Ueberpruefung jr z,CMcpbrd ; Ok CMchkloop: ld hl,ComCol ; Zeiger auf Spalte inc (hl) ; Erhoehen ld a,(hl) sub 8+1 ; Test ob alle durch jr nz,CMchkgo ; Nein ld (hl),1 ; Spalte neu initialisiern inc hl inc (hl) ; Zeile erhoehen ld a,(hl) sub 8+1 ; Test ob alle durch jr nz,CMchkgo ; Nein jp CMscnd CMcpbrd: ld hl,$BOARD ; Spielfeldzeiger setzen ld bc,$CPBOARD ld e,c CMcpyloop: ld a,(hl) ; Spielfeld umkopieren ld (bc),a inc hl inc bc ld a,l cp e jr nz,CMcpyloop ld hl,(BoardAdr) ; Zeiger auf Spielfeld laden ld a,l add a,maxcol ; Naechste Videozeile ld l,a ld (BoardAdr),hl ; Zeiger auf Spielfeld sichern ld (hl),_COMP ; Computer setzen call LoadPXY ; Adresse und Koordinaten laden ld d,0 ; Nach oben ld e,2 call MoveThru ; Durch das Spielfeld gehen ld a,d sub _OK jr nz,CMmov1 ld hl,(BoardAdr) ; Zeiger auf Spielfeld laden ld d,2*8+8 ld e,_HUMAN call FlipPieces ; Nach oben bewegen CMmov1: call LoadPXY ; Adresse und Koordinaten laden ld d,1 ; Rechts hoch einstellen ld e,2 call MoveThru ; Durch das Spielfeld gehen ld a,d sub _OK jr nz,CMmov2 ld hl,(BoardAdr) ; Zeiger auf Spielfeld laden ld d,2*8+7 ld e,_HUMAN call FlipPieces ; Nach oben rechts bewegen CMmov2: call LoadPXY ; Adresse und Koordinaten laden ld d,1 ; Rechts einstellen ld e,0 call MoveThru ; Durch das Spielfeld gehen ld a,d sub _OK jr nz,CMmov3 ld hl,(BoardAdr) ; Zeiger auf Spielfeld laden ld d,1 ld e,_HUMAN call FlipPieces ; Nach rechts bewegen CMmov3: call LoadPXY ; Adresse und Koordinaten laden ld d,1 ; Rechts unten einstellen ld e,1 call MoveThru ; Durch das Spielfeld gehen ld a,d sub _OK jr nz,CMmov4 ld hl,(BoardAdr) ; Zeiger auf Spielfeld laden ld d,8+1 ld e,_HUMAN call FlipPieces ; Nach rechts unten bewegen CMmov4: call LoadPXY ; Adresse und Koordinaten laden ld d,0 ; Unten einstellen ld e,1 call MoveThru ; Durch das Spielfeld gehen ld a,d sub _OK jr nz,CMmov5 ld hl,(BoardAdr) ; Zeiger auf Spielfeld laden ld d,8 ld e,_HUMAN call FlipPieces ; Nach unten bewegen CMmov5: call LoadPXY ; Adresse und Koordinaten laden ld d,2 ; Links unten einstellen ld e,1 call MoveThru ; Durch das Spielfeld gehen ld a,d sub _OK jp nz,CMmov6 ld hl,(BoardAdr) ; Zeiger auf Spielfeld laden ld d,8-1 ld e,_HUMAN call FlipPieces ; Nach links unten bewegen CMmov6: call LoadPXY ; Adresse und Koordinaten laden ld d,2 ; Links einstellen ld e,0 call MoveThru ; Durch das Spielfeld gehen ld a,d sub _OK jr nz,CMmov7 ld hl,(BoardAdr) ; Zeiger auf Spielfeld laden ld d,2*8+1 ld e,_HUMAN call FlipPieces ; Nach links bewegen CMmov7: call LoadPXY ; Adresse und Koordinaten laden ld d,2 ; Links hoch einstellen ld e,2 call MoveThru ; Durch das Spielfeld gehen ld a,d sub _OK jr nz,CMmov8 ld hl,(BoardAdr) ; Zeiger auf Spielfeld laden ld d,2*8+9 ld e,_HUMAN call FlipPieces ; Nach links oben bewegen CMmov8: call CountCmp ; Steine zaehlen ld b,1 ld c,1 ld de,$CPBOARD-1 ld d,_COMP call CheckDir ; Test ob Richtung ok ld a,d sub _OK ; Ueberpruefung jr z,CMexe2 ; Ok ld b,1 ld c,8 ld de,$CPBOARD-1 ld d,_COMP call CheckDir ; Test ob Richtung ok ld a,d sub _OK ; Ueberpruefung jr z,CMexe2 ; Ok ld b,8 ld c,1 ld de,$CPBOARD-1 ld d,_COMP call CheckDir ; Test ob Richtung ok ld a,d sub _OK ; Ueberpruefung jr z,CMexe2 ; Ok ld b,8 ld c,8 ld de,$CPBOARD-1 ld d,_COMP call CheckDir ; Test ob Richtung ok ld a,d sub _OK ; Ueberpruefung jr nz,CMnotok ; Nicht gut CMexe2: ld a,(ComMod1) sub 2 jp nz,CMchkloop ld hl,(ComCol) ; Zeile und Spalte laden ld (ComXY),hl ld h,1 ld l,1 ld (ComMod1),hl jp CMchkloop CMnotok: ld a,(ComMod1) sub 2 jr nz,CMother1 CMresxy: ld hl,(ComCol) ; Zeile und Spalte laden ld (ComXY),hl ld a,(ModSav1) ld (ComMod2),a ld a,(ModSav2) ld (ComMod1),a jp CMchkloop CMother1: ld hl,ComMod1 ld a,(ModSav2) sub 1 jr z,CMother2 ld a,(hl) sub 1 jr z,CMresxy ld (ModSav1),a inc hl sub (hl) jp m,CMchkloop jr CMresxy CMother2: ld a,(hl) sub 1 jp nz,CMchkloop ld (ModSav1),a inc hl sub (hl) jp m,CMresxy jp CMchkloop CMtstmov: ld a,0 ld (ComMod1),a CMscnd: ld a,(ComMod1) sub 2 jr nz,CMscs0 ld a,1 ld (ComCol),a ; Spalte einstellen ld (ComRow),a ; Und Zeile CMscLoop: ld a,(ComCol) ; Spalte laden ld b,a ld a,(ComRow) ; Zeile holen ld c,a ld de,$BOARD-1 ld d,_HUMAN call CheckDir ; Test ob Richtung ok ld a,d sub _OK ; Ueberpruefung jp z,CMexe1 ; Ok ld hl,ComCol ; Zeiger auf Spalte inc (hl) ; Erhoehen ld a,(hl) sub 8+1 ; Test ob alle durch jr nz,CMscLoop ld (hl),a ; Spalte neu initialisiern inc (hl) inc hl inc (hl) ; Zeile erhoehen ld a,(hl) sub 8+1 ; Test ob alle durch jr nz,CMscLoop ; Nein call outBoard ; Spielfeld ausgeben ld bc,SOLvid+_AS ld de,$ICANOT call strgVID ; Computer kann nicht ziehen jp HMstart CMscs0: ld hl,(ComXY) ld b,h ld c,l ld de,$BOARD-1 ld d,_HUMAN call CheckDir ; Test ob Richtung ok ld hl,(BoardAdr) ; Zeiger auf Spielfeld laden ld (hl),_COMP ; Computer setzen call LoadPXY ; Adresse und Koordinaten laden ld d,0 ; Nach oben ld e,2 call MoveThru ; Durch das Spielfeld gehen ld a,d sub _OK jr nz,CMscs1 ld hl,(BoardAdr) ; Zeiger auf Spielfeld laden ld d,2*8+8 ld e,_HUMAN call FlipPieces ; Nach oben bewegen CMscs1: call LoadPXY ; Adresse und Koordinaten laden ld d,1 ; Rechts hoch einstellen ld e,2 call MoveThru ; Durch das Spielfeld gehen ld a,d sub _OK jr nz,CMscs2 ld hl,(BoardAdr) ; Zeiger auf Spielfeld laden ld d,2*8+7 ld e,_HUMAN call FlipPieces ; Nach oben rechts bewegen CMscs2: call LoadPXY ; Adresse und Koordinaten laden ld d,1 ; Rechts einstellen ld e,0 call MoveThru ; Durch das Spielfeld gehen ld a,d sub _OK jr nz,CMscs3 ld hl,(BoardAdr) ; Zeiger auf Spielfeld laden ld d,1 ld e,_HUMAN call FlipPieces ; Nach rechts bewegen CMscs3: call LoadPXY ; Adresse und Koordinaten laden ld d,1 ; Rechts unten einstellen ld e,1 call MoveThru ; Durch das Spielfeld gehen ld a,d sub _OK jr nz,CMscs4 ld hl,(BoardAdr) ; Zeiger auf Spielfeld laden ld d,8+1 ld e,_HUMAN call FlipPieces ; Nach rechts unten bewegen CMscs4: call LoadPXY ; Adresse und Koordinaten laden ld d,0 ; Unten einstellen ld e,1 call MoveThru ; Durch das Spielfeld gehen ld a,d sub _OK jr nz,CMscs5 ld hl,(BoardAdr) ; Zeiger auf Spielfeld laden ld d,8 ; Nach unten bewegen ld e,_HUMAN call FlipPieces CMscs5: call LoadPXY ; Adresse und Koordinaten laden ld d,2 ; Links unten einstellen ld e,1 call MoveThru ; Durch das Spielfeld gehen ld a,d sub _OK jr nz,CMscs6 ld hl,(BoardAdr) ; Zeiger auf Spielfeld laden ld d,8-1 ld e,_HUMAN call FlipPieces ; Nach links unten bewegen CMscs6: call LoadPXY ; Adresse und Koordinaten laden ld d,2 ; Links einstellen ld e,0 call MoveThru ; Durch das Spielfeld gehen ld a,d sub _OK jr nz,CMscs7 ld hl,(BoardAdr) ; Zeiger auf Spielfeld laden ld d,2*8+1 ld e,_HUMAN call FlipPieces ; Nach links bewegen CMscs7: call LoadPXY ; Adresse und Koordinaten laden ld d,2 ; Links hoch einstellen ld e,2 call MoveThru ; Durch das Spielfeld gehen ld a,d sub _OK jp nz,HumMove ld hl,(BoardAdr) ; Zeiger auf Spielfeld laden ld d,2*8+9 ld e,_HUMAN call FlipPieces ; Nach links oben bewegen jp HumMove ; Spieler zieht ; ; Zaehlen der Computer-Steine ; CountCmp: ld hl,ModSav1+1 xor a ld (hl),a ; Steinzaehler Null setzen dec hl ld (hl),a ld de,$CPBOARD+8*8 ld bc,$CPBOARD CCloop: ld a,(bc) ; Spielstein holen cp '.' ; Test ob leer jr z,CCnext ; Ja cp _COMP ; Test ob eigener Stein jr nz,CChum ; Nein inc (hl) ; Hochzaehlen jr nc,CCnext inc hl ld (hl),0 dec hl jr CCptr CChum: dec (hl) ; Runterzaehlen jr nc,CCnext inc hl ld (hl),1 CCptr: dec hl CCnext: inc bc ; Spielfeldzeiger erhoehen ld a,c ; Test ob Ende cp e jr nz,CCloop ; Nein ret ; ds 2*32 LocStk equ $ end