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

#include "stdafx.h"
#include "material.h"

// data layout in info field:
//bits	
//0-2	pawns
//3-5	knights
//6-8	bishops
//9-11	rooks
//12-14	queens
//15    kings

static const int16 masks[] =
 { 0, 1, 0x8, 0x40, 0x200, 0x1000, 0x8000, 0 };

static const int16 masks2[] =
 { 0, 0x7, 0x38, 0x1c0, 0xe00, 0x7000, 0x8000, 0 };

void Material::add_piece(const Piece::PieceType p)
{
    info += masks[(int)p];
    total += Piece::Value(p);
}

void Material::remove_piece(const Piece::PieceType p)
{
    info -= masks[(int)p];
    total -= Piece::Value(p);
}

unsigned Material::count(const Piece::PieceType p) const
{
    int16 info2 = info & masks2[(int)p];
    if (info2 == 0)
       return 0;
    switch (p)
    {
       case Piece::Pawn:
          return info2;
       case Piece::Knight:
          return info2 >> 3;
       case Piece::Bishop:
          return info2 >> 6;
       case Piece::Rook:
          return info2 >> 9;
       case Piece::Queen:
          return info2 >> 12;
       case Piece::King:
          return 1;
       default:
         return 0;
    }
}

unsigned Material::piece_count() const
{
	unsigned info2 = info & 0x7007;
	unsigned count = 0;
	for (int i = 0; i < 4; i++)
	{
	   info2 = info2 >> 3;
	   count += info2 & 0x7;
	}
	return count;
}

void Material::clear()
{
	info = total = 0;
}