Funciones generales para mover las piezas de ajedrez
Ahora veremos el código mas difícil de hacer, todo lo que hicimos hasta el momento ha estado relativamente fácil comparado con lo que vamos a ver. Pero creo que no va a ser tan dificil por que todo el codigo fuente esta explicado y será pan comido.
Antes de seguir debemos implementar algunas funciones que nos va a permitir controlar todas las movidas. Todo empieza desde la función OnLButtonDown que invoca a la función MoverFicha.
Función: MoverFicha
Algoritmo:
- Si hay una ficha seleccionada.
- Si la celda es nula o es del otro equipo, entonces intentamos mover la pieza.
- Sino, mostramos el mensaje “Movida no permitida” y volvemos a esperar la movida del usuario.
- Sino
- Si la celda esta vacía, no hacemos nada.
- Si la pieza corresponde al turno es el correcto:
- Cambiamos la variable m_celdaSel con la posición actual.
- Levantamos el flag m_bFichaSeleccionada
- Mostramos un mensaje para hacerle saber al usuario que debe realizar el siguiente paso.
- Refrescar la pantalla.
void CAjedrezView::MoverFicha(int x,int y) { if(m_bFichaSeleccionada) { if(EsCeldaNula(x,y) || (!EsPiezaBlanca(x,y) && m_bTurnoBlancas) || (EsPiezaBlanca(x,y) && !m_bTurnoBlancas)) { IntentarMovidaHacia(x,y); } else { Mensaje("Movida no permitida"); CancelarMovida(); } } else { if(EsCeldaNula(x,y)) return; if((EsPiezaBlanca(x,y) && m_bTurnoBlancas ) || (!EsPiezaBlanca(x,y) && !m_bTurnoBlancas)) { m_celdaSel.x = x; m_celdaSel.y = y; m_bFichaSeleccionada = true; Mensaje("Presione ESC para cancelar la selección"); Invalidate(); } } }
Función: IntentarMovidaHacia
Algoritmo:
- Obtener el valor de la celda de la celda seleccionada.
- Identificar el tipo de pieza y e invocar a la función que corresponde.
- Si hay resultado exitoso al intentar mover la pieza
- Mostrar mensaje
- Realizar la movida.
- Sino
- Mostar mensaje de error
Implementación:
void CAjedrezView::IntentarMovidaHacia(int x, int y) { int nPiezaActual = m_pCeldas[m_celdaSel.y][m_celdaSel.x]; bool bSePuedeMover = false; switch(nPiezaActual) { case PEONB: case PEONN: bSePuedeMover = MoverPeonHacia(x,y); break; case ALFILB: case ALFILN: bSePuedeMover = MoverAlfilHacia(x,y); break; case CABALLOB: case CABALLON: bSePuedeMover = MoverCaballoHacia(x,y); break; case REYB: case REYN: bSePuedeMover = MoverReyHacia(x,y); break; case REINAB: case REINAN: bSePuedeMover = MoverReinaHacia(x,y); break; case TORREB: case TORREN: bSePuedeMover = MoverTorreHacia(x,y); break; } if(bSePuedeMover) { Mensaje("Movida correcta, siguiente jugador"); RealizarMovida(x, y); } else { Mensaje("Movida incorrecta, intenta nuevamente"); CancelarMovida(); } }
La función EsViaLibre
Algoritmo:
- Inicialmente obtenemos la diferenca entre las coordenadas, esto nos ayudará a identificar que tipo de movida se ha realizado.
- Si la diferencia de las coordenadas x es igual a cero entonces se ha realizado un movimiento vertical.
- Recorremos todas las celdas que hay entre las dos coordenadas, si encontramos alguna celda con una pieza de ajedrez entonces retornamos false.
- Si la diferencia de las coordenadas y es igual a cero entonces se ha realizado un movimiento horizontal.
- Recorremos todas las celdas que hay entre las dos coordenadas, si encontramos alguna celda con una pieza de ajedrez entonces retornamos false.
- Si la diferencia de las coordenas x e y son iguales entonces se ha realizado un movimiento diagonal
- Recorremos todas las celdas que hay entre las dos coordenadas, si encontramos alguna celda con una pieza de ajedrez entonces retornamos false.
- Si al final no se ha determinado que tipo de movimiento se ha realizado entonces se devuelve el valor de ok que en ese punto deberá ser false.
Codigo fuente de la función EsViaLibre
bool CAjedrezView::EsViaLibre(int x, int y) { int dify = y - m_celdaSel.y; int difx = x - m_celdaSel.x; bool ok = true; if(difx == 0) //Movimiento Vertical { for(int i = 1 ; i < abs(dify) ; i++) { if(m_pCeldas[m_celdaSel.y + (dify<0?-i:i)][m_celdaSel.x] != VACIO) { ok = false; } } } else if(dify == 0) //Movimiento Horizontal { for(int i = 1 ; i < abs(difx) ; i++) { if(m_pCeldas[m_celdaSel.y][m_celdaSel.x + (difx<0?-i:i)] != VACIO ) { ok = false; } } } else if(abs(difx) == abs(dify)) //Movimiento diagonal { for(int i = 1 ; i < abs(dify) ; i++) { if(m_pCeldas[m_celdaSel.y + (dify<0?-i:i)][m_celdaSel.x + (difx<0?-i:i)] != VACIO) { ok = false; } } } return ok; }
En adelante, para todos los casos se utilizará la diferencia de coordenadas, por que es una manera facil y rápida de identificar la dirección y tipo de movida.
Función: RealizarMovida
Algoritmo:
- Cambiar turno de jugador.
- Ubicar la pieza de origen a la posición de destino.
- Cambiar los valores que tienen que ver con la ficha seleccionada.
- Repintar.
Codigo fuente de la función RalizarMovida.
void CAjedrezView::RealizarMovida(int x, int y) { //Cambiar Turno m_bTurnoBlancas = !m_bTurnoBlancas; //Asignar la pieza de origen al destino m_pCeldas[y][x] = m_pCeldas[m_celdaSel.y][m_celdaSel.x]; //TODO: Agregar a la lista de eliminados m_pCeldas[m_celdaSel.y][m_celdaSel.x] = VACIO; //Soltar la ficha seleccionada m_bFichaSeleccionada = false; m_celdaSel.x = -1; m_celdaSel.y = -1; Invalidate(); }
Hola amigo como estas, oye estoy interesado en una plataforma de juegos, ajedrez, damas inglesas, bagkammon y dominó, me gustaría platicar contigo haber si estas interesado, que tengas un excelente día
Claro, cuando quieras
https://youtu.be/6nw9wMbbQoc