package modelo;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import modelo.excepciones.ExcepcionCasillaDestinoOcupada;
import modelo.excepciones.ExcepcionCasillaOrigenVacia;
import modelo.excepciones.ExcepcionCoordenadaErronea;
import modelo.excepciones.ExcepcionMovimientoCoronacion;
import modelo.excepciones.ExcepcionMovimientoIlegal;
import modelo.excepciones.ExcepcionNoExisteMovimiento;
import modelo.excepciones.ExcepcionPiezaDesconocida;
import modelo.excepciones.ExcepcionPosicionNoValida;
import modelo.excepciones.ExcepcionTurnoDelContrario;
/**
* Clase PartidaAjedrez.
* @author JESUS MANRESA PARRES
* @version 4.0
* @date 09/11/2012
*/
public class PartidaAjedrez
{
/** Variable privada de clase que instancia nuestra clase. */
private static PartidaAjedrez partida;
/** Variable privada que indica nuestro fichero de entrada. */
private String fentrada;
/** Variable privada que indica nuestro fichero de salida. */
private String fsalida;
/** Vector de piezas. */
private ArrayList <Pieza> piezas;
/** Vector de casillas. */
private ArrayList <Movimiento> movs;
/** Varialbe que relaciona con Tablero. */
private Tablero tablero;
/** Variable de turno*/
Color turno;
/**
* Constructor protegido de clase, solo puede ser llamado por metodos del mismo paquete.
*/
protected PartidaAjedrez()
{
tablero= new Tablero(8,8);
piezas= new ArrayList<Pieza>();
movs= new ArrayList<Movimiento>();
turno= Color.BLANCO;
}
/**
* Getter.
* @return PartidaAjedrez
*/
public static PartidaAjedrez getInstancia()
{
if(partida==null)
partida= new PartidaAjedrez();
return partida;
}
/**
* Run.
* @throws FileNotFoundException la excepcion filenotnofound
*/
public void run() throws FileNotFoundException
{
if(fentrada!=null)
{
colocaPiezas();
cargaMovimientos();
}
try
{
int i=0;
while(i<movs.size())
{
ejecutaMovimiento(i);
i++;
}
}
catch (ExcepcionNoExisteMovimiento e)
{
System.err.println("Error " + e.getMessage());
}
catch (ExcepcionCasillaOrigenVacia e)
{
System.err.println("Error " + e.getMessage());
}
catch (ExcepcionTurnoDelContrario e)
{
System.err.println("Error " + e.getMessage());
}
if(piezas.size()==0 && movs.size()==0)
inicializaTablero();
if(fsalida!=null)
{
PrintStream ps= new PrintStream(fsalida);
ps.print(toString());
ps.close();
}
}
/**
* Inicializa el tablero con todas las piezas.
*/
private void inicializaTablero()
{
int i= getTablero().getDimy();
char letra='A';
Color color= Color.NULO;
try
{
while(i>0)
{
if(i==2 || i==7)
{
if(i==2)
color=Color.BLANCO;
else
color=Color.NEGRO;
int j=8;
while(j>0)
{
tablero.colocaPiezaAt(new Coordenada(letra,i), FactoriaPieza.creaPieza('P', color));
piezas.add(getPiezaAt(new Coordenada(letra,i)));
letra++;
j--;
}
}
letra='A';
i--;
}
//Piezas Blancas
tablero.colocaPiezaAt(new Coordenada('H',1), FactoriaPieza.creaPieza('T', Color.BLANCO));
piezas.add(getPiezaAt(new Coordenada('H',1)));
tablero.colocaPiezaAt(new Coordenada('G',1), FactoriaPieza.creaPieza('C', Color.BLANCO));
piezas.add(getPiezaAt(new Coordenada('G',1)));
tablero.colocaPiezaAt(new Coordenada('F',1), FactoriaPieza.creaPieza('A', Color.BLANCO));
piezas.add(getPiezaAt(new Coordenada('F',1)));
tablero.colocaPiezaAt(new Coordenada('E',1), FactoriaPieza.creaPieza('R', Color.BLANCO));
piezas.add(getPiezaAt(new Coordenada('E',1)));
tablero.colocaPiezaAt(new Coordenada('D',1), FactoriaPieza.creaPieza('D', Color.BLANCO));
piezas.add(getPiezaAt(new Coordenada('D',1)));
tablero.colocaPiezaAt(new Coordenada('C',1), FactoriaPieza.creaPieza('A', Color.BLANCO));
piezas.add(getPiezaAt(new Coordenada('C',1)));
tablero.colocaPiezaAt(new Coordenada('B',1), FactoriaPieza.creaPieza('C', Color.BLANCO));
piezas.add(getPiezaAt(new Coordenada('B',1)));
tablero.colocaPiezaAt(new Coordenada('A',1), FactoriaPieza.creaPieza('T', Color.BLANCO));
piezas.add(getPiezaAt(new Coordenada('A',1)));
//Piezas Negras
tablero.colocaPiezaAt(new Coordenada('H',8), FactoriaPieza.creaPieza('T', Color.NEGRO));
piezas.add(getPiezaAt(new Coordenada('H',8)));
tablero.colocaPiezaAt(new Coordenada('G',8), FactoriaPieza.creaPieza('C', Color.NEGRO));
piezas.add(getPiezaAt(new Coordenada('G',8)));
tablero.colocaPiezaAt(new Coordenada('F',8), FactoriaPieza.creaPieza('A', Color.NEGRO));
piezas.add(getPiezaAt(new Coordenada('F',8)));
tablero.colocaPiezaAt(new Coordenada('E',8), FactoriaPieza.creaPieza('R', Color.NEGRO));
piezas.add(getPiezaAt(new Coordenada('E',8)));
tablero.colocaPiezaAt(new Coordenada('D',8), FactoriaPieza.creaPieza('D', Color.NEGRO));
piezas.add(getPiezaAt(new Coordenada('D',8)));
tablero.colocaPiezaAt(new Coordenada('C',8), FactoriaPieza.creaPieza('A', Color.NEGRO));
piezas.add(getPiezaAt(new Coordenada('C',8)));
tablero.colocaPiezaAt(new Coordenada('B',8), FactoriaPieza.creaPieza('C', Color.NEGRO));
piezas.add(getPiezaAt(new Coordenada('B',8)));
tablero.colocaPiezaAt(new Coordenada('A',8), FactoriaPieza.creaPieza('T', Color.NEGRO));
piezas.add(getPiezaAt(new Coordenada('A',8)));
}
catch(ExcepcionCoordenadaErronea e)
{
System.err.println(e.getMessage());
}
}
/**
* Setter.
* @param f nombre de fichero de entrada
*/
public void setEntrada(String f)
{
fentrada= f;
}
/**
* Setter.
* @param f nombre de fichero de salida
*/
public void setSalida(String f)
{
fsalida= f;
}
/**
* Getter.
* @return String
*/
public String getEntrada()
{
return fentrada;
}
/**
* Getter.
* @return String
*/
public String getSalida()
{
return fsalida;
}
/**
* Getter.
* @return Tablero
*/
public Tablero getTablero()
{
return tablero;
}
/**
* Getter.
* @param c the c
* @return Pieza
* @throws ExcepcionCoordenadaErronea the excepcion coordenada erronea
*/
public Pieza getPiezaAt(Coordenada c) throws ExcepcionCoordenadaErronea
{
return tablero.getCasillaAt(c).getPieza();
}
/**
* Getter.
* @param numMov numero de movimiento
* @return Movimiento
* @throws ExcepcionNoExisteMovimiento the excepcion no existe movimiento
*/
public Movimiento getMovimientoAt(int numMov) throws ExcepcionNoExisteMovimiento
{
if(numMov>=movs.size() || movs.get(numMov)==null)
throw new ExcepcionNoExisteMovimiento(numMov);
else
return movs.get(numMov);
}
/**
* Metodo que anyade un movimiento al vector de movimientos.
* @param co coordenada origen
* @param cd coordenada destino
* @throws ExcepcionCoordenadaErronea the excepcion coordenada erronea
*/
public void addMovimiento(Coordenada co, Coordenada cd) throws ExcepcionCoordenadaErronea
{
if(tablero.getCasillaAt(co)==null)
throw new ExcepcionCoordenadaErronea(co.getLetra(), co.getY());
else if(tablero.getCasillaAt(cd)==null)
throw new ExcepcionCoordenadaErronea(co.getLetra(), co.getY());
else
movs.add(new MovimientoOrdinario(co,cd));
}
/**
* Metodo que devuelve el numero de movimientos realizados.
* @return int
*/
public int getNumMovimientos()
{
return movs.size();
}
/**
* Tostring.
* @return String
*/
public String toString()
{
Pieza p;
Coordenada c;
String cadena= new String();
int i,j;
i= tablero.getDimy();
j= tablero.getDimx();
char letra='A';
char tipo='\0';
try
{
while(i>0)
{
while(j>0)
{
c= new Coordenada(letra, i);
p= PartidaAjedrez.getInstancia().getPiezaAt(c);
if(p!=null)
{
if(p instanceof Rey)
tipo='R';
else if(p instanceof Peon)
tipo='P';
else if(p instanceof Alfil)
tipo='A';
else if(p instanceof Torre)
tipo='T';
else if(p instanceof Caballo)
tipo='C';
else if(p instanceof Dama)
tipo='D';
if(p.getColor().equals(Color.BLANCO))
cadena+= tipo;
else
cadena+= Character.toLowerCase(tipo);
}
else
cadena+="-";
letra++;
j--;
}
cadena+="\n";
letra='A';
i--;
j=8;
}
}
catch(ExcepcionCoordenadaErronea e)
{
System.err.println(e.getMessage());
}
return cadena;
}
/**
* Metodo que coloca las piezas.
*/
protected void colocaPiezas()
{
File f= new File(fentrada);
Scanner sc;
try
{
sc = new Scanner(f);
String line="";
while(sc.hasNext())
{
line= sc.nextLine();
System.out.println(line);
if(line.length()==5)
if(line.charAt(1)<'1' || line.charAt(1)>'8')
colocaPieza(line);
}
if(piezas.size()==0)
inicializaTablero();
}
catch (FileNotFoundException e)
{
System.err.println(e.getMessage());
}
catch (ExcepcionCoordenadaErronea e)
{
System.err.println(e.getMessage());
}
catch (ExcepcionPiezaDesconocida e)
{
System.err.println(e.getMessage());
}
catch (ExcepcionPosicionNoValida e)
{
System.err.println(e.getMessage());
}
}
/**
* Metodo que separa coloca la pieza que se le pasa por parametro
* @param s String
* @throws ExcepcionCoordenadaErronea the excepcion coordenada erronea
* @throws ExcepcionPiezaDesconocida the excepcion pieza desconocida
* @throws ExcepcionPosicionNoValida the excepcion posicion no valida
*/
protected void colocaPieza(String s) throws ExcepcionCoordenadaErronea, ExcepcionPiezaDesconocida, ExcepcionPosicionNoValida
{
Color color= Color.NULO;
Pieza coloca= null;
char[] pchar = new char[2];
pchar[0]= s.charAt(0);
pchar[1]= s.charAt(1);
String pieza= String.copyValueOf(pchar);
pchar[0]= s.charAt(3);
pchar[1]= s.charAt(4);
String casilla= String.copyValueOf(pchar);
if(pieza.charAt(1)=='n')
color= Color.NEGRO;
else if(pieza.charAt(1)=='b')
color= Color.BLANCO;
if(pieza!=null)
coloca= FactoriaPieza.creaPieza(pieza.charAt(0), color);
if(coloca==null)
throw new ExcepcionPiezaDesconocida(pieza.charAt(0));
try
{
Coordenada coor= new Coordenada(casilla.charAt(0), Integer.parseInt(Character.toString(casilla.charAt(1))));
Casilla cas= PartidaAjedrez.getInstancia().getTablero().getCasillaAt(coor);
if(cas==null)
throw new ExcepcionCoordenadaErronea(coor.getLetra(), coor.getY());
else if(cas!=null && cas.isOcupada())
throw new ExcepcionPosicionNoValida(coor);
else
{
tablero.colocaPiezaAt(cas.getCoordenada(), coloca);
piezas.add(coloca);
}
}
catch(ExcepcionCoordenadaErronea e)
{
System.err.println("Error: " + e.getMessage());
}
}
/**
* Metodo que carga los movimientos.
*/
protected void cargaMovimientos()
{
File f= new File(fentrada);
Scanner sc;
Coordenada co, cd;
try
{
sc = new Scanner(f);
String line="";
while(sc.hasNext())
{
line= sc.nextLine();
if(line.length()>=5)
{
if(line.charAt(0)>='A' && line.charAt(0)<='H'
&& line.charAt(1)>='1' && line.charAt(1)<='8'
&& line.charAt(3)>='A' && line.charAt(3)<='H'
&& line.charAt(4)>='1' && line.charAt(4)<='8')
{
co= new Coordenada(line.charAt(0), Integer.parseInt(Character.toString(line.charAt(1))));
cd= new Coordenada(line.charAt(3), Integer.parseInt(Character.toString(line.charAt(4))));
if(line.length()>5)
{
int i=5;
String s= new String();
while(i<line.length())
{
s+=line.charAt(i);
i++;
}
Color c= PartidaAjedrez.getInstancia().getPiezaAt(co).getColor();
try
{
Pieza p= FactoriaPieza.creaPieza(s, c);
System.out.println("Pieza");
if(p!=null)
addMovimientoCoronacion(co, cd, p);
}
catch (ExcepcionPiezaDesconocida e)
{
System.err.println(e.getMessage());
}
}
else
addMovimiento(co,cd);
}
}
}
}
catch (FileNotFoundException e)
{
System.err.println(e.getMessage());
}
catch (ExcepcionCoordenadaErronea e)
{
System.err.println(e.getMessage());
}
}
/**
* Metodo que ejecuta los movimeintos.
* @param i the integer
* @throws ExcepcionNoExisteMovimiento la excepcion no existe movimiento
* @throws ExcepcionCasillaOrigenVacia la excepcion casilla origen vacia
* @throws ExcepcionTurnoDelContrario la excepcion turno del contrario
*/
protected void ejecutaMovimiento(int i) throws ExcepcionNoExisteMovimiento, ExcepcionCasillaOrigenVacia, ExcepcionTurnoDelContrario
{
if(i<=movs.size())
{
Movimiento m= getMovimientoAt(i);
Coordenada co= m.getCoordenadaOrigen();
Coordenada cd= m.getCoordenadaDestino();
if(m!=null)
{
try
{
Pieza p= getPiezaAt(co);
Casilla cas= tablero.getCasillaAt(cd);
if(p!=null && p.getColor().equals(turno))
{
if(cas!=null)
{
if(m instanceof MovimientoOrdinario)
p.mueve(cas);
else if(m instanceof MovimientoCoronacion)
{
if(p.puedeMover(cas))
{
p.mueve(cas);
p.quitaDeCasilla();
Pieza pi= ((MovimientoCoronacion) m).getPieza();
pi.setCasilla(cas);
piezas.add(pi);
}
}
turno= Pieza.changeColor(turno);
}
}
}
catch (ExcepcionCoordenadaErronea e)
{
System.err.println("Error " + e.getMessage());
}
catch (ExcepcionMovimientoIlegal e)
{
System.err.println("Error " + e.getMessage());
}
catch (ExcepcionCasillaDestinoOcupada e)
{
System.err.println("Error " + e.getMessage());
}
}
}
else
throw new ExcepcionNoExisteMovimiento(i);
}
/**
* Metodo que dado un color devuelve una lista de las piezas de ese color
* @param c el color
* @return List<Pieza>
*/
public List<Pieza> getPiezas(Color c)
{
List<Pieza> lista= new ArrayList<Pieza>();
int i=0;
while(i<piezas.size())
{
if(piezas.get(i)!=null && piezas.get(i).getColor().equals(c))
lista.add(piezas.get(i));
i++;
}
return lista;
}
/**
* Metodo que corona un peon
* @param peon el peon a coronar
* @param pieza la pieza coronada
* @throws ExcepcionMovimientoCoronacion la excpecion
*/
protected void coronar(Peon peon, Pieza pieza) throws ExcepcionMovimientoCoronacion
{
Casilla cas;
try
{
if(peon!=null && peon.isEnUltimaFila() && pieza!=null
&& pieza.getCasilla()==null && peon.isMismoColor(pieza))
{
if(!(pieza instanceof Rey) && !(pieza instanceof Peon))
{
cas= tablero.getCasillaAt(peon.getCasilla().getCoordenada());
peon.quitaDeCasilla();
tablero.colocaPiezaAt(cas.getCoordenada(), pieza);
piezas.add(pieza);
}
else
throw new ExcepcionMovimientoCoronacion(peon, pieza);
}
else
throw new ExcepcionMovimientoCoronacion(peon, pieza);
}
catch (ExcepcionCoordenadaErronea e)
{
System.err.println(e.getMessage());
}
}
/**
* Metodo que anyade un movimiento al vector de movimientos Coronacion
* @param co coordenada origen
* @param cd coordenada destino
* @throws ExcepcionCoordenadaErronea the excepcion coordenada erronea
*/
public void addMovimientoCoronacion(Coordenada co, Coordenada cd, Pieza p) throws ExcepcionCoordenadaErronea
{
if(tablero.getCasillaAt(co)==null)
throw new ExcepcionCoordenadaErronea(co.getLetra(), co.getY());
else if(tablero.getCasillaAt(cd)==null)
throw new ExcepcionCoordenadaErronea(co.getLetra(), co.getY());
else
movs.add(new MovimientoCoronacion(co,cd,p));
}
}