From 207c68e5250d8dd7b11c4e116025de2226dc30c4 Mon Sep 17 00:00:00 2001 From: p5okw7erl <1557888938@qq.com> Date: Sat, 22 Jun 2024 22:52:36 +0800 Subject: [PATCH] Update README.md --- README.md | 272 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 272 insertions(+) diff --git a/README.md b/README.md index b7a426b..a6efd82 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,274 @@ # WZQ +#include "gamewidget.h" +#include "ui_gamewidget.h" +#include +#include +#include + +const int kBoardSize = 15; // 棋盘大小 +const int kCellSize = 40; // 格子大小 +const int kMargin = 20; // 棋盘边距 +const int kPieceSize = 30; // 棋子大小 + +enum PieceType { + kEmpty, + kBlack, + kWhite +}; + +GameWidget::GameWidget(QWidget *parent) : + QWidget(parent), + ui(new Ui::GameWidget) +{ + ui->setupUi(this); + + // 创建棋盘场景 + scene = new QGraphicsScene(this); + ui->boardView->setScene(scene); + ui->boardView->setRenderHint(QPainter::Antialiasing); + + // 绘制棋盘 + for (int i = 0; i < kBoardSize; i++) { + for (int j = 0; j < kBoardSize; j++) { + QGraphicsRectItem* rect = new QGraphicsRectItem(i * kCellSize, j * kCellSize, kCellSize, kCellSize); + rect->setPen(Qt::NoPen); + rect->setBrush(QBrush(QColor("#D18B47"), Qt::SolidPattern)); + scene->addItem(rect); + } + } + + // 初始化棋盘数组 + for (int i = 0; i < kBoardSize; i++) { + for (int j = 0; j < kBoardSize; j++) { + board_[i][j] = kEmpty; + } + } + + // 初始化当前玩家为黑色 + currentPlayer_ = kBlack; + ui->statusLabel->setText(tr("Black's turn")); +} + +GameWidget::~GameWidget() +{ + delete ui; +} + +void GameWidget::mousePressEvent(QMouseEvent* event) { + if (event->button() != Qt::LeftButton) { + return; + } + + QPointF pos = ui->boardView->mapToScene(event->pos()); + + // 将落点转换为棋盘坐标 + int x = qRound(pos.x() / kCellSize); + int y = qRound(pos.y() / kCellSize); + + // 判断落点是否有效,如果无效则返回 + if (x < 0 || x >= kBoardSize || y < 0 || y >= kBoardSize || board_[x][y] != kEmpty) { + return; + } + + // 在落点绘制棋子 + QGraphicsEllipseItem* item = new QGraphicsEllipseItem(x * kCellSize + kMargin, y * kCellSize + kMargin, + kPieceSize, kPieceSize); + item->setBrush(QBrush((currentPlayer_ == kBlack) ? Qt::black : Qt::white, Qt::SolidPattern)); + scene->addItem(item); + + // 记录落子位置和棋子对象 + QPoint point(x, y); + history_.push(point); + lastItem_ = item; + + // 更新棋盘数组 + board_[x][y] = currentPlayer_; + + // 判断游戏是否结束 + if (checkWin(x, y)) { + QString message = (currentPlayer_ == kBlack) ? tr("Black wins!") : tr("White wins!"); + QMessageBox::StandardButton button = QMessageBox::information(this, tr("Game Over"), message); + if (button == QMessageBox::Ok) { + resetGame(); + } + return; + } else if (checkTie()) { + QMessageBox::StandardButton button = QMessageBox::information(this, tr("Game Over"), tr("Tie!")); + if (button == QMessageBox::Ok) { + resetGame(); + } + return; + } + + // 切换玩家 + currentPlayer_ = (currentPlayer_ == kBlack) ? kWhite : kBlack; + ui->statusLabel->setText((currentPlayer_ == kBlack) ? tr("Black's turn") : tr("White's turn")); +} + +bool GameWidget::checkWin(int x, int y) { + int i, j, count; + + // 判断横向是否五子连珠 + count = 1; + for (i = x - 1; i >= 0 && board_[i][y] == currentPlayer_; i--) { + count++; + } + for (i = x + 1; i < kBoardSize && board_[i][y] == currentPlayer_; i++) { + count++; + } + if (count >= 5) { + return true; + } + + // 判断纵向是否五子连珠 + count = 1; + for (j = y - 1; j >= 0 && board_[x][j] == currentPlayer_; j--) { + count++; + } + for (j = y + 1; j < kBoardSize && board_[x][j] == currentPlayer_; j++) { + count++; + } + if (count >= 5) { + return true; + } + + // 判断左上到右下是否五子连珠 + count = 1; + for (i = x - 1, j = y - 1; i >= 0 && j >= 0 && board_[i][j] == currentPlayer_; i--, j--) { + count++; + } + for (i = x + 1, j = y + 1; i < kBoardSize && j < kBoardSize && board_[i][j] == currentPlayer_; i++, j++) { + count++; + } + if (count >= 5) { + return true; + } + + // 判断左下到右上是否五子连珠 + count = 1; + for (i = x - 1, j = y + 1; i >= 0 && j < kBoardSize && board_[i][j] == currentPlayer_; i--, j++) { + count++; + } + for (i = x + 1, j = y - 1; i < kBoardSize && j >= 0 && board_[i][j] == currentPlayer_; i++, j--) { + count++; + } + if (count >= 5) { + return true; + } + + return false; +} + +bool GameWidget::checkTie() { + for (int i = 0; i < kBoardSize; i++) { + for (int j = 0; j < kBoardSize; j++) { + if (board_[i][j] == kEmpty) { + return false; + } + } + } + return true; +} + +void GameWidget::resetGame() { + // 清空棋盘场景和棋盘数组 + scene->clear(); + for (int i = 0; i < kBoardSize; i++) { + for (int j = 0; j < kBoardSize; j++) { + board_[i][j] = kEmpty; + } + } + + // 重置历史记录和当前玩家 + while (!history_.empty()) { + history_.pop(); + } + currentPlayer_ = kBlack; + + // 更新状态栏 + ui->statusLabel->setText(tr("Black's turn")); +} + +void GameWidget::undo() { + // 如果历史记录为空,则返回 + if (history_.empty()) { + return; + } + + // 恢复上一个落子点的状态,并从历史记录中删除该点 + QPoint point = history_.top(); + history_.pop(); + board_[point.x()][point.y()] = kEmpty; + scene->removeItem(lastItem_); + delete lastItem_; + lastItem_ = nullptr; + + // 切换当前玩家 + currentPlayer_ = (currentPlayer_ == kBlack) ? kWhite : kBlack; + ui->statusLabel->setText((currentPlayer_ == kBlack) ? tr("Black's turn") : tr("White's turn")); +} + +void GameWidget::newGame() { + // 弹出确认对话框 + QMessageBox::StandardButton button = QMessageBox::question(this, tr("New Game"), + tr("Are you sure you want to start a new game?"), + QMessageBox::Yes | QMessageBox::No); + if (button == QMessageBox::Yes) { + resetGame(); + } +} + +void GameWidget::saveGame() { + // 弹出保存对话框,获取保存文件路径 + QString fileName = QFileDialog::getSaveFileName(this, tr("Save Game"), ".", tr("Game files (*.game)")); + if (fileName.isEmpty()) { + return; + } + + // 打开保存文件,保存棋盘数组和当前玩家 + QFile file(fileName); + if (file.open(QIODevice::WriteOnly)) { + QDataStream stream(&file); + stream.writeRawData((const char*)board_, sizeof(board_)); + stream << currentPlayer_; + file.close(); + } +} + +void GameWidget::loadGame() { + // 弹出打开对话框,获取打开文件路径 + QString fileName = QFileDialog::getOpenFileName(this, tr("Load Game"), ".", tr("Game files (*.game)")); +if (fileName.isEmpty()) { +return; +} +// 打开保存文件,读取棋盘数组和当前玩家 +QFile file(fileName); +if (file.open(QIODevice::ReadOnly)) { + QDataStream stream(&file); + stream.readRawData((char*)board_, sizeof(board_)); + stream >> currentPlayer_; + file.close(); + + // 清空棋盘场景,重新绘制棋盘和棋子 + scene->clear(); + for (int i = 0; i < kBoardSize; i++) { + for (int j = 0; j < kBoardSize; j++) { + QGraphicsRectItem* rect = new QGraphicsRectItem(i * kCellSize, j * kCellSize, kCellSize, kCellSize); + rect->setPen(Qt::NoPen); + rect->setBrush(QBrush(QColor("#D18B47"), Qt::SolidPattern)); + scene->addItem(rect); + + if (board_[i][j] != kEmpty) { + QGraphicsEllipseItem* item = new QGraphicsEllipseItem(i * kCellSize + kMargin, j * kCellSize + kMargin, + kPieceSize, kPieceSize); + item->setBrush(QBrush((board_[i][j] == kBlack) ? Qt::black : Qt::white, Qt::SolidPattern)); + scene->addItem(item); + } + } + } + + // 更新状态栏 + ui->statusLabel->setText((currentPlayer_ == kBlack) ? tr("Black's turn") : tr("White's turn")); +} +} \ No newline at end of file