.model small .data .stack 100h .386 .code .startup ideal model small assume cs:@code, ds:@code; codeseg P486 org 100h Proc Main mov ax,cs mov ds,ax mov ax, 0b800h mov es, ax ;-=-=[ Init Seed]=-=- mov ah,2ch int 21h mov [Seed],dx ;-=-=[ CLS ]=-=- mov ax,0720h ; Цвет 07h – белый, Символ 20h – ” ” mov cx,45*80 ;45 строчек по 80 столбцов sub di,di ;с начала экрана ­ es:0000h rep stosw ;очистить экран ;-=-=[ Title ]=-=- mov ah,02h sub bx,bx mov dx,001Dh int 10h mov ah,09h mov dx,offset Mess1 int 21h ;-=-=[ Batte Fields]=-=- call InitBattleData mov di, 0338h call DrawField mov di, 0384h call DrawField mov si, offset Fields mov si, offset Fields+144 call ComputerPlaceShips mov si, offset Fields mov di, 0478h call DrawBattleData mov si, offset Fields+144 mov di, 04C4h call DrawBattleData mov si, offset Fields mov di, 0478h call HumanPlaceShips mov cx,100 TestLoop: mov si, offset Fields mov ax,10 call Random mov bh,al mov ax,10 call Random mov bl,al push cx call IsShipDestroyed mov si, offset Fields mov di, 0478h call DrawBattleData sub ax,ax pop cx loop TestLoop ;-=-=[ Any Key & Exit ]=-=- sub ax,ax int 16h mov ax,4c00h int 21h Endp ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-[ DrawField ]-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Proc DrawField ;Рисование пустого поля боя ;Вход: DI – Адрес на экране, где нужно рисовать ;-=-=[Прорисовка горизонтальных цифр ]=-=- mov ax, 0730h ;Цвет 7 – белый, Символ 30h - "0" mov cx,10 DFLoop1: stosw add di,2 inc al loop DFLoop1 ;-=-=[ Прорисовка вертикальных букв ]=-=- add di, 118 push di add di,158 mov ax,0741h ;Цвет 7 – белый, символ 41h - "A" mov cx,10 DFLoop2: stosw add di,318 inc al loop DFLoop2 ;-=-=[ Прорисовка поля боя из таблицы]=-=- pop di mov si, offset Cell call DrawFieldLine mov cx, 9 DFLoop3: push si call DrawFieldLine call DrawFieldLine pop si loop DFLoop3 add si,10 call DrawFieldLine call DrawFieldLine ret Endp ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-[ DrawFieldLine ]-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Proc DrawFieldLine ; Рисование одной линии боя, из таблицы ; Вход es:di – экран, si – таблица для линии push eax push cx mov ah, 17h ; Цвет 17h – белые символы, синий фон lodsb stosw lodsb push ax lodsb push ax pop eax mov cx,9 rep stosd lodsb stosw lodsb stosw add di,118 pop cx pop eax ret Endp ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-[ InitBattleData ]-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Proc InitBattleData mov di,offset Fields ; Смещение данных боя push es ; mov ax,cs ; В es mov es,ax ; Сегмент кода (cs). sub ax,ax ; 144 раза mov cx,144 ; по 2 байта rep stosw ; заполнить 0 pop es ret Endp ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-[ DrawBattleData ]-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Proc DrawBattleData ; Вход es:di – экран, si – данные боя add si,13 mov ch,10 DBDLoop1: mov cl,10 DBDLoop2: lodsb ; al – данные из клетки боя ; 7 – Был ли реальный выстрел по клетке ; 6 - Был ли виртуальный выстрел по клетке ; 5 – Показывать ли клетку, если по ней не стреляли ; 012 – Содержимое клетки: 0 – вода, 1, 2, 3, 4 – палуба корабля mov ah,"±" test al,16 jnz DBDCont1 mov ah,' ' test al,160 ; Бит 7 и 5, если ни один не установлен jz DBDCont1 ; Не показывать содержимое клетки test al,7 jnz DBDShip ;-=-=[ Вода ]=-=- DBDWater: test al,128 jz DBDCont1 mov ah,'' jmp DBDCont1 ;-=-=[ Корабль ]=-=- DBDShip: mov ah,'Ы' test al,128 jz DBDCont1 mov ah,' ' DBDCont1: mov al,ah stosb add di,3 dec cl jnz DBDLoop2 inc si inc si add di,280 dec ch jnz DBDLoop1 ret Endp ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-[ CanPlaceShip ]-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Proc CanPlaceShip ; Проверка, можно ли поместить корабль по заданным координатам ; Вход: bl – X координата (0-9), bh – Y координата (0-9) ; ch –Направление корабля (0-гориз, не 0 - верт), cl – длинна корабля (1-4) ; si – Адрес массива с полем боя ; Выход: al (0- можно, 1 – не умещается на поле, 2 – мешает другой корабль) mov ax,0a00h ;Размер поля and cl,7 sub ah,cl ;‚Вычесть длину корабля and ch,1 jz CPSHoriz ;-=-=[ Корабль вертикально]=-=- cmp ah,bh ; Вычесть координату Y jb CPSRet1 ; Перейти, если корабль не умещается mov ch,cl ; Высота ограничивающего прямоугольника add ch,2 ; на два больше длинны корабля mov cl,3 ; Ширина ограничивающего прямоугольника-3 jmp CPSCont1 ;-=-=[Вход если корабль не умещается]=-=- CPSRet1: mov al,1 ; Вернуть 1, если корабль не умещается на поле ret ; Возврат ;-=-=[Корабль горизонтально]=-=- CPSHoriz: cmp ah,bl ; Вычесть координату Y jb CPSRet1 ; Перейти, если корабль не умещается add cl,2 mov ch,3 CPSCont1: call CalcBattleAddr sub si, 13 CPSLoop2: push si ; Проверка позиций вокруг и внутри push cx ; корабля на наличие других кораблей sub ch,ch ; CPSLoop1: lodsb and al,7 jnz CPSRet2 loop CPSLoop1 pop cx pop si add si,12 dec ch jnz CPSLoop2 sub al,al ; Вернуть 0, если кругом только вода ret ; CPSRet2: pop cx ; Вернуть 2, если pop si ; есть другой корабль рядом mov al,2 ret Endp ;-=-=-=-=-=-=-=-=-=-=-=-=-=-[ CalcBattleAddr ]-=-=-=-=-=-=-=-=-=-=-=-=-=- Proc CalcBattleAddr mov ax, 12 ; Y*12 mul bh add al, bl ; +X add ax, 13 add si, ax ; Адрес=Начальный+(Y+1)*12+(X+1) ret Endp ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-[ PlaceShip ]-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Proc PlaceShip ; Поместить корабль по заданным координатам ; Вход: bl – X координата (0-9), bh – Y координата (0-9), ; ch - Направление корабля (0-гориз, не 0 - верт) ; cl - длинна корабля (1-4) + видимость его (5 bit) ; si - Адрес массива с полем боя call CalcBattleAddr mov al,cl and cl,7 mov bx,1 ; Горизонтальный корабль and ch,ch mov ch,bh jz PSCont1 mov bx,12 ; Вертикальный корабль PSCont1: mov [ds:si],al ; Поместить палубу! add si,bx loop PSCont1 ret Endp ;-=-=-=-=-=-=-=-=-=-=-=-=-=-[ PlaceShipInRandomPosition ]-=-=-=-=-=-=-=-=-=-=-=-=-=- Proc PlaceShipInRandomPosition ; Помещает корабль указанной длинны в случайную позицию ; В случае невозможности поместить корабль – гарантированное зависание! ; Вход: cl - длинна корабля (1-4) + видимость его (5 bit) ; si - Адрес массива с полем боя PSIRPLoop: mov ax,10 call Random mov bl,al mov ax,10 call Random mov bh,al mov ax,256 call Random mov ch,al and ch,1 push bx cx si and cl,7 call CanPlaceShip pop si cx bx and al,al jnz PSIRPLoop or cl,32 ; RemoveIt!!!!!!!! [ Только для откладки!!!] jmp PlaceShip Endp ;-=-=-=-=-=-=-=-=-=-=-=-=-=-[ ComputerPlaceShips ]-=-=-=-=-=-=-=-=-=-=-=-=-=- Proc ComputerPlaceShips ; Размещение всех кораблей компьютером ; ;Вход si - Адрес массива с полем боя mov dx,si mov cl,4 call PlaceShipInRandomPosition mov cl,3 mov si,dx call PlaceShipInRandomPosition mov cl,3 mov si,dx call PlaceShipInRandomPosition mov cl,2 mov si,dx call PlaceShipInRandomPosition mov cl,2 mov si,dx call PlaceShipInRandomPosition mov cl,2 mov si,dx call PlaceShipInRandomPosition mov cl,1 mov si,dx call PlaceShipInRandomPosition mov cl,1 mov si,dx call PlaceShipInRandomPosition mov cl,1 mov si,dx call PlaceShipInRandomPosition mov cl,1 mov si,dx jmp PlaceShipInRandomPosition Endp ;-=-=-=-=-=-=-=-=-=-=-=-=-=-[ HumanDrawShip ]-=-=-=-=-=-=-=-=-=-=-=-=-=- Proc HumanDrawShip ; Нарисовать корабль по заданным координатам нормальным, если можно поставить его тут, и поврежденным, если нельзя ;Вход: bl – Х координата (0-9), bh - Y координата (0-9), ; ch – направление корабля (0-гориз, не 0-верт) ; cl – длина корабля (1-4) + видимость его ҐЈ® (bit 5) ; si - Ђ¤аҐб ¬ ббЁў б Ї®«Ґ¬ Ў®п ; di - Ђ¤аҐб ў нЄа ­Ґ ; ax - Ђ¤аҐб ўаҐ¬Ґ­­®Ј® ЎгдҐа (а §¬Ґа®¬ 100 Ў ©в) push es ax di cx ; сохранить все mov di,ax ; скопировать текущее состояние поля mov cx,cs ; в буфер mov es,cx mov cx,72 rep movsw pop cx di push cx bx and cl,7 mov si,ax ; Проверить можно ли поместить корабль call CanPlaceShip ; по заданным координатам? pop bx cx or cl,32 ; показываемый test al,al jz HDSNormal or cl,16 ; взорванный HDSNormal: pop si push si call PlaceShip ; поместить корабль во временный буфер pop si es jmp DrawBattleData ; изобразить временный буфер на экране Endp ;-=-=-=-=-=-=-=-=-=-=-=-=-=-[ HumanPlaceOneShip ]-=-=-=-=-=-=-=-=-=-=-=-=-=- Proc HumanPlaceOneShip ; постановка корабля человеком вручную, с управлением от клавиатуры ;вход si-адрес массива , di - экран ­, cl – количество палуб sub ch,ch sub bx,bx PHOSLoop1: call HumanRedrawAll sub ax,ax int 16h cmp ax,011bh ; Esc – выход моментально! jnz HPOSCont1 mov ax,4c00h int 21h HPOSCont1: cmp ax,04b00h ; стрелка влево jnz HPOSCont2 sub bl,1 adc bl,0 jmp PHOSLoop1 HPOSCont2: cmp ax,04d00h ; стрелка вправо jnz HPOSCont3 cmp bl,9 jae PHOSLoop1 push bx cx si inc bl sub ax,ax call CanPlaceShip pop si cx bx and al,1 jnz PHOSLoop1 inc bl jmp PHOSLoop1 HPOSCont3: cmp ax,04800h ; стрелка вверх jnz HPOSCont4 sub bh,1 adc bh,0 jmp PHOSLoop1 HPOSCont4: cmp ax,05000h ; стрелка вниз jnz HPOSCont5 cmp bh,9 jae PHOSLoop1 push bx cx si inc bh sub ax,ax call CanPlaceShip pop si cx bx and al,1 jnz PHOSLoop1 inc bh jmp PHOSLoop1 HPOSCont5: cmp ax,03920h ; пробел – переворот судна jnz HPOSCont6 push bx cx si xor ch,1 call CanPlaceShip pop si cx bx and al,1 jnz PHOSLoop1 xor ch,1 jmp PHOSLoop1 HPOSCont6: cmp ax,01c0dh ; Enter – постановка судна jnz HPOSCont7 push bx cx si call CanPlaceShip pop si cx bx and al,al jnz PHOSLoop1 jmp PlaceShip HPOSCont7: cmp ax,01372h ; R – поставить судно в случайное место jnz PHOSLoop1 jmp PlaceShipInRandomPosition endp ;-=-=-=-=-=-=-=-=-=-=-=-=-=-[ HumanRedrawAll ]-=-=-=-=-=-=-=-=-=-=-=-=-=- Proc HumanRedrawAll ; перерисовка временного буфера pusha mov ax, offset Fields+288 call HumanDrawShip popa ret Endp ;-=-=-=-=-=-=-=-=-=-=-=-=-=-[ HumanPlaceShips ]-=-=-=-=-=-=-=-=-=-=-=-=-=- Proc HumanPlaceShips ; размещение всех кораблей человеком mov dx,si mov cl,4+32 call HumanPlaceOneShip mov cl,3+32 mov si,dx call HumanPlaceOneShip mov cl,3+32 mov si,dx call HumanPlaceOneShip mov cl,2+32 mov si,dx call HumanPlaceOneShip mov cl,2+32 mov si,dx call HumanPlaceOneShip mov cl,2+32 mov si,dx call HumanPlaceOneShip mov cl,1+32 mov si,dx call HumanPlaceOneShip mov cl,1+32 mov si,dx call HumanPlaceOneShip mov cl,1+32 mov si,dx call HumanPlaceOneShip mov cl,1+32 mov si,dx jmp HumanPlaceOneShip Endp ;-=-=-=-=-=-=-=-=-=-=-=-=-=-[ MakeHit ]-=-=-=-=-=-=-=-=-=-=-=-=-=- Proc MakeHit ; Выстрел по указанным координатам ; Вход: bl – Х координата (0-9), bh - Y координата (0-9), ; si – адрес массива с полем боя ;Выход: al - 1-4 - попал, 0 - промазал call CalcBattleAddr mov al,[ds:si] or al,128+64 ; выстрел по клетке (реальный и виртуальный) mov [byte ds:si],al and al,7 jnz MHCont1 ret MHCont1: sub si,13 mov dx,bx xor dl,dh dec bh dec bl mov cx,0303h MHLoop1: push si cx bx sub ch,ch MHLoop2: mov dh,bh xor dh,bl xor dh,dl and dh,1 jnz MHNotSet or [byte ds:si],64 ; выстрел по клетке виртуальный MHNotSet: inc si inc bl loop MHLoop2 pop bx cx si add si,12 inc bh dec ch jnz MHLoop1 and al, al ret Endp Proc IsShipDestroyed push bx si call MakeHit pop si bx jnz ISDCont1 ret ISDCont1: cmp al,1 pushf call CalcBattleAddr popf jne ISDCont2 or [byte ds:si], 16 mov al,2 ret ISDCont2: mov dx,si and [byte ds:si], 127 sub si,13 mov cx,0303h ISDLoop1: push si cx sub ch,ch ISDLoop2: lodsb test al,128 jz ISDNotFound1 and al,7 jnz ISDFound1 ISDNotFound1: loop ISDLoop2 pop cx si add si,12 dec ch jnz ISDLoop1 mov si,dx or [byte ds:si], 128 ISDHurted: mov al,1 ret ISDFound1: pop cx cx xchg si,dx or [byte ds:si], 128 dec dx sub dx,si jnc ISDForward ISDBackward: add si,dx mov al, [ds:si] test al,7 jnz ISDBackward sub si,dx neg dx ISDForward: mov bx, si sub ch,ch mov cl, [ds:si] and cl, 7 ISDLoop3: mov al, [ds:si] test al, 128 jz ISDHurted test al, 7 jz ISDHurted add si, dx loop ISDLoop3 mov si, bx mov cl, [ds:si] and cl, 7 sub si, dx or [byte ds:si],64 add si,dx ISDLoop4: or [byte ds:si],16 add si, dx loop ISDLoop4 or [byte ds:si],64 mov al,2 ret Endp ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-[ Random ]-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Proc Random ;случайное число ;Вход: ax-верхняя граница push bx dx mov bx,ax mov ax,[Seed] mov dx,25173 mul dx add ax,13879 mov [Seed],ax mul bx mov ax,dx pop dx bx ret Endp Proc PrintHEX pusha push es ds mov ax,cs mov ds,ax mov ax,0b800h mov es,ax mov cx,4 mov bx,offset HEXData mov ah,07h PHLoop1: mov si,dx and si,15 add si,bx lodsb std stosw cld shr dx,4 loop PHLoop1 std mov al,"x" stosw mov al,"0" stosw cld pop ds es popa ret Endp ;-=-=-=-=-=-=-[Данные]-=-=-=-=- Mess1 db "-=-=[Морской бой ]=-=-$" ;Mess2 db "Курсорные стрелки – перемещение, пробел – повернуть ,$",10,13 ;Mess3 db "Enter - поставить, R – поставить в случайную позицию $" HEXData db "0123456789ABCDEF" Cell db "-T--¬","¦¦ ¦","++-¦","¦¦ ¦","L¦==-" Fields db 432 dup (0) Status db 0 LastXY dw 0 Seed dw 0 ends END MAIN