1. 9. 2008, 15:40 napsal Yo'Sarin, sekce Škola, přečteno 1180×,
Tentokrát pro vás mám svou semestrální (čerstvě odevzdanou) práci na předmět X36SOJ (strojově orientované jazyky). Semestrálka je psaná (pochopitelně) v assembleru (fuj) a myslím že celkem povedená.
Jde o aplikaci na způsob "The game of Life" - aplikace podle určitých parametrů simuluje život.
Hra života je jednoduchý matematický model, simulující život řídící se jednoduchými pravidly. Na počátku hry je dán "počáteční stav" (jediný prvek náhody v celém modelu) a model se dále rozvíjí podle jednoduchých pravidel:
Počet živých sousedů se vždy počítá vzhledem k situaci *před* aplikováním těchto pravidel - nejdříve prostě musíme najít všechny kolonie které vzniknou/zaniknou, než kteroukoli z nich změníme.
Práci jsem odevzdával Ivanu Šimečkovi - celé odevzdávání zabralo cca 5 minut (maximálně). Práce má lehce přes 600 řádků (+ cca 200 řádků v souboru ve kterém je uložená počáteční mapa.
Celou semestrálku si můžete stáhnout. (zip soubor, cca 6kb, obsahuje startovní plán, zdrojový kód a readme)
;org 70000
org 256
jmp start
%include "herniplan.asm"
; ukazatel (7*7)
cursorPointer db 0, 0, 0, 2, 0, 0, 0
db 0, 0, 0, 0, 0, 0, 0
db 0, 0, 0, 0, 0, 0, 0
db 2, 0, 0, 9, 0, 0, 2
db 0, 0, 0, 0, 0, 0, 0
db 0, 0, 0, 0, 0, 0, 0
db 0, 0, 0, 2, 0, 0, 0
cursorPos dw 320*200/2 - 160 + 3 + 3*320 ; startovní pozice kurzoru - jeho levý horní roh
pauza dw 1
upraveno dw 1
perioda dw 20
seed dw 33442
start:
; nastavení zobrazení
mov ah, 0
mov al, 13h ; 320 * 200 * 256
int 10h
call initPlan
mov cx, 2 ; že program poběží nadále
xor dx, dx
krok:
add dx, 1
int 1Ch
mov al, 20h
out 50h, al
call odstranKurzor
cmp byte[pauza], 0
jne zapauzovano
cmp [perioda], dx
ja zapauzovano
call zij
call upravovani
xor dx, dx
zapauzovano:
call cteniKlavesy
call initPlan
loop krok
mov ah, 00
mov al, 03
int 10h ; zpet do textoveho rezimu
ret
konec:
mov cx, 1 ; cx = 1 -> konec loop
ret
pridej: ; přidání bodu
push si
push ax
mov si, plan
add si, 320*200
sub si, [cursorPos]
add si, 320*3+3
mov byte[si], 1
pop ax
pop si
ret
smaz: ; smazání bodu
push si
mov si, plan
add si, 320*200
sub si, [cursorPos]
add si, 320*3+3
mov byte[si], 0
pop si
ret
smazCtverec: ; smazání bodu a celého jeho okolí
push si
push cx
mov si, plan
add si, 320*200
sub si, [cursorPos]
mov cx, 7
smazRadek:
push cx
mov cx, 7
smazBod:
mov byte[si], 0
inc si
loop smazBod
add si, 320-7
pop cx
loop smazRadek
pop cx
pop si
ret
zapauzovat: ; pauza - život se zastaví
push ax
mov ax, word[pauza]
xor ax, 1
mov word[pauza], ax
pop ax
ret
krokovat: ; jeden krok života
push ax
mov ax, [upraveno]
call odstranKurzor
cmp ax, 1
je budemeZit
call upravovani
jmp konecKrokovani
budemeZit:
call zij
konecKrokovani:
;call initPlan
xor ax, 1
mov [upraveno], ax
pop ax
ret
novyPlan: ; vytvoří nový (náhodný) plán
push ax
push si
push cx
mov si, plan
mov cx, 320 * 200
vygenerujBod:
mov ax, 100
call nahCislo
cmp ax, 30 ; pravděpodobnost (%) že bude v tomhle bodě kolonie
ja neniKolonie
mov byte[si], 1
jmp dalsiBod
neniKolonie:
mov byte[si], 0
dalsiBod:
inc si
loop vygenerujBod
pop cx
pop si
pop ax
ret
smazatVse:
push cx
push si
mov cx, 320*200
smazBodik:
mov byte[si], 0
inc si
loop smazBodik
;call initPlan
pop si
pop cx
ret
initPlan: ; inicializace plánu podle [plan]
push ax
push es
push di
push cx
push si
mov ax, 0A000h;
;mov ax, 0B800h
mov es, ax
mov cx, 320*200
mov si, plan
vybarvi:
cmp cx, [cursorPos]
jne nekresliKurzor
call kresliKurzor
nekresliKurzor:
cmp byte[si], 0
je mrtvaBarva
cmp byte[si], 1
je zivaBarva
cmp byte[si], 3
je budeZivaBarva
cmp byte[si], 2
je budeMrtvaBarva
jmp vlastniBarva
mrtvaBarva:
mov al,0 ; černá
jmp udelejTecku
zivaBarva:
mov al,8 ; ?
jmp udelejTecku
budeMrtvaBarva:
mov al,4 ; červená (?)
jmp udelejTecku
budeZivaBarva:
mov al,2 ; zelená
jmp udelejTecku
vlastniBarva:
mov al,byte[si]
jmp udelejTecku
udelejTecku:
stosb
inc si
loop vybarvi
pop si
pop cx
pop di
pop es
pop ax
ret
kresliKurzor: ; do mapy (plánu) přidá kurzor
push cx
push si
push ax
push di
mov cx, 7
mov di, cursorPointer
kurzorRadek:
push cx
mov cx, 7
kurzorKrok:
mov al, byte[si]
add al, byte[di]
mov byte[si], al
inc si
inc di
loop kurzorKrok
add si, 320 - 7
pop cx
loop kurzorRadek
pop di
pop ax
pop si
pop cx
ret
odstranKurzor: ; odstraní kurzor z mapy
push cx
push si
push ax
push di
mov cx, 7
mov di, cursorPointer
mov si, plan
add si, 320*200
sub si, [cursorPos]
smazKurzorRadek:
push cx
mov cx, 7
smazKurzorKrok:
mov al, byte[si]
mov ah, byte[di]
cmp ah, al
ja preskocBod ;kurzor tady v tom místě už byl asi smazán
sub al, ah
mov byte[si], al
preskocBod:
inc si
inc di
loop smazKurzorKrok
add si, 320 - 7
pop cx
loop smazKurzorRadek
pop di
pop ax
pop si
pop cx
ret
kurzorUp:
push ax
mov ax, [cursorPos]
add ax, 320
cmp ax, 320*200 - 1
jnb upNeukladat
mov [cursorPos], ax
upNeukladat:
pop ax
ret
kurzorDown:
push ax
mov ax, [cursorPos]
sub ax, 320
cmp ax, 7*320
jbe downNeukladat
mov [cursorPos], ax
downNeukladat:
pop ax
ret
kurzorLeft:
push ax
mov ax, [cursorPos]
add ax, 1
cmp ax, 320*200 - 1
jnb leftNeukladat
mov [cursorPos], ax
leftNeukladat:
pop ax
ret
kurzorRight:
push ax
mov ax, [cursorPos]
sub ax, 1
cmp ax, 7*320 + 7
jbe rightNeukladat
mov [cursorPos], ax
rightNeukladat:
pop ax
ret
speedUp:
push ax
mov ax, [perioda]
cmp ax, 0
je speedUpEnd
dec ax
mov [perioda], ax
speedUpEnd:
pop ax
ret
speedDown:
push ax
mov ax, [perioda]
cmp ax, 255
je speedDownEnd
inc ax
mov [perioda], ax
speedDownEnd:
pop ax
ret
cteniKlavesy: ; a provedení příslušné akce
mov cx, 2 ; pokračujeme dál
mov ah, 1
int 16h ; zjišťujeme, jestli uživatel něco zmáčkl
jne klavesaStisknuta
ret
klavesaStisknuta:
mov ah, 0
int 16h ; čekáme na stisk klavesy
cmp al, 'k' ; 'K'- konec programu
je callKonec
cmp ah, 01h ; Esc - konec programu
je callKonec
cmp al, 'n' ; 'N' - přidání nové kolonie
je callPridej
cmp al, 's' ; 'S' - smazání kolonie
je callSmaz
cmp al, 'S' ; 'S' - smazání kolonií
je callSmazCtverec
cmp al, 'p' ; 'P' - pauza
je callPauza
cmp ah, 0Fh ; Tab - krokovat
je callKrokovat
cmp ah, 39h ; mezerník - vytvoří nový (náhodný) plán hry
je callNovyPlan
cmp ah, 0Eh ; backspace - smazat vše
je callSmazatVse
cmp ah, 50h ; dolů
je callKurzorDown
cmp ah, 4bh ; vlevo
je callKurzorLeft
cmp ah, 4dh ; vpravo
je callKurzorRight
cmp ah, 48h ; nahoru
je callKurzorUp
cmp ah, 49h ; pageUp
je callSpeedUp
cmp ah, 51h ; pageDown
je callSpeedDown
jmp dal
callKonec:
mov cx, 1 ; končíme
call konec
jmp dal
callPridej:
call pridej
jmp dal
callSmaz:
call smaz
jmp dal
callSmazCtverec:
call smazCtverec
jmp dal
callPauza:
call zapauzovat
jmp dal
callKrokovat:
call krokovat
jmp dal
callNovyPlan:
call novyPlan
jmp dal
callSmazatVse:
call smazatVse
jmp dal
callKurzorDown:
call kurzorDown
jmp dal
callKurzorUp:
call kurzorUp
jmp dal
callKurzorLeft:
call kurzorLeft
jmp dal
callKurzorRight:
call kurzorRight
jmp dal
callSpeedUp:
call speedUp
jmp dal
callSpeedDown:
call speedDown
jmp dal
dal:
ret
zij:
push si
push cx
push ax
push bx
push di
push dx
mov si, plan
mov di, si
mov dx, di
mov cx, 320*200
add dx, cx
budeZit:
push si
call sousedi
pop si
cmp ax, 2
je dalsiKolonie
cmp ax, 3
je ozij
umri:
cmp byte[si], 1
jne dalsiKolonie
mov byte[si], 2
jmp dalsiKolonie
ozij:
cmp byte[si], 0
jne dalsiKolonie
mov byte[si], 3
jmp dalsiKolonie
dalsiKolonie:
inc si
loop budeZit
pop dx
pop di
pop bx
pop ax
pop cx
pop si
ret
upravovani:
push cx
push si
mov cx, 320*200
mov si, plan
uprav:
cmp byte[si], 2
je umrela
cmp byte[si], 3
je ozila
jmp opravaDalsiKolonie
umrela:
mov byte[si], 0
jmp opravaDalsiKolonie
ozila:
mov byte[si], 1
jmp opravaDalsiKolonie
opravaDalsiKolonie:
inc si
loop uprav
pop si
pop cx
ret
sousedi: ; do ax uloží počet sousedů - nic nezálohuje na zásobník - je to součást fce "zij" - vyčleněno jen kvůli max. délce skoku
xor ax, ax ; počet sousedů
sub si, 320 + 1; levý horní soused
cmp si, di
jbe stredniHorni
cmp si, dx
jnb stredniHorni
cmp byte[si], 0
je stredniHorni
cmp byte[si], 3
je stredniHorni
inc ax
stredniHorni:
inc si
cmp si, di
jbe pravyHorni
cmp si, dx
jnb pravyHorni
cmp byte[si], 0
je pravyHorni
cmp byte[si], 3
je pravyHorni
inc ax
pravyHorni:
inc si
cmp si, di
jbe levyStredni
cmp si, dx
jnb levyStredni
cmp byte[si], 0
je levyStredni
cmp byte[si], 3
je levyStredni
inc ax
levyStredni:
add si, 320 - 2
cmp si, di
jbe pravyStredni
cmp si, dx
jnb pravyStredni
cmp byte[si], 0
je pravyStredni
cmp byte[si], 3
je pravyStredni
inc ax
pravyStredni:
add si, 2
cmp si, di
jbe levyDolni
cmp si, dx
jnb levyDolni
cmp byte[si], 0
je levyDolni
cmp byte[si], 3
je levyDolni
inc ax
levyDolni:
add si, 320 - 2
cmp si, di
jbe stredniDolni
cmp si, dx
jnb stredniDolni
cmp byte[si], 0
je stredniDolni
cmp byte[si], 3
je stredniDolni
inc ax
stredniDolni:
inc si
cmp si, di
jbe pravyDolni
cmp si, dx
jnb pravyDolni
cmp byte[si], 0
je pravyDolni
cmp byte[si], 3
je pravyDolni
inc ax
pravyDolni:
inc si
cmp si, di
jbe neniSoused
cmp si, dx
jnb neniSoused
cmp byte[si], 0
je neniSoused
cmp byte[si], 3
je neniSoused
inc ax
neniSoused:
ret
nahCislo: ; vygeneruje pseudonahodne cislo v rozmezi 0 - ax a vysledek ulozi do ax
push cx
push dx
mov cx, ax
mov ax, [seed]
mov dx, 19
mul dx
add al, ah
xor al, 11111111b
mov [seed], ax
div cx
mov ax, dx
pop dx
pop cx
ret
Diskusní příspěvky vyjadřují názory diskutujících, nikoli autora článku.
Příspěvky nemající souvislost s článkem a příspěvky jejichž jediným účelem je urážet a nadávat budou po zralé úvaze smazány - uvědomte si, že jste na mém písečku.
U článku ještě není žádný příspěvek