Files
utun2/tools/lightsout/src/boardwidget.h
T

57 lines
3.1 KiB
C++

/* Игровое поле Lights Out, все вызовы — GUI-поток. После создания вызвать newGame(3..8).
* Хранит real-биты и показывает XOR клетки с существующими ортогональными соседями.
* Клик меняет один real-бит и тем самым отображаемый крест; игра не блокируется после победы. */
#ifndef LIGHTSOUT_BOARDWIDGET_H
#define LIGHTSOUT_BOARDWIDGET_H
#include <QWidget>
#include <QVector>
class BoardWidget : public QWidget {
Q_OBJECT
public:
// Создаёт пустой виджет без партии; parent управляет временем жизни.
explicit BoardWidget(QWidget *parent = nullptr);
// Начинает size x size, сбрасывает ходы, сохраняет флаг подсказки и испускает stateChanged.
// size должен быть 3..8 (метод не проверяет); позиция решаемая, но может сразу оказаться погашенной.
void newGame(int size);
// Включает/выключает показ подсказки (точка на клетках real == 0).
void setHintEnabled(bool enabled);
// Показывается ли сейчас подсказка.
bool isHintEnabled() const { return m_hintEnabled; }
// Число ходов с начала партии.
int moves() const { return m_moves; }
signals:
// После newGame и каждого хода; solved проверяет отображаемые клетки, а не равенство всех real нулю.
void stateChanged(bool solved);
protected:
void paintEvent(QPaintEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
private:
// Центрированный квадрат: клетки 36 px, промежутки 4 px; не масштабируется под размер виджета.
QRectF boardRect() const;
// XOR клетки row/col и существующих соседей; индексы должны быть внутри поля.
int displayValue(int row, int col) const;
// Меняет real[row,col], увеличивает moves, обновляет рисунок и испускает stateChanged; индексы внутри поля.
void toggleCell(int row, int col);
// Проверяет, все ли отображаемые клетки погашены.
bool isSolved() const;
int m_size = 0; // 0 до newGame; затем размер поля, заданный вызывающим кодом (3..8).
QVector<quint8> m_real; // size*size битов 0/1, индекс row*size+col.
bool m_hintEnabled = false; // Зелёные точки на real == 0, сохраняется между партиями.
int m_moves = 0; // Число переключений после newGame, генерация поля не учитывается.
};
#endif // LIGHTSOUT_BOARDWIDGET_H