
/***************************************************************************

                                 ChessV

                   COPYRIGHT (C) 2005 BY GREGORY STRONG

This file is part of ChessV.  ChessV 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.

ChessV is distributed in the hope that it will be useful, but WITHOUT ANY 
WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
more details; the file 'COPYING' contains the License text, but if for
some reason you need a copy, please write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

****************************************************************************/


#include "StdAfx.h"
#include "ExtinctionChessGame.h"
#include "../../Resource.h"
#include "../../ChessV.h"
#include "../../GameParameters.h"


// *** DEBUG MEMORY ALLOCATION *** //
#ifdef _DEBUG
#define new SAFE_NEW
#endif


Game *CreateExtinctionChessGame( Board &brd, Player &plr0, Player &plr1 )
{
	return new ExtinctionChessGame( brd, plr0, plr1 );
}

ExtinctionChessGame::ExtinctionChessGame( Board &board, Player &whitePlayer, Player &blackPlayer ):
	ChessGame(board, whitePlayer, blackPlayer)
{
	// *** change settings from ChessGame that are not correct *** //


	//	there is no Check or Checkmate
	goalIsCheckmate = false;

	//	the king is not royal, and we'll give it a combat value of 4000 
	OrthodoxKing::orthodoxKing.SetRoyal( false );
	OrthodoxKing::orthodoxKing.SetBaseValue( 4000 );

	//	since the king is not royal, change the piece-square-tables to 
	//	encourage it to move to the center rather than hide in the corner
	OrthodoxKing::orthodoxKing.SetSquareBonuses( 0, endgameKingSquareBonuses );
	OrthodoxKing::orthodoxKing.SetSquareBonuses( 1, endgameKingSquareBonuses );
}

void ExtinctionChessGame::ChangeRulesByVariant
	( char *gameName,
	  char *&array,
	  char *&book )
{
	// *** EXTINCTION CHESS *** //
	if( !strcmp( gameName, "Extinction Chess" ) )
	{
		//	use the same handling as Orthodox Chess, except for
		//	the name of the opening book which we will change after
		ChessGame::ChangeRulesByVariant( "Orthodox Chess", array, book );
		//	set name of opening book
		book = "openings\\ExtinctionChess.txt";
	}
}

Piece *ExtinctionChessGame::AddPiece
	( PieceType &pieceType,
	  int nPlayer,
	  int nRank,
	  int nFile )
{
	Piece *newPiece = ChessGame::AddPiece( pieceType, nPlayer, nRank, nFile );

	//	since King's aren't royal, we need to look for them here and set the 
	//	Board class's King property so that they can be used for castling
	if( &pieceType == &OrthodoxKing::orthodoxKing )
		board.SetKing( nPlayer, newPiece );

	return newPiece;
}

bool ExtinctionChessGame::TestForWinLossDraw
	( int &eval )
{
	//	TODO:  This whole function needs a rewrite!!!
	//		(a) it should use the bitboards
	//		(b) it needs to handle special pawn 
	//			capture/promotion case

	bool knights[2] = { false, false };
	bool bishops[2] = { false, false };
	bool rooks[2] = { false, false };
	bool pawns[2] = { false, false };
	bool kings[2] = { false, false };
	bool queens[2] = { false, false };
	//	look through player 0's pieces
	for( int x = 0; x < board.GetNumberOfPieces( 0 ); x++ )
	{
		Piece *piece = board.GetPiece( 0, x );
		if( !piece->IsCaptured() )
		{
			if( &(piece->GetType()) == &OrthodoxKnight::orthodoxKnight )
				knights[0] = true;
			else if( &(piece->GetType()) == &OrthodoxBishop::orthodoxBishop )
				bishops[0] = true;
			else if( &(piece->GetType()) == &OrthodoxRook::orthodoxRook )
				rooks[0] = true;
			else if( &(piece->GetType()) == &OrthodoxPawn::orthodoxPawn )
				pawns[0] = true;
			else if( &(piece->GetType()) == &OrthodoxKing::orthodoxKing )
				kings[0] = true;
			else if( &(piece->GetType()) == &OrthodoxQueen::orthodoxQueen )
				queens[0] = true;
		}
	}
	//	look through player 1's pieces
	for( int x = 0; x < board.GetNumberOfPieces( 1 ); x++ )
	{
		Piece *piece = board.GetPiece( 1, x );
		if( !piece->IsCaptured() )
		{
			if( &(piece->GetType()) == &OrthodoxKnight::orthodoxKnight )
				knights[1] = true;
			else if( &(piece->GetType()) == &OrthodoxBishop::orthodoxBishop )
				bishops[1] = true;
			else if( &(piece->GetType()) == &OrthodoxRook::orthodoxRook )
				rooks[1] = true;
			else if( &(piece->GetType()) == &OrthodoxPawn::orthodoxPawn )
				pawns[1] = true;
			else if( &(piece->GetType()) == &OrthodoxKing::orthodoxKing )
				kings[1] = true;
			else if( &(piece->GetType()) == &OrthodoxQueen::orthodoxQueen )
				queens[1] = true;
		}
	}
	if( !knights[0] || !bishops[0] || !rooks[0] || !pawns[0] || !kings[0] || !queens[0] )
	{
		//	a white piece type has gone extinct
		if( board.GetCurrentPlayerNumber() == 0 )
			eval = -INFINITY;
		else
			eval = INFINITY;
		return true;
	}
	if( !knights[1] || !bishops[1] || !rooks[1] || !pawns[1] || !kings[1] || !queens[1] )
	{
		//	a black piece type has gone extinct
		if( board.GetCurrentPlayerNumber() == 1 )
			eval = -INFINITY;
		else
			eval = INFINITY;
		return true;
	}
	return false;
}
