; *** Fire på stribe ***
;
; Copyright (C) 2001 Lars K. Schunk

[BITS 16]

;------------------------------------------------------------

;----------------------Code Section--------------------------

;------------------------------------------------------------

SEGMENT code

; *** Main Program ***

..start:
     mov  ax,data
     mov  ds,ax               ; Initialisér data-segmentet.
     mov  ax,minStak
     mov  ss,ax               ; Initialisér stakken.
     mov  sp,stacktop

     call clrBoard            ; Tømmer pladen for brikker.

turn:
     mov  BYTE [spiller],'1'  ; Spiller 1's tur.
     call drawScreen          ; Tegner pladen.
     call getMove             ; Henter spiller 1's træk.
     call makeMove            ; Udfører spiller 1's træk.
     call checkStatus         ; Er spillet vundet eller uafgjort?

     mov  BYTE [spiller],'2'  ; Spiller 2's tur.
     call drawScreen          ; Tegner pladen.
     call getMove             ; Henter spiller 2's træk.
     call makeMove            ; Udfører spiller 2's træk.
     call checkStatus         ; Er spillet vundet eller uafgjort?

     jmp  turn

 

; *** Generelle procedurer ***

gotoXY:                  ; !!! Gem X i DL og Y i DH !!!
     mov  bh,0           ; Display Page 0
     mov  ah,02h         ; VIDEO Service 02h: Position Cursor
     int  10h
     ret

clrScreen:
     mov  cx,0           ; Vælg hele skærmen.
     mov  dx,184Fh       ;   (184Fh <=> Y=24 og X=79)
     mov  al,0           ; 0=Slet i stedet for scroll.
     mov  bh,07h         ; Display attribute = 7 (Normal)
     mov  ah,06h         ; VIDEO Service 06h: Initialize/Scroll
     int  10h
     ret

write:                   ; !!! Gem strengens adresse i DS:DX !!!
     mov  ah,09h         ; DOS-funktion 09h: Print String
     int  21h
     ret

end:
     mov  ax,4C00h       ; Afslut programmet.
     int  21h

 

; *** Clear Board ***

clrBoard:
     mov  ax,ds
     mov  es,ax          ; Gem Data-segment i ES.

     mov  di,plade       ; Gem pladens start-offset i DI.
     mov  cx,6*7         ; Alle pladens felter (6*7)
     mov  al,'+'         ;   skal sættes lig med '+'.

     cld                 ; Vi skal skyde +'er nede fra og op.
rep stosb                ; Her skyder vi vores +'er!

     ret

 

; *** Draw Screen ***

drawScreen:
     call clrScreen      ; Rydder skærmen.

     mov  dl,60          ; X=60
     mov  dh,0           ; Y=0
     call gotoXY         ; Placér markør.
     mov  dx,streng1     ; Skriver "9: Afslutter spillet" i
     call write          ;   skærmens øverste højre hjørne.

     mov  dx,streng2     ; Skriver "    1234567"
     call write

     mov  bx,1           ; File Handle=1 (Standard Output)
     mov  cx,7           ; Skriv 7 byte.
     mov  si,0           ; Start med pladens første række.

printRow:
     mov  dx,plade       ; Gem pladens start-offset i DX.
     add  dx,si          ; Gem rækkenr. i DX.

     mov  ah,40h         ; DOS-funktion 40h: Write to File
     int  21h

     mov  dx,streng3     ; Linjeskift + "    "
     call write

     add  si,7           ; Gå til næste række
     cmp  si,42          ;   hvis der er flere...
     jne  printRow

     mov  dx,nylinje     ; Linjeskift.
     call write

     ret

 

; *** Get Move ***

getMove:
     mov  dx,streng4     ; Skriver "Spiller "
     call write

     mov  dl,[spiller]   ; Skriver spillerens nr.
     mov  ah,02h         ; DOS-funktion 02h: Print Character
     int  21h

     mov  dx,streng5     ; Skriver "---------".
     call write

prompt:
     mov  dx,streng6     ; Skriver "Indtast træk: "
     call write

     mov  ah,0           ; Keyboard Service 00h: Get Key From Buffer
     int  16h

     cmp  al,'9'         ; 9 slutter spillet.
     je   end

     cmp  al,'1'         ; Tester for mindre end 1.
     jl   badKey

     cmp  al,'7'         ; Tester for større end 7.
     jg   badKey

     sub  al,49               ; Konverterer ASCII-koden
                              ;   til en værdi mellem 0 og 6.
     mov  bx,plade            ; Gem pladens start-offset i BX.
     mov  ah,00               ; Sørger for at high byte ikke ændrer værdien.
     mov  di,ax               ; Gem trækket i DI.
     cmp  BYTE [bx+di],'+'    ; Hvis det _ikke_ er et +, så er
     jne  illegalMove         ;   trækket ugyldigt.

     ret

badKey:
     mov  dx,streng7     ; Skriver "Du skal indtaste..."
     call write
     jmp  prompt

illegalMove:
     mov  dx,streng8     ; Skriver "Ugyldigt træk!"
     call write
     jmp  prompt



; *** Make Move ***

makeMove:
     mov  bx,plade            ; Gem pladens start-offset i BX.
     add  bx,35               ; Hop til pladens nederste række.
     mov  di,ax               ; Gem træk (kolonne) i DI.
                              ;   AL blev lig med træk i getMove.
itIsNot:
     cmp  BYTE [bx+di],'+'    ; Tester om feltet er tomt (et +).
     je   itIs
     sub  bx,7                ; Hop op til næste række.
     jmp  itIsNot

itIs:
     cmp  BYTE [spiller],'1'  ; Er det spiller 1's træk?
     jne  player2
     mov  BYTE [bx+di],'X'    ; Læg spiller 1's brik (X) på pladen.

     ret

player2:
     mov  BYTE [bx+di],'O'    ; Læg spiller 2's brik (O) på pladen.

     ret
 

; *** Check Status ***

checkStatus:
     cmp  BYTE [spiller],'1'  ; Er det spiller 1's tur?
     je   yes
     mov  BYTE [spiller],'O'  ; Nej, læg spiller 2's brik i spiller.
     jmp  horizInit

yes:
     mov  BYTE [spiller],'X'  ; Ja, læg spiller 1's brik i spiller.

 

; --- Tjekker for 4 på stribe vandret ---

horizInit:
     mov  bx,plade            ; Gem pladens start-offset i BX.
     mov  al,[spiller]        ; Flyt spillerens brik ind i AL til testning.

     mov  di,0                ; Start i pladens øverste venstre hjørne.
     mov  cx,0

horiz:
     cmp  [bx+di],al
     jne  not1
     cmp  [bx+di+1],al
     jne  not1
     cmp  [bx+di+2],al
     jne  not1
     cmp  [bx+di+3],al
     jne  not1
     jmp  gameWon             ; Der er 4 på stribe vandret!

not1:
     inc  di                  ; Næste felt.
     inc  cx

     cmp  di,39               ; Er vi færdige med at tjekke vandret?
     je   vertInit            ; Ja, fortsæt med lodret.

     cmp  cx,4                ; Bevæger vi os over i 3. zone?
     je   newRow1             ; Ja, næste række.

     jmp  horiz               ; Nej, fortsæt med næste felt.

newRow1:
     add  di,3                ; Næste række.
     mov  cx,0

     jmp  horiz               ; Gennemløb løkken igen.

 

; --- Tjekker for 4 på stribe lodret ---

vertInit:
     mov  di,0                ; Start i pladens øverste venstre hjørne.

vert:
     cmp  [bx+di],al
     jne  not2
     cmp  [bx+di+7],al
     jne  not2
     cmp  [bx+di+14],al
     jne  not2
     cmp  [bx+di+21],al
     jne  not2
     jmp  gameWon             ; Der er 4 på stribe lodret!

not2:
     inc  di                  ; Næste felt.

     cmp  di,21               ; Er vi færdige med at tjekke lodret?
     je   diag1Init           ; Ja, fortsæt med diagonalt.

     jmp  vert                ; Nej, fortsæt med næste felt.

 

; --- Tjekker 1. zone for 4 på stribe diagonalt ---

diag1Init:
     mov  di,0                ; Start i pladens øverste venstre hjørne.
     mov  cx,0

diag1:
     cmp  [bx+di],al
     jne  not3
     cmp  [bx+di+8],al
     jne  not3
     cmp  [bx+di+16],al
     jne  not3
     cmp  [bx+di+24],al
     jne  not3
     jmp  gameWon             ; Der er 4 på stribe diagonalt!

not3:
     inc  di                  ; Næste felt.
     inc  cx

     cmp  di,18               ; Er vi færdige med at tjekke 1. zone?
     je   diag2Init           ; Ja, fortsæt med 2. zone.

     cmp  cx,4                ; Bevæger vi os over i 3. zone?
     je   newRow3             ; Ja, næste række.

     jmp  diag1               ; Nej, fortsæt med næste felt.

newRow3:
     add  di,3                ; Næste række.
     mov  cx,0

     jmp  diag1               ; Gennemløb løkken igen.

 

; --- Tjekker 2. zone for 4 på stribe diagonalt ---

diag2Init:
     mov  di,21               ; Start i række 3 (3*7=21).
     mov  cx,0

diag2:
     cmp  [bx+di],al
     jne  not4
     cmp  [bx+di-6],al
     jne  not4
     cmp  [bx+di-12],al
     jne  not4
     cmp  [bx+di-18],al
     jne  not4
     jmp  gameWon           ; Der er 4 på stribe diagonalt!

not4:
     inc  di
     inc  cx

     cmp  di,39               ; Er vi færdige med at tjekke 2. zone?
     je   tieInit             ; Ja, fortsæt med test for uafgjort.

     cmp  cx,4                ; Bevæger vi os over i 3. zone?
     je   newRow4             ; Ja, næste række.

     jmp  diag2               ; Nej, fortsæt med næste felt.

newRow4:
     add  di,3                ; Næste række.
     mov  cx,0

     jmp  diag2               ; Gennemløb løkken igen.

 

; --- Tjekker om spillet er uafgjort (ingen tomme felter) ---

tieInit:
     mov  di,0

tie:
     cmp  BYTE [bx+di],'+'    ; Er der flere tomme felter?
     je   notTie              ; Ja, fortsæt spillet.

     inc  di
     cmp  di,7                ; Er sidste felt nået?
     je   gameTie             ; Ja, spillet er uafgjort.
     jmp  tie                 ; Nej, gennemløb løkken igen.

notTie:
     ret

 

; --- Spillet er uafgjort ---

gameTie:
     call drawScreen
     mov  dx,strengB
     call write
     call end

 

; --- Spillet er vundet ---

gameWon:
     cmp  al,'X'              ; Har spiller 1 vundet?
     jne  player2won

     call drawScreen
     mov  dx,streng9          ; Ja.
     call write
     call end

player2won:
     call drawScreen
     mov  dx,strengA          ; Nej, spiller 2 vandt.
     call write
     call end

 

;------------------------------------------------------------

;----------------------Data Section--------------------------

;------------------------------------------------------------

SEGMENT data

plade    resb 6*7       ; Pladens højde=6, bredde=7

streng1  db   "9: Afslutter spillet",13,10,13,10,'$'
streng2  db   "    1234567",13,10,"    $"
streng3  db   13,10,"    $"
streng4  db   "Spiller $"
streng5  db   13,10,"---------$"
streng6  db   13,10,"Indtast Træk: $"
streng7  db   13,10,13,10,"Du skal indtaste et træk mellem 1 og 7!",13,10,'$'
streng8  db   13,10,13,10,"Ugyldigt træk!",13,10,'$'
streng9  db   13,10,"Spiller 1 har vundet!",13,10,'$'
strengA  db   13,10,"Spiller 2 har vundet!",13,10,'$'
strengB  db   13,10,"Spillet er uafgjort!",13,10,'$'

nylinje  db   13,10,'$'

spiller  db   '*'

 

;------------------------------------------------------------

;----------------------Stack Section-------------------------

;------------------------------------------------------------

SEGMENT minStak stack

     resb 512

stacktop:

 
;----------------------End Of File---------------------------

