how to make a pseudo random things to appear after one another on screen?

43 views Asked by At

I'm making snake game for school and i need to use pseudo random to create the apples. We have kind of a book but I don't understand it the way the explain it. I would love for somebody to try to explain it to me in the simplest way.

In the book it says the method we need to use is based on timer, and that we need to use the address 0040:006Ch.

By the way I'm using assembly and I'm pretty sure I'm considered really beginner & I'm using DosBox.

For now my code only moves a '*' with wasd and I set boundries.

IDEAL
MODEL small
STACK 100h
DATASEG
; --------------------------
; Your variables here
; --------------------------
    saveal db ' '


CODESEG
proc black
body:
    mov [es:si], ax
    add si, 2
    cmp si, 25*80*2
    jnz body
  ret
endp black

proc up
    
    mov di, 80*2
    cmp si, di
    jb not_move_up
    
    mov ah, 0
    mov al, ' '
    mov [es:si], ax
    sub si, 80*2
    mov ah, 156
    mov al, '*'
    mov [es:si], ax
not_move_up:
  ret
endp up

proc down

    mov di, (24*80*2)-1
    cmp si, di
    jg not_move_down
    
    mov ah, 0
    mov al, ' '
    mov [es:si], ax
    add si, 80*2
    mov ah, 156
    mov al, '*'
    mov [es:si], ax
not_move_down:
  ret
endp down
proc left

    mov dx, 0
    mov bx, si
    mov ax, si
    mov si, 80*2
    div si
    mov si, bx
    cmp dx,0
    jz not_move_left
    
    mov ah, 0
    mov al, ' '
    mov [es:si], ax
    sub si, 2
    mov ah, 156
    mov al, '*'
    mov [es:si], ax
not_move_left:
  ret
endp left
proc right

    mov dx, 0
    mov bx, si
    mov ax, si
    mov si, 80*2
    div si
    mov si, bx
    cmp dx,158
    jz not_move_right

    mov ah, 0
    mov al, ' '
    mov [es:si], ax
    add si, 2
    mov ah, 156
    mov al, '*'
    mov [es:si], ax
not_move_right:
  ret
endp right
start:
    mov ax, @data
    mov ds, ax
; --------------------------
; Your code here
; --------------------------
    mov ax, 0b800h
    mov es, ax
    
    mov si,0
    mov al, ' '
    mov ah, 0
    call black
    mov si, (12*80+40)*2
    mov al, '*'
    mov ah, 156
    mov [es:si], ax
    
yesOrno:
    mov ah, 1h
    int 21h
    
    mov [byte ptr saveal], al
    cmp [byte ptr saveal], 'w'
    jz w
    cmp [byte ptr saveal], 'a'
    jz a
    cmp [byte ptr saveal], 's'
    jz s
    cmp [byte ptr saveal], 'd'
    jz d
    cmp [byte ptr saveal], 'q'
    jmp exit
    
w:
    call up
    jmp yesOrno
s:
    call down
    jmp yesOrno 
a:
    call left
    jmp yesOrno
d:
    call right
    jmp yesOrno
    
exit:
    mov ax, 4c00h
    int 21h
END start
1

There are 1 answers

2
Sep Roland On

In the book it says the method we need to use is based on timer, and that we need to use the address 0040:006Ch

The BIOS.TimerTick at linear address 0000046Ch is a 32-bit variable that monotonously increments during 24 hours after which it resets to 0 (at midnight). There are about 18 increments per second. For the purpose of displaying the apples in your snake game (really beginner level), it is fine to use this timer as a source of randomness. But do read @PeterCordes' comment.
The procedure is as follows:

  • You fetch the dword of the timer and divide it by the width of the playfield which in your case is 80. This will produce a remainder in the range [0,79] and that's going to be the X coordinate for the apple.
  • Next you repeat the operation but use the height of the playfield which is 25 in your case. This will produce a remainder in the range [0,24] and that's going to be the Y coordinate for the apple.
  ; IN () OUT (ax) MOD (cx,dx)
  push ds
  xor  cx, cx
  mov  ds, cx
  mov  ax, [046Ch]  ; DX:AX is [0,1573040]
  mov  dx, [046Eh]
  mov  cl, 80
  div  cx           ; -> AX is quotient [0,19663], DX is remainder [0,79]
  push dx           ; (1)
  ; don't care if it got incremented in the mean time
  mov  ax, [046Ch]  ; DX:AX is [0,1573040]
  mov  dx, [046Eh]
  mov  cl, 25 
  div  cx           ; -> AX is quotient [0,62921], DX is remainder [0,24]
  pop  ax           ; (1)
  mov  ah, dl
  pop  ds
  ret

See The quintessential Snake Game. How to keep track of the snake? for more detailed info about creating a snake game, and especially look for the NewFood subroutines that use another method of random number generation.