You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
p5okw7erl 6f732c1211
Update README.md
1 year ago
README.md Update README.md 1 year ago

README.md

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"));

} }