/***************************************************************************
                          CapturingMove.cpp  -  description
                             -------------------
    begin                : Tue May 22 2001
    copyright            : (C) 2001 by Sven Reichard
    email                : reichard@math.udel.edu
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
# include "Moves/CapturingMove.h"
# include "Board.h"
# include "Pieces/Piece.h"
# include "Game/Game.h"
using namespace Alice;

int CapturingMove::created = 0;
int CapturingMove::deleted = 0;
CapturingMove::CapturingMove(const Square& from, const Square& to):
  Move(from, to)
{
};

CapturingMove::~CapturingMove()
{
};

void
CapturingMove::makeOn(Board& b)
{
  mCapture = b.at(destination());
  b.clear( destination());
  b.put(b.at(source()), destination());
  b.clear(source());
};
void
CapturingMove::takeBackOn(Board& b)
{
  assert(! capture()->isNull());
  b.put(b.at(destination()), source());
  b.clear(destination());
  b.put(capture(), destination());
};
void
CapturingMove::makeOn(GameObserver& b)
{
  b.doCapturingMove(*this);
};
void
CapturingMove::takeBackOn(GameObserver& b)
{
  b.takeBackCapturingMove(*this);
};
const Piece*
CapturingMove::capture() const
{
  return mCapture;
};
void
CapturingMove::printOn(std::ostream& out) const
{
  out<<char('a'+source().file())<<char('1'+source().rank());
  out<<'x';
  out<<char('a'+destination().file())<<char('1'+destination().rank());
};
/** make sure there is something to capture */
bool CapturingMove::isLegal(const Game& game)  const{
	if (!Move::isLegal(game))
		return false;
	const Piece* capturedPiece = game.board().at(destination());
	if (capturedPiece->isNull())
		return false;
	if (capturedPiece->color() == game.colorToMove())
		return false;
	return true;
}

int CapturingMove::reuse = 0;
CapturingMove::Link*
CapturingMove::capturePool = 0;

void
CapturingMove::printInfo()
{
	std::cout<<"CapturingMove: "<<std::endl;
	std::cout<<created<<" created new"<<std::endl;
	std::cout<<deleted<<" deleted"<<std::endl;
	std::cout<<reuse<<" reused"<<std::endl;
	int i = 0;
	Link* l = capturePool;
	while(l) {
		l = l->next;
		i++;
	}
	std::cout<<"pool size: "<<i<<std::endl;
};

void*
CapturingMove::operator new(size_t s)
{
	assert(s == sizeof(CapturingMove));
	if (s == sizeof(CapturingMove) && capturePool != 0) {
		CapturingMove* p = reinterpret_cast<CapturingMove*>(capturePool);
		capturePool = capturePool->next;
		reuse ++;
		return p;
	}
	created ++;
	return malloc(sizeof(CapturingMove));
};

void
CapturingMove::operator delete (void* p, size_t s)
{
	Link* l = reinterpret_cast<Link*>(p);
	l->next = capturePool;
	capturePool = l;
};
