Пытаюсь сделать генератор случайных чисел для моей игры в сборке 8086 - PullRequest
1 голос
/ 01 мая 2019

Как сделать функцию, которая генерирует случайное число от 0 до 80? Я пытаюсь сделать игру с астероидами в сборке 8086.

Я пробовал этот код, но он генерирует слишком маленькие числа ...

 _RAND:
    mov ah,2Ch
    int 21h
    mov ax,dx
    mov ax,0Fh
    mov al,dl
    cmp al,80d
    jg _RAND

Это дало мне число от 1 до 8 или что-то в этом роде. Это случайное, но слишком маленькое число для позиции X моих астероидов.

1 Ответ

0 голосов
/ 02 мая 2019

Если вам нужно сгенерировать много случайных значений за очень короткий период времени, вы можете использовать это:

; Description  : get RND between any bl and bh includs (max 0 -255)
; Input        : 1. Bl = min (from 0) , BH , Max (till 255)
;                2. RndCurrentPos a  word variable,   help to get good rnd number
;                   Declre it at DATASEG :  RndCurrentPos dw ,0
;                3. EndOfCsLbl: is label at the end of the program one line above END start     
; Output:        Al - rnd num from bl to bh  (example 50 - 150)
; More Info:
;   Bl must be less than Bh 
;   in order to get good random value again and agin the Code segment size should be 
;   at least the number of times the procedure called at the same second ... 
;   for example - if you call to this proc 50 times at the same second  - 
;   Make sure the cs size is 50 bytes or more 
;   (if not, make it to be more) 
proc RandomByCs
    push es
    push si
    push di

    mov ax, 40h
    mov es, ax

    sub bh,bl  ; we will make rnd number between 0 to the delta between bl and bh
               ; Now bh holds only the delta
    cmp bh,0
    jz @@ExitP

    mov di, [word RndCurrentPos]
    call MakeMask ; will put in si the right mask according the delta (bh) (example for 28 will put 31)

RandLoop: ;  generate random number 
    mov ax, [es:06ch] ; read timer counter
    mov ah, [byte cs:di] ; read one byte from memory (from semi random byte at cs)
    xor al, ah ; xor memory and counter

    ; Now inc di in order to get a different number next time
    inc di
    cmp di,(EndOfCsLbl - start - 1)
    jb @@Continue
    mov di, offset start
@@Continue:
    mov [word RndCurrentPos], di

    and ax, si ; filter result between 0 and si (the nask)
    cmp al,bh    ;do again if  above the delta
    ja RandLoop

    add al,bl  ; add the lower limit to the rnd num

@@ExitP:    
    pop di
    pop si
    pop es
    ret
endp RandomByCs

Обратите внимание, если ваш кодовый сегмент недостаточно длинный, попробуйте добавить его в кодовый сегмент:

    ; put some data in Code segment in order to have enough bytes to xor with 
    SomeRNDData     db 227  ,111    ,105    ,1      ,127
                    db 234  ,6      ,116    ,101    ,220
                    db 92   ,60     ,21     ,228    ,22
                    db 222  ,63     ,216    ,208    ,146
                    db 60   ,172    ,60     ,80     ,30
                    db 23   ,85     ,67     ,157    ,131
                    db 120  ,111    ,105    ,49     ,107
                    db 148  ,15     ,141    ,32     ,225
                    db 113  ,163    ,174    ,23     ,19
                    db 143  ,28     ,234    ,56     ,74
                    db 223  ,88     ,214    ,122    ,138
                    db 100  ,214    ,161    ,41     ,230
                    db 8    ,93     ,125    ,132    ,129
                    db 175  ,235    ,228    ,6      ,226
                    db 202  ,223    ,2      ,6      ,143
                    db 8    ,147    ,214    ,39     ,88
                    db 130  ,253    ,106    ,153    ,147
                    db 73   ,140    ,251    ,32     ,59
                    db 92   ,224    ,138    ,118    ,200
                    db 244  ,4      ,45     ,181    ,62

...