File indexing completed on 2023-11-26 04:09:35

0001 /*
0002     This file is part of the KDE games kwin4 program
0003     SPDX-FileCopyrightText: 2006 Martin Heni <kde@heni-online.de>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #ifndef KWIN4DOC_H
0009 #define KWIN4DOC_H
0010 
0011 // own
0012 #include "aiboard.h"
0013 #include "kgamepropertyarray.h"
0014 #include "kwin4global.h"
0015 #include "kwin4player.h"
0016 // KDEGames
0017 #define USE_UNSTABLE_LIBKDEGAMESPRIVATE_API
0018 #include <libkdegamesprivate/kgame/kgame.h>
0019 #include <libkdegamesprivate/kgame/kgameio.h>
0020 // KF
0021 #include <KConfig>
0022 // Qt
0023 #include <QList>
0024 #include <QVector>
0025 
0026 class KWin4View;
0027 class Score;
0028 
0029 /**
0030  * The game document or game engine. It is derived from the KGame framework.
0031  */
0032 class KWin4Doc : public KGame
0033 {
0034     Q_OBJECT
0035 
0036     friend class KWin4GameSequence;
0037 
0038 public:
0039     /**
0040      * Constructor.
0041      * @param parent The parent widget
0042      */
0043     explicit KWin4Doc(QWidget *parent);
0044 
0045     /**
0046      * The destructor.
0047      */
0048     ~KWin4Doc() override;
0049 
0050     /**
0051      * Adds a view to the document which displays the document contents.
0052      * @param view The view to add
0053      */
0054     void setView(KWin4View *view);
0055 
0056     /**
0057      * Initializes the KGame derived players.
0058      */
0059     void initPlayers();
0060 
0061     /**
0062      * Save the document in the datastrem. This is a KGame function.
0063      * @param stream  The data stream to use
0064      * @param network Is the saving via the network (a network game)
0065      * @param reset   Reset parameter forward to KGame
0066      * @return True on success, false otherwise.
0067      */
0068     bool loadgame(QDataStream &stream, bool network, bool reset) override;
0069 
0070     /**
0071      * Read the game config from the config file.
0072      * @param config The config
0073      */
0074     void readConfig(KConfig *config);
0075 
0076     /**
0077      * Write the game config to the config file.
0078      * @param config The config
0079      */
0080     void writeConfig(KConfig *config);
0081 
0082     /**
0083      * End a game. Update statistic and forward end game to view.
0084      * @param mode Indicate how the game ended for the current player [TWin, TLost, TRemis, TBrk]
0085      */
0086     void endGame(TABLE mode);
0087 
0088     /**
0089      * Reset all the player stats.
0090      */
0091     void resetStatistic();
0092 
0093     /**
0094      * Redoes a move if possible.
0095      * @return True on success.
0096      */
0097     bool redoMove();
0098 
0099     /**
0100      * Undoes a move if possible.
0101      * @return True on success.
0102      */
0103     bool undoMove();
0104 
0105     /**
0106      * Generate a computer AI move and show it to the player as hint.
0107      */
0108     void calculateHint();
0109 
0110     /**
0111      * Returns the all time statistics for player of given color
0112      * The mode determines what statistics to access.
0113      * @param col  The player color
0114      * @param mode The type of data to retrieve [TWin, TRemis, TLost, TBrk, TSum]
0115      * @return The amount of the queried category.
0116      */
0117     int getStatistic(COLOUR col, TABLE mode);
0118 
0119     /**
0120      * Retrieve the name of the player of the given color.
0121      * @param col The color
0122      * @return The name.
0123      */
0124     QString getName(COLOUR col);
0125 
0126     /**
0127      * Set the name of the player of the given color.
0128      * @param col The color
0129      * @param n   The new name
0130      */
0131     void setName(COLOUR col, const QString &n);
0132 
0133     /**
0134      * Query the IO mode of player og the given color.
0135      * @param col The color
0136      * @return The input device mode.
0137      */
0138     KGameIO::IOMode playedBy(int col);
0139 
0140     /**
0141      * Sets the input device mode for the given player color.
0142      * @param col  The color
0143      * @param mode The input device code (Mouse, Key, ...)
0144      */
0145     void setPlayedBy(int col, KGameIO::IOMode mode);
0146 
0147     /**
0148      * Retrieve the player object for the given player colour.
0149      * @param col The player color
0150      * @return The player object.
0151      */
0152     KWin4Player *getPlayer(COLOUR col);
0153 
0154     /**
0155      * Swap the start player so that the game is started alternatingly.
0156      * @return The new start player color.
0157      */
0158     COLOUR switchStartPlayer();
0159 
0160     /**
0161      * Sets the current player.
0162      * @param no The current player
0163      */
0164     void setCurrentPlayer(COLOUR no);
0165 
0166     /**
0167      * Retrieve the player whose turn it is next.
0168      * @return The current player.
0169      */
0170     COLOUR getCurrentPlayer();
0171 
0172     /**
0173      * Retrieve the current move number.
0174      * @return The amount [0..42]
0175      */
0176     int getCurrentMove();
0177 
0178     /**
0179      * Retrieve the maximum move which has been made before undos.
0180      * @return The amount [0..42]
0181      */
0182     int getMaxMove();
0183 
0184     /**
0185      * Retrieve the amount of moves in the undo/redo history.
0186      * @return The amount [0..42]
0187      */
0188     int getHistoryCnt();
0189 
0190     /**
0191      * Find the name of the AI process executable file.
0192      * @return The filename
0193      */
0194     QString findProcessName();
0195 
0196 protected:
0197     /**
0198      * Create and add an KGameIO device to an given player.
0199      * The old ones have to be removed manually before.
0200      * @param player The player to modify
0201      * @param io     The IO mode (Mouse, AI, Keyboard, ...)
0202      */
0203     void createIO(KPlayer *player, KGameIO::IOMode io);
0204 
0205     /**
0206      * Create a player of a given type (here only one type possible)
0207      * and equip it with a given KGameIO device. Virtual players
0208      * are remote network players.
0209      * @param rtti  Unused
0210      * @param io    The IO mode
0211      * @param isvirtual True for network players (without physical IO)
0212      */
0213     KPlayer *createPlayer(int rtti, int io, bool isvirtual) override;
0214 
0215     /**
0216      * KGame function to determine the next player. In KWin4 players alternate.
0217      * @param last      The last player to move
0218      * @param exclusive unused
0219      */
0220     KPlayer *doNextPlayer(KPlayer *last, bool exclusive = true);
0221 
0222     /**
0223      * This is also an overwritten function of KGame. It is
0224      * called in the game negotiation upon connect. Here
0225      * the games have to determine what player is remote and
0226      * what is local.
0227      * @param list     Unused
0228      * @param newList  List of new players
0229      * @param inactive List of inactive players
0230      */
0231     void newPlayersJoin(KGamePlayerList *list, KGamePlayerList *newList, QList<int> &inactive) override;
0232 
0233     /**
0234      * Reset the whole game to the beginning (clear board, ...)
0235      * @param initview  If true also reset the view
0236      */
0237     void resetGame(bool initview);
0238 
0239     /**
0240      * Make a game move to the given position and return a status.
0241      * Also displays it in the view.
0242      * @param x    The position to move to
0243      * @param mode The mode of the move (0: normal move: 1: redo move)
0244      * @return The movement status (allowed, normal, ...)
0245      */
0246     MOVESTATUS makeMove(int x, int mode);
0247 
0248     /**
0249      * Perform a game move. Calls makeMove().
0250      *  @param x  The position to move to
0251      *  @param id The player id
0252      *  @return True if the move was successful.
0253      */
0254     bool doMove(int x, int id);
0255 
0256     /**
0257      * Check whether the field has a game over situation. KGame standard
0258      * function.
0259      * @param player The current player
0260      * @return -1: draw, 1: won, 0: continue game
0261      */
0262     int doCheckGameOver(KPlayer *player);
0263 
0264     /**
0265      * Check whether the field has a game over situation. Called by
0266      * above standard KGame function but with more suitable parameters.
0267      * @param x   The position of the last move
0268      * @param col The color of the last move
0269      */
0270     int checkGameOver(int x, COLOUR col);
0271 
0272     /**
0273      * Pack the current game into a data stream so that it can be
0274      * send to the computer AI.
0275      * @param stream The data stream to write to
0276      * @param pl     The player id
0277      */
0278     void prepareGameMessage(QDataStream &stream, qint32 pl);
0279 
0280     /**
0281      * Main function to handle player input. This function is
0282      * the central input for all player inputs. Mouse, Keyboard
0283      * AI or network end here in the same format. A move is
0284      * initiated here.
0285      * @param msg    The game move message
0286      * @param player The sender player
0287      */
0288     bool playerInput(QDataStream &msg, KPlayer *player) override;
0289 
0290     /**
0291      * Set the IO devices new.
0292      */
0293     void recalcIO();
0294 
0295     /**
0296      * Set the turn of the current player to true so that
0297      * he can move.
0298      */
0299     void activateCurrentPlayer();
0300 
0301     /**
0302      * Set the score value of the AI.
0303      * @param value The score value.
0304      */
0305     void setScore(long value);
0306 
0307     /**
0308      * Set the colour of a position on the game board.
0309      * @param x The x position [0-6]
0310      * @param y The y position [0-5]
0311      * @param c The color [Red, Yellow, Nobody]
0312      */
0313     void setColour(int x, int y, COLOUR c);
0314 
0315     /**
0316      * Retrieve the colour of a position on the game board.
0317      * @param x The x position [0-6]
0318      * @param y The y position [0-5]
0319      * @return The color [Red, Yellow, Nobody]
0320      */
0321     COLOUR getColour(int x, int y);
0322 
0323     /**
0324      * Retrieve the color of the i-th player. Player 0 is the start
0325      * player and player 1 the follow up player.
0326      * @param player The player number [0,1]
0327      * @return The color of the player.
0328      */
0329     COLOUR getPlayerColour(int player);
0330 
0331 public Q_SLOTS:
0332     /**
0333      * Indication from the view that a move has been displayed. Now
0334      * The next player can be switched.
0335      * @param mode A user defined (unused) mode
0336      */
0337     void moveDone(int mode);
0338 
0339     /**
0340      * Load the game properties from the settings. Either the config file
0341      * or the config dialog call this.
0342      */
0343     void loadSettings();
0344 
0345 protected Q_SLOTS:
0346     /**
0347      * Initiate a repeat of the move. This happens if somehow the player
0348      * input created an invalid move. The same player has to input again.
0349      */
0350     void repeatMove();
0351 
0352     /**
0353      * An AI command was received from the computer AI _hint_ process. Process it.
0354      * Currently this is only the hint move.
0355      * @param in The input stream from the process
0356      * @param io The io device
0357      */
0358     void processAIHintCommand(QDataStream &in, KGameProcessIO *io);
0359 
0360     /**
0361      * An AI command was received from the computer AI _input device_ process. Process it.
0362      * Currently this is only the move score value.
0363      * @param in The input stream from the process
0364      * @param io The io device
0365      */
0366     void processAICommand(QDataStream &in, KGameProcessIO *io);
0367 
0368     /**
0369      * This slot is called by the signal of KGame to indicated
0370      * that the network connection is done and a new client is
0371      * connected
0372      * @param cid Is the id of the client connected. If this is equal gameId() WE are the client.
0373      * @param me  The game
0374      */
0375     void clientConnected(quint32 cid, KGame *me);
0376 
0377     /**
0378      * This slot is called by the KGame input device when we should prepare a message
0379      * to the AI process.
0380      * @param stream   The message stream
0381      * @param b        True if it is our turn
0382      * @param input    The input device
0383      * @param eatevent Set to true if a message has been send
0384      */
0385     void prepareAITurn(QDataStream &stream, bool b, KGameIO *input, bool *eatevent);
0386 
0387     /**
0388      * Debug: Listen to network messages.
0389      * @param id       The message id
0390      * @param sender   The sender
0391      * @param receiver The receiver
0392      */
0393     void networkMessageUpdate(int id, quint32 sender, quint32 receiver);
0394 
0395     /**
0396      * Called by KGame when a player property has changed.
0397      * We check whether the name changed and then update the score widget.
0398      * @param prop   The property
0399      * @param player The affected player
0400      */
0401     void playerPropertyChanged(KGamePropertyBase *prop, KPlayer *player);
0402 
0403     /**
0404      * Called by KGame when a game property has changed. We update the game
0405      * status etc.
0406      * @param prop  The property
0407      * @param me    The game
0408      */
0409     void gamePropertyChanged(KGamePropertyBase *prop, KGame *me);
0410 
0411     /**
0412      * Received a debug message from the AI (debug only)
0413      * @param s The message
0414      */
0415     void receivedStderr(const QString &s);
0416 
0417 Q_SIGNALS:
0418     /**
0419      * Emitted if the game status changes to run.
0420      */
0421     void signalGameRun();
0422 
0423     /**
0424      * Emitted if the chat origin changes.
0425      * @param player The affected player
0426      */
0427     void signalChatChanged(KWin4Player *player);
0428 
0429     /**
0430      * Emitted when the next players move is due.
0431      * @param playerNumber The number of the player
0432      */
0433     void signalNextPlayer(int playerNumber);
0434 
0435 private:
0436     // The view
0437     KWin4View *pView;
0438 
0439     // Last x position moved to
0440     KGamePropertyInt mLastColumn;
0441 
0442     // Colour of last move
0443     KGamePropertyInt mLastColour;
0444 
0445     // Amount of info in history
0446     KGamePropertyInt mHistoryCnt;
0447 
0448     // 42 pieces construct the game board
0449     KGamePropertyArray<int> mField;
0450 
0451     // Player who started game
0452     KGamePropertyInt mStartPlayer;
0453 
0454     // Player's to move
0455     KGamePropertyInt mAmzug;
0456 
0457     // Maximal move made in a game before undo
0458     KGamePropertyInt mMaxMove;
0459 
0460     // Current move number in the game
0461     KGamePropertyInt mCurrentMove;
0462 
0463     // To what height is a column filled
0464     KGamePropertyArray<int> mFieldFilled;
0465 
0466     // Position of last hint given
0467     KGamePropertyInt mLastHint;
0468 
0469     // Computer score value (position estimation)
0470     KGamePropertyInt mScore;
0471 
0472     // History of all moves (x positions)
0473     KGamePropertyArray<int> mHistory;
0474 
0475     // Input device of players
0476     KGameIO::IOMode mPlayedBy[2];
0477 
0478     // Process AI for hints
0479     KGameProcessIO *mHintProcess;
0480 
0481     // Score and status storage to communicate with view
0482     Score *mStatus;
0483 
0484     // Keep AI move values
0485     QVector<long> mAIValues;
0486 };
0487 
0488 #endif // KWIN4DOC_H