#include "boardwidget.h" #include #include /*类静态数据成员定义*/ const QSize BoardWidget::WIDGET_SIZE(430, 430); const QSize BoardWidget::CELL_SIZE(25, 25); const QPoint BoardWidget::START_POS(40, 40); const QPoint BoardWidget::ROW_NUM_START(15, 45); const QPoint BoardWidget::CLU_NUM_START(39, 25); const int BoardWidget::BOARD_WIDTH; const int BoardWidget::BOARD_HEIGHT; const int BoardWidget::NO_PIECE; const int BoardWidget::WHITE_PIECE; const int BoardWidget::BLACK_PIECE; const bool BoardWidget::WHITE_PLAYER; const bool BoardWidget::BLACK_PLAYER; BoardWidget::BoardWidget(QWidget *parent) : QWidget(parent) { setFixedSize(WIDGET_SIZE); setMouseTracking(true); initBoard(); } void BoardWidget::paintEvent(QPaintEvent *event) { QPainter painter(this); painter.fillRect(0, 0, width(), height(), Qt::gray); //背景颜色 for (int i = 0; i < BOARD_WIDTH; i++) { painter.drawText(CLU_NUM_START + QPoint(i * CELL_SIZE.width(), 0), QString::number(i + 1)); } for (int i = 0; i < BOARD_HEIGHT; i++) { painter.drawText(ROW_NUM_START + QPoint(0, i * CELL_SIZE.height()), QString::number(i + 1)); } for (int i = 0; i < BOARD_WIDTH - 1; i++) //绘制棋盘格子 { for (int j = 0; j < BOARD_HEIGHT - 1; j++) { painter.drawRect(QRect( START_POS + QPoint(i * CELL_SIZE.width(), j * CELL_SIZE.height()), CELL_SIZE)); } } painter.setPen(Qt::red); //落子提示 QPoint poses[12] = {trackPos + QPoint(0, 8), trackPos, trackPos + QPoint(8, 0), trackPos + QPoint(17, 0), trackPos + QPoint(25, 0), trackPos + QPoint(25, 8), trackPos + QPoint(25, 17), trackPos + QPoint(25, 25), trackPos + QPoint(17, 25), trackPos + QPoint(8, 25), trackPos + QPoint(0, 25), trackPos + QPoint(0, 17)}; painter.drawPolyline(poses, 3); painter.drawPolyline(poses + 3, 3); painter.drawPolyline(poses + 6, 3); painter.drawPolyline(poses + 9, 3); painter.setPen(Qt::NoPen); for (int i = 0; i < BOARD_WIDTH; i++) //绘制棋子 { for (int j = 0; j < BOARD_HEIGHT; j++) { if (board[i][j] != NO_PIECE) { QColor color = (board[i][j] == WHITE_PIECE) ? Qt::white : Qt::black; painter.setBrush(QBrush(color)); painter.drawEllipse( START_POS.x() - CELL_SIZE.width() / 2 + i * CELL_SIZE.width(), START_POS.y() - CELL_SIZE.height() / 2 + j * CELL_SIZE.height(), CELL_SIZE.width(), CELL_SIZE.height()); } } } painter.setPen(Qt::red); if (lastPos.x() != -1) { QPoint drawPos = START_POS + QPoint(lastPos.x() * CELL_SIZE.width(), lastPos.y() * CELL_SIZE.height()); painter.drawLine(drawPos + QPoint(0, 5), drawPos + QPoint(0, -5)); painter.drawLine(drawPos + QPoint(5, 0), drawPos + QPoint(-5, 0)); } for (QPoint pos : winPoses) { QPoint drawPos = START_POS + QPoint(pos.x() * CELL_SIZE.width(), pos.y() * CELL_SIZE.height()); painter.drawLine(drawPos + QPoint(0, 5), drawPos + QPoint(0, -5)); painter.drawLine(drawPos + QPoint(5, 0), drawPos + QPoint(-5, 0)); } } void BoardWidget::mouseReleaseEvent(QMouseEvent *event) { if (!endGame) { QPoint pos = event->pos() - START_POS; int x = pos.x(); int y = pos.y(); int pieceX = x / CELL_SIZE.width(); int pieceY = y / CELL_SIZE.height(); int offsetX = x % CELL_SIZE.width(); int offsetY = y % CELL_SIZE.height(); if (offsetX > CELL_SIZE.width() / 2) { pieceX++; } if (offsetY > CELL_SIZE.height() / 2) { pieceY++; } downPiece(pieceX, pieceY); } } void BoardWidget::mouseMoveEvent(QMouseEvent *event) { QPoint pos = event->pos() - START_POS + QPoint(CELL_SIZE.width() / 2, CELL_SIZE.height() / 2); int x = pos.x(); int y = pos.y(); //超过范围 if (x < 0 || x >= CELL_SIZE.width() * BOARD_WIDTH || y < 0 || y >= CELL_SIZE.height() * BOARD_HEIGHT) { return; } int offsetX = x % CELL_SIZE.width(); int offsetY = y % CELL_SIZE.height(); setTrackPos(QPoint(x - offsetX, y - offsetY) + START_POS - QPoint(CELL_SIZE.width() / 2, CELL_SIZE.height() / 2)); } void BoardWidget::initBoard() { for (int i = 0; i < BOARD_WIDTH; i++) { for (int j = 0; j < BOARD_HEIGHT; j++) { board[i][j] = NO_PIECE; } } trackPos = QPoint(28, 28); lastPos = QPoint(-1, -1); endGame = false; winPoses.clear(); nextPlayer = BLACK_PLAYER; } void BoardWidget::downPiece(int x, int y) { if (x >= 0 && x < BOARD_WIDTH && y >= 0 && y < BOARD_HEIGHT && board[x][y] == NO_PIECE) { board[x][y] = (nextPlayer == WHITE_PLAYER) ? WHITE_PIECE : BLACK_PIECE; nextPlayer = !nextPlayer; lastPos = QPoint(x, y); checkWinner(); update(); } } void BoardWidget::checkWinner() { bool fullPieces = true; for (int i = 0; i < BOARD_WIDTH; i++) { for (int j = 0; j < BOARD_HEIGHT; j++) { if (board[i][j] == NO_PIECE) { fullPieces = false; } if (board[i][j] != NO_PIECE && isFivePieceFrom(i, j)) { bool winner = (board[i][j] == WHITE_PIECE) ? WHITE_PLAYER : BLACK_PLAYER; endGame = true; emit gameOver(winner); } } } if (fullPieces) { endGame = true; emit gameOver(2); //代表和棋 } } bool BoardWidget::isFivePieceFrom(int x, int y) { return isVFivePieceFrom(x, y) || isHFivePieceFrom(x, y) || isFSFivePieceFrom(x, y) || isBSFivePieceFrom(x, y); } bool BoardWidget::isVFivePieceFrom(int x, int y) { int piece = board[x][y]; for (int i = 1; i < 5; i++) { if (y + i >= BOARD_HEIGHT || board[x][y + i] != piece) { return false; } } winPoses.clear(); for (int i = 0; i < 5; i++) { winPoses.append(QPoint(x, y + i)); } return true; } bool BoardWidget::isHFivePieceFrom(int x, int y) { int piece = board[x][y]; for (int i = 1; i < 5; i++) { if (x + i >= BOARD_WIDTH || board[x + i][y] != piece) { return false; } } winPoses.clear(); for (int i = 0; i < 5; i++) { winPoses.append(QPoint(x + i, y)); } return true; } bool BoardWidget::isFSFivePieceFrom(int x, int y) { int piece = board[x][y]; for (int i = 1; i < 5; i++) { if (x + i >= BOARD_WIDTH || y - i < 0 || board[x + i][y - i] != piece) { return false; } } winPoses.clear(); for (int i = 0; i < 5; i++) { winPoses.append(QPoint(x + i, y - i)); } return true; } bool BoardWidget::isBSFivePieceFrom(int x, int y) { int piece = board[x][y]; for (int i = 1; i < 5; i++) { if (x + i >= BOARD_WIDTH || y + i >= BOARD_HEIGHT || board[x + i][y + i] != piece) { return false; } } winPoses.clear(); for (int i = 0; i < 5; i++) { winPoses.append(QPoint(x + i, y + i)); } return true; } void BoardWidget::setTrackPos(const QPoint &value) { trackPos = value; update(); }