casilleros libres/ocupados

Started by Hola, October 12, 2010, 11:31:20 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Hola

Hola, no me sale hacer una cosa, necesito hacer que mi programa recorra 5 casilleros para detectar si hay algun obstaculo en medio o si el casillero esta ocupado partiendo de una posicion inicial que se encuentra dentro de una matriz hasta un destino que tambien se encuentra en la matriz..., quiero que se cumpla que si hay obstaculo no deje que se mueva el grafico y no se realiza el movimiento, si no hay obstaculo, que realice el movimiento.

Gracias.

Windgate

Pues suena muy sencillo pero a ver:

1) ¿Usas BennuGD?
2) ¿Cómo has definido la matriz? ¿Por ejemplo te vale con una matriz de enteros en la que 1 indica "ocupada" y 0 "libre"?
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

Hola

#2
Uso fenix, la matriz la he definido asi: CASILLAS[5][5]; osea que es un pequeño tablero de 6x6, mm, si, 0 seria libre y 1 seria ocupada..., necesito mover un grafico de una posicion a otra, pero esto sera posible solo si desde la posicion inicial hasta la posicion final o destino no se detecta obstaculo, de lo contrario no se realiza el movimiento.
Como hago esto?


Hola

#4
Bueno, el link no se de que es, entro en la pagina pero no me dice nada, igual ya busque en google 'algoritmo de busqueda' y entre en una pagina que decia mas o menos como hacerlo, pero no me funciona..., tengo hecho esto:

//si el valor de la posicion inicial seleccionada es igual a 2
IF(TABLA[POSX][POSY]==2)
//y si la posicion destino es igual a la posicion inicial mas dos posiciones arriba...
IF(DESX==POSX AND DESY==POSY+2)
//recorre casilleros desde la posicion inicial hasta la posicion destino en busca de obstaculos,
o numeros que no sean 0
       [b] (*)[/b]
//si encuentra un '1' en el camino...
IF(TABLA[POSX][VY]==1)
//deja de recorrer y no se realiza el movimiento de posicion inicial- a destino
BREAK;
END
END
//si no encuentra obstaculos o numeros distintos de 0, se realiza el movimiento..
ELSE
TABLA[DESX][DESY]=2; //ocupa la posicion destino con el nuevo valor
TABLA[POSX][POSY]=0; //la posicion inicial la deja libre
END
END


Pero esto no me funciona, aunque haya obstaculo (numero distinto de cero), realiza el movimiento igual, traspasandolo..., alguien puede ayudarme?

gracias..

(*) FOR(VY=POSY; VY<DESY; VY++)       este for, va donde esta el asterisco arriba en el code

lo puse ahi abajo porque me salia mal el codigo.

DCelso

ups, que raro, el asterísco no se queda dentro del enlace.
bueno, prueba con este otro
Algorito de búsqueda A*
La cosa es que hay miles de algoritmos para hacer lo que quieres, incluso bennugd tiene una funcion para ello, path_find.

Monstruos Diabólicos

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

Hola

Ah...xD, creo que no se me entendio lo que realmente quiero hacer jeje ,aver..., mejor lo muestro con imagenes.

Las posiciones se ordenan por x e y, numero antes de la coma es la x, numero despues de la coma es la y.
Ok, lo que quiero hacer es esto:



En esa imagen, la casilla 0,2 esta ocupada, supongamos que quiero mover la bolita azul desde la posicion inicial en la que se encuentra (0,0) hasta la posicion destino que seria por ejemplo 0,3..., yo quiero que esto no sea posible, ya que estaria atravezando un obstaculo (la bolita roja, es decir la casilla 0,2, que se encuentra ocupada), casilla libre es 0, casilla ocupada vale 1, supongamos que la bolita azul vale 2, la roja vale 1 y las casillas vacias o libres valen 0.

Ok, supongo que ya se entiende mejor o no¿

en esta otra imagen:



si, es lo mismo, pero la casilla 0,2 esta libre, esa casilla valdria 0, entonces si quiero mover la bolita azul que vale 2 desde 0,0 (su posicion inicial) hasta 0,3 (destino), lo tiene que hacer sin problemas porque no hay obstaculo en medio.

A ver ahora si me podeis ayudar mejor...

Aclaracion: uso Fenix, no bennu.

DCelso

Bueno, he hecho este ejemplo en bennu usando path_find, pruébalo y mira a ver si se ajusta a tus necesidades.


Program caminoCorto;
import "mod_path"
import "mod_map"
import "mod_video"
import "mod_key"
import "mod_mouse"
import "mod_proc"
import "mod_draw"

#define CASILLAS_WIDTH  16
#define CASILLAS_HEIGHT  16

Global
mapa, durezas;
jugador;
casillas[CASILLAS_WIDTH][CASILLAS_HEIGHT];
End
Begin
scale_resolution=m640x480;
set_mode(16,16,16);
set_fps(10,0);


// creamos puntero cuadrado   
mouse.graph = new_map(1,1,16);
    map_clear(0,mouse.graph,rgb(255,0,0));
   
// Creamos un mapa a recorrer, por defecto está todo a 0
casillas[2][2] = 1; //ponemos algunos obstáculsos
casillas[2][3] = 1;
casillas[2][5] = 1;
casillas[2][6] = 1;
casillas[6][1] = 1;
casillas[6][2] = 1;

// creamos un mapa con la información de casillas para pasar a path_find
durezas = new_map(CASILLAS_WIDTH,CASILLAS_HEIGHT,8); // la imagen de entrada a path_find solo puede ser de 8 bits
mapa = new_map(CASILLAS_WIDTH,CASILLAS_HEIGHT,16); // la imagen a mostrar

for (y = 0 ; y < CASILLAS_HEIGHT;y++)
for (x = 0 ; x < CASILLAS_WIDTH;x++)
if (casillas[x][y]==1)
map_put_pixel(0,durezas,x,y,255);
map_put_pixel(0,mapa,x,y,RGB(120,120,120));
else
map_put_pixel(0,durezas,x,y,0);
map_put_pixel(0,mapa,x,y,RGB(240,240,240));
end
end
end

//lo ponemos en la esquina superior izquierda
point_set(0,mapa,0,0,0);
p_mapa(mapa); //mostramos en pantalla

jugador = player(1,1); // ponemos al jugador

    while (!key(_esc))
if (mouse.left)
    while (mouse.left); frame; end
    // Si la casilla en la que se encuentra el ratón es distinta de 1 y hay camino para llegar
    if ((casillas[mouse.x][mouse.y]!=1) && (path_find(0, durezas, jugador.x, jugador.y , mouse.x  , mouse.y ,1 )))
     while ( path_getxy(&jugador.x, &jugador.y) AND not mouse.left )
        frame;
     end
    end
end
        frame;
end
let_me_alone();
unload_map(0,mouse.graph);
unload_map(0,mapa);
end


process player (x,y)
begin
    z = -255;
graph = new_map(1,1,16);
    map_clear(0,graph,rgb(0,0,255));
    while (!key(_esc))
        Frame;
end;
unload_map(0,mouse);
end

process p_mapa (graph)
begin
    while (!key(_esc))
        Frame;
end;
end



El ratón en un pixel gigante rojo, el objeto a mover es un pixel gigante azul, las casillas libres son pixeles blancos, y las casillas ocupadas son pixeles grises. Apunta con el ratón a cualquier lado del mapa y a ver si funciona como tu quieres.
El mapa lo he agrandado a 16,16 para ver más posibilidades pero puedes encogerlo a lo que necesites cambiando las constantes.
Monstruos Diabólicos

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

Windgate

Yo creo que busca algo más sencillo que path_find, simplemente para mover las fichas a lo largo de una columna o de una fila, ¿Es así?

En ese caso puedes hacer:

FROM x = x_inicial TO x_final;
   IF ( matriz [ x ] [ y ] != 0 )
      RETURN FALSE;
   ELSE
      RETURN TRUE;
   END
END


El código anterior sirve para cuando se quiere mover en una fila y siempre y cuando la x final sea mayor que la inicial, pero a partir de él es trivial construir los 4 casos posibles.
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

DCelso

Monstruos Diabólicos

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

Hola

Quote from: Windgate on October 13, 2010, 07:25:35 PM
Yo creo que busca algo más sencillo que path_find, simplemente para mover las fichas a lo largo de una columna o de una fila, ¿Es así?

En ese caso puedes hacer:

FROM x = x_inicial TO x_final;
   IF ( matriz [ x ] [ y ] != 0 )
      RETURN FALSE;
   ELSE
      RETURN TRUE;
   END
END


El código anterior sirve para cuando se quiere mover en una fila y siempre y cuando la x final sea mayor que la inicial, pero a partir de él es trivial construir los 4 casos posibles.

Gracias por eso..., mm, ya tengo hecho que se mueven las fichas y eso..., mas bien lo que busco es que, el movimiento o desplazamiento a lo largo de la fila o columna desde una posicion inicial a una posicion final sea posible solo si no se encuentran casillas ocupadas en medio de este desplazamiento, osea entre punto A y punto B (punto A seria posicion inicial, no hablo de path find ni nada de eso, punto B seria posicion final o destino) para que el movimiento sea valido, tienen que haber todas casillas que por valor tengan cero, osea, estan libres..., si se encuentra un 1, el movimiento no se realiza.

Windgate

Entonces con mi solución te sobra, el path find es para movimientos más complejos, en plan laberintos y cosas así 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

Hola

#12
-.- xD, me dices que con tu solucion me sobra pero donde esta la solucion? xd, osea, con ese codigo que me has puesto lo que se logra es que el objeto o lo que sea se mueva a traves de las filas, columnas o lo que sea..., pero a ver nose si es que no me leen bien..., el movimiento esta muy bien, se mueve y todo pero no se como agregarle a ese codigo que me has puesto o directamente no se como hacer para que solo se mueva (de pos inicial a pos final) si comprueba que desde la pos inicial hasta la pos final no encuentra ningun obstaculo! me falta esa comprobacion, que compruebe si desde la casilla inicio hasta la final hay o no hay un obstaculo, si encuentra una casilla de valor 1 hay obstaculo entonces se cancela el movimiento y no puedes moverte hasta alli..., de lo contrario si desde pos inicial hasta pos final solo se ven ceros (casilleros libres), entonces puedes trasladarte tranquilamente hasta alli, hasta esa casilla..., porque significaria que no hay nada, no hay obstaculos.

Noivern

Quote from: Windgate on October 13, 2010, 07:25:35 PM
Yo creo que busca algo más sencillo que path_find, simplemente para mover las fichas a lo largo de una columna o de una fila, ¿Es así?

En ese caso puedes hacer:

FROM x = x_inicial TO x_final;
   IF ( matriz [ x ] [ y ] != 0 )
      RETURN FALSE;
   ELSE
      RETURN TRUE;
   END
END


El código anterior sirve para cuando se quiere mover en una fila y siempre y cuando la x final sea mayor que la inicial, pero a partir de él es trivial construir los 4 casos posibles.

Creo que te pasaste un pequeño error: el from no va a avanzar nunca al pillar un return si o si. En su lugar yo pondría:

FROM x = x_inicial TO x_final;
   IF ( matriz [ x ] [ y ] != 0 )
      RETURN FALSE; //si pilla un obstaculo, devuelve false, osea que no se puede realizar el movimiento
   END     
END
RETURN TRUE; //si llega a este punto es por que el camino está libre, es decir puede realizar el movimiento
END

Windgate

Me refería a un FROM dentro de una FUNCTION, para que la función retorne el valor indicando si el movimiento es posible o no.

Hola, sube el proyecto tal cual lo tienes y le echo un vistazo, si es medianamente legible te lo dejo listo y comentado.
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