以下是符合5.14.2qt版本的代码,实现五子棋规则和悔棋功能:
mainwindow.h
```
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPushButton>
#include <QLabel>
#include <QGridLayout>
#include <QMessageBox>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void buttonClicked();
void undoClicked();
private:
QPushButton *buttons[15][15];
QPushButton *undoButton;
QLabel *messageLabel;
QGridLayout *gridLayout;
int chessboard[15][15];
int currentPlayer;
bool gameOver;
int steps;
int history[225][3];
void initUI();
void initChessboard();
bool checkWin(int row, int col);
bool checkHorizontal(int row, int col);
bool checkVertical(int row, int col);
bool checkDiagonal1(int row, int col);
bool checkDiagonal2(int row, int col);
void showMessage(QString message);
void updateChessboard(int row, int col);
void undoChessboard();
};
#endif // MAINWINDOW_H
```
mainwindow.cpp
```
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
initUI();
initChessboard();
}
MainWindow::~MainWindow()
{
}
void MainWindow::initUI()
{
QWidget *centralWidget = new QWidget(this);
setCentralWidget(centralWidget);
gridLayout = new QGridLayout(centralWidget);
gridLayout->setSpacing(0);
for (int i = 0; i < 15; i++) {
for (int j = 0; j < 15; j++) {
buttons[i][j] = new QPushButton(centralWidget);
buttons[i][j]->setFixedSize(40, 40);
buttons[i][j]->setProperty("row", i);
buttons[i][j]->setProperty("col", j);
gridLayout->addWidget(buttons[i][j], i, j);
connect(buttons[i][j], SIGNAL(clicked()), this, SLOT(buttonClicked()));
}
}
undoButton = new QPushButton(tr("悔棋"), centralWidget);
undoButton->setFixedSize(80, 40);
connect(undoButton, SIGNAL(clicked()), this, SLOT(undoClicked()));
gridLayout->addWidget(undoButton, 15, 0, 1, 2);
messageLabel = new QLabel(centralWidget);
messageLabel->setFixedSize(150, 40);
gridLayout->addWidget(messageLabel, 15, 2, 1, 13, Qt::AlignLeft | Qt::AlignVCenter);
setFixedSize(620, 620);
setWindowTitle(tr("五子棋"));
}
void MainWindow::initChessboard()
{
for (int i = 0; i < 15; i++) {
for (int j = 0; j < 15; j++) {
chessboard[i][j] = 0;
}
}
currentPlayer = 1;
gameOver = false;
steps = 0;
memset(history, 0, sizeof(history));
showMessage(tr("黑方先手"));
}
bool MainWindow::checkWin(int row, int col)
{
if (checkHorizontal(row, col) || checkVertical(row, col) ||
checkDiagonal1(row, col) || checkDiagonal2(row, col)) {
return true;
}
return false;
}
bool MainWindow::checkHorizontal(int row, int col)
{
int count = 1;
for (int i = col - 1; i >= 0; i--) {
if (chessboard[row][i] == chessboard[row][col]) {
count++;
} else {
break;
}
}
for (int i = col + 1; i < 15; i++) {
if (chessboard[row][i] == chessboard[row][col]) {
count++;
} else {
break;
}
}
if (count >= 5) {
return true;
}
return false;
}
bool MainWindow::checkVertical(int row, int col)
{
int count = 1;
for (int i = row - 1; i >= 0; i--) {
if (chessboard[i][col] == chessboard[row][col]) {
count++;
} else {
break;
}
}
for (int i = row + 1; i < 15; i++) {
if (chessboard[i][col] == chessboard[row][col]) {
count++;
} else {
break;
}
}
if (count >= 5) {
return true;
}
return false;
}
bool MainWindow::checkDiagonal1(int row, int col)
{
int count = 1;
for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
if (chessboard[i][j] == chessboard[row][col]) {
count++;
} else {
break;
}
}
for (int i = row + 1, j = col + 1; i < 15 && j < 15; i++, j++) {
if (chessboard[i][j] == chessboard[row][col]) {
count++;
} else {
break;
}
}
if (count >= 5) {
return true;
}
return false;
}
bool MainWindow::checkDiagonal2(int row, int col)
{
int count = 1;
for (int i = row - 1, j = col + 1; i >= 0 && j < 15; i--, j++) {
if (chessboard[i][j] == chessboard[row][col]) {
count++;
} else {
break;
}
}
for (int i = row + 1, j = col - 1; i < 15 && j >= 0; i++, j--) {
if (chessboard[i][j] == chessboard[row][col]) {
count++;
} else {
break;
}
}
if (count >= 5) {
return true;
}
return false;
}
void MainWindow::showMessage(QString message)
{
messageLabel->setText(message);
}
void MainWindow::updateChessboard(int row, int col)
{
buttons[row][col]->setIcon(currentPlayer == 1 ? QIcon(":/black.png") : QIcon(":/white.png"));
chessboard[row][col] = currentPlayer;
history[steps][0] = row;
history[steps][1] = col;
history[steps][2] = currentPlayer;
steps++;
if (checkWin(row, col)) {
gameOver = true;
QString message = QString("恭喜%1方获胜!").arg(currentPlayer == 1 ? "黑" : "白");
showMessage(message);
QMessageBox::information(this, "游戏结束", message);
} else if (steps == 15 * 15) {
gameOver = true;
showMessage("平局");
QMessageBox::information(this, "游戏结束", "平局");
} else {
currentPlayer = currentPlayer == 1 ? 2 : 1;
QString message = QString("%1方落子").arg(currentPlayer == 1 ? "黑" : "白");
showMessage(message);
}
}
void MainWindow::undoChessboard()
{
if (steps > 0) {
steps--;
int row = history[steps][0];
int col = history[steps][1];
int player = history[steps][2];
buttons[row][col]->setIcon(QIcon());
chessboard[row][col] = 0;
currentPlayer = player;
QString message = QString("%1方悔棋").arg(currentPlayer == 1 ? "黑" : "白");
showMessage(message);
}
}
void MainWindow::buttonClicked()
{
if (gameOver) {
return;
}
QPushButton *button = qobject_cast<QPushButton *>(sender());
int row = button->property("row").toInt();
int col = button->property("col").toInt();
if (chessboard[row][col] == 0) {
updateChessboard(row, col);
}
}
void MainWindow::undoClicked()
{
if (gameOver) {
return;
}
undoChessboard();
}
```
注意:在工程的资源文件 (.qrc) 中需要添加黑棋图标(black.png)和白棋图标(white.png)。