package logic;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Map;
import java.util.Set;
import logic.PieceMovements.MovementDirection;
import models.Board;
import models.Piece;
import models.Square;
import utility.FileUtility;
import com.google.common.collect.Maps;
public class PieceBuilder implements Serializable
{
/**
* Static Initializer Read in the saved HashMap from a file. If that fails,
* build a new HashMap with Classic chess pieces and save that to a file.
*/
static
{
initPieceTypes();
}
/**
* Initialize types...
*/
public static void initPieceTypes()
{
mPieceTypes = Maps.newHashMap();
mPieceTypes.put(Messages.getString("pawn"), new PieceBuilder(Messages.getString("pawn"))); //$NON-NLS-1$ //$NON-NLS-2$
mPieceTypes.put(Messages.getString("rook"), new PieceBuilder(Messages.getString("rook"))); //$NON-NLS-1$ //$NON-NLS-2$
mPieceTypes.put(Messages.getString("bishop"), new PieceBuilder(Messages.getString("bishop"))); //$NON-NLS-1$ //$NON-NLS-2$
mPieceTypes.put(Messages.getString("knight"), new PieceBuilder(Messages.getString("knight"))); //$NON-NLS-1$ //$NON-NLS-2$
mPieceTypes.put(Messages.getString("queen"), new PieceBuilder(Messages.getString("queen"))); //$NON-NLS-1$ //$NON-NLS-2$
mPieceTypes.put(Messages.getString("king"), new PieceBuilder(Messages.getString("king"))); //$NON-NLS-1$ //$NON-NLS-2$
}
/**
* Constructor. Generic Constructor, initializing movement HashMap.
*/
public PieceBuilder()
{
// TODO: are both of these constructors necessary?
mPieceMovements = new PieceMovements();
}
/**
* Constructor. Initializes name and movement HashMap based on given
* parameter.
*
* @param name Name of desired Piece.
*/
public PieceBuilder(String name)
{
/*
* Changes made here. PieceBuilders need to check if they already have
* an instantiation before making another copy of movements.
*/
mName = name;
if (!PieceBuilder.isPieceType(name))
mPieceMovements = new PieceMovements();
else
mPieceMovements = mPieceTypes.get(name).getPieceMovements();
}
/**
* Get the Set of the names of Piece types
*
* @return The Set of names of Piece types
*/
public static Set<String> getSet()
{
return mPieceTypes.keySet();
}
/**
* Check if there is a Piece type of a given name
*
* @param name The Piece type being searched for
* @return Whether or not there is a Piece type with the given name
*/
public static boolean isPieceType(String name)
{
return mPieceTypes.containsKey(name);
}
/**
* Make a new instance of a Piece type
*
* @param name The name of the Piece to make
* @param isBlack The team for the Piece
* @param origin The Square the Piece occupies
* @param board The Board the Piece occupies
* @return The new Piece
* @throws IOException
*/
public static Piece makePiece(String name, boolean isBlack, Square origin, Board board) throws IOException
{
PieceBuilder loadedBuilder = loadFromDisk(name);
if (loadedBuilder == null)
{
loadedBuilder = new PieceBuilder(name);
}
if (!mPieceTypes.containsKey(name))
mPieceTypes.put(name, loadedBuilder);
return mPieceTypes.get(name).makePiece(isBlack, origin, board);
}
/**
* Save the given PieceBuilder in the HashMap
*
* @param p The PieceBuilder to save
*/
public static void savePieceType(PieceBuilder p)
{
mPieceTypes.put(p.mName, p);
}
public static void writeToDisk(PieceBuilder p)
{
try
{
FileOutputStream f_out = new FileOutputStream(FileUtility.getPieceFile(p.mName));
ObjectOutputStream out = new ObjectOutputStream(f_out);
out.writeObject(p);
out.close();
f_out.close();
}
catch (Exception e)
{
}
}
public static PieceBuilder loadFromDisk(String pieceName)
{
PieceBuilder toReturn;
if (mPieceTypes.containsKey(pieceName))
return mPieceTypes.get(pieceName);
try
{
ObjectInputStream in = new ObjectInputStream(new FileInputStream(FileUtility.getPieceFile(pieceName)));
toReturn = (PieceBuilder) in.readObject();
in.close();
return toReturn;
}
catch (Exception e)
{
e.printStackTrace();
return null;
}
}
public void addMovement(MovementDirection direction, int distance)
{
mPieceMovements.addMovement(direction, distance);
}
/**
* Make a new instance of a Piece type
*
* @param isBlack The team of the Piece
* @param origin The Square this Piece is on
* @param board the Board this Piece is on
* @return The created Piece object
* @throws IOException
*/
private Piece makePiece(boolean isBlack, Square origin, Board board) throws IOException
{
// TODO is it worth using reflection to get rid of that if/else?
if (mName.equals(Messages.getString("bishop"))) //$NON-NLS-1$
return GameBuilder.createBishop(isBlack, origin, board);
if (mName.equals(Messages.getString("king"))) //$NON-NLS-1$
return GameBuilder.createKing(isBlack, origin, board);
if (mName.equals(Messages.getString("knight"))) //$NON-NLS-1$
return GameBuilder.createKnight(isBlack, origin, board);
if (mName.equals(Messages.getString("pawn"))) //$NON-NLS-1$
return GameBuilder.createPawn(isBlack, origin, board);
if (mName.equals(Messages.getString("queen"))) //$NON-NLS-1$
return GameBuilder.createQueen(isBlack, origin, board);
if (mName.equals(Messages.getString("rook"))) //$NON-NLS-1$
return GameBuilder.createRook(isBlack, origin, board);
else
return new Piece(mName, isBlack, origin, board, mPieceMovements, mCanJump);
}
public void setName(String name)
{
mName = name;
}
public String getName()
{
return mName;
}
public PieceMovements getPieceMovements()
{
return mPieceMovements;
}
public boolean canJump()
{
return mCanJump;
}
public void setCanJump(boolean mCanJump)
{
this.mCanJump = mCanJump;
}
public void clearBidirectionalMovements()
{
mPieceMovements.clearBidirectionalMovements();
}
public void addBidirectionalMovement(BidirectionalMovement movement)
{
mPieceMovements.addBidirectionalMovement(movement);
}
public static void removePieceType(String pieceName)
{
if (mPieceTypes != null && mPieceTypes.containsKey(pieceName))
mPieceTypes.remove(pieceName);
}
private static final long serialVersionUID = -1351201562740885961L;
private static Map<String, PieceBuilder> mPieceTypes;
private boolean mCanJump;
private String mName;
private PieceMovements mPieceMovements;
}