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

                                 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

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


#ifndef FILE__CHESS_GAME_H
#define FILE__CHESS_GAME_H


#include "../../Board.h"
#include "../../Player.h"
#include "../../PieceType.h"
#include "../../Game.h"
#include "ChessPieceTypes.h"


//	***********************
//	**                   **
//	**     ChessGame     **
//	**                   **
//	***********************
//
//	the ChessGame class overrides the Game class to provide all the extra 
//	capabilities needed to play a game of Chess.  the Universal Chess Engine 
//	provided supports almost all the rules of Chess natively: move, capture, 
//	promotion, checkmate, stalemate, repetition-draw, 50-move draw, ... 
//	but the ChessGame class overrides virtual functions to provide support 
//	for the following "special rules":  Castling and En Passant 
//	
//	this class also provides support for:
//		Fisher Random Chess - same game, but pieces switched around
//		Almost Chess - same as Chess, but the Queen is replaced with the 
//			Chancellor, which moves as a Rook+Knight, instead of Rook+Bishop 
//		Chess with Different Armies - each side may chose an army from a 
//			set of predefined "armies", each with special pieces 


//	constants for supported variants
#define CHESS_GAME_ORTHODOX					1000
#define CHESS_GAME_ALMOST_CHESS				1001
#define CHESS_GAME_CWDA						1002
#define CHESS_GAME_CWAK						1003
#define CHESS_GAME_FISCHER_RANDOM_CHESS		1004
#define CHESS_GAME_CHESS_480				1005

//	constants for CWDA armies
#define CWDA_ARMY_FABULOUS_FIDES			0
#define CWDA_ARMY_COLORBOUND_CLOBBERERS		1
#define CWDA_ARMY_COLORBOUND_CLOBBERERS2	2
#define CWDA_ARMY_NUTTY_KNIGHTS				3
#define CWDA_ARMY_REMARKABLE_ROOKIES		4
#define CWDA_ARMY_FORWARD_FIDES				5
#define CWDA_ARMY_ALL_AROUND_ALLSTARS		6
#define CWDA_ARMY_METICULOUS_MASHERS		7
#define CWDA_ARMY_ALMOST_CHESS				8
#define CWDA_ARMY_DEADLY_DEMOLISHERS        9
#define CWDA_ARMY_MIGHTY_MEN               10


class ChessGame:
	public Game
{
  protected:
	//	data members
	PieceType64 *castlingPieceTypes[2];
	PieceType64 *minorPieceTypes[2][4];
	PieceType64 *colorboundPieceTypes[2][2];
	PieceType64 *queenPieceTypes[2];
	PieceType64 *pawnPieceTypes[2];
	
	//	bitboards
	BitBoard64 player0PawnTwoSpaceZone;
	BitBoard64 player1PawnTwoSpaceZone;
	BitBoard64 whiteSquares;
	BitBoard64 blackSquares;


	// Current Rules in Effect
	int castlingType;			//	castling type to be used in this game
	bool enPassant;				//	does this game have the en-passant rule?
	bool derivedClassEP;		//	en-passant handled by derived class?
	bool bareKingRule;			//	Shatranj 'bare king' rule in effect?

	bool castlingPiecesSlideNorth[2];
	//	if the castling pieces for the given player can slide north, 
	//	set this to true so that a bonus will be given for placing them
	//	on an open or semi-open file

	int castlingPieceSquare0L;	//	\   initial squares of castling pieces
	int castlingPieceSquare0R;	//	 \_	these are used for games like FRC and
	int castlingPieceSquare1L;	//	 /	Chess 480 where the castling pieces 
	int castlingPieceSquare1R;	//	/	are not necessarily in the corners

	//	Positional Hash Values
	word32 castlingHash0k;		//	\   Zobrist keys for castling privledge.
	word32 castlingHash0q;		//	 \_ these values are x-or'ed in if the
	word32 castlingHash1k;		//	 /  player has not lost the ability to
	word32 castlingHash1q;		//	/   castle on the given side.

	HashMap *enPassantHashMap;
	//	Zobrist keys which are x-or'ed into the board's primary hash
	//	for the current "en passant" square, if any


  public:
	// *** INITIALIZATION *** //
	ChessGame( Board &board, Player &whitePlayer, Player &blackPlayer );

	virtual void Initialize();

	virtual void AddPlayerPieceTypes( char *gameName );

	virtual void ChangeRulesByVariant( char *gameName, char *&array, char *&book );

	virtual void ChangeRulesByVariableDefinition( char *gameName );


	// ******************************* //
	// ***                         *** //
	// ***     VIRTUAL METHODS     *** //
	// ***                         *** //
	// ******************************* //

	virtual void SetPersonality
		( int personality );

	virtual bool RemovePieceType
		( PieceType *pieceType );

	virtual bool AddPieceType
		( PieceType *pieceType,
		  int nPlayer );

	virtual bool MoveBeingMade
		( MoveInfo &moveInfo,
		  GameRec &gameRecord );

	virtual void AddSpecialMoves
		( int currentPlayer, 
		  MovementList &stack,
		  GameRec &gameRecord,
		  bool quiescentSearch );

	virtual word32 AdjustPrimaryHash
		( word32 primaryHash );

	virtual Phase &AdjustEvaluation
		( int &eval,
		  PawnHash *pPawnHash );

	virtual int EnumeratePromotions
		( Piece *piece,
		  int fromSquare,
		  int toSquare,
		  PieceType **promotions,
		  bool quiescentSearch );

	virtual bool TestForWinLossDraw
		( int &eval );

	virtual void GenerateMoves
		( int currentPlayer, 
		  MovementList &list );

	virtual void GenerateCaptures
		( int currentPlayer, 
		  MovementList &list );

	virtual bool IsSquareAttacked
		( int squareNumber, 
		  int playerNumber );

	virtual Piece *AddPiece
		( PieceType &pieceType,
		  int nPlayer,
		  int nRank,
		  int nFile );

	virtual void DeletePiece
		( Piece *piece );

	virtual void DefaultSettings();

	virtual void AboutToStartThinking
		( int currentPlayer );
};


#endif
