Add initial source files for Tic-Tac-Toe game implementation

Signed-off-by: Elmar Kresse <elmar.kresse@stud.htwk-leipzig.de>
This commit is contained in:
Elmar Kresse
2025-07-03 15:53:46 +02:00
commit 2a94dfb8d5
10 changed files with 1121 additions and 0 deletions

401
game.asm Normal file
View File

@ -0,0 +1,401 @@
;****************************************
; 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