Hola, otra vez necesito algo referido a las matrices y todo eso..., nose porque no me sale, lo hago supuestamente de la forma correcta, pero nose que pasa con la matriz..., no me voy a poner a explicar todo el problema..., pero bueno, lo que necesito simplemente, es hacer algo parecido a lo que hacen los reyes en el ajedrez..., que no se puedan acercar..., que esten a una casilla de distancia y no se puedan juntar, bueno, vamos, como los reyes de un juego de ajedrez..., yo lo intente hacer, pero nose que hace el programa..., es como que confunde los numeros de la matriz, intente resolver el problema tambien, pero parece que no tiene caso, en fin...
gracias
Hola, esta funcion vale para moverte a cualquier posición en la que no haya ninguna ficha adyacente a su alrededor, osea sirve para el movimiento del rey pero puedes también usarla para movimientos mayores a una sola casilla. :D.
function puedo_moverme(actual_x,actual_y, siguiente_x, siguiente_y)
private
int valor_actual_en_matriz;
int retorno;
begin
valor_actual_en_matriz = matriz[actual_x][actual_y]; // copio dato de la matriz
matriz[actual_x][actual_y]= 0; // pongo un cero para simular que me he ido
retorno = nadie_adyacente(siguiente_x,siguiente_y); // miro si no hay nadie adyacente a la nueva posicion
matriz[actual_x][actual_y]= actual_en_matriz; // pongo el valo que copie en la matriz.
return retorno; // devuelvo si es posible moverse
end
function nadie_adyacente(x,y)
private
begin
if ( matriz[x+1][y] ==1 )
return false;
end
if ( matriz[x-1][y] ==1 )
return false;
end
if (matriz
- [y+1] ==1)
return false;
end
if (matriz - [y-1] ==1)
return false;
end
if (matriz[x+1][y+1] ==1)
return false;
end
if (matriz[x-1][y+1] ==1)
return false;
end
if (matriz[x+1][y-1] ==1)
return false;
end
if (matriz[x-1][y-1] ==1)
return false;
end
return true;
end
Ahí está la solución DCelso, ¿Le sirve tal y como lo tiene implementado?, para eso hace falta conocer bien su estructura de datos.
Para hacer un buen ajedrez con IA ya sí que necesitas algoritmos de IA como A*. Me vienen a la mente el MiniMax y alguna cosa más... La verdad es que esos temas no me llaman mucho la atención, ya ha habido alguien que lo ha resuelto en su día, seguro que un código C que lo resuelve está disponible por ahí.
Ok.. , he copiado y pegado la funcion en mi programa..., basicamente hace lo mismo que yo habia logrado hacer..., pero sigo teniendo el mismo problema..., a ver..., supongamos que tengo los dos reyes, un rey en 4,7 y el otro en 4,0, olvidemos las otras fichas, esta el rey en 4,7 y el otro en 4,0 y no hay nada mas, ok..., ahora tomo el rey de 4,0 y lo subo una casilla, se encontraria en 4,1 , y aqui viene el problema..., si quiero (desde alli), bajar otra vez (a 4,0) no me deja..., lo mismo me pasa, estando en 4,0, si me quiero mover una casilla hacia la derecha (5,0), no me deja.., es como si abajo de la matriz estuviera el otro rey o nose..., el otro rey esta en la otra punta, se supone que el rey de 4,0 se debe mover sin problemas ya que no hay ningun rey abajo (y no podria haber nunca, ya que la Y de la matriz esta 0, no hay nada antes del 0)..., nose si se entiende el problema..
La matriz que almacena las "fichas" que hay posicionada debe estar actualizada, esto es, si mueves el rey de la (4,0) a la (4,1) deberías modificar la (4,0) para dejarla "vacía" y poner el rey en la (4,1).
Para cada pieza del tablero de ajedrez podrías usar un entero. El 0 indica que la casilla está libre, mientras que números distintos de 0 indican la pieza, un ejemplo:
_PEON = 1;
_TORRE = 2;
_ALFIL = 3;
...
El problema potencial vendría cuando se trata de determinar si las piezas son blancas o negras, para ese caso puedes utilizar tipos de dato y almacenar en cada casilla el color de la pieza (_BLANCO = 0; _NEGRO = 1) además del tipo de pieza o algo así.
Si..., todo eso lo tengo hecho..., la posicion se actualiza y todo, tengo el peon en 1, torre en 2, etc..., pero como dije antes, tengo este problema con el rey..., nose como solucionarlo.
(4,0) y (4,7)... me suena a mi que se está provocando una salida del rango de valores válidos. Es decir, que estás intentando acceder a (4,-1), posición que no existe en la matriz... o más bien que sí existe, pero en realidad es la (3,7), que queda justo al lado del otro rey.
Cuidado con salirse del rango de valores de matrices, es el principal motivo de "segmentation faults", errores en ejecución y fallos con los punteros.
No sé si será el error, pero mi intuición me dice que sí (y no suele fallar... a menos que lo mencione ^^U).
Quote from: Drumpi on October 24, 2010, 01:43:09 AM
(4,0) y (4,7)... me suena a mi que se está provocando una salida del rango de valores válidos. Es decir, que estás intentando acceder a (4,-1), posición que no existe en la matriz... o más bien que sí existe, pero en realidad es la (3,7), que queda justo al lado del otro rey.
Cuidado con salirse del rango de valores de matrices, es el principal motivo de "segmentation faults", errores en ejecución y fallos con los punteros.
No sé si será el error, pero mi intuición me dice que sí (y no suele fallar... a menos que lo mencione ^^U).
Algo de eso habia pensado, me parece que tienes buena intuicion xD, ya creo que lo solucioné, en realidad, hice una trampa en la matriz..., la tenia en 7x7, la modifique y la puse en 8x8 y ya está..., no es una solucion muy limpia pero bueno, lo importante es el resultado..., ahora cuando quiera bajar el rey de (4,1) a (4,0), va a intentar ver si hay un rey en la (4,8)..., que seria una fila vacia...jeje.
:D, olvidé intencionadamente las salidas de rango (creí que eso ya se sabría :D y la tuya de aumentar la matriz no está mal :) ), pero se puede solucionar con unos ifs de la siguiente forma:
function puedo_moverme(actual_x,actual_y, siguiente_x, siguiente_y)
private
int valor_actual_en_matriz;
int retorno;
begin
valor_actual_en_matriz = matriz[actual_x][actual_y]; // copio dato de la matriz
matriz[actual_x][actual_y]= 0; // pongo un cero para simular que me he ido
retorno = nadie_adyacente(siguiente_x,siguiente_y); // miro si no hay nadie adyacente a la nueva posicion
matriz[actual_x][actual_y]= actual_en_matriz; // pongo el valo que copie en la matriz.
return retorno; // devuelvo si es posible moverse
end
function nadie_adyacente(x,y)
private
begin
if (x+1 < MAX_X) // si no nos salimos del máximo en X
if ( matriz[x+1][y] ==1 )
return false;
end
if (y+1 < MAX_Y) // si no nos salimos del máximo en y
if (matriz[x+1][y+1] ==1)
return false;
end
end
if (y-1 > -1) // si no nos salimos del mínimo en y
if (matriz[x+1][y-1] ==1)
return false;
end
end
end
if (x-1 > -1) // si no nos salimos del mínimo en x
if ( matriz[x-1][y] ==1 )
return false;
end
if (y+1 < MAX_Y) // si no nos salimos del máximo en y
if (matriz[x-1][y+1] ==1)
return false;
end
end
if (y-1 > -1) // si no nos salimos del mínimo en y
if (matriz[x-1][y-1] ==1)
return false;
end
end
end
if (matriz [y+1] ==1)
return false;
end
if (matriz [y-1] ==1)
return false;
end
return true;
end
Son las mismas ocho comprobaciones reorganizadas para poder comprobar los límites de la matriz.
¿Y no es más fácil usar dos bucles anidados, usando 4 índices (2 horizontales y 2 verticales) que se modifican en función que cuantas casillas se pueden leer? Vale, comprobarás el centro donde está tu propio rey, pero es un mal menor ^^U
:), pues sí, muchas formas haberlas haylas :D.
Yo hice la que puse porque es la primera que se me ocrrió y me parecía muy intuitiva :D.
function nadie_adyacente(x,y)
private
i,j;
x_ini, x_fin
y_ini,y_fin;
begin
// condicionales para esquivar extremos de la matriz
if (x > 0)
x_ini = x-1;
else
x_ini = 0;
end
if (y > 0)
y_ini = y-1;
else
y_ini = 0;
end
if (x < MAX_X -1)
x_fin = x +1
else
x_fin = MAX_X ;
end
if (y > 0)
y_ini = y-1;
else
y_ini = 0;
end
if (y < MAX_Y -1)
y_fin = y +1:
else
y_fin = MAX_Y ;
end
// bucle para comprobar la matriz
for (i = x_ini ; i<x_fin; i++)
for (j = y_ini ; j<y_fin; j++)
// si estamos en una posición distinta a la pasada por parámetro (x,y) comprobamos matriz
if (i != x AND j!= y AND matriz[i][j]==1)
return false;
end
end
end
return true;
end