File indexing completed on 2024-04-28 04:05:21

0001 /*
0002     SPDX-FileCopyrightText: 2015 Jakob Gruber <jakob.gruber@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #ifndef PICMI_H
0008 #define PICMI_H
0009 
0010 #include <KGameHighScoreDialog>
0011 
0012 #include "boardmap.h"
0013 #include "boardstate.h"
0014 #include "elapsedtime.h"
0015 #include "settings.h"
0016 #include "streaks.h"
0017 
0018 /* Moved from picmi.cpp to work around QSharedPointer issues with forward declarations.
0019  * TODO: move this back once when Qt 5 is used. */
0020 class IOHandler
0021 {
0022 public:
0023     IOHandler(BoardMap *map, BoardState *state, ElapsedTime *timer) : m_map(map), m_state(state), m_timer(timer) { }
0024     virtual ~IOHandler() { }
0025 
0026     void set(int x, int y, Board::State state);
0027 
0028 protected:
0029     virtual void setCross(int x, int y);
0030     virtual void setBox(int x, int y) = 0;
0031 
0032     BoardMap *m_map;
0033     BoardState *m_state;
0034     ElapsedTime *m_timer;
0035 };
0036 
0037 class Picmi : public QObject
0038 {
0039     Q_OBJECT
0040 public:
0041 
0042     Picmi();
0043     explicit Picmi(QSharedPointer<BoardMap> board);
0044 
0045     int width() const;
0046     int height() const;
0047     int remainingBoxCount() const { return m_map->boxCount() - m_state->boxCount(); }
0048     QSharedPointer<BoardMap> getBoardMap() const { return m_map; }
0049     bool outOfBounds(int x, int y) const;
0050 
0051     /* 0 <= x < width(); 0 <= y < height() */
0052     Board::State stateAt(int x, int y) const { return m_state->get(x, y); }
0053     void setState(int x, int y, Board::State state);
0054 
0055     void setPaused(bool paused);
0056     int elapsedSecs() const;
0057 
0058     /* ends the current game and returns the current high score object */
0059     KGameHighScoreDialog::FieldInfo endGame();
0060 
0061     /* undo last action (if it exists) and return the changed coordinate. */
0062     QPoint undo();
0063 
0064     /* Uncovers a single, random, still uncovered cell. */
0065     QPoint hint();
0066 
0067     /* Solves the entire board, but does not emit the gameWon signal. */
0068     void solve();
0069 
0070     /* if a saved state exists, load it. otherwise, do nothing */
0071     void loadState() { m_state->loadState(); m_streaks->update(); Q_EMIT stateChanged(); }
0072     void saveState() { m_state->saveState(); }
0073     int currentStateAge() const { return m_state->currentStateAge(); }
0074 
0075     /* returns the request row/col streak. these contain the least information required by
0076       the frontend, which is (for each position within a streak): "which number is this",
0077       and "is this position solved" */
0078     QList<Streaks::Streak> getRowStreak(int y) const;
0079     QList<Streaks::Streak> getColStreak(int x) const;
0080 
0081 Q_SIGNALS:
0082     /** Emitted when the game has been completed in any way. Also triggered if "Solve" was used. */
0083     void gameCompleted();
0084 
0085     /** Emitted when the game has actually been won (i.e. "Solve" wasn't used). */
0086     void gameWon();
0087 
0088     /**
0089      * Emitted whenever the board state has changed (i.e. by undoing an action,
0090      * setting a state explicitly, or loading a saved state).
0091      */
0092     void stateChanged();
0093 
0094     void undoStackSizeChanged(int size);
0095     void saveStackSizeChanged(int size);
0096 
0097 private:
0098 
0099     /* returns true if the game has been won */
0100     bool won() const;
0101 
0102     void setupSlots();
0103 
0104 private:
0105     QSharedPointer<BoardMap> m_map;
0106     QSharedPointer<BoardState> m_state;
0107     QSharedPointer<IOHandler> m_io_handler;
0108     QSharedPointer<Streaks> m_streaks;
0109 
0110     ElapsedTime m_timer;
0111 };
0112 
0113 #endif // PICMI_H