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 BOARDSTATE_H
0008 #define BOARDSTATE_H
0009 
0010 #include <QObject>
0011 #include <QPoint>
0012 #include <QStack>
0013 #include <QSharedPointer>
0014 
0015 #include "board.h"
0016 
0017 class BoardState : public QObject, public Board
0018 {
0019     Q_OBJECT
0020 public:
0021     /* initializes an empty field of given width and height,
0022       and creates initial (empty) streaks.
0023       width, height > 0 */
0024     BoardState(int width, int height);
0025 
0026     /* 0 <= x < m_width; 0 <= y < m_height
0027       sets point (x, y) to state */
0028     void set(int x, int y, enum State state);
0029 
0030     /* undo the last stored action and return the changed coordinate.
0031        if none are left, nothing occurs and QPoint() is returned*/
0032     QPoint undo();
0033 
0034     /* save the current state and push it onto the state stack. */
0035     void saveState();
0036 
0037     /* pop and load a state if state stack is non-empty.
0038        otherwise, do nothing */
0039     void loadState();
0040 
0041     /* returns the age (in steps) of the current game state
0042        compared to the latest saved state. for example, if the
0043        current undo_queue.size() == 15, and the top of saved_states
0044        is 10, currentStateAge returns 5. */
0045     int currentStateAge() const;
0046 
0047     /* returns the count of player-set boxes */
0048     int boxCount() const { return m_box_count; }
0049 
0050     /* replaces all occurrences of prev with next.
0051        bookkeeping information (undo history, box count) is _not_ updated */
0052     void replace(enum State prev, enum State next);
0053 
0054     /* Copies the board to this state. Like replace(), bookkeeping
0055        information is not updated since this is the final action in a game. */
0056     void solve(const Board *board);
0057 
0058 Q_SIGNALS:
0059     void undoStackSizeChanged(int size);
0060     void saveStackSizeChanged(int size);
0061 
0062 private:
0063 
0064     /* updates the box count according to old state prev and incoming state next. */
0065     void updateBoxCount(Board::State prev, Board::State next);
0066 
0067 private:
0068 
0069     struct UndoAction {
0070         int x, y;
0071         enum State state;
0072     };
0073 
0074     QStack<UndoAction> m_undo_queue;
0075     QStack<int> m_saved_states;     /* size of m_undo_queue when state was saved */
0076 
0077     int m_box_count;
0078 };
0079 
0080 #endif // BOARDSTATE_H