;**************************************** ; Elmar Kresse 19-INB-1 (2021) ; game.asm ; file contains source code for the ; basic functions of the game logic ; ; - conkf MACRO x_kord, y_kord ; - conkf_prog PROC FAR ; - game_logic PROC ; - check_won_value MACRO a, b, c ; - check_draw PROC ; - reset_player_data PROC ; - check_won PROC ; - reset_timerisr PROC ; - start_game PROC ;**************************************** conkf MACRO x_kord, y_kord ;MACRO for coordinates to field push dx push cx mov cx, x_kord mov dx, y_kord mov field, 0h call conkf_prog pop cx pop dx ENDM conkf_prog PROC FAR ;PROC for coordinates to field push ax push bx push cx push dx ;horizontal x cmp cx, 482 jg out_of_range cmp cx, 352 mov x_wert, 357 jnl x_3 cmp cx, 218 mov x_wert, 223 jnl x_2 cmp cx, 84 mov x_wert, 89 jnl x_1 jmp out_of_range x_3: mov ax, 2 jmp y_kordi x_2: mov ax, 1 jmp y_kordi x_1: mov ax, 0 y_kordi: ;vertical y cmp dx, 412 jg out_of_range cmp dx, 282 mov y_wert, 287 jnl y_3 cmp dx, 148 mov y_wert, 153 jnl y_2 cmp dx, 14 mov y_wert, 19 jnl y_1 jmp out_of_range y_3: mov bx, 6 jmp calc_field y_2: mov bx, 3 jmp calc_field y_1: mov bx, 0 calc_field: add ax, bx ;(A = ax) * (B = bx) = (goal = AX) mov field, ax jmp kord_final out_of_range: mov field, 10 ;not in range(0-8) 10 is set for later checks kord_final: pop dx pop cx pop bx pop ax ret conkf_prog ENDP game_logic PROC conkf x_wert, y_wert ;check valid field 0-8 cmp field, 0ah je end_game_logic ;Feld frei push ax push si mov si, field shl si, 1 cmp player1[si], 1 pop si pop ax je end_game_logic push ax push si mov si, field shl si, 1 cmp player2[si], 1 pop si pop ax je end_game_logic mov ax, spieler cmp ax, 0 je kreuz_spieler jne kreis_spieler kreuz_spieler: cross_draw x_wert, y_wert, 120 ;Sound PUSH AX BX CX DX MOV BX, OFFSET placeSound MOV CX, OFFSET placeSoundLength CALL playbeep POP DX CX BX AX mov spieler, 1 ;Spieler umschalten ;Geklicketes Feld belegen push ax push si mov si, field shl si, 1 mov player1[si], 1 pop si pop ax push cx mov cx, offset player1 call check_won pop cx cmp ax, 1 jne end_game_logic mov cx, 2 call reset_timerisr call start_programm kreis_spieler: ;Kreis zeichnen circle_draw x_wert, y_wert, 60 ;Sound PUSH AX BX CX DX MOV BX, OFFSET placeSound MOV CX, OFFSET placeSoundLength CALL playbeep POP DX CX BX AX mov spieler, 0 ;Spieler umschalten ;Geklicketes Feld belegen push ax push si mov si, field shl si, 1 mov player2[si], 1 pop si pop ax push cx mov cx, offset player2 call check_won pop cx cmp ax, 1 jne end_game_logic mov cx, 3 call reset_timerisr call start_programm end_game_logic: call check_draw ret game_logic ENDP check_won_value MACRO a, b, c push ax push bx mov bx, 0 mov ax, a; shl ax, 1 add bp, ax add bx, ds:[bp] mov bp, cx mov ax, b; shl ax, 1 add bp, ax add bx, ds:[bp] mov bp, cx mov ax, c; shl ax, 1 add bp, ax add bx, ds:[bp] mov bp, cx cmp bx, 3 pop bx pop ax je got_winner ENDM check_draw PROC ;Überprüfen ob Unentschieden push bx ;Counter ob alle Felder belegt sind push ax ;Zahlvariable für Shiften push cx ;Pointer für das Array des jeweiligen Spielers push dx ;Zählvariable für Schleifen push bp mov bx, 0 mov ax, 0 mov dx, 0 mov cx, offset player1 ;pointer for player1 player1_field_loop: mov ax, dx shl ax, 1 mov bp, cx add bp, ax add bx, ds:[bp] inc dx cmp dx, 9 jne player1_field_loop mov cx, offset player2 ;pointer for player2 mov dx, 0 player2_field_loop: mov ax, dx shl ax, 1 mov bp, cx add bp, ax add bx, ds:[bp] inc dx cmp dx, 9 jne player2_field_loop cmp bx, 9 pop bp pop dx pop cx pop ax pop bx je draw_end jmp check_draw_end draw_end: mov cx, 4 ; 4 = Unentschieden call reset_timerisr call start_programm check_draw_end: ret check_draw ENDP reset_player_data PROC push ax push si push bx ;Schleifen Zähler mov bx, 0 resetloop_player1: mov si, bx shl si, 1 mov player1[si], 0 inc bx cmp bx, 9 jne resetloop_player1 mov bx, 0 resetloop_player2: mov si, bx shl si, 1 mov player2[si], 0 inc bx cmp bx, 9 jne resetloop_player2 pop bx pop si pop ax ret reset_player_data ENDP check_won PROC push bp mov bp, cx ;vertical check_won_value 0, 3, 6 check_won_value 1, 4, 7 check_won_value 2, 5, 8 ;horizontal check_won_value 2, 1, 0 check_won_value 3, 4, 5 check_won_value 6, 7, 8 ;cross check_won_value 0, 4, 8 check_won_value 6, 4, 2 jmp ende_check_won got_winner: pop bp ;play gameover sound MOV BX, OFFSET gameOverSound MOV CX, gameOverSoundLength CALL playbeep mov ax, 1 ;var for save winner exists ret ende_check_won: pop bp mov ax, 0 ret check_won ENDP reset_timerisr PROC PUSH CX PUSH DS PUSH AX PUSH DX MOV AX, 251Ch ; Restore old user timer interrupt vector MOV DX, [CS:old_timer] MOV CX, [CS:old_segment] MOV DS, CX INT 21h POP DX POP AX POP DS POP CX ret reset_timerisr ENDP start_game PROC CLI mov ax,00h int 33h or ax,ax call reset_player_data ;Spieler Array reset mov ax,12h ;Videomodus int 10h call prepare_display mov ax, 1 ;Curser an int 33h ;Ersten Spieler setzten call prepare_mouse mov spieler, 0 call prepare_display STI ret start_game endp