Mensajepor na_th_an » Mar, 20 May 2014, 16:26
Venga, va
$this->bbcode_second_pass_code('', '// random.h
// New random routines. Code by Patrik Rak, adapted by na_th_an
extern unsigned int seed1 [0];
extern unsigned int seed2 [0];
extern unsigned char randres [0];
#asm
._seed1 defw 0
._seed2 defw 0
._randres defb 0
#endasm
unsigned char rand (void) {
#asm
.rnd
ld hl,0xA280
ld de,0xC0DE
ld a,h ; t = x ^ (x << 1)
add a,a
xor h
ld h,l ; x = y
ld l,d ; y = z
ld d,e ; z = w
ld e,a
rra ; t = t ^ (t >> 1)
xor e
ld e,a
ld a,d ; w = w ^ ( w << 3 ) ^ t
add a,a
add a,a
add a,a
xor d
xor e
ld e,a
ld (rnd+1),hl
ld (rnd+4),de
ld (_randres), a
#endasm
return randres [0];
}
void srand (void) {
#asm
ld hl, (_seed1)
ld (rnd+1),hl
ld hl, (_seed2)
ld (rnd+4),hl
#endasm
}')
Para iniciar, hacer:
$this->bbcode_second_pass_code('', 'seed1 [0] = a; seed2 [0] = b;
srand ();')
Con a y b los dos numericos que más os gusten.
Luego cada vez que queráis un random, llamad a rand. Da un valor entre 0 y 255. Con módulos y ANDs tenéis lo que necesitéis. Un número entre 0 y 3...
$this->bbcode_second_pass_code('', 'c = rand () & 3;')
Ya que hay cuatro posibilidades y 4 es potencia de 2, podemos usar un AND aritmético y volar.
Un número entre 0 y 11, como 11 no es potencia de 2 ni nada...
$this->bbcode_second_pass_code('', 'c = rand () % 12;')
Un número entre a y b, ambos inclusive, con a < b
$this->bbcode_second_pass_code('', 'c = a + (rand () % (b - a + 1));')
Lo bueno es que para a y b fijos, la secuencia aleatoria siempre es la misma, lo cual viene muy bien para hacer güegos. Si queréis a y b más o menos aleatorios, asignadles los valores de la variable de sistema FRAMES (23672), por ejemplo.
Es mejor procurar que tus randoms sean en rangos que sean potencias de 2 porque así no tienes que dividir, que es lento y costoso. Por ejemplo, para seleccionar una columna de la pantalla al azar, al ser 32 los posibles valores y ser 32 potencia de 2, podemos hacer:
$this->bbcode_second_pass_code('', 'c = rand () & 31;')
Un AND aritmético es inmediato, mientras que para dividir y hacer un módulo hay que tirar de una función porque el z80 no divide.
Como diría Rorshach: "Urm..."