;
;Darin Arrick
;Computer Science III
;2/27/89
;
; TTT.ASM - Tic-Tac-Toe in 8088 assembly language
;
datarea  segment
board    db   3 dup ('...',0Dh,0Ah)
bstop    db   '$'
row      db   '1'
col      db   '1'
rowprmt  db   'Enter Row : $'
colprmt  db   'Enter Column : $'
x_win    db   '0'
o_win    db   '0'
x_won    db   'X won$'
o_won    db   'O won$'
cat_won  db   'Cat (tie) game$'
player   db   'X'
datarea  ends

ttt      segment
main proc far
         assume cs:ttt,ds:datarea,ss:ttt,es:ttt
start:
         push ds                ;set up stack for return
         sub  ax,ax             ;to DOS
         push ax
         mov  ax,datarea
         mov  ds,ax
         mov  dh,0
here:                           ;start main loop
         cmp  dh,9              ;if 9 moves,quit
         je   finish
         inc  dh                ;else inc moves and go
         call crlf
         call print_board       ;print board
         call crlf
         call inrowcol          ;input row & column
         call makemove          ;place X or O in board
         call crlf
         call chkhzx1           ;check row 1 for X winning
         call chkhzx2           ;check row 2 for X winning
         call chkhzx3           ;check row 3 for X winning
         call chkvzx1           ;check col 1 for X winning
         call chkvzx2           ;check col 2 for X winning
         call chkvzx3           ;check col 3 for X winning
         call chkdzx1           ;check 1,1 to 3,3 for X
         call chkdzx2           ;check 3,1 to 1,3 for X
         call chkhzo1           ;check row 1 for O winning
         call chkhzo2           ;check row 2 for O winning
         call chkhzo3           ;check row 3 for O winning
         call chkvzo1           ;check row 1 for O winning
         call chkvzo2           ;check row 2 for O winning
         call chkvzo3           ;check row 3 for O winning
         call chkdzo1           ;check 1,1 to 3,3 for O
         call chkdzo2           ;check 3,1 to 1,3 for O
         jmp  here2             ;jump around helping label
finish:                         ;corrects jump out of range
         jmp  game_end          ;if line 37 was 'je game_end'
here2:
         mov  dl,[x_win]        ;see if X won
         cmp  dl,'0'
         jne  game_endx         ;if so,congrat and quit
         mov  dl,[o_win]        ;see if O won
         cmp  dl,'0'
         jne  game_endo         ;if so,congrat and quit
         mov  dl,[player]       ;change player
         cmp  dl,'X'            ;  "      "
         je   chtoo             ;  "      "
         jne  chtox             ;  "      "
         jmp  here
chtoo:                          ;player - X to O
         mov  [player],'O'
         jmp  here              ;begin main loop again
chtox:                          ;player - X to O
         mov  [player],'X'
         jmp  here              ;begin main loop again
game_endx:                      ;print board,congrat X,quit
         call print_board
         mov  dx,offset x_won
         mov  ah,9
         int  21h
         jmp  exit
game_endo:                      ;print board,congrat O,quit
         call print_board
         mov  dx,offset o_won
         mov  ah,9
         int  21h
         jmp  exit
game_end:                       ;print board,cat won,quit
         call print_board
         mov  dx,offset cat_won
         mov  ah,9
         int  21h
exit:                            ;return to DOS
         call crlf
         call crlf
         ret

print_board proc near             ;print board
            push ax
            push bx
            push cx
            push dx
            mov  dx,offset board
            mov  ah,9
            int  21h
            pop  dx
            pop  cx
            pop  bx
            pop  ax
            ret
print_board endp

makemove proc near                  ;put X or O in board
         push ax                    ;BX-address of board
         push bx                    ;DI-offset IN board
         push cx                    ;DH-X or O
         push dx
         push di
         mov  dh,[player]           ;X or O in DH
         sub  bx,bx                 ;zero BX,DI
         sub  di,di
         mov  bl,[col]              ;column in BX
         mov  di,bx                 ;column in DI
         sub  bx,bx                 ;zero BX
         cmp  [row],'1'             ;if row 1,put there
         je   row1
         cmp  [row],'2'             ;if row 2,put there
         je   row2
         jmp  row3                  ;row 3,put there
row1:
         mov  bx,offset board       ;address of board -> BX
         mov  board[di-1],dh        ;figure out offset & move
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret                        ;back to main loop

row2:
         mov  bx,offset board       ;same as row1
         mov  board[bx+di+4],dh
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret

row3:    mov  bx,offset board     ;same as row 1
         mov  board[bx+di+9],dh
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret

makemove endp


inrowcol proc near               ;input row and column
         push ax
         push bx
         push cx
         push dx
         mov  dx,offset rowprmt  ;print "Enter Row : "
         mov  ah,9
         int  21h
         mov  ah,1               ;input character
         int  21h
         mov  [row],al           ;put row into [row]
         call crlf
         mov  dx,offset colprmt  ;print "Enter Col : "
         mov  ah,9
         int  21h
         mov  ah,1               ;input character
         int  21h
         sub  al,30h             ;turn into absolute value
         mov  [col],al           ;put column into [col]
         call crlf
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret                     ;back to main loop
inrowcol endp

chkhzx1 proc near                ;check row 1 , X
         push ax
         push bx
         push cx
         push dx
         push di
xchr1:                           ;if 1,1=X then check 1,2
         mov  bx,offset board    ;address of board into BX
         cmp  board[0],'X'       ;see if X
         je   xchr12             ;if 1,1=X ,check 1,2
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret                     ;if 1,1 not X,goto main loop
xchr12:                          ;check 1,2
         cmp  board[1],'X'
         je   xchr13             ;if X, check 1,3
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret                     ;back to main loop
xchr13:                          ;check 1,3
         cmp  board[2],'X'
         je   xwinr1             ;if X,then X won
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret                     ;back to main loop
xwinr1:                          ;X won
         mov  dh,'1'             ;put 1 into [X_win]
         mov  [x_win],dh
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret                    ;back to main loop
chkhzx1 endp

chkhzx2 proc near               ;see chkhzx1 procedure
         push ax
         push bx
         push cx
         push dx
         push di
xchr2:
         mov  bx,offset board
         cmp  board[5],'X'
         je   xchr22
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
xchr22:
         cmp  board[6],'X'
         je   xchr23
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
xchr23:
         cmp  board[7],'X'
         je   xwinr2
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
xwinr2:
         mov  dh,'2'
         mov  [x_win],dh
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
chkhzx2 endp

chkhzx3 proc near                    ;see chkhzx1 procedure
         push ax
         push bx
         push cx
         push dx
         push di
xchr3:
         mov  bx,offset board
         cmp  board[10],'X'
         je   xchr32
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
xchr32:
         cmp  board[11],'X'
         je   xchr33
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
xchr33:
         cmp  board[12],'X'
         je   xwinr3
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
xwinr3:
         mov  dh,'3'
         mov  [x_win],dh
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
chkhzx3 endp

chkvzx1 proc near                 ;see chkhzx1 procedure
         push ax
         push bx
         push cx
         push dx
         push di
xchv1:
         mov  bx,offset board
         cmp  board[0],'X'
         je   xchv12
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
xchv12:
         cmp  board[5],'X'
         je   xchv13
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
xchv13:
         cmp  board[10],'X'
         je   xwinv1
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
xwinv1:
         mov  dh,'1'
         mov  [x_win],dh
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
chkvzx1 endp


chkvzx2 proc near                 ;see chkhzx1 procedure
         push ax
         push bx
         push cx
         push dx
         push di
xchv2:
         mov  bx,offset board
         cmp  board[1],'X'
         je   xchv22
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
xchv22:
         cmp  board[6],'X'
         je   xchv23
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
xchv23:
         cmp  board[11],'X'
         je   xwinv2
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
xwinv2:
         mov  dh,'2'
         mov  [x_win],dh
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
chkvzx2 endp


chkvzx3 proc near                 ;see chkhzx1 procedure
         push ax
         push bx
         push cx
         push dx
         push di
xchv3:
         mov  bx,offset board
         cmp  board[2],'X'
         je   xchv32
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
xchv32:
         cmp  board[7],'X'
         je   xchv33
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
xchv33:
         cmp  board[12],'X'
         je   xwinv3
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
xwinv3:
         mov  dh,'3'
         mov  [x_win],dh
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
chkvzx3 endp

chkhzo1 proc near                 ;see chkhzx1 procedure
         push ax                  ;the following checks are
         push bx                  ;for O
         push cx
         push dx
         push di
ochr1:
         mov  bx,offset board
         cmp  board[0],'O'
         je   ochr12
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
ochr12:
         cmp  board[1],'O'
         je   ochr13
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
ochr13:
         cmp  board[2],'O'
         je   owinr1
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
owinr1:
         mov  dh,'1'
         mov  [o_win],dh
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
chkhzo1 endp

chkhzo2 proc near                ;see chkhzx1 procedure
         push ax
         push bx
         push cx
         push dx
         push di
ochr2:
         mov  bx,offset board
         cmp  board[5],'O'
         je   ochr22
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
ochr22:
         cmp  board[6],'O'
         je   ochr23
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
ochr23:
         cmp  board[7],'O'
         je   owinr2
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
owinr2:
         mov  dh,'2'
         mov  [o_win],dh
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
chkhzo2 endp

chkhzo3 proc near                ;see chkhzx1 procedure
         push ax
         push bx
         push cx
         push dx
         push di
ochr3:
         mov  bx,offset board
         cmp  board[10],'O'
         je   ochr32
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
ochr32:
         cmp  board[11],'O'
         je   ochr33
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
ochr33:
         cmp  board[12],'O'
         je   owinr3
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
owinr3:
         mov  dh,'3'
         mov  [o_win],dh
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
chkhzo3 endp

chkvzo1 proc near                ;see chkhzx1 procedure
         push ax
         push bx
         push cx
         push dx
         push di
ochv1:
         mov  bx,offset board
         cmp  board[0],'O'
         je   ochv12
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
ochv12:
         cmp  board[5],'O'
         je   ochv13
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
ochv13:
         cmp  board[10],'O'
         je   owinv1
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
owinv1:
         mov  dh,'1'
         mov  [o_win],dh
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
chkvzo1 endp


chkvzo2 proc near                ;see chkhzx1 procedure
         push ax
         push bx
         push cx
         push dx
         push di
ochv2:
         mov  bx,offset board
         cmp  board[1],'O'
         je   ochv22
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
ochv22:
         cmp  board[6],'O'
         je   ochv23
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
ochv23:
         cmp  board[11],'O'
         je   owinv2
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
owinv2:
         mov  dh,'2'
         mov  [o_win],dh
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
chkvzo2 endp


chkvzo3 proc near                ;see chkhzx1 procedure
         push ax
         push bx
         push cx
         push dx
         push di
ochv3:
         mov  bx,offset board
         cmp  board[2],'O'
         je   ochv32
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
ochv32:
         cmp  board[7],'O'
         je   ochv33
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
ochv33:
         cmp  board[12],'O'
         je   owinv3
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
owinv3:
         mov  dh,'3'
         mov  [o_win],dh
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
chkvzo3 endp

chkdzx1 proc near                ;see chkhzx1 procedure
         push ax                 ;the following checks are the
         push bx                 ;2 diagonal checks
         push cx                 ;1,1 to 3,3
         push dx
         push di
xchd1:
         mov  bx,offset board
         cmp  board[0],'X'
         je   xchd12
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
xchd12:
         cmp  board[6],'X'
         je   xchd13
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
xchd13:
         cmp  board[12],'X'
         je   xwind1
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
xwind1:
         mov  dh,'1'
         mov  [x_win],dh
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
chkdzx1 endp

chkdzx2 proc near                ;see chkhzx1 procedure
         push ax                 ;3,1 to 1,3
         push bx
         push cx
         push dx
         push di
xchd2:
         mov  bx,offset board
         cmp  board[2],'X'
         je   xchd22
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
xchd22:
         cmp  board[6],'X'
         je   xchd23
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
xchd23:
         cmp  board[10],'X'
         je   xwind2
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
xwind2:
         mov  dh,'2'
         mov  [x_win],dh
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
chkdzx2 endp


chkdzo1 proc near                ;see chkhzx1 procedure
         push ax                 ;1,1 to 3,3
         push bx
         push cx
         push dx
         push di
ochd1:
         mov  bx,offset board
         cmp  board[0],'O'
         je   ochd12
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
ochd12:
         cmp  board[6],'O'
         je   ochd13
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
ochd13:
         cmp  board[12],'O'
         je   owind1
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
owind1:
         mov  dh,'1'
         mov  [o_win],dh
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
chkdzo1 endp

chkdzo2 proc near                ;call chkhzx1 procedure
         push ax                 ;1,3 to 3,1
         push bx
         push cx
         push dx
         push di
ochd2:
         mov  bx,offset board
         cmp  board[2],'O'
         je   ochd22
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
ochd22:
         cmp  board[6],'O'
         je   ochd23
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
ochd23:
         cmp  board[10],'O'
         je   owind2
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
owind2:
         mov  dh,'2'
         mov  [o_win],dh
         pop  di
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
chkdzo2 endp


crlf     proc near               ;procedure to print
         push ax                 ;CR and LF
         push bx
         push cx
         push dx
         mov  ah,2
         mov  dl,0Dh
         int  21h
         mov  dl,0Ah
         int  21h
         pop  dx
         pop  cx
         pop  bx
         pop  ax
         ret
crlf     endp

main endp                         ; Und das ist Alles!
ttt      ends
end      start
         end