File indexing completed on 2024-04-28 04:02:09

0001 /*
0002     This file is part of the KDE games kwin4 program
0003     SPDX-FileCopyrightText: 1995-2007 Martin Heni <kde@heni-online.de>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #ifndef _KWIN4PROC_H_
0009 #define _KWIN4PROC_H_
0010 
0011 // own
0012 #include "aiboard.h"
0013 #include "kgameprocess.h"
0014 #include "kwin4global.h"
0015 // Qt
0016 #include <QHash>
0017 // St
0018 #include <cmath>
0019 
0020 // Save storage for color arrays
0021 typedef char FARBE;
0022 
0023 #define SIZE_Y_ALL 36
0024 #define SIZE_X 6
0025 #define SIZE_Y 5
0026 
0027 /**
0028  * The computer (AI) player.
0029  * It is used via the KGameIO framework and serves as abstract input device
0030  * to the game.
0031  */
0032 class KComputer : public QObject
0033 {
0034     Q_OBJECT
0035 
0036 public:
0037     /**
0038      * Constructor
0039      */
0040     KComputer();
0041 
0042     /**
0043      * The KGameProcess is the main program and event loop.
0044      */
0045     KGameProcess proc;
0046 
0047 public Q_SLOTS:
0048     /**
0049      * KGameIO slot to receive a command from the main program.
0050      * @param in       The data stream
0051      * @param msgid    The message id
0052      * @param received The received (we)
0053      * @param sender   The sender (the game)
0054      */
0055     void slotCommand(QDataStream &in, int msgid, int receiver, int sender);
0056 
0057     /**
0058      * KGameIO slot to init a KGameIO device.
0059      * @param in  The data stream
0060      * @param id  The message id
0061      */
0062     void slotInit(QDataStream &in, int id);
0063 
0064     /**
0065      * KGameIO slot to receive the setTurn() command, that is a turn is
0066      * started or aborted.
0067      * @param in    The data stream
0068      * @param turn  True if a turn is started
0069      */
0070     void slotTurn(QDataStream &in, bool turn);
0071 
0072 protected:
0073     /**
0074      * Move result structure. Combines move position and value.
0075      */
0076     typedef struct {
0077         // Move value
0078         long value;
0079         // Move x-position
0080         int move;
0081     } MoveResult;
0082 
0083     /**
0084      * Sends the game value/rating back to the main program.
0085      * @param value  The rating
0086      * @param moveNo Which move
0087      */
0088     void sendValue(long value, int moveNo);
0089 
0090     /**
0091      * Generate a random number from 0..max
0092      * @param max The range [0..max[
0093      */
0094     int random(int max);
0095 
0096     /**
0097      * Start thinking about a new move. Will read the input stream and
0098      * then start the MinMax AI algorithm.
0099      * @param in    The data stream
0100      * @param out   The outgoing data stream
0101      * @param hint  True if it is a hint move (unused)
0102      */
0103     MoveResult think(QDataStream &in, QDataStream &out, bool hint);
0104 
0105     /**
0106      * Check whether the current board is a game over situation.
0107      * @param field   The board
0108      * @param numbers The number matrix
0109      * @return The winner color or Nobody.
0110      */
0111     COLOUR isGameOver(FARBE field[][SIZE_X + 1], char numbers[]);
0112 
0113     /**
0114      * Execute move in given color to the given position on the given game board.
0115      * @param move    The move x coordinate
0116      * @param color   The move color
0117      * @param field   The game board
0118      * @param numbers The number board
0119      */
0120     void DoMove(int move, COLOUR color, FARBE field[][SIZE_X + 1], char numbers[]);
0121 
0122     /**
0123      * Execute the AI MinMax code. The best move and its (negative) value are returned.
0124      * @param color    The current player's color.
0125      * @param field    The game board
0126      * @param numbers  The number board
0127      * @param reklev   The recursion level
0128      * @param moveNo   The current move number
0129      * @param first    First recursion
0130      * @return The move result (best move and its value).
0131      */
0132     MoveResult MinMax(COLOUR color, FARBE field[][SIZE_X + 1], char numbers[], int reklev, int moveNo, bool first);
0133 
0134     /**
0135      * Evaluate a position at the end of the recursion.
0136      * @param curColor The current players' color
0137      * @param field The game board
0138      * @return The position value.
0139      */
0140     long PositionEvaluation(COLOUR curColor, FARBE field[][SIZE_X + 1]);
0141 
0142     /**
0143      * Load the computer brain from disk.
0144      */
0145     void loadBrain();
0146 
0147     /**
0148      * Save the computer brain to disk.
0149      */
0150     void saveBrain();
0151 
0152 private:
0153     // Move number in game 0..41
0154     int mCurMoveNo;
0155 
0156     // Maximum recursion of MinMax search (level)
0157     int mLevel;
0158 
0159     // Amount of positions evaluated (Statistic)
0160     int mPosEvaluations;
0161 
0162     // How many pos calculated per [ms] (Statistic)
0163     float mCalcPosPerMS;
0164 
0165     // Speed up matrix access
0166     // rows: 0-5  =6 : horiz(i:0-6)
0167     //       6-12 =7 : vert(i:0-5)
0168     //      13-24 =12: diag-45(i:...)
0169     //      25-36 =12: diag45(i:...)
0170     // Length of the rows (number meaning above)
0171     char mRowLengths[38];
0172     // Start of the rows (number meaning above)
0173     char mStartOfRows[38];
0174 
0175     // Learning of AI:
0176     // Store learned boards
0177     QHash<AIBoard, AIValue> mBrain;
0178 
0179     // Best board in move
0180     AIBoard mMaxAIBoard;
0181 
0182     // Learning on or off
0183     bool mIsLearning;
0184 
0185     // Is the brain already loaded
0186     bool mBrainLoaded;
0187 
0188     // Path to the brain file
0189     QString mBrainDir;
0190 
0191     // Statistics on brain usage
0192     long mBrainUsed;
0193 };
0194 
0195 #endif // _KWIN4PROC_H_