org 100h
jmp start
s_size equ 7
snake dw s_size dup(0)
tail dw ?
left equ 4bh
right equ 4dh
up equ 48h
down equ 50h
cur_dir db right
wait_time dw 0
msg1 db " Snake game", 0dh,0ah,0ah
db " Yilani on oklari ile kontrol et.", 0dh,0ah,0ah
db " Duvarlara degersen yanarsin!!!", 0dh,0ah, 0ah
db " Esc programi sonlandirir.", 0dh,0ah,0ah,0ah
db " Baslamak icin bir tusa bas.$"
msg3 db "", 0dh,0ah, 0ah,0ah, 0ah,0ah,0ah, 0ah,0ah,0ah, 0ah,0ah,0ah, 0ah,0ah, 0ah, 0ah, 0ah,
db " !!GAME OVER!!", 0dh,0ah,0ah, 0ah, 0ah, 0ah,0ah, 0ah,0ah,
db " $"
start:
; print welcome message:
mov dx, offset msg1
mov ah, 9
int 21h
; wait for any key:
mov ah, 00h
int 16h
mov ax, 0xB800 ; Video memory segment
mov es, ax ; Set ES segment to video memory
es: mov [09b4h],'?'
es: mov [0848h],'0'
es: mov [06b0h],'0'
es: mov [01E8h],'0'
; hide text cursor:
mov ah, 1
mov ch, 2bh
mov cl, 0bh
int 10h
game_loop:
; === select first video page
mov al, 0
mov ah, 05h
int 10h
mov dx, snake[0]
; set cursor at dl,dh
mov ah, 02h
int 10h
; print 'o' at the location:
mov al, 'o'
mov ah, 09h
mov bl, 0eh
mov cx, 1
int 10h
; === keep the tail:
mov ax, snake[s_size * 2 - 2]
mov tail, ax
call move_snake
; === hide old tail:
mov dx, tail
; set cursor at dl,dh
mov ah, 02h
int 10h
; print '.' at the old location:
mov al, ' '
mov ah, 09h
mov bl, 0eh
mov cx, 1
int 10h
check_for_key:
; === check for player commands:
mov ah, 01h
int 16h
jz no_key
mov ah, 00h
int 16h
cmp al, 1bh ; esc - key?
je stop_game ;
mov cur_dir, ah
no_key:
; === wait a few moments here:
; get number of clock ticks
; (about 18 per second)
; since midnight into cx:dx
mov ah, 00h
int 1ah
cmp dx, wait_time
jb check_for_key
add dx, 4
mov wait_time, dx
; === eternal game loop:
jmp game_loop
stop_game:
; show cursor back:
mov ah, 1
mov ch, 0bh
mov cl, 0bh
int 10h
ret
move_snake proc near
; set es to bios info segment:
mov ax, 40h
mov es, ax
; point di to tail
mov di, s_size * 2 - 2
; move all body parts
; (last one simply goes away)
mov cx, s_size-1
move_array:
mov ax, snake[di-2]
mov snake[di], ax
sub di, 2
loop move_array
cmp cur_dir, left
je move_left
cmp cur_dir, right
je move_right
cmp cur_dir, up
je move_up
cmp cur_dir, down
je move_down
jmp stop_move ; no direction.
move_left:
mov al, b.snake[0]
dec al
mov b.snake[0], al
cmp al, -1
jne stop_move
mov al, es:[4ah] ; col number.
dec al
call game_over ; return to right.
jmp stop_move
move_right:
mov al, b.snake[0]
inc al
mov b.snake[0], al
cmp al, es:[09b4h]
cmp al, es:[4ah] ; col number.
jb stop_move
call game_over ; return to left.
jmp stop_move
move_up:
mov al, b.snake[1]
dec al
mov b.snake[1], al
cmp al, -1
jne stop_move
mov al, es:[84h] ; row number -1.
call game_over ; return to bottom.
jmp stop_move
move_down:
mov al, b.snake[1]
inc al
mov b.snake[1], al
cmp al, es:[84h] ; row number -1.
jbe stop_move
call game_over ; return to top.
jmp stop_move
stop_move:
ret
grow_snake:
ret
game_over:
mov dx, offset msg3
mov ah, 9
int 21h
; wait for any key:
mov ah, 00h
int 16h
move_snake endp
I tried to grow snake when it reaches to these memory locations:
es: mov [09b4h],'?'
es: mov [0848h],'0'
es: mov [06b0h],'0'
es: mov [01E8h],'0'
but i couldnt get it done. My first plan was check it in stop_game and call grow_snake in there but i didnt work no matter how i tried. But couldnt do anything about grow_snake part triend to inc s_size but it also doesnt work.
How am i gonna check if snake reaches the memory location that i printed something and gro accordingly?
Thank you.
Update
If You don't mind I wrote CheckFood proc
after printing snake's head on screen. Which translates head's X Y coords to offset in mem and search if there is same address in array targetInMem
.
org 100h jmp start s_size equ 7 snake dw s_size dup(0) tail dw ? left equ 4bh right equ 4dh up equ 48h down equ 50h targetInMem dw 09b4h,0848h,06b0h,01E8h cur_dir db right wait_time dw 0 Food1 db "Food 1 ", 0dh,0ah,'$' Food2 db "Food 2 ", 0dh,0ah,'$' Food3 db "Food 3 ", 0dh,0ah,'$' questMark db "Question mark", 0dh,0ah,'$' msg1 db " Snake game",0dh,0ah,0ah db " Yilani on oklari ile kontrolet.",0dh,0ah,0ah db " Duvarlara degersen yanarsin!!!", 0dh,0ah, 0ah db " Esc programi sonlandirir.", 0dh,0ah,0ah,0ah db " Baslamak icin bir tusa bas.$" msg3 db "", 0dh,0ah, 0ah,0ah, 0ah,0ah,0ah, 0ah,0ah,0ah, 0ah,0ah,0ah, db " !!GAME OVER!!", 0dh, 0ah, db 0ah, 0ah, 0ah, 0ah,0ah, 0ah,0ah," $" start: mov ax,0003h int 10h ; print welcome message: mov dx, offset msg1 mov ah, 9 int 21h ; wait for any key: mov ah, 00h int 16h mov ax, 0xB800 ; Video memory segment mov es, ax ; Set ES segment to video memory es: mov [09b4h],'?' es: mov [0848h],'1' es: mov [06b0h],'2' es: mov [01E8h],'3' ; hide text cursor: mov ah, 1 mov ch, 2bh mov cl, 0bh int 10h game_loop: ; === select first video page mov al, 0 mov ah, 05h int 10h mov dx, snake[0] ; set cursor at dl,dh mov ah, 02h int 10h ; print 'o' at the location: mov al, 'o' mov ah, 09h mov bl, 0eh mov cx, 1 int 10h call CheckFood ; === keep the tail: mov ax, snake[s_size * 2 - 2] mov tail, ax call move_snake ; === hide old tail: mov dx, tail ; set cursor at dl,dh mov ah, 02h int 10h ; print '.' at the old location: mov al, ' ' mov ah, 09h mov bl, 0eh mov cx, 1 int 10h check_for_key: ; === check for player commands: mov ah, 01h int 16h jz no_key mov ah, 00h int 16h cmp al, 1bh ; esc - key? je stop_game ; mov cur_dir, ah no_key: ; === wait a few moments here: ; get number of clock ticks ; (about 18 per second) ; since midnight into cx:dx mov ah, 00h int 1ah cmp dx, wait_time jb check_for_key add dx, 4 mov wait_time, dx ; === eternal game loop: jmp game_loop stop_game: ; show cursor back: mov ah, 1 mov ch, 0bh mov cl, 0bh int 10h ret move_snake proc near ; set es to bios info segment: mov ax, 40h mov es, ax ; point di to tail mov di, s_size * 2 - 2 ; move all body parts ; (last one simply goes away) mov cx, s_size-1 move_array: mov ax, snake[di-2] mov snake[di], ax sub di, 2 loop move_array cmp cur_dir, left je move_left cmp cur_dir, right je move_right cmp cur_dir, up je move_up cmp cur_dir, down je move_down jmp stop_move ; no direction. move_left: mov al, b.snake[0] dec al mov b.snake[0], al cmp al, -1 jne stop_move mov al, es:[4ah] ; col number. dec al call game_over ; return to right. jmp stop_move move_right: mov al, b.snake[0] inc al mov b.snake[0], al cmp al, es:[09b4h] cmp al, es:[4ah] ; col number. jb stop_move call game_over ; return to left. jmp stop_move move_up: mov al, b.snake[1] dec al mov b.snake[1], al cmp al, -1 jne stop_move mov al, es:[84h] ; row number -1. call game_over ; return to bottom. jmp stop_move move_down: mov al, b.snake[1] inc al mov b.snake[1], al cmp al, es:[84h] ; row number -1. jbe stop_move call game_over ; return to top. jmp stop_move stop_move: ret grow_snake: ret CheckFood: pusha xor ax,ax ;calculate head position mov al,dh;[yPos] mov cl,80 mul cl xor cx,cx mov cl,dl;[xPos] add ax,cx ; ax offset in mem mov cx,2 mul cx mov bx, offset targetInMem mov cx,4 push dx MemSearch: ;search array, what snake eat mov dx,[bx] cmp dx,ax jz PrintMsg add bx,2 loop MemSearch jmp NoFood PrintMsg: ; set cursor at dl,dh mov ah, 2 mov bh,0 mov dx, 1010h int 10h cmp cx,4 jz msgFood1 cmp cx,3 jz msgFood2 cmp cx,2 jz msgFood3 cmp cx,1 jz qMark jmp NoFood msgFood1: mov dx, offset questMark mov ah, 9 int 21h jmp NoFood msgFood2: mov dx, offset Food1 mov ah, 9 int 21h jmp NoFood msgFood3: mov dx, offset Food2 mov ah, 9 int 21h jmp NoFood qMark: mov dx, offset Food3 mov ah, 9 int 21h NoFood: pop dx popa ret game_over: mov dx, offset msg3 mov ah, 9 int 21h ; wait for any key: mov ah, 00h int 16h move_snake endp
I don't know if this will be Your answer. This is just an example. Screen coords translate to video memory offset.
xor ax,ax ;calculate head position mov al,[yPos] mov cl,80 mul cl xor cx,cx mov cl,[xPos] add ax,cx mov cx,2 mul cx mov cx,[targetInMem] cmp cx,ax jz game_over
And Example below
org 100h jmp start s_size equ 7 snake dw s_size dup(0) tail dw ? Head db 79 KeyNumber db ? xPos db 2 ;cursor x position on screen yPos db 2 ;cursor y position on screen targetX db 13 targetY db 3 targetInMem dw 01fah msg1 db "Use arrows. $" msg2 db "Target reached!$" msg3 db "!!GAME OVER!!$" ;;;Macros SetCharAttrib MACRO char,attr push bx push ax push dx push cx mov ah,9 mov al,char mov cx,1 ;mov dl,y ;mov dh,x mov bh,0 mov bl,attr int 10h pop cx pop dx pop ax pop bx ENDM SetCursor MACRO x,y push bx push ax push dx push cx mov ah,02h mov dl,x mov dh,y mov bh, 00h int 10h pop cx pop dx pop ax pop bx ENDM start: mov ax,0003h int 10h mov ax, 0xB800 ; Video memory segment mov es, ax ; Set ES segment to video memory es: mov [01fah],'X' ;506 ; print welcome message: mov dx, offset msg1 mov ah, 9 int 21h ; hide text cursor: mov ah, 1 mov ch, 2bh mov cl, 0bh int 10h ;set cursor position SetCursor [xPos],[yPos] SetCharAttrib 79,14 game_loop: ; wait for any key: call CheckKey cmp al,27 ;Esc, exit program jz stop_game ;SetCursor [xPos]+12,[yPos] call BoardAction SetCharAttrib 0,0 SetCursor [xPos],[yPos] SetCharAttrib 79,14 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Translate from screen coords ;;;; to video mem adress xor ax,ax ;calculate head position mov al,[yPos] mov cl,80 mul cl xor cx,cx mov cl,[xPos] add ax,cx mov cx,2 mul cx mov cx,[targetInMem] cmp cx,ax jz game_over ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; === eternal game loop: jmp game_loop stop_game: ; show cursor back: mov ah, 1 mov ch, 0bh mov cl, 0bh int 10h jmp game_over CheckKey Proc mov ah,0 int 16h cmp al,0 jz Extended jmp Normal Extended: mov [KeyNumber], ah mov al,ah jmp NextTurn Normal: mov [KeyNumber], al NextTurn: ret CheckKey Endp 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 jmp BoardEdge moveRight: mov al,[xPos] cmp al,15 jz BoardEdge add [xPos],1 jmp BoardEdge moveLeft: mov al,[xPos] cmp al,2 jz BoardEdge sub [xPos],1 jmp BoardEdge moveUp: mov al,[yPos] cmp al,1 jz BoardEdge sub [yPos],1 jmp BoardEdge moveDown: mov al,[yPos] cmp al,5 jz BoardEdge add [yPos],1 BoardEdge: ret BoardAction Endp game_over: mov dx, offset msg2 mov ah, 9 int 21h mov ax, 4c00h int 21h