Duda sobre rand_seed

Started by peterpollito, October 04, 2010, 04:51:37 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

peterpollito

Hola soy nuevo con Bennu y he propbado a utilizar el Random_seed para que genere la posicion aleatoria del personaje principal utilizando un numero RANDOM, así:

rand_seed ( time ( ) );

El problema es que solo modifica la posicion de Y, pero la de X no.
he probado cargando un numero aleatorio para el random_seed asi:

rand ( 0 , 1 );   

La pregunta es: ¿hay algun metodo mejor para solucionar este problema?

Gracias de antemano y felicidades por el foro.

SplinterGU

bienvenido!

bien, x o y no tiene que ver con rand... podrias poner un codigo de ejemplo que muestre el problema?
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

peterpollito

Mi protagonista hace esto despues de hacer lo de rand_seed, el problema es que el valor de X no cambia solo cambia Y.Cargando el numero aleatorio como te puse se soluciona,pero queria saber si existe alguna solucion mejor.


x = rand ( 0 , 800 ); //Posicion aleatoria del protagonista
y = rand ( 0 , 600 ); //Posicion aleatoria del protagonista



SplinterGU

el valor no puede quedar fijo, puede ser que entre corridas diferentes te de el mismo valor, pero no puedo ser que en una misma corrida te de 100 o 1000 valores iguales, sin cambio en la x.
el rand_seed(time....) hace que no se use el seed inicial por defecto del sistema, sino que use uno con respecto a la fecha actual con precision de segundos.

para la proxima, pon un codigo completo, que sea compilable, porque la mayoria de los reportes de error son de mala programacion de quien esta pidiendo ayuda, y asi podemos ver el error con claridad, como ser que por ejemplo, tengas en alguna parte del codigo un x = 0 o una comparacion de x == 0, donde te comiste un = y quedo x = 0, y esto no es una comparacion sino una asignacion.

saludos.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2


DCelso

tienes esto dentro del bucle infinito del proceso (donde debe estar tambien frame)?
x = rand ( 0 , 800 );   //Posicion aleatoria del protagonista
y = rand ( 0 , 600 );   //Posicion aleatoria del protagonista
Monstruos Diabólicos

"A PAck of classic GAMEs For BennuGD" en desarrollo
http://code.google.com/p/apagame4be/

peterpollito

PROCESS protagonista ();
//carga los controles del protagonista

BEGIN //Proceso protagonista

//Bloque inicial , siempre con asignaciones
graph = 1; //Establece el gráfico 1 del fpg
x = rand ( 0 , 800 ); //Posicion aleatoria del protagonista
y = rand ( 0 , 600 ); //Posicion aleatoria del protagonista
angle = 1;              //Angulo en milesimas
alpha = 255; //Tamaño en tanto por ciento
size = 100;

//Bloque repetitivo
LOOP //A partir de aquí repetiremos siempre las siguiente instrucciones usando ELSE IF y no se movera en diagonal

//Arriba
IF ( key ( _UP) ) //Con la FLECHA ARRIBA el personaje avanza hacia la derecha
y = y - 4; //Se puede poner y -= 4;
graph = graph + 1; //Se puede poner graph++; para añadir uno.

//Abajo
ELSEIF ( key ( _DOWN) ) //Con la FLECHA ABAJO el personaje avanza hacia la derecha
y = y + 4; //Se puede poner y += 4;
graph = graph + 1; //Se puede poner graph++; para añadir uno.

//Izquierda
ELSEIF ( key ( _LEFT) ) //Con la FLECHA IZQUIERDA el personaje avanza hacia la derecha
x = x - 4; //Se puede poner x -= 4;
graph = graph + 1; //Se puede poner graph++; para añadir uno.
flags = 1;

//Derecha
ELSEIF ( key ( _RIGHT) )    //Con la FLECHA DERECHA el personaje avanza hacia la derecha
x = x + 2; //Se puede poner x += 4;
graph = graph + 1; //Se puede poner graph++; para añadir uno.
flags = 0;

//Disparo
ELSEIF ( key ( _SPACE ) )    //Con la FLECHA DERECHA el personaje avanza hacia la derecha
disparo ();

ELSE   //Cuando no pulsas ninguna de estas teclas el grafico vuelve a la posicion 1
graph = 1;//graph = graph + 1;

END

//Al terminar los 11 graficos de andar vuelve a emprezar
IF ( graph >= 11)
graph = 1;  // = asignacion, == comparacion
END

//Mostramos el resultado por pantalla NO SOLO DIBUJA, tambien es para que haga lo que tenga que hacer el proceso y se pare
FRAME; //Sincroniza y dibuja

END //Fin de las instrucciones que se repiten siempre

END


PROCESS config ();
//configura el modo de video y carga los recursos graficos
BEGIN

//Modo grafico
set_mode ( 800 , 600 , 32 , MODE_WINDOW ); //Resolución de pantalla a 800x600 píxel, 32 bits de color y en modo ventana
set_fps ( 30 , 0 ); // Carga los frames por segundo,si pones 0 sera el maximo soportado por la tarjeta, numero maximo de dibujados que se salta si no da de si la potencia del ordenador

//Carga el fichero para gráficos maki.fpg de la carpeta images
load_fpg ( "images/maki.fpg" );

//Configuracion de la serie aleatoria para que cambie de sitio
//el prota en base a la fecha del sistema
//Se hace SOLO una vez para generar la semilla

rand_seed ( time ( ) ); //Desecha el primer valor del rand y escoge un numero aleatorio segun la fecha de sistema
rand ( 0 , 1 ); //Le asignamos un primer numero para que cambie la posicion de X que no cambiaba

//Comportamiento repetitivo
LOOP

//Cierra el juego al pulsar ESCAPE no lo ponemos en videojuego.prg porque si muere el prota, ya no funcionará.


IF ( key (_esc) ) //Condición: Si se pulsa la tecla _esc
exit ( "Adios" ); //Salimos del juego
END //Fin de la condición

FRAME; //Mostramos el resultado por pantalla NO SOLO DIBUJA tambien es para que haga lo que tenga que hacer el proceso y se pare
END

END






se que tiene muchos comentarios pero es que estoy empezando.Ya pillo como va el foro.gracias de antemano y un saludo!!!

SplinterGU

claro, solo tomas el valor 1 vez, y si, la semilla inicial es siempre la misma, es logico que te de el mismo valor en todas las corridas, con el rand_seed que pusiste se soluciona, es correcto.

saludos.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

FreeYourMind

Ese nick me suena a algo  ::)

Welcome to your DOOM!


DCelso

Quote from: peterpollito on October 04, 2010, 06:35:35 PM
PROCESS protagonista ();
//carga los controles del protagonista

BEGIN //Proceso protagonista

//Bloque inicial , siempre con asignaciones
graph = 1; //Establece el gráfico 1 del fpg
x = rand ( 0 , 800 ); //Posicion aleatoria del protagonista
y = rand ( 0 , 600 ); //Posicion aleatoria del protagonista
angle = 1;              //Angulo en milesimas
alpha = 255; //Tamaño en tanto por ciento
size = 100;

//Bloque repetitivo
LOOP //A partir de aquí repetiremos siempre las siguiente instrucciones usando ELSE IF y no se movera en diagonal

//Arriba
IF ( key ( _UP) ) //Con la FLECHA ARRIBA el personaje avanza hacia la derecha
y = y - 4; //Se puede poner y -= 4;
graph = graph + 1; //Se puede poner graph++; para añadir uno.

//Abajo
ELSEIF ( key ( _DOWN) ) //Con la FLECHA ABAJO el personaje avanza hacia la derecha
y = y + 4; //Se puede poner y += 4;
graph = graph + 1; //Se puede poner graph++; para añadir uno.

//Izquierda
ELSEIF ( key ( _LEFT) ) //Con la FLECHA IZQUIERDA el personaje avanza hacia la derecha
x = x - 4; //Se puede poner x -= 4;
graph = graph + 1; //Se puede poner graph++; para añadir uno.
flags = 1;

//Derecha
ELSEIF ( key ( _RIGHT) )    //Con la FLECHA DERECHA el personaje avanza hacia la derecha
x = x + 2; //Se puede poner x += 4;
graph = graph + 1; //Se puede poner graph++; para añadir uno.
flags = 0;

//Disparo
ELSEIF ( key ( _SPACE ) )    //Con la FLECHA DERECHA el personaje avanza hacia la derecha
disparo ();

ELSE   //Cuando no pulsas ninguna de estas teclas el grafico vuelve a la posicion 1
graph = 1;//graph = graph + 1;

END

//Al terminar los 11 graficos de andar vuelve a emprezar
IF ( graph >= 11)
graph = 1;  // = asignacion, == comparacion
END

//Mostramos el resultado por pantalla NO SOLO DIBUJA, tambien es para que haga lo que tenga que hacer el proceso y se pare
FRAME; //Sincroniza y dibuja

END //Fin de las instrucciones que se repiten siempre

END


PROCESS config ();
//configura el modo de video y carga los recursos graficos
BEGIN

//Modo grafico
set_mode ( 800 , 600 , 32 , MODE_WINDOW ); //Resolución de pantalla a 800x600 píxel, 32 bits de color y en modo ventana
set_fps ( 30 , 0 ); // Carga los frames por segundo,si pones 0 sera el maximo soportado por la tarjeta, numero maximo de dibujados que se salta si no da de si la potencia del ordenador

//Carga el fichero para gráficos maki.fpg de la carpeta images
load_fpg ( "images/maki.fpg" );

//Configuracion de la serie aleatoria para que cambie de sitio
//el prota en base a la fecha del sistema
//Se hace SOLO una vez para generar la semilla

rand_seed ( time ( ) ); //Desecha el primer valor del rand y escoge un numero aleatorio segun la fecha de sistema
rand ( 0 , 1 ); //Le asignamos un primer numero para que cambie la posicion de X que no cambiaba

//Comportamiento repetitivo
LOOP

//Cierra el juego al pulsar ESCAPE no lo ponemos en videojuego.prg porque si muere el prota, ya no funcionará.


IF ( key (_esc) ) //Condición: Si se pulsa la tecla _esc
exit ( "Adios" ); //Salimos del juego
END //Fin de la condición

FRAME; //Mostramos el resultado por pantalla NO SOLO DIBUJA tambien es para que haga lo que tenga que hacer el proceso y se pare
END

END






se que tiene muchos comentarios pero es que estoy empezando.Ya pillo como va el foro.gracias de antemano y un saludo!!!
umn con estos procesos debes de asegurarte de ejecutar primero config para que rand_seed cambie la semilla antes de que rand la use en el proceso protagonista. Y aún así no se yo si al ser ambos hilos puede que alguna vez vaya más rápido el proceso protagonista y se ejecuten sus rand antes que el rand_seed de config.
Yo el rand_seed lo haría el el proceso "main()" al principio de todo, para asegurarte que se invoca antes que ningún rand, o en su defecto ejecútalo también en el proceso protagonista.
Monstruos Diabólicos

"A PAck of classic GAMEs For BennuGD" en desarrollo
http://code.google.com/p/apagame4be/

Windgate

peterpollito es alumno mío, le había invitado a preguntar aquí una cosa muy rara que le estaba pasando así que podéis bienvenirlo adecuadamente.

El problema es el siguiente:

Cuando usamos:

rand_seed ( time ( ) );

Aseguramos que la serie aleatoria se base en la fecha del sistema (segundos) y cambie en cada ejecución. Lo que pasa es que el primer valor generado (La x asignada al protagonista en nuestro caso) es la misma en cada ejecución...

¿Por qué? Pues ahí dudo un poco. Estoy casi seguro de que en ejecuciones muy próximas, la serie es generada en base a semillas muy próximas entre sí, y de ahí que el primer valor generado es también muy próximo, prácticamente el mismo.

Esto se da realmente, lo hemos comprobado largo y tendido hace un rato.

Como sólo es el primer valor el que da problemas, lo hemos solucionado así:

rand_seed ( time ( ) );
rand ( 0 , 1 );   // Este primer valor generado lo ignoramos
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

SplinterGU

como ya dije, la precision del time() es segundos, para hacerlo un poco mas aleatorio, podrian usar el get_timer().

otra cosa, es que el valor del primer rand depende del algoritmo de la implementacion C, posiblemente el primero de el mismo valor siempre, lo pueden descartar y listo.

yo hace un tiempo encontre una libreria de rands, con diferentes algoritmos e incluso diferentes tendencias, pero ahora no la vuelvo a encontrar, la idea era incluirla en el mod_rand, por eso es un modulo aparte.

si alguien sabe algo al respecto o encuentra una wiki o algo con algoritmos rands, estare agradecido, me evitan buscarla.

gracias.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

DCelso

Aqui hay unas cuantas implementaciones en C,C++ y JAVA.
http://www.cs.sunysb.edu/~algorith/files/random-numbers.shtml

Aqui hay una implementación de un tío que dice que es muy buena (claro la ha hecho el :D)
http://benpfaff.org/writings/clc/random.html

Aqui hay diferentes implementaciones del algoritmo Mersenne Twister en C, C++
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/VERSIONS/C-LANG/c-lang.html
A destacar esta que está en C:
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/VERSIONS/C-LANG/deifik.c

Aqui hay fórmulas y enlaces a otras páginas
http://en.wikipedia.org/wiki/Pseudorandom_number_generator

Seria cojonudo tenerlas todas en Bennu :D
Monstruos Diabólicos

"A PAck of classic GAMEs For BennuGD" en desarrollo
http://code.google.com/p/apagame4be/

Windgate

Personalmente no veo necesario cambiar la función y menos aún tener varios tipos de rand disponibles en la mod_rand oficial... Me parece "engordarla" innecesariamente. Si acaso se ganase un X% de eficiencia en algún sentido quizás convendría cambiar el rand ( ) actual por otro más eficiente, pero sin añadir más.

El único problema que he visto durante el tiempo que llevo aquí ha sido lo del primer valor al generar la serie aleatoria en base a time ( ), y solamente cuando las ejecuciones se suceden en un intervalo de unos pocos segundos. De momento me quedo con lo de desechar el primer valor porque el problema desaparece :P

Por supuesto, si se modifica mod_rand para mejor bienvenido sea, y si se crea otra mod_rand "no oficial" con más algoritmos disponible pues adelante, será por dlls... Si te atreves con algo así DCelso por favor súbenos el código de la .dll para ensayar con él xD
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

SplinterGU

hay casos en los que es necesario, en algunos casos se requiere tener una distribucion rand menos pareja, con alguna inclinacion en especial y no romperse la cabeza para lograrlo, el rand actual tiene una distribucion pareja, si lo dejamos correr en el tiempo, vemos que todos los numeros del rango especificado aparecen todos la misma cantidad de ocurrencias, esto es: si hacemos del 1 al 3, a lo largo del tiempo (supongamos 300 ejecuciones del rand) veremos que obtenemos que cada uno salio 99-101 veces. cosa que hace que el azar no sea tanto azar.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2