como los reyes en ajedrez

Started by Hola, October 23, 2010, 04:50:40 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Hola

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

DCelso

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

Monstruos Diabólicos

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

Windgate

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í.
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

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..

Windgate

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í.
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

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.

Drumpi

(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).
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)

Hola

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.

DCelso

: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.
Monstruos Diabólicos

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

Drumpi

¿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
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)

DCelso

:), 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
Monstruos Diabólicos

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