Алгоритм программы
В начале программы идет инициализация данных: задаются координаты зайца и волка,их цвет. Также происходит прорисовка разделительной линии, время работы программы задается 0. После нажатия клавиши происходит получение ее кода и, в зависимости от того, является ли она управляющей, либо происходит перемещение волка, либо ничего не происходит. Кролик начинает свое движения в наилучшем для него направлении осле просчета всех возможных вариантов. Когда хищник и его жертва оказываются на соседних клетках, игра заканчивается:волк «съедает кролика», отсчет времени прекращается и после нажатия клавиши игровой экран закрывается.
На рисунке 1 приведена блок-схема работы программы.

Рисунок 1 – Блок схема работы программы
Текст программы
;"облик" переменных
addresbuf equ 0b800h ;адрес текстовой видеопамяти
space equ 0000000000100000b ;пробел на черным фоне
sprt equ 0000111111000100b ;белый знак '-' на черным фоне
krolik equ 0000111110110010b ;живой заяц
deadkrol equ 0000110010110010b ;мёртвый заяц
wolfy equ 0000100110110010b ;волк
codesg segment para 'code'
assume ss:codesg,ds:codesg,cs:codesg
org 100h
begin: jmp main
; объявление переменных
krol dw ? ;координаты зайца
wolf dw ? ;координаты волка
step db ? ;флаг, указывающий, что сделан ход
exit db ? ;флаг конца игры
time dw ? ;для хранения времени
; управляющая функция
main proc near
tostart:
call init
q0:
call info ;вывод времени
call getchar ;проверим нажатия клавиш
call prepare ;обработка нажатой клавиши
call wolf_hod ;ход волка
call krol_hod ;ход зайца
call extest
cmp [exit],1
je toexit
jmp q0
toexit: ;ожидаем нажатия 1-го символа
mov ah,1
int 21h
ret
main endp
;инициализация
init proc
push addresbuf
pop es ;поместим в es адрес текстового видеобуфера
mov ah,2 ;поместим курсор
mov dh,25 ;на 25 строку
int 10h ;т.е. спрячем его
call setscreen ;очистим экран
call liner ;проводим разделительную линию
mov [krol],0b13h ;начальные координаты зайца
mov [wolf],0b3bh ;начальные координаты волка
call drawkrolik ;нарисовать зайца
call drawwolf ;нарисовать волка
mov [exit],0 ;не конец игры
mov ah,0
int 1ah ;получим текущее время
mov [time],dx ;сохраним его
ret
init endp
; очистка экрана
setscreen proc
mov cx,2000 ;80 * 25 = 2000
mov si,0
mov ax,space ;очищаем пробелами
a0:
mov es:[si],ax ;поместим в видеобуфер
add si,2 ;к следующему символу
loop a0
ret
setscreen endp
;разделительная линия
liner proc
mov cx,80 ;линия во всю строку
mov si,3680 ;80 * 23 * 2 = 3680
mov ax,sprt
b0:
mov es:[si],ax ;поместим в видеобуфер
add si,2 ;к следующему символу
loop b0
ret
liner endp
; рисует символ
draw proc ;координаты передаются в bx
;символ с атрибутами передаётся в ax
call trans ;рассчитать положение в видеобуфере
mov es:[bx],ax ;нарисовать символ
ret
draw endp
;рисует живого зайца
drawkrolik proc
mov ax,krolik ;вид живого зайца
mov bx,[krol] ;получить координаты
call draw ;нарисовать
ret
drawkrolik endp
; рисует мёртвого зайца
drawdeadkrol proc
mov ax,deadkrol ;вид мёртвого зайца
mov bx,[krol] ;получить координаты
call draw ;нарисовать
ret
drawdeadkrol endp
; рисует волка
drawwolf proc
mov ax,wolfy ;вид волка
mov bx,[wolf] ;получить координаты
call draw ;нарисовать
ret
drawwolf endp
; очищает позицию
clear proc ;координаты передаются в bx
push ax
mov ax,space ;пробел
call draw ;нарисовать
pop ax
ret
clear endp
; очищает позицию зайца
clearkrol proc
mov bx,[krol]
call clear ;очистить
ret
clearkrol endp
;очищает позицию волка
clearwolf proc
mov bx,[wolf]
call clear ;очистить
ret
clearwolf endp
; перевод координат в положение в текстовом видеобуфере
trans proc ;координаты передаются в bx, bl - x, bh - y
push ax
mov al,80
mul bh ;80 * y, результат умножения в ax
mov bh,0 ;теперь в bx содержится значение x
add bx,ax ;80 * y + x
shl bx,1 ;(80 * y + x) * 2
pop ax
ret ;положение в видеобуфере возвращается в bx
trans endp
; получение кода нажатой клавиши
getchar proc
mov ah,1
int 16h ;проверим, есть ли в буфере символ
jz c0 ;если нет, то уйдём
mov ah,0
int 16h ;если есть, то считаем его
c0:
ret ;код нажатой клавиши сохраняется в ax
getchar endp
;обработка нажатой клавиши
prepare proc
mov [step],0 ;сбрасываем флаг
cmp ax,4800h ;клавиша «Вверх»?
jne testdn ;если нет, перейти к проверке «Вниз»
mov bx,0ff00h ;16h = 22
jmp tostep
testdn:
cmp ax,5000h ;клавиша «Вниз»?
jne testlf ;если нет, перейти к проверке «Влево»
mov bx,0100h ;18h = 24
jmp tostep
testlf:
cmp ax,4b00h ;клавиша «Влево»?
jne testrt ;если нет, перейти к проверке «Вправо»
mov bx,00ffh ;4fh = 79
jmp tostep
testrt:
cmp ax,4d00h ;клавиша «Вправо»?
jne tonoth ;если нет, эта клавиша не повлияет на работу программы
mov bx,0001h ;51h = 81
tostep:
mov [step],1 ;если нажата клавиша управления, устанавливаем флаг
tonoth:
ret
prepare endp
; ход волка
wolf_hod proc
cmp [step],1
jne d0
mov ax,[wolf]
add al,bl
cmp al,0ffh ;если al = -1
je d0
cmp al,50h ;если al = 80
je d0
add ah,bh
cmp ah,0ffh ;если ah = -1
je d0
cmp ah,17h ;если ah = 23
je d0
call clearwolf
mov [wolf],ax
call drawwolf
jmp d1
d0:
mov [step],0
d1:
ret
wolf_hod endp
;ход зайца
krol_hod proc
cmp [step],1
jne g4
mov ax,[krol]
mov cx,ax
call getdist ;найдём текущее расстояние между З и В
mov si,ax ;сохраним его в si
mov ax,[krol]
add al,0ffh ;если пойдём влево
mov dx,ax ;сохраним полученные координаты
cmp al,0ffh ;если al = -1
je g0
call getdist ;найдём предполагаемое расстояние
cmp ax,si
jbe g0 ;если получилось ещё меньше, проверять дальше
mov si,ax ;а если нет, запомнить расстояние
mov cx,dx ; и координаты
g0:
mov ax,[krol]
add al,01h ;если пойдём вправо
mov dx,ax ;сохраним полученные координаты
cmp al,50h ;если al = 80
je g1
call getdist ;найдём предполагаемое расстояние
cmp ax,si
jbe g1 ;если получилось ещё меньше, проверять дальше
mov si,ax ;а если нет, запомнить расстояние
mov cx,dx ; и координаты
g1:
mov ax,[krol]
add ah,0ffh ;если пойдём вверх
mov dx,ax ;сохраним полученные координаты
cmp ah,0ffh ;если ah = -1
je g2
call getdist ;найдём предполагаемое расстояние
cmp ax,si
jbe g2 ;если получилось еще меньше, проверять дальше
mov si,ax ;а если нет, запомнить расстояние
mov cx,dx ; и координаты
g2:
mov ax,[krol]
add ah,01h ;если пойдём вниз
mov dx,ax ;сохраним полученные координаты
cmp ah,17h ;если ah = 23
je g3
call getdist ;найдём предполагаемое расстояние
cmp ax,si
jbe g3 ;если получилось ещё меньше, проверять дальше
mov si,ax ;а если нет, запомнить расстояние
mov cx,dx ; и координаты
g3:
call clearkrol ;стереть зайца
mov [krol],cx ;сохранить новые координаты
call drawkrolik ;по ним нарисовать нового зайца
g4:
mov [step],0
ret
krol_hod endp
;определение расстояния между зайцем и волком
getdist proc ;в ax передаётся предполагаемая координата зайца
mov bx,[wolf] ;получение координат волка
;найдём расстояние между волком и зайцем по x
cmp al,bl
ja f0 ;если al > bl
xchg al,bl
f0:
sub al,bl
;найдём расстояние между волком и зайцем по y
cmp ah,bh
ja f1 ;если ah > bh
xchg ah,bh
f1:
sub ah,bh ;рассчитаем количество шагов, между зайцем и вол-ком
add al,ah
mov ah,0
dec ax
ret ;расстояние возвращается в ax
getdist endp
; вывод игрового времени
info proc
mov ah,0
int 1ah ;получим текущее время
sub dx,[time] ;найдём разницу
mov ax,dx ;напечатаем её
mov dx,0
mov bx,18
div bx
mov si,10 ;делим на 10
mov cx,0 ;счёт чисел помещённых в стек
h0:
mov dx,0
div si ;частное в ax, остаток в dx
push dx ;поместить 1 цифру в стек
inc cx
cmp ax,0 ;сравнение ax с 0
jne h0
mov bl,0
mov bh,24
call trans
h1:
pop dx ;взять цифры в обратном порядке
add dl,'0'
mov dh,00001111b ;белый цвет на чёрном фоне
add bx,2
mov es:[bx],dx
loop h1
ret
info endp
; проверка на конец игры
extest proc
mov ax,[wolf]
cmp ax,[krol]
jne x0
call drawdeadkrol
mov [exit],1
x0:
ret ;расстояние возвращается в ax
extest endp
codesg ends
end begin
