// Copyright 1993 by Jon Dart.  All Rights Reserved.

#include "stdafx.h"
#include "attacke.h"
#include "bearing.h"
#include "util.h"
#include "constant.h"
#include "debug.h"

int attack_estimate( const Board &board, const ExtendedMove &emove )
{
    ColorType my_side = emove.PieceMoved().Color();
    ColorType side = my_side;
    Square square = (emove.Special() == ExtendedMove::EnPassant) ?
         board.EnPassantSq(OppositeColor(side)) : emove.DestSquare();
    if (board.num_attacks(square,OppositeColor(side)) == 0)
    {
       // piece is undefended
       return board[square].Value();
    }
    Square piece_square = emove.StartSquare();
    Piece::PieceType on_square = board[square].Type();
    Piece::PieceType attacker = board[piece_square].Type();
    int score_count = 0;
    int score_list[16];
    int swap_score = 0;
    int gain;
    // make copies of the attack info for the square:
    Attack_Entry my_atcks(board.get_attacks(square,side));
    Attack_Entry opp_atcks(board.get_attacks(square,OppositeColor(side)));
    my_atcks.remove_attack(attacker);
    do
    {
	gain = Piece::Value(on_square);
	if (attacker == Piece::Pawn &&
	    square.Rank(side) == 8)
	{
	    gain += Piece::Value(Piece::Queen) - Piece::Value(Piece::Pawn);
	}
	if (side == my_side)
	    swap_score += gain;
	else
	    swap_score -= gain;
	ASSERT(score_count <16);
	score_list[score_count++] = swap_score;
	side = OppositeColor(side);
	on_square = attacker;
    	if (side == my_side)
	   attacker = my_atcks.remove_min_attacker();
        else
	   attacker = opp_atcks.remove_min_attacker();
    } while (attacker != Piece::Empty);
    if (score_count > 1 && score_count % 2 == 0)
    {
        // last capture is by other side, can't avoid it
	score_list[score_count-2] = score_list[score_count-1];
	--score_count; 
    }
    int i = score_count;
    while (i >= 3)
    {
	int max_score = Util::Max(score_list[i-1],score_list[i-2]);
	if (max_score < score_list[i-3])
	    score_list[i-3] = max_score;
	i -= 2;
    }
    return score_list[0];
}
