
chesspresso.position.AbstractMutablePosition Maven / Gradle / Ivy
/*
* Chessplorer-Lib - an open source chess library written in Java
* Copyright (C) 2016 Chessplorer.org
* Copyright (C) 2012-2016 Gerhard Kalab
* Copyright (C) 2002-2003 Bernhard Seybold
*
* This software is published under the terms of the LGPL Software License,
* a copy of which has been included with this distribution in the LICENSE.txt
* file.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
*/
package chesspresso.position;
import chesspresso.*;
import java.util.*;
import chesspresso.move.Move;
import chesspresso.move.IllegalMoveException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* @author Bernhard Seybold
* @author Andreas Rudolph
*/
public abstract class AbstractMutablePosition extends AbstractPosition implements MutablePosition
{
private final static Logger LOGGER = LoggerFactory.getLogger( AbstractMutablePosition.class );
protected PositionListener[] m_listeners; // protected to allow fast read access
protected PositionChangeListener[] m_changeListeners;
protected boolean m_notifyListeners; // ... to check whether or not to fire
protected boolean m_notifyPositionChanged;
/*================================================================================*/
protected AbstractMutablePosition()
{
m_listeners = null;
m_changeListeners = null;
m_notifyListeners = true;
m_notifyPositionChanged = true;
}
/*================================================================================*/
public int getPiece(int sqi) {return Chess.stoneToPiece(getStone(sqi));}
public int getColor(int sqi) {return Chess.stoneToColor(getStone(sqi));}
public boolean isSquareEmpty(int sqi) {return getStone(sqi) == Chess.NO_STONE;}
/*================================================================================*/
public void toggleToPlay() {setToPlay(Chess.otherPlayer(getToPlay()));}
/*================================================================================*/
public void clear()
{
boolean notify = m_notifyPositionChanged;
m_notifyPositionChanged = false;
for (int sqi=0; sqi < Chess.NUM_OF_SQUARES; sqi++) {
setStone(sqi, Chess.NO_STONE);
}
setSqiEP(Chess.NO_SQUARE);
setCastles(NO_CASTLES);
setToPlay(Chess.WHITE);
setPlyNumber(0);
setHalfMoveClock(0);
m_notifyPositionChanged = notify;
firePositionChanged();
}
public void setStart()
{
boolean notify = m_notifyPositionChanged;
m_notifyPositionChanged = false;
FEN.initFromFEN(this, FEN.START_POSITION, true);
m_notifyPositionChanged = notify;
firePositionChanged();
}
public void set(ImmutablePosition position)
{
boolean notify = m_notifyPositionChanged;
m_notifyPositionChanged = false;
for (int sqi=0; sqi < Chess.NUM_OF_SQUARES; sqi++) {
setStone(sqi, position.getStone(sqi));
}
setCastles(position.getCastles());
setSqiEP(position.getSqiEP());
setToPlay(position.getToPlay());
setPlyNumber(position.getPlyNumber());
setHalfMoveClock(position.getHalfMoveClock());
m_notifyPositionChanged = notify;
firePositionChanged();
}
/*================================================================================*/
// inverse
public final void inverse()
{
/*---------- inverse stones ----------*/
// avoid to have two same kings on the board at the same time
int[] stones = new int[Chess.NUM_OF_SQUARES];
for (int sqi = 0; sqi < Chess.NUM_OF_SQUARES; sqi++) {
stones[sqi] = getStone(sqi);
setStone(sqi, Chess.NO_STONE);
}
for (int sqi = 0; sqi < Chess.NUM_OF_SQUARES; sqi++) {
int partnerSqi = Chess.coorToSqi(Chess.sqiToCol(sqi), Chess.NUM_OF_ROWS - Chess.sqiToRow(sqi) - 1);
setStone(sqi, Chess.getOpponentStone(stones[partnerSqi]));
}
/*---------- inverse en passant square ----------*/
int sqiEP = getSqiEP();
if (sqiEP != Chess.NO_SQUARE) {
setSqiEP(Chess.coorToSqi(Chess.sqiToCol(sqiEP), Chess.NUM_OF_ROWS - Chess.sqiToRow(sqiEP) - 1));
}
/*---------- inverse castles ----------*/
int castles = getCastles();
setCastles(NO_CASTLES);
if ((castles & WHITE_SHORT_CASTLE) != 0) includeCastles(BLACK_SHORT_CASTLE);
if ((castles & WHITE_LONG_CASTLE) != 0) includeCastles(BLACK_LONG_CASTLE);
if ((castles & BLACK_SHORT_CASTLE) != 0) includeCastles(WHITE_SHORT_CASTLE);
if ((castles & BLACK_LONG_CASTLE) != 0) includeCastles(WHITE_LONG_CASTLE);
/*---------- inverse to play ----------*/
toggleToPlay();
}
/*================================================================================*/
// convenience methods
public final void includeCastles(int whichCastles)
{
setCastles(getCastles() | whichCastles);
}
public final void excludeCastles(int whichCastles)
{
setCastles(getCastles() & (~whichCastles));
}
public final void resetHalfMoveClock()
{
setHalfMoveClock(0);
}
public final void incHalfMoveClock()
{
setHalfMoveClock(getHalfMoveClock() + 1);
}
/*================================================================================*/
// trigger listeners
protected void fireSquareChanged(int sqi)
{
if (m_notifyListeners && m_listeners != null) {
int stone = getStone(sqi);
for (int i=0; i
}
}
}
public final synchronized void setNotifyListeners(boolean notify)
{
m_notifyListeners = notify;
}
/*================================================================================*/
// IChPositionChangeListener
public final void addPositionChangeListener(PositionChangeListener listener)
{
//LOGGER.debug("addPositionChangeListener " + listener);
if (m_changeListeners == null) {
m_changeListeners = new PositionChangeListener[1];
m_changeListeners[0] = listener;
} else {
PositionChangeListener[] oldListeners = m_changeListeners;
m_changeListeners = new PositionChangeListener[oldListeners.length + 1];
System.arraycopy(oldListeners, 0, m_changeListeners, 0, oldListeners.length);
m_changeListeners[m_changeListeners.length-1] = listener;
}
listener.notifyPositionChanged(this); // for initialization
//for (int i=0; i
}
}
//for (int i=0; i
© 2015 - 2025 Weber Informatics LLC | Privacy Policy