summaryrefslogtreecommitdiffstats
path: root/libksirtet/common/ai.h
blob: da298abc02cde4aaf59df08433659ca26e7d18ed (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#ifndef COMMON_AI_H
#define COMMON_AI_H

#include <qtimer.h>
#include <qvaluevector.h>

#include <kdialogbase.h>
#include <knuminput.h>
#include <krandomsequence.h>
#include "lib/libksirtet_export.h"

class Board;
class Piece;


//-----------------------------------------------------------------------------
class LIBKSIRTET_EXPORT AIPiece
{
 public:
    AIPiece();
    ~AIPiece();

    void init(const Piece *p, Board *b);
    bool place();
    bool increment();

    int dec() const  { return curDec; }
    uint rot() const { return curRot; }

 private:
    uint         nbPos, nbRot, curPos, curRot;
    int          curDec;
    const Piece *_piece;
    Piece       *_current;
    Board       *_board;

    void reset();
};

//-----------------------------------------------------------------------------
class LIBKSIRTET_EXPORT AI : public QObject
{
 Q_OBJECT
 public:
    struct Data {
        const char *name, *label, *whatsthis;
        bool triggered;
        double (*function)(const Board &, const Board &);
    };
    static const Data LastData;

    AI(uint thinkTime, uint orderTime, const Data *DATA);
    virtual ~AI();

    void launch(Board *main);
    void stop();
    void start();

    class Element {
    public:
        const Data *data;
        double coefficient;
        int trigger;
    };
    const QValueVector<Element> &elements() const { return _elements; }

    void settingsChanged();

 private slots:
    void timeout();

 protected:
    virtual void initThink();

    static double nbOccupiedLines(const Board &, const Board &);
    static double nbHoles(const Board &, const Board &);
    static double nbSpaces(const Board &, const Board &);
    static double peakToPeak(const Board &, const Board &);
    static double mean(const Board &, const Board &);
    static double nbRemoved(const Board &, const Board &);

 private:
    bool think();
    void startTimer();
    bool emitOrder();
    double points() const;
    void resizePieces(uint size);

    QTimer                 timer;
    enum ThinkState { Thinking, GivingOrders };
    ThinkState             state;
    uint                   thinkTime, orderTime;
    bool                   stopped;
    QMemArray<AIPiece *>   pieces;
    QValueVector<Element>  _elements;
    Board                 *main, *board;
    KRandomSequence        random;

    bool   hasBestPoints;
    double bestPoints;
    int    bestDec;
    uint   bestRot;
};

//-----------------------------------------------------------------------------
class LIBKSIRTET_EXPORT AIConfig : public QWidget
{
 Q_OBJECT
 public:
    AIConfig(const QValueVector<AI::Element> &elements);

    static double coefficient(const AI::Data &data);
    static int trigger(const AI::Data &data);

 private:
    static QCString triggerKey(const char *name);
    static QCString coefficientKey(const char *name);

    static const uint minThinkingDepth, maxThinkingDepth;
};

#endif