예제 소스
VLM을 이용한 테트리스 학습 · 파일 31개
tetris_widget.cpp
#include "tetris_widget.h"
#include "tetris_engine.h"
#include <algorithm>
#include <QFont>
#include <QPainter>
#include <QPaintEvent>
#include <QResizeEvent>
namespace {
QColor color_for_cell(uint8_t v) {
switch (v) {
case 1:
return QColor(80, 220, 250); // I
case 2:
return QColor(250, 220, 60); // O
case 3:
return QColor(180, 80, 220); // T
case 4:
return QColor(90, 220, 120); // S
case 5:
return QColor(240, 90, 90); // Z
case 6:
return QColor(80, 120, 240); // J
case 7:
return QColor(240, 160, 60); // L
default:
return QColor(40, 44, 52);
}
}
} // namespace
TetrisWidget::TetrisWidget(QWidget* parent) : QWidget(parent) {
setMinimumSize(260, 560);
}
void TetrisWidget::refresh() {
update();
}
void TetrisWidget::resizeEvent(QResizeEvent*) {
if (!engine_) {
return;
}
const int w = engine_->config().board_width;
const int visible_h = engine_->config().board_height - engine_->config().hidden_rows;
const int avail_w = std::max(1, width() - 24);
const int avail_h = std::max(1, height() - 24);
cell_px_ = std::max(10, std::min(avail_w / w, avail_h / visible_h));
}
void TetrisWidget::paintEvent(QPaintEvent*) {
QPainter p(this);
p.fillRect(rect(), QColor(24, 26, 32));
if (!engine_) {
p.setPen(Qt::white);
p.drawText(rect(), Qt::AlignCenter, QStringLiteral("No engine"));
return;
}
const auto& cfg = engine_->config();
const int w = cfg.board_width;
const int h = cfg.board_height;
const int hidden = cfg.hidden_rows;
const int visible_rows = h - hidden;
std::vector<uint8_t> cells;
engine_->fill_render_grid(cells);
const int ox = (width() - w * cell_px_) / 2;
const int oy = (height() - visible_rows * cell_px_) / 2;
p.setPen(QColor(60, 64, 74));
for (int y = 0; y < visible_rows; ++y) {
for (int x = 0; x < w; ++x) {
const int gy = y + hidden;
const uint8_t v = cells[gy * w + x];
const QRect r(ox + x * cell_px_, oy + y * cell_px_, cell_px_, cell_px_);
p.fillRect(r.adjusted(1, 1, -1, -1), color_for_cell(v));
p.drawRect(r);
}
}
// 상태 오버레이
if (engine_->game_over()) {
p.fillRect(rect(), QColor(0, 0, 0, 170));
QFont f = p.font();
f.setPointSize(22);
f.setBold(true);
p.setFont(f);
p.setPen(QColor(240, 80, 80));
p.drawText(rect().adjusted(0, 0, 0, -40), Qt::AlignCenter, QStringLiteral("GAME OVER"));
f.setPointSize(13);
f.setBold(false);
p.setFont(f);
p.setPen(QColor(200, 200, 200));
p.drawText(rect().adjusted(0, 40, 0, 0), Qt::AlignCenter, QStringLiteral("R 키로 재시작"));
} else if (paused_) {
p.fillRect(rect(), QColor(0, 0, 0, 130));
QFont f = p.font();
f.setPointSize(22);
f.setBold(true);
p.setFont(f);
p.setPen(QColor(250, 200, 60));
p.drawText(rect().adjusted(0, 0, 0, -40), Qt::AlignCenter, QStringLiteral("PAUSED"));
f.setPointSize(13);
f.setBold(false);
p.setFont(f);
p.setPen(QColor(200, 200, 200));
p.drawText(rect().adjusted(0, 40, 0, 0), Qt::AlignCenter, QStringLiteral("P 키로 재개 / R 키로 재시작"));
}
}