File indexing completed on 2024-07-14 04:00:04

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