/***************************************************************************
*   KBlocks, a falling blocks game for KDE                                *
*   Copyright (C) 2010 University Freiburg                                *
*                                                                         *
*   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.                                   *
***************************************************************************/
#ifndef KBLOCKSAIEVALUATION_H
#define KBLOCKSAIEVALUATION_H

#include "KBlocksAITypeDefine.h"

#include "EvaluationInterface.h"

#include "../KBlocksField.h"

enum DecisionFeatureEnumeration {
    DF_HEIGHT_MAX,
    DF_PEEKS_COUNT,
    DF_BLOCK_SCAN,
    DF_LAYER_SCAN,
    DF_CREATING_TETRIS,
    DF_REMOVE_TETRIS,
    DF_DEEP_NARROW
};

bool getDecisionFeature(const DecisionFeatureEnumeration, KBlocksField *);

/******************************************************
****   Evaluation Function    *************************
*******************************************************/
class BaseEvaluation : public EvaluationInterface
{
public:
    double evaluate(KBlocksField *);
    static BaseEvaluation *instance()
    {
        if (_instance == 0) {
            _instance = new BaseEvaluation();
        }
        return _instance;
    }
    CLASSNAME(BaseEvaluation)

private:
    BaseEvaluation() {};
    ~BaseEvaluation() {};
    static BaseEvaluation *_instance;
};
/*###################################################*/
class HalfBaseEvaluation : public EvaluationInterface
{
public:
    double evaluate(KBlocksField *);
    static HalfBaseEvaluation *instance()
    {
        if (_instance == 0) {
            _instance = new HalfBaseEvaluation();
        }
        return _instance;
    }
    CLASSNAME(HalfBaseEvaluation)

private:
    HalfBaseEvaluation() {};
    ~HalfBaseEvaluation() {};
    static HalfBaseEvaluation *_instance;
};
/*###################################################*/
class WellsFillerEvaluation : public EvaluationInterface
{
public:
    double evaluate(KBlocksField *);
    static WellsFillerEvaluation *instance()
    {
        if (_instance == 0) {
            _instance = new WellsFillerEvaluation();
        }
        return _instance;
    }
    CLASSNAME(WellsFillerEvaluation)

private:
    WellsFillerEvaluation() {};
    ~WellsFillerEvaluation() {};
    static WellsFillerEvaluation *_instance;
};
/*###################################################*/
class HeightKillerEvaluation : public EvaluationInterface
{
public:
    double evaluate(KBlocksField *);
    static HeightKillerEvaluation *instance()
    {
        if (_instance == 0) {
            _instance = new HeightKillerEvaluation();
        }
        return _instance;
    }
    CLASSNAME(HeightKillerEvaluation)

private:
    HeightKillerEvaluation() {};
    ~HeightKillerEvaluation() {};
    static HeightKillerEvaluation *_instance;
};
/*###################################################*/
class BlockRemoverEvaluation : public EvaluationInterface
{
public:
    double evaluate(KBlocksField *);
    static BlockRemoverEvaluation *instance()
    {
        if (_instance == 0) {
            _instance = new BlockRemoverEvaluation();
        }
        return _instance;
    }
    CLASSNAME(BlockRemoverEvaluation)

private:
    BlockRemoverEvaluation() {};
    ~BlockRemoverEvaluation() {};
    static BlockRemoverEvaluation *_instance;
};
/*###################################################*/
class DeepNarrowRemoverEvaluation : public EvaluationInterface
{
public:
    double evaluate(KBlocksField *);
    static DeepNarrowRemoverEvaluation *instance()
    {
        if (_instance == 0) {
            _instance = new DeepNarrowRemoverEvaluation();
        }
        return _instance;
    }
    CLASSNAME(DeepNarrowRemoverEvaluation)

private:
    DeepNarrowRemoverEvaluation() {};
    ~DeepNarrowRemoverEvaluation() {};
    static DeepNarrowRemoverEvaluation *_instance;
};
/*###################################################*/
class TetrisPreparingEvaluation : public EvaluationInterface
{
public:
    double evaluate(KBlocksField *);
    static TetrisPreparingEvaluation *instance()
    {
        if (_instance == 0) {
            _instance = new TetrisPreparingEvaluation();
        }
        return _instance;
    }
    CLASSNAME(TetrisPreparingEvaluation)

private:
    TetrisPreparingEvaluation() {};
    ~TetrisPreparingEvaluation() {};
    static TetrisPreparingEvaluation *_instance;
};
/*###################################################*/
class TetrisEliminationEvaluation : public EvaluationInterface
{
public:
    double evaluate(KBlocksField *);
    static TetrisEliminationEvaluation *instance()
    {
        if (_instance == 0) {
            _instance = new TetrisEliminationEvaluation();
        }
        return _instance;
    }
    CLASSNAME(TetrisEliminationEvaluation)

private:
    TetrisEliminationEvaluation() {};
    ~TetrisEliminationEvaluation() {};
    static TetrisEliminationEvaluation *_instance;
};
/*###################################################*/
class NBSEvaluation : public SpecialEvaluationInterface
{
public:
    double evaluate(KBlocksField *);
    static NBSEvaluation *instance()
    {
        if (_instance == 0) {
            _instance = new NBSEvaluation();
        }
        return _instance;
    }
    CLASSNAME(NBSEvaluation)

private:
    NBSEvaluation() {};
    ~NBSEvaluation() {};
    static NBSEvaluation *_instance;
};
/*###################################################*/

#endif //KBLOCKSAIEVALUATION_H
