# include "HashedAlphaBetaTestCase.h"
# include "TestHeader.h"
# include "Color.h"
# include "Game/Game.h"

CPPUNIT_TEST_SUITE_REGISTRATION( HashedAlphaBetaTestCase );
using namespace Alice;
void
HashedAlphaBetaTestCase::simpleCapture()
{
	int before= Move::getInstances();
	{
  Game g;
  g.forsytheString("r6k/8/8/8/8/8/8/R6K/w");
  HashedAlphaBeta algo(g);
  algo.search(1);
  assert(g.forsytheString() == "r6k/8/8/8/8/8/8/R6K/w");
  assertLongsEqual( 5, algo.score());
  }
  assertLongsEqual(before, Move::getInstances());
};
void
HashedAlphaBetaTestCase::fork()
{
  Game g;
  g.forsytheString("1k6/8/8/8/8/1n6/8/Q1K5/w");
  HashedAlphaBeta algo(g);
  for (int i = 0; i < 2; i++)
    algo.search(i);
  //algo.bestMove()->printOn(cout);
  assert(g.forsytheString() == "1k6/8/8/8/8/1n6/8/Q1K5/w");
  assertLongsEqual( 0, algo.score());
};
void
HashedAlphaBetaTestCase::fork2()
{
  Game g;
  g.forsytheString("r3k3/8/N7/8/8/8/8/7K/w");
  AlphaBetaWithQSearch algo(g);
  algo.search(3);
  assert(g.forsytheString() == "r3k3/8/N7/8/8/8/8/7K/w");
  assertLongsEqual( 3, algo.score());
};
void
HashedAlphaBetaTestCase::twoGames()
{
  Game g;
  HashedAlphaBeta algo(g);
    
  {
    g.forsytheString("1k6/8/8/8/8/1n6/8/Q1K5/w");
    algo.setGame(g);
    algo.search(2);
    CPPUNIT_ASSERT_EQUAL(0, algo.getHeight());
    CPPUNIT_ASSERT(g.forsytheString() == "1k6/8/8/8/8/1n6/8/Q1K5/w");
    CPPUNIT_ASSERT_EQUAL( Evaluation::Score(0), algo.score());
  }
  {
    Game g;
    g.forsytheString("r3k3/8/N7/8/8/8/8/7K/w");
    algo.setGame(g);
    algo.search(3);
    CPPUNIT_ASSERT(g.forsytheString() == "r3k3/8/N7/8/8/8/8/7K/w");
    CPPUNIT_ASSERT_EQUAL( Evaluation::Score(3), algo.score());
  }
};

void
HashedAlphaBetaTestCase::testSecondBest()
{
  Game g;
  g.forsytheString("rR6/1n6/8/8/8/2K5/8/7k/w");
  HashedAlphaBeta algo(g);
  algo.setGame(g);
  MoveList moves;
  g.pseudoLegalMoves( moves );
  algo.searchFixedDepth(3, moves);
  SmartPointer<Move> best = algo.bestMove();
  CPPUNIT_ASSERT_EQUAL( Evaluation::Score(2), algo.score());
  for (MoveList::iterator it = moves.begin();
       it != moves.end(); ++ it)
    if ((**it) == *best)
      {
	moves.erase(it);
	break;
      }
  algo.searchFixedDepth(3, moves);
  CPPUNIT_ASSERT_EQUAL( Evaluation::Score(0), algo.score() );
};

void
HashedAlphaBetaTestCase::testGetSearchDepth()
{
  Game g;
  g.forsytheString("rR6/1n6/8/8/8/2K5/8/7k/w");
  HashedAlphaBeta algo(g);
  algo.setGame(g);
  algo.search(3);
  int depth = algo.getSearchDepth();
  CPPUNIT_ASSERT_EQUAL( 3, depth );
  
};
