/**********************************************************************
 *
 *   FreeDoko a Doppelkopf-Game
 *    
 *   Copyright (C) 2001-2006  by Diether Knof and Borg Enders
 *
 *   This program 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.
 *
 *   This program 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.
 *   You can find this license in the file 'gpl.txt'.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *   MA  02111-1307  USA
 *
 *  Contact:
 *    Diether Knof dknof@gmx.de
 *    Borg Enders  borg@borgsoft.de
 *
 ********************************************************************/

#include "constants.h"

#include "weighting.h"

#include "w_virtual_games.h"
#include "gametree.h"
#include "w_monte_carlo.h"
#include "../../ui/ui.h"
#ifdef DKNOF
#include "cards_information.h"
#include "../../party/party.h"
#endif

/**
 ** constructor
 **
 ** @param	t	ai type
 **
 ** @return	-
 **
 ** @author	Borg Enders
 **
 ** @version	0.7.0
 **/
Weighting::Weighting(AiType const t) :
  choose_ai_p(t)
{ }

/**
 ** destructor
 **
 ** @param	t	ai type
 **
 ** @return	-
 **
 ** @author	Borg Enders
 **
 ** @version	0.7.0
 **/
Weighting::~Weighting()
{ }

/**
 ** gets a card to play by using an aitype
 **
 ** @param	ai	the ai
 **
 ** @return	-
 **
 ** @author	Borg Enders
 **
 ** @version	0.7.0
 **/
Card
Weighting::choosebestcard(Ai const& ai)
{
  DEBUG_CALLING(INFO_WEIGHTING && INFO_OTHER_FUNCTION,
		"Weighting::choosebestcard(Ai)");

  if (!ai.game().isvirtual())
    ::ui->set_busy();

  Card c=Card();
#ifndef RELEASE
  Ai* ai_bak = ai.clone();
#endif

  switch(this->choose_ai_p) {
  case AITYPE::NO_CHOOSEBESTCARD:
    c = Card();
    break;
  case AITYPE::RANDOM:
    {
      HandCards validcards = ai.hand().validcards(ai.game().trick_current());
#ifdef OUTDATED
      c = validcards.card(RAND(validcards.cardsnumber() - 1));
#endif
      c = validcards.card(0);
    }
    break;
  case AITYPE::VIRTUAL_GAMES:
    c = WVirtualGames(ai, ai.future_limit()).best_card();
    break;
  case AITYPE::GAMETREE:
    c = Gametree(ai, ai.future_limit(), false).best_card();
    break;
  case AITYPE::GAMETREE_WITH_HEURISTICS:
    c = Gametree(ai, ai.future_limit(), true).best_card();
    break;
  case AITYPE::MONTE_CARLO:
    c = WMonteCarlo(ai, ai.future_limit()).best_card();
    break;

  default:
    DEBUG_ASSERTION(false,
		    "Weighting::choosebestcard():\n"
		    "  no aitype"
		   );
    break;
  } // switch(choose_ai_p)
  if (::game_status != GAMESTATUS::GAME_PLAY) {
    ::ui->set_not_busy();
    return Card();
  }

  DEBUG_ASSERTION( (this->choose_ai_p == AITYPE::NO_CHOOSEBESTCARD)
		   || c,
		   "Weighting::choosebestcard():\n"
		   "  '" << this->choose_ai_p << "' returns no card");

#ifndef RELEASE
  DEBUG_ASSERTION(ai.isequal(*ai_bak),
		  "Weighting::choosebestcard():\n"
		  "  ai has changed!\n");
  delete ai_bak;
#endif

  if (!ai.game().isvirtual())
    ::ui->set_not_busy();

  DEBUG_RETURNING(c,
		  INFO_WEIGHTING && INFO_OTHER_FUNCTION,
		  "Weighting::choosebestcard(Ai)");
} // Card Weighting::choosebestcard(Ai ai)
