57 lines
3.1 KiB
C++
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
|