File indexing completed on 2024-04-21 04:02:24

0001 /*
0002     SPDX-FileCopyrightText: 2009 Ian Wadham <iandw.au@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #ifndef KGRRUNNER_H
0008 #define KGRRUNNER_H
0009 
0010 #include "kgrglobals.h"
0011 
0012 #include <QObject>
0013 #include <QElapsedTimer> // IDW
0014 
0015 class KGrLevelPlayer;
0016 class KGrLevelGrid;
0017 class KGrRuleBook;
0018 class KGrEnemy;
0019 
0020 enum  Situation {NotTimeYet, CaughtInBrick, MidCell, EndCell};
0021 
0022 /**
0023  * This class provides the shared features of all runners (hero and enemies).
0024  */
0025 class KGrRunner : public QObject
0026 {
0027     Q_OBJECT
0028 public:
0029     /**
0030      * The constructor of the KGrRunner virtual class.
0031      *
0032      * @param pLevelPlayer The object that owns the runner and will destroy it
0033      *                     if the KGoldrunner application is terminated during
0034      *                     play.  The object also provides helper functions to
0035      *                     the runners.
0036      * @param pGrid        The grid on which the runner is playing.
0037      * @param i            The starting column-number (>=1).
0038      * @param j            The starting row-number (>=1).
0039      * @param pSpriteId    The sprite ID of the runner, as used in animation.
0040      * @param pRules       The rules that apply to this game and level.
0041      * @param startDelay   The starting-time advantage enemies give to the hero.
0042      */
0043     KGrRunner (KGrLevelPlayer * pLevelPlayer, KGrLevelGrid * pGrid,
0044                int i, int j, const int pSpriteId,
0045                KGrRuleBook  * pRules, const int startDelay);
0046     ~KGrRunner() override;
0047 
0048     /**
0049      * Returns the exact position of a runner (in grid-points or cell
0050      * sub-divisions) and the number of grid-points per cell, from which the
0051      * cell's column-number and row-number can be calculated if required.
0052      *
0053      * @param x            X-coordinate in grid-points (return by reference).
0054      * @param y            Y-coordinate in grid-points (return by reference).
0055      *
0056      * @return             The number of grid-points per cell.
0057      */
0058     inline int whereAreYou (int & x, int & y) {
0059                             x = gridX; y = gridY; return pointsPerCell; }
0060 
0061 Q_SIGNALS:
0062     /**
0063      * Requests the KGoldrunner game to add to the human player's score.
0064      *
0065      * @param n            The amount to add to the score.
0066      */
0067     void incScore          (const int n);
0068 
0069     /**
0070      * Requests the view-object to display an animation of a runner at a
0071      * particular cell, cancelling and superseding any current animation.
0072      *
0073      * @param spriteId     The ID of the sprite (hero or enemy).
0074      * @param repeating    If true, repeat the animation until the next signal.
0075      * @param i            The column-number of the cell to start at.
0076      * @param j            The row-number of the cell to start at.
0077      * @param time         The time in which to traverse one cell.
0078      * @param dirn         The direction of motion, or STAND.
0079      * @param type         The type of animation (walk, climb. etc.).
0080      */
0081     void startAnimation    (const int spriteId, const bool repeating,
0082                             const int i, const int j, const int time,
0083                             const Direction dirn, const AnimationType type);
0084 
0085 protected:
0086     KGrLevelPlayer * levelPlayer;
0087     KGrLevelGrid *   grid;
0088     KGrRuleBook *    rules;
0089 
0090     int              spriteId;
0091 
0092     int              gridI;
0093     int              gridJ;
0094     int              gridX;
0095     int              gridY;
0096     int              deltaX;
0097     int              deltaY;
0098 
0099     int              pointCtr;
0100     int              pointsPerCell;
0101     bool             turnAnywhere;
0102 
0103     void             getRules();
0104 
0105     Situation        situation (const int scaledTime);
0106     char             nextCell();
0107     bool             setNextMovement (const char spriteType,
0108                                       const char cellType,
0109                                       Direction & dir,
0110                                       AnimationType & anim, int & interval);
0111 
0112     bool             falling;
0113     KGrEnemy *       onEnemy;       // If standing or riding on an enemy.
0114     Direction        currDirection;
0115     AnimationType    currAnimation;
0116 
0117     int              runTime;       // Time interval for hero/enemy running.
0118     int              fallTime;      // Time interval for hero/enemy falling.
0119     int              enemyFallTime; // Time interval for enemy falling.
0120     int              trapTime;      // Time interval for which an enemy can
0121                     // stay trapped in a brick.
0122 
0123     int              interval;      // The runner's current time interval.
0124     int              timeLeft;      // Time till the runner's next action.
0125 
0126     bool             leftRightSearch;   // KGoldrunner-rules enemy search-mode.
0127 
0128     QElapsedTimer            t; // IDW
0129 };
0130 
0131 
0132 /**
0133  * This class models the behaviour of the hero.  It inherits from KGrRunner.
0134  *
0135  * The hero's main functions are running, digging holes in bricks and collecting
0136  * gold.  If he is caught by an enemy or trapped in a closing brick, he dies.
0137  * If he collects all the gold and runs to the top row, he wins the level.
0138  */
0139 class KGrHero : public KGrRunner
0140 {
0141     Q_OBJECT
0142 public:
0143     /**
0144      * The constructor of the KGrHero class.  The parameters are the same as
0145      * for the KGrRunner constructor, which does most of the work, but this
0146      * constructor also initialises the hero's timing, which depends on the
0147      * rules being used.
0148      *
0149      * @param pLevelPlayer The object that owns the hero and will destroy him
0150      *                     if the KGoldrunner application is terminated during
0151      *                     play.  The object also provides helper functions to
0152      *                     the hero.
0153      * @param pGrid        The grid on which the hero is playing.
0154      * @param i            The starting column-number (>=1).
0155      * @param j            The starting row-number (>=1).
0156      * @param pSpriteId    The sprite ID of the hero, as used in animation.
0157      * @param pRules       The rules that apply to this game and level.
0158      */
0159     KGrHero (KGrLevelPlayer * pLevelPlayer, KGrLevelGrid * pGrid,
0160                 int i, int j, int pSpriteId, KGrRuleBook  * pRules);
0161     ~KGrHero() override;
0162 
0163     /**
0164      * Makes the hero run, under control of a pointer or the keyboard and
0165      * guided by the layout of the grid.  The method is invoked by a periodic
0166      * timer and returns NORMAL status while play continues.  If the hero is
0167      * caught by an enemy or trapped in a brick, it returns DEAD status, or
0168      * if he collects all the gold and reaches the top row, the method returns
0169      * WON_LEVEL status.  Otherwise it changes the hero's position as required
0170      * and decides the type of animation to display (run left, climb, etc.).
0171      *
0172      * @param scaledTime   The amount by which to adjust the time, scaled
0173      *                     according to the current game-speed setting.  Smaller
0174      *                     times cause slower running in real-time: larger times
0175      *                     cause faster running.
0176      *
0177      * @return             The hero's status: NORMAL, DEAD or WON_LEVEL.
0178      */
0179     HeroStatus       run (const int scaledTime);
0180 
0181     /**
0182      * Decides whether the hero can dig as is required by pressing a key or a
0183      * mouse-button.  If OK, the KGrLevelPlayer will control the dug brick.
0184      *
0185      * @param dirn         The direction in which to dig: L or R of the hero.
0186      * @param digI         The column-number of the brick (return by reference).
0187      * @param digJ         The row-number of the brick (return by reference).
0188      *
0189      * @return             If true, a hole can be dug in the direction required.
0190      */
0191     bool             dig (const Direction dirn, int & digI, int & digJ);
0192 
0193     /**
0194      * Tells the hero whether dig while falling is allowed, or not.
0195      */
0196     inline void      setDigWhileFalling (const bool dwf)
0197                                         { digWhileFalling = dwf; }
0198 
0199     /**
0200      * Tells the hero how many gold nuggets are remaining.
0201      *
0202      * @param nGold        The number of gold nuggets remaining.
0203      */
0204     inline void      setNuggets (const int nGold) { nuggets = nGold; }
0205 
0206     /**
0207      * Implements the author's debugging aid that shows the hero's state.
0208      */
0209     void             showState();
0210 
0211 Q_SIGNALS:
0212     void             soundSignal (const int n, const bool onOff = true);
0213     void             invalidDig();  // Warning re dig while falling.
0214 
0215 private:
0216     bool             digWhileFalling;   // If dig while falling is allowed.
0217     int              nuggets;       // Number of gold pieces remaining.
0218 };
0219 
0220 
0221 /**
0222  * This class models the behaviour of an enemy.  It inherits from KGrRunner.
0223  *
0224  * An enemy's main functions are running, chasing the hero and collecting or
0225  * dropping gold.  If he comes to a dug brick, he must fall in and give up any
0226  * gold he is carrying.  If he is trapped in a closing brick, he dies but
0227  * reappears elsewhere on the grid.
0228  */
0229 class KGrEnemy :     public KGrRunner
0230 {
0231     Q_OBJECT
0232 public:
0233     /**
0234      * The constructor of the KGrEnemy class.
0235      *
0236      * @param pLevelPlayer The object that owns the enemy and will destroy him
0237      *                     if the KGoldrunner application is terminated during
0238      *                     play.  The object also provides helper functions to
0239      *                     the enemies.
0240      * @param pGrid        The grid on which the enemy is playing.
0241      * @param i            The starting column-number (>=1).
0242      * @param j            The starting row-number (>=1).
0243      * @param pSpriteId    The sprite ID of the enemy, as used in animation.
0244      * @param pRules       The rules that apply to this game and level.
0245      */
0246     KGrEnemy (KGrLevelPlayer * pLevelPlayer, KGrLevelGrid * pGrid,
0247                  int i, int j, int pSpriteId, KGrRuleBook  * pRules);
0248     ~KGrEnemy() override;
0249 
0250     /**
0251      * Makes an enemy run, guided by the position of the hero and the layout of
0252      * the grid.  The method is invoked by a periodic timer.  If the enemy is
0253      * trapped in a brick, he reappears somewhere else on the grid, depending
0254      * on the rules for the game and level.  While running, the enemy picks up
0255      * and randomly drops gold.  If he comes to a dug brick, he must fall in
0256      * and give up any gold he is carrying.  He can climb out after a time: or
0257      * the hole might close first.  Otherwise the method changes the enemy's
0258      * position as required, avoids collisions and decides the type of animation
0259      * to display (run left, climb, etc.).
0260      *
0261      * @param scaledTime   The amount by which to adjust the time, scaled
0262      *                     according to the current game-speed setting.  Smaller
0263      *                     times cause slower running in real-time: larger times
0264      *                     cause faster running.
0265      */
0266     void             run (const int scaledTime);
0267 
0268     /**
0269      * Returns the direction in which the enemy is running: used for avoiding
0270      * collisions with other enemies.
0271      */
0272     inline Direction direction() { return (currDirection); }
0273 
0274     /**
0275      * Returns the ID of an enemy who already occupied the same cell (or -1).
0276      */
0277     inline int       getPrevInCell()  { return (prevInCell); }
0278 
0279     /**
0280      * Sets the ID of an enemy who already occupied the same cell (or -1).
0281      *
0282      * @param prevEnemy    The sprite ID of the previous enemy (or -1).
0283      */
0284     inline void      setPrevInCell (const int prevEnemy) {
0285                                     prevInCell = prevEnemy; }
0286 
0287     /**
0288      * Returns true if the enemy is falling.
0289      */
0290     inline bool      isFalling() { return falling; }
0291 
0292     /**
0293      * Implements the author's debugging aid that shows the enemy's state.
0294      */
0295     void             showState();
0296 
0297 private:
0298     char             rulesType;     // Rules type and enemy search method.
0299 
0300     int              nuggets;       // Number of gold pieces an enemy holds.
0301     int              birthI;        // Enemy's starting position (used in
0302     int              birthJ;        // KGoldrunner rules for re-birth).
0303     int              prevInCell;    // ID of previous enemy in cell or -1.
0304 
0305     void             dropGold();
0306     void             checkForGold();
0307     void             dieAndReappear();
0308 
0309     void             reserveCell (const int i, const int j);
0310     void             releaseCell (const int i, const int j);
0311 };
0312 
0313 #endif // KGRRUNNER_H