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

                                 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 "LosAlamosGame.h"
#include "../../ChessV.h"
#include "../../PieceType.h"
#include "../../Piece.h"
#include "../../Direction.h"
#include "../../GameParameters.h"


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


int laPawnSquareBonuses[] = {  0,  0,  0,  0,  0,  0, 
                               5,  0,  0,  0,  0,  5, 
							   5,  5, 35, 35,  5,  5, 
							  10, 35, 50, 50, 35, 10,
							  25, 45, 80, 80, 45, 25,
							   0,  0,  0,  0,  0,  0 };

int laRookSquareBonuses[] = {  0, 30, 60, 60, 30,  0, 
                               0, 30, 60, 60, 30,  0, 
							   0, 30, 60, 60, 30,  0, 
							   0, 30, 60, 60, 30,  0,
							  40, 60, 90, 90, 60, 40,
							  10, 40, 70, 70, 40, 10 };

int laKnightSquareBonuses[] = {-60,  0,-60,-60,  0,-60, 
                               -60, 20, 20, 20, 20,-60, 
							   -60, 20, 50, 50, 20,-60, 
							   -60, 20, 50, 50, 20,-60,
							   -60, 20, 20, 20, 20,-60,
							   -60,-60,-60,-60,-60,-60 };

int laZeroes[] =            {  0,  0,  0,  0,  0,  0, 
                               0,  0,  0,  0,  0,  0, 
							   0,  0,  0,  0,  0,  0, 
							   0,  0,  0,  0,  0,  0,
							   0,  0,  0,  0,  0,  0,
							   0,  0,  0,  0,  0,  0 };


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

LosAlamosGame::LosAlamosGame( Board &board, Player &whitePlayer, Player &blackPlayer ):
	Game(board, whitePlayer, blackPlayer)
{
	//	turn on use of pawn structure evaluation
	usePawnStructureEvaluation = true;

	//	implement 50-move draw rule
	autoDrawPeriod = 100;

	//	turn off null-move after 14 pieces have been captured
	endgameCaptureThreshold = 14;

	//	reduce the value of squares
	boardAverageSquareValue = 50;

	// *** PHASES *** //

	//	we have to set up the phases we wish to have in this game;
	//	we will keep it very simple and have just one
	nPhases = 1;

	//	settings for phase 0
	phases[0].SetNumber( 0 );
	phases[0].SetMobilityFactor( 0 );
	phases[0].SetPawnDeficiencyFactor( 10 );
	phases[0].SetSquareValuesFactor( 1 );
	phases[0].SetKingSafetyFactor( 4 );
	phases[0].SetTropismFactor( 10 );

	// *** INITIALIZATION *** //
	board.Initialize( this, BITBOARD_64 );
}

void LosAlamosGame::AddPlayerPieceTypes( char *gameName )
{
	//	add the piece types that each player may have
	board.AddPlayerPieceTypeBothPlayers( OrthodoxRook::orthodoxRook );
	board.AddPlayerPieceTypeBothPlayers( OrthodoxKnight::orthodoxKnight );
	board.AddPlayerPieceTypeBothPlayers( OrthodoxQueen::orthodoxQueen );
	board.AddPlayerPieceTypeBothPlayers( OrthodoxKing::orthodoxKing );
	board.AddPlayerPieceTypeBothPlayers( LamePawn::lamePawn );
}

void LosAlamosGame::ChangeRulesByVariant
	( char *gameName,
	  char *&array,
	  char *&book )
{
	// *** LOS ALAMOS CHESS *** //
	if( !strcmp( gameName, "Los Alamos Chess" ) )
	{
		//	update piece types for smaller board
		OrthodoxRook::orthodoxRook.ReduceBoardSize( 6, 6 );
		OrthodoxKnight::orthodoxKnight.ReduceBoardSize( 6, 6 );
		OrthodoxQueen::orthodoxQueen.ReduceBoardSize( 6, 6 );
		OrthodoxKing::orthodoxKing.ReduceBoardSize( 6, 6 );
		LamePawn::lamePawn.ReduceBoardSize( 6, 6 );
		//	adjust value of pieces for smaller board
		OrthodoxRook::orthodoxRook.SetBaseValue( 3500 );
		OrthodoxRook::orthodoxRook.SetPerCaptureBonusThreshold( 1000 );
		OrthodoxKnight::orthodoxKnight.SetBaseValue( 2600 );
		OrthodoxQueen::orthodoxQueen.SetBaseValue( 6000 );
		OrthodoxQueen::orthodoxQueen.SetPerCaptureBonusThreshold( 1000 );
		//	update piece-square-value tables for small board
		LamePawn::lamePawn.SetSquareBonuses( 0, laPawnSquareBonuses );
		OrthodoxKnight::orthodoxKnight.SetSquareBonuses( 0, laKnightSquareBonuses );
		OrthodoxQueen::orthodoxQueen.SetSquareBonuses( 0, laKnightSquareBonuses );
		OrthodoxRook::orthodoxRook.SetSquareBonuses( 0, laRookSquareBonuses );
		OrthodoxKing::orthodoxKing.SetSquareBonuses( 0, laZeroes );
		//	place pieces
		array = "rnqknr/pppppp/6/6/PPPPPP/RNQKNR";
		//	set name of opening book
		book = "openings\\LosAlamos.txt";
	}
}

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

	if( newPiece->GetType().IsPawn() )
	{
		if( newPiece->GetPlayerNumber() == 0 )
			newPiece->GetPromotionZone().AddToZone( 30, 35 );
		else
			newPiece->GetPromotionZone().AddToZone( 0, 5 );
	}

	return newPiece;
}

Phase &LosAlamosGame::AdjustEvaluation
	( int &eval,
	  PawnHash *pPawnHash )
{
	return phases[0];
}
