package modelo;
import java.util.Set;
import modelo.excepciones.ExcepcionCasillaDestinoOcupada;
import modelo.excepciones.ExcepcionCoordenadaErronea;
import modelo.excepciones.ExcepcionMovimientoIlegal;
/**
* La clase Pieza.
*
* @author JESUS MANRESA PARRES
* @version 1.4
* @date 04.10.2012
*/
public abstract class Pieza
{
/** Variable privada de clase Pieza que indica el color de esta. */
private Color color;
/** Variable privada de clase Casilla que indica la casilla de la pieza. */
private Casilla casilla;
/** Variable que comprobara si el metodo setCasilla es llamado o no desde setPieza. */
private boolean mutex;
/** Variable que indica si una pieza ha movido */
protected boolean haMovido;
/**Variable que indica el valor */
protected double valor;
/**
* Contructor de clase Pieza.
*
* @param c Color de la pieza
*/
public Pieza(Color c)
{
color=c;
mutex=false;
haMovido=false;
}
/**
* Metodo que nos indica si una pieza es del mismo color que otra.
*
* @param p la pieza que queremos comprobar
* @return boolean
*/
public boolean isMismoColor(Pieza p){ return color==p.getColor();}
/**
* Metodo que devuelve el color de la pieza.
*
* @return Color
*/
public Color getColor() { return color; }
/**
* Metodo que devuelve si una pieza es valida o no.
*
* @return boolean
*/
public boolean isValida() { return color!=Color.NULO; }
/**
* Metodo que devuelve la casilla de la pieza.
*
* @return Casilla
*/
public Casilla getCasilla() { return casilla;}
/**
* Metodo que asigna una casilla a la pieza.
*
* @param c la Casilla
* @return boolean
*/
public boolean setCasilla(Casilla c)
{
if(c==casilla && c.getPieza()==this)
return true;
else
{
//Si la pieza tiene casilla asignada y no ha sido llamada desde setPieza
if(casilla!=null && !mutex)
return false;
//Si la casilla que le pasas por parametro tiene pieza asignada y no ha sido enviado desde setPieza
if(c.isOcupada() && !mutex)
return false;
if(isValida() && !c.isNula())
{
casilla=c;
if(!mutex)
{
casilla.changeMutex();
casilla.setPieza(this);
casilla.changeMutex();
}
return true;
}
}
return false;
}
/**
* Metodo que quita una pieza de la casilla.
*
* @return Casilla
*/
public Casilla quitaDeCasilla()
{
if(casilla!=null)
{
Casilla aux= casilla;
if(!mutex)
{
casilla.changeMutex();
casilla.quitaPieza();
casilla.changeMutex();
}
casilla=null;
return aux;
}
return null;
}
/**
* Metodo que indica si una pieza puede mover (casilla dentro de tablero y no ocupada, si esta
* ocupada que nosea del mismo color.
* @param c Casilla a la que se va a mover
* @return boolean
*/
public boolean puedeMover(Casilla c)
{
if(casilla!=null && isValida() && getCasillasAmenazadas().contains(c))
{
try
{
Pieza p= PartidaAjedrez.getInstancia().getPiezaAt(c.getCoordenada());
if(p!=null && isMismoColor(p))
return false;
else
{
if((this instanceof Rey) && c.isAmenazada(Pieza.changeColor(color)))
return false;
return true;
}
}
catch (ExcepcionCoordenadaErronea e)
{
System.err.println(e.getMessage());
}
}
return false;
}
/**
* Metodo que mueve la casilla si el movimiento es valido y no esta ocupada por una pieza
* del mismo color. SI es de disinto color la quitara del tablero y luego asignara nuestra
* pieza a esa casilla.
*
* @param c una casilla
* @throws ExcepcionMovimientoIlegal the excepcion movimiento ilegal
* @throws ExcepcionCasillaDestinoOcupada the excepcion casilla destino ocupada
*/
public void mueve(Casilla c) throws ExcepcionMovimientoIlegal, ExcepcionCasillaDestinoOcupada
{
Movimiento m= new MovimientoOrdinario(getCasilla().getCoordenada(), c.getCoordenada());
try
{
Casilla cas;
cas= PartidaAjedrez.getInstancia().getTablero().getCasillaAt(c.getCoordenada());
if(puedeMover(c))
{
if(cas.getPieza()!=null)
cas.quitaPieza();
quitaDeCasilla();
setCasilla(cas);
haMovido=true;
}
else
{
if(cas.getPieza()!=null && cas.getPieza().isMismoColor(this))
throw new ExcepcionCasillaDestinoOcupada(m);
else
throw new ExcepcionMovimientoIlegal(this,m);
}
}
catch (ExcepcionCoordenadaErronea e)
{
e.printStackTrace();
}
}
/**
* Metodo que nos dice si es el mismo tipo de pieza.
*
* @param p pieza
* @return boolean
*/
public abstract boolean isMismoTipo(Pieza p);
/**
* Metodo que devuelve el tipo de pieza.
*
* @return char
*/
public abstract char getTipo();
/**
* Setter
* @param c el color al que va a cambiar la pieza
*/
public void setColor(Color c)
{
//Comprobar si color es nulo
color=c;
}
/**
* Metood que indica si una pieza ha movido
* @return boolean
*/
public boolean haMovido()
{
return haMovido;
}
/**
* Devuelve el valor de la pieza
* @return double
*/
public double getValor()
{
return valor;
}
/**
* Cambia mutex de estado.
*/
public void changeMutex() { mutex=!mutex; }
/**
* Devuelve el estado de mutex.
*
* @return boolean
*/
public boolean getMutex() { return mutex; }
/**
* Metodo que devuelve la distancia entre columnas
* @param c Casilla a la que se va a mover
* @return int
*/
public int distColumn(Casilla c) { return (c.getCoordenada().getLetra() - getCasilla().getCoordenada().getLetra()); }
/**
* Metodo que devuelve la distancia entre filas.
* @param c Casilla a la que se va a mover
* @return int
*/
public int distRow(Casilla c) { return (c.getCoordenada().getY() - getCasilla().getCoordenada().getY()); }
/**
* Metodo que devuelve la diferencia entre dos casillas
* @param c la casilla con que marcara la diferencia
* @return int[]
*/
public int[] getDiferencia(Casilla c)
{
int[] dif= new int[2];
if(!casilla.isNula() && !c.isNula())
{
/** Diferencia vertical */
dif[0]= c.getCoordenada().getY() - casilla.getCoordenada().getY();
/** Diferencia horizontal */
dif[1]= c.getCoordenada().getLetra() - casilla.getCoordenada().getLetra();
return dif;
}
return null;
}
/**
* Change color.
* @param c the c
* @return the color
*/
public static Color changeColor(Color c)
{
if(c==Color.NEGRO)
return Color.BLANCO;
else if(c==Color.BLANCO)
return Color.NEGRO;
else
return Color.NULO;
}
/**
* Devuelve una lista de las casilllas a las que la pieza puede ir para comer otra pieza
* @return Set<Casilla>
*/
public abstract Set<Casilla> getCasillasAmenazadas();
}