组件 8086 井字棋程序不工作

问题描述 投票:0回答:1

汇编 8086 检查井字游戏中获胜者的程序仅检查第一行

我正在制作一个终极井字游戏,我几乎制作了整个游戏,我映射到数组,我检查单板获胜者并将它们映射到 3 x 3 数组,所有这些都有效,但由于某种原因,过程检查 3 x 3 板时仅检查第一行。我已经为单个井字棋游戏制作了一个测试文件,它在那里工作,所以也许我的代码中隐藏了另一个程序或其他东西的问题

CHECK_WINNER PROC

    XOR BX, BX
    XOR CX, CX
    XOR DX, DX
    XOR DI, DI
    LEA DI, BIG_BOARD
    
VERIFICA_VENCEDOR_LINHA1:

    CMP CX, 3
    JE VERIFICA_VENCEDOR_COLUNA1
    MOV AL, [DI]
    CMP AL, JOGADOR_CURR
    JNE PROXIMA_LINHA1
    INC DI
    MOV AL, [DI]
    CMP AL, JOGADOR_CURR
    JNE PROXIMA_LINHA1
    INC DI
    MOV AL, [DI]
    CMP AL, JOGADOR_CURR
    JNE PROXIMA_LINHA1
    INC DI
    
    JMP GANHOU_BOARD1
    
PROXIMA_LINHA1:

    MOV DI, DX
    ADD BX, 3
    ADD DI, BX
    INC CX
    JMP VERIFICA_VENCEDOR_LINHA1

VERIFICA_VENCEDOR_COLUNA1:
    
    XOR BX, BX
    XOR CX, CX
    MOV DI, DX
    
COLUNA_LOOP1:

    CMP CX, 3
    JE VERIFICA_VENCEDOR_DIAGONAL1
    MOV AL, [DI]
    CMP AL, JOGADOR_CURR
    JNE PROXIMA_COLUNA1
    ADD DI, 3
    MOV AL, [DI]
    CMP AL, JOGADOR_CURR
    JNE PROXIMA_COLUNA1
    ADD DI, 3
    MOV AL, [DI]
    CMP AL, JOGADOR_CURR
    JNE PROXIMA_COLUNA1
    ADD DI, 3
    
    JMP GANHOU_BOARD1

PROXIMA_COLUNA1:

    MOV DI, DX
    INC BX
    ADD DI, BX
    INC CX
    JMP COLUNA_LOOP1
    
    
VERIFICA_VENCEDOR_DIAGONAL1:
    XOR BX, BX
    XOR CX, CX
    MOV CX, 3
    MOV DI, DX
    
    MOV AL, [DI]
    CMP AL, JOGADOR_CURR
    JNE DIAG21
    ADD DI, 4
    MOV AL, [DI]
    CMP AL, JOGADOR_CURR
    JNE NAO_GANHOU1
    ADD DI, 4
    MOV AL, [DI]
    CMP AL, JOGADOR_CURR
    JNE DIAG21
    
    JMP GANHOU_BOARD1
    
DIAG21:
    MOV DI, DX
    ADD DI, 2
    MOV AL, [DI]
    CMP AL, JOGADOR_CURR
    JNE NAO_GANHOU1
    ADD DI, 2
    MOV AL, [DI]
    CMP AL, JOGADOR_CURR
    JNE NAO_GANHOU1
    ADD DI, 2
    MOV AL, [DI]
    CMP AL, JOGADOR_CURR
    JNE NAO_GANHOU1
    
    JMP GANHOU_BOARD1
    
NAO_GANHOU1:
    RET
    
GANHOU_BOARD1:
    CALL EXIT
    
CHECK_WINNER ENDP
assembly x86-16 dos tic-tac-toe
1个回答
-1
投票

我决定纠正我最后一个很糟糕的答案。 :/ 我也不知道这个是否会更好。好吧,我发现了这个错误...

程序不起作用,因为寄存器

di
中的值计算方式错误。

第一个

di
包含
offset big_board
,并且在每个
row/column
之后该值都会更改。所以
di
指向错误的内存区域。

我写了其余的代码。程序使用更正的 OP 程序。

如果您发现更多错误,请告诉我。 ;)


.286
.model small
.stack 0ffh

.data

big_board   db 0,0,0
            db 0,0,0
            db 0,0,0
                    
board   db 13,10,13,10                  ; new  line
        db 218,196,196,196,194,196,196,196,194,196,196,196,191,13,10
        db 179,  0,  0,  0,179,  0,  0,  0,179,  0,  0,  0,179,13,10    ;;
        db 195,196,196,196,197,196,196,196,197,196,196,196,180,13,10
        db 179,  0,  0,  0,179,  0,  0,  0,179,  0,  0,  0,179,13,10    ;;
        db 195,196,196,196,197,196,196,196,197,196,196,196,180,13,10
        db 179,  0,  0,  0,179,  0,  0,  0,179,  0,  0,  0,179,13,10    ;;
        db 192,196,196,196,193,196,196,196,193,196,196,196,217,'$'

        turnnumber   db 49  
        firsttime    db 0       ;draw everything, skip user keys 
        keynumber    db ?       ;what key user pressed
        xpos         db 6           ;cursor x position on screen    
        ypos         db 5           ;cursor y position on screen    
        xboard       db 1           ;cursor board x position
        yboard       db 1           ;cursor board y position
        x_o          db 88          ;79=o 88=x  
        spacepressed db 0
        playercolor  db 0ah ;0ah=green 0dh=purple   
        winner       db 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;        
         
        howto        db "Move: use arrows       Accept: space bar$"
        turn         db "Turn: ",'$'
        move         db 32,32,32,32,"Move: ",'$'
        game_winner  db "Winner! "
        player       db "Player "         
        jogador_curr db 49  ;player number
        newline      db 13,10,13,10,'$'
        byebye       db "--- See you next time ---- ",'$'
        win_x        db "The game ended in a draw.",'$'     
        
          
;--- macros
          
setcharattr macro attr;x,y,attr       
    pusha

    mov ah,9        ; service number
    mov al,0        ; character code    
    mov cx,1        ; number of chars to write  
    mov bh,0        ; active page
    mov bl,attr     ; character attribute
    int 10h
    
    popa
endm
                  
setcursor macro x,y        
    pusha

    mov ah,02h      ; service number
    mov dl,x        ; column
    mov dh,y        ; row
    mov bh, 00h     ; active page
    int 10h

    popa
endm

curshow macro
    pusha

    mov ah,01h      ; service number       
    mov ch,11       ; start
    mov cl,12       ; end
    int 10h

    popa
endm

curhide macro
    pusha

    mov ah,01h      ; service number 
    mov ch,20h      ; stack, 20h hides the cursor
    int 10h

    popa
endm
        
;;------------------------------------------------------------
.code
start:        
    mov ax,@data
    mov ds,ax
    mov es,ax
        
    mov ax,0003h                ; text mode
    int 10h

;mov [firsttime], 1 ;=1 we already draw everythig, now check user input
                
    mov ah,9            ; print "board"
    mov dx,offset board
    int 21h
                        
    setcursor [xpos],[ypos]     ; board coords                                  
    setcharattr [playercolor]   ; current color
                    
    mov ah,2                    ; show x or o                       
    mov dl,[x_o]
    int 21h             
                    
    setcursor [xpos],[ypos]
    
    call info
    
    mainloop:                   
        setcursor 0,0         
                
;--------------------------------               
        mov ah,9                ; print "turn"
        mov dx,offset turn
        int 21h
                
        setcharattr 14          ; yellow
                
        mov ah,2                ; print turnnumber  
        mov dl,[turnnumber]             
        int 21h
                
        mov ah,9                ; print "move: "
        mov dx,offset move
        int 21h
                
        mov bx, offset player   ; print "player "
        mov cx,8                ; number of characters in "player x"
                
        mov dx,18   ;?      
        setcursor 17,0
                
        playertext:                                 
            push bx         ; save player offset
            push cx         ; save counter  
                    
            mov ah,9
            mov al,[bx]     ; char in "player "
                    
            xor bx,bx
            mov bl,[playercolor]        

            mov cx,1                    
            int 10h
                    
            pop cx          ; restore counter
            pop bx          ; restore player offset     
            inc bx          ; next char     
                    
            mov ah,2                    
            int 10h
            add dl,1        ; next position, increase column number
        loop playertext
        
        
        
;-------------- draw board
                
;               setcursor 15,6      
;               mov ah,2            
;               mov dl,[xpos]
;               add dl,30h              
;               int 21h
;               mov ah,2            
;               mov dl,20h
;               int 21h
;               mov ah,2            
;               mov dl,[ypos]       
;               add dl,30h
;               int 21h
        setcursor [xpos],[ypos]     ; board coords      
                    
        call checkkey
        cmp al,27       ;esc, exit program
        jz endgame  
                
;;--------------------------------------------------------
        call boardaction                
;;--------------------------------------------------------
        mov al,[x_o]
        xor dx,dx
        mov dl,[jogador_curr]
        push dx
        mov [jogador_curr],al
        
        call check_winner
        
        pop dx
        mov [jogador_curr],dl

        mov al,[winner]         ; we have the winner
        cmp al,1
        jz player_wins
        
;--- switch player

        mov al,[spacepressed]   ; player pressed spacebar ?
        cmp al,1
        jnz DontSwitchPlayer
        
        call SwitchPlayer   

        DontSwitchPlayer:

;--- check if game is finished
    
        mov al,[turnnumber]     ; draw or continue game
        cmp al,58
        jae textmode
        
    jmp mainloop
            
    textmode:
        mov ax,0003h        ; back to text move
        int 10h 
        
    nowinner:   
        setcursor 0,1   
        mov ah,9
        mov dx,offset win_x
        int 21h 
        jmp endgame

    player_wins:    
        mov ax,0003h        ; back to text move
        int 10h 
        
        setcursor 0,1   
        mov ah,9
        mov dx,offset game_winner
        int 21h     
        
        ;mov ah,2           
        ;mov dl,[jogador_curr]
        ;int 21h            
        
    endgame:           
        setcursor 0,2
        mov ah,9
        mov dx,offset byebye
        int 21h
        
    exit:         
        mov ax, 4c00h       ; end app
        int 21h
        
;--- procedures ----------

info proc   
    setcursor 0,23
    
    mov cx,80
    
    show_line:
        mov ah,2
        mov dl,'_'
        int 21h
        dec cx  
        jnz show_line
    
    setcursor 1,24
    
    mov ah,9
    mov dx,offset howto
    int 21h
    
    setcursor 0,0
    
    ret
info endp

checkkey proc
    mov ah,0    ; read key
    int 16h
          
    cmp al,0    
    jz extended
    jmp normal
    
    extended:      
        mov [keynumber], ah     ; save
        mov al,ah
    jmp nextturn
    
    normal:                       
        mov [keynumber], al     ; save
                                   
    nextturn:   
    ret
checkkey endp

SwitchPlayer proc
    ;switch_player: 
    cmp [jogador_curr],49   ;1=x 2=o
    jz switchtoplayer2
        
    sub [jogador_curr],1
    mov [playercolor],0ah
    mov [x_o], 88
                    
    jmp turn_inc
                
    switchtoplayer2:
        add [jogador_curr],1
        mov [playercolor],0dh
        mov [x_o], 79
                       
    turn_inc:
                ;mov [spacepressed],0  ;;???
        inc [turnnumber]                    

    ret
SwitchPlayer endp

;--- boardaction ----------
;   checks board boundries
;   calculates if position on big_board is free/taken    
;   and draws graphics accordingly

boardaction proc            
    cmp al,77      ;right arrow
    jz moveright                 
    cmp al,75      ;left arrow
    jz moveleft
    cmp al,72      ;up arrow
    jz moveup             
    cmp al,80      ;down arrow
    jz movedown
    cmp al,32      ;space, place x,o on board
    jz space
    jmp boardactiondone

    bb_field:
        mov si,offset big_board     ; current position
        mov bh,[xboard]
        mov bl,[yboard]
        ;3*[yboard]+[xboard]
        xor ax,ax           ; calculate new position
        mov al,3
        mul bl
        add al,bh
    
        add si,ax
        mov al,[si]         ; and see what is there 
        cmp al,0            ; empty field?
        ret
        
    moveright:
        mov al,[xpos]       ; current x position on board, screen coords
        cmp al,10           ; right bound detection, is cursor in last column?
        jz boardactiondone  ; yes
                            
        call bb_field       ; no, it is not
        jnz move_right      ; there is x/o in this field, just calculate new coords
        
        setcharattr 0       ; clear current field
        
        move_right:         ; new x coords
            add [xpos],4
            add [xboard],1
            jmp boardactiondone
        
    moveleft:
        mov al,[xpos]       ; current x position on board, screen coords        
        cmp al,2            ; left bound detection, is cursor in first column?
        jz boardactiondone  ; yes
        
        call bb_field       ; no it is not
        jnz move_left       ; there is x/o in this field, just calculate new coords
        
        setcharattr 0       ; clear current field
        
        move_left:          ; new x coords
            sub [xpos],4
            sub [xboard],1
            jmp boardactiondone
        
    moveup:
        mov al,[ypos]       ; current y position on board, screen coords    
        cmp al,3            ; top bound detection, is cursor in first row?
        jz boardactiondone  ; yes
        
        call bb_field       ; no it is not
        jnz move_up         ; there is x/o in this field, just calculate new coords

        setcharattr 0       ; clear current field

        move_up:            ; new y coords      
            sub [ypos],2
            sub [yboard],1
            jmp boardactiondone
        
    movedown:
        mov al,[ypos]       ; current y position on board, screen coords    
        cmp al,7            ; bottom bound detection, is cursor in last row?
        jz boardactiondone  ; yes
        
        call bb_field       ; no it is not
        jnz move_down       ; there is x/o in this field, just calculate new coords
        
        setcharattr 0       ; clear current field
        
        move_down:          ; new y coords  
            add [ypos],2
            add [yboard],1      
            jmp boardactiondone
        
    space:  
        call bb_field       ; is field empty or taken?      
        jnz boardactiondone ; something is there
        
        mov [spacepressed],1
        mov al,[x_o]        ; insert x/o        
        mov [si],al         ; in big_board
        
        setcursor [xpos],[ypos]             
        setcharattr [playercolor]   
        mov ah,2            ; and show on the screen
        mov dl,al
        int 21h
        setcursor [xpos],[ypos] 
        jmp space1
;       switch_player:  
;           cmp [jogador_curr],49   ;1=x 2=o
;           jz switchtoplayer2
;       
;           sub [jogador_curr],1
;           mov [playercolor],0ah
;           mov [x_o], 88
;                   
;           jmp turn_inc
;               
;           switchtoplayer2:
;               add [jogador_curr],1
;               mov [playercolor],0dh
;               mov [x_o], 79
;                      
;           turn_inc:
;               ;mov [spacepressed],0  ;;???
;               inc [turnnumber]                    
            
    boardactiondone:            
        mov [spacepressed],0
    space1:     
;--- show char at new coords    
    mov si,offset big_board
    mov bh,[xboard]
    mov bl,[yboard]
    ;3*[yboard]+[xboard]
    xor ax,ax
    mov al,3
    mul bl
    add al,bh
    
    add si,ax
    xor ax,ax
    
    cmp [si],al
    jnz fieldtaken

    setcursor [xpos],[ypos] 
                
    setcharattr [playercolor]   
    mov ah,2            
    mov dl,[x_o]        
    int 21h

    fieldtaken:
        setcursor [xpos],[ypos] 
            
    endd:
    ret
boardaction endp

;--- clear screen ----------

clrscr proc
    mov ax,0600h
    mov cx,0h
    mov bx,0007h
    mov dx,184fh    
    
    int 10h
    ret
clrscr endp
    
;--- check winner ----------    
; op's procedure to see who won
    
check_winner proc
    xor bx, bx
    xor cx, cx
    xor dx, dx
    xor di, di
    lea di, big_board
    
    verifica_vencedor_linha1:               ; check_winner_line1
        cmp cx, 3
        je verifica_vencedor_coluna1        ; check_winner_column1
        push di
        
        mov al, [di]        
        cmp al, jogador_curr                ; player_curr
        jne proxima_linha1                  ; next_line1
        inc di
        
        mov al, [di]        
        cmp al, jogador_curr                ; player_curr
        jne proxima_linha1                  ; next_line1
        inc di
        
        mov al, [di]
        cmp al, jogador_curr                ; player_curr
        jne proxima_linha1                  ; next_line1
        inc di
    
    jmp ganhou_board1                       ; won_board1
    
    proxima_linha1:                         ; next_line1    
        pop di
        add di, 3                           ; move to next line
        inc cx
        jmp verifica_vencedor_linha1        ; check_winner_line1

    verifica_vencedor_coluna1:              ; check_winner_column1    
        xor bx, bx
        xor cx, cx
        sub di, 9                           ; reset big_board offset
    
    coluna_loop1:                           ; column_loop1
        cmp cx, 3
        je verifica_vencedor_diagonal1      ; check_winner_diagonal1
        push di
        
        mov al, [di]
        cmp al, jogador_curr                ; player_curr
        jne proxima_coluna1                 ; next_column1
        add di, 3
        
        mov al, [di]
        cmp al, jogador_curr                ; player_curr
        jne proxima_coluna1                 ; next_column1
        add di, 3
        
        mov al, [di]
        cmp al, jogador_curr                ; player_curr
        jne proxima_coluna1                 ; next_column1
        add di, 3
    
        jmp ganhou_board1                   ; won_board1

    proxima_coluna1:                        ; next_column1
        pop di
        inc di                              ; move to next column       
        inc cx
        jmp coluna_loop1                    ; column_loop1
    
    verifica_vencedor_diagonal1:            ; check_winner_diagonal1
        mov cx, 3
        sub di, 3                           ; reset big_board offset
    
        mov al, [di]
        cmp al, jogador_curr                ; player_curr
        jne diag21
        add di, 4
        mov al, [di]
        cmp al, jogador_curr                ; player_curr
        jne nao_ganhou1
        add di, 4
        mov al, [di]
        cmp al, jogador_curr                ; player_curr
        jne diag21_sub_di_8                 ; reset big_board offset
    
        jmp ganhou_board2
    
    diag21_sub_di_8:    
        sub di, 8                           ; row 1 column 3
    diag21:
        add di, 2       
        mov al, [di]
        cmp al, jogador_curr                ; player_curr
        jne nao_ganhou1                     ; didn't win1
        add di, 2
        mov al, [di]
        cmp al, jogador_curr                ; player_curr
        jne nao_ganhou1                     ; didn't win1
        add di, 2
        mov al, [di]
        cmp al, jogador_curr                ; player_curr
        jne nao_ganhou1                     ; didn't win1
    
        jmp ganhou_board2                   ; won_board1
    
    nao_ganhou1:                            ; didn't win1
        ret
    
    ganhou_board1:                          ; won_board1
        pop di
    ganhou_board2:      
        mov [winner],1  
        ret ;call exit
    
check_winner endp   
end start
© www.soinside.com 2019 - 2024. All rights reserved.