QT中五子棋代码实现
时间: 2024-06-20 07:02:41 浏览: 131
在Qt中实现五子棋游戏,你可以使用QWidgets库来创建用户界面,以及QGraphicsView和QGraphicsScene来处理棋盘和棋子的图形表示。以下是一个简单的步骤概述:
1. **设置项目**:
创建一个新的Qt Widgets Application项目。
2. **设计界面**:
- 设计一个QGraphicsView,显示棋盘背景。
- 使用QGraphicsItems(如QGraphicsRectItem或自定义棋子形状)代表棋盘格和棋子。
- 添加两个QPushButton或QToolButton,用于切换玩家颜色。
3. **棋盘布局**:
- 创建一个二维数组表示棋盘,每个元素表示一个格子。
- 使用QGraphicsScene中的网格来绘制棋盘。
4. **实现游戏逻辑**:
- 使用继承自QObject的类作为棋子对象,包含位置信息、颜色等。
- 实现AI对手或用户输入的逻辑,判断落子是否合法,检测是否胜利条件(连线五子)。
5. **事件处理**:
- 对于用户点击或落子事件,更新棋盘状态,并检查是否需要重绘棋盘。
- 在AI对手落子时,同样更新棋盘并检查状态。
6. **游戏循环**:
- 在主循环中,交替执行玩家和AI的回合,直到游戏结束。
7. **显示结果**:
- 游戏结束后,根据胜者显示提示信息。
相关问题
基于Qt实现五子棋代码
以下是基于Qt实现五子棋的代码:
mainwindow.h
```cpp
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPushButton>
#include <QLabel>
#include <QMouseEvent>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
protected:
void paintEvent(QPaintEvent *event);
void mousePressEvent(QMouseEvent *event);
private:
enum {ROW = 15, COL = 15}; // 棋盘行列数
enum {WIDTH = 40, HEIGHT = 40}; // 棋子大小
QPushButton *startButton; // 开始按钮
QPushButton *backButton; // 悔棋按钮
QPushButton *exitButton; // 退出按钮
QLabel *turnLabel; // 提示当前轮到哪个玩家
QLabel *blackCountLabel; // 黑方棋子数
QLabel *whiteCountLabel; // 白方棋子数
QPoint mousePos; // 鼠标点击位置
int board[ROW][COL] = {0}; // 棋盘,0表示空,1表示黑,2表示白
int turn = 1; // 当前轮到哪个玩家,1表示黑,2表示白
int blackCount = 0; // 黑方棋子数
int whiteCount = 0; // 白方棋子数
bool isGameOver = false; // 是否结束游戏
void initUI(); // 初始化UI
void startGame(); // 开始游戏
void drawBoard(QPainter &painter); // 绘制棋盘
void drawPiece(QPainter &painter, int row, int col); // 绘制棋子
bool checkWin(int row, int col); // 检查是否胜利
void gameOver(); // 游戏结束
void reset(); // 重置游戏
};
#endif // MAINWINDOW_H
```
mainwindow.cpp
```cpp
#include "mainwindow.h"
#include <QPainter>
#include <QMessageBox>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
initUI();
}
MainWindow::~MainWindow()
{
}
void MainWindow::initUI()
{
setFixedSize(620, 620);
startButton = new QPushButton("开始游戏", this);
startButton->setGeometry(500, 50, 100, 40);
connect(startButton, &QPushButton::clicked, this, &MainWindow::startGame);
backButton = new QPushButton("悔棋", this);
backButton->setGeometry(500, 130, 100, 40);
backButton->setEnabled(false);
connect(backButton, &QPushButton::clicked, [=]() {
if (!isGameOver) { // 游戏未结束才能悔棋
board[mousePos.x()][mousePos.y()] = 0; // 当前位置清空
turn = turn == 1 ? 2 : 1; // 切换玩家
backButton->setEnabled(false); // 禁用悔棋按钮
update(); // 重新绘制
}
});
exitButton = new QPushButton("退出游戏", this);
exitButton->setGeometry(500, 210, 100, 40);
connect(exitButton, &QPushButton::clicked, [=]() {
if (QMessageBox::Yes == QMessageBox::question(this, "提示", "确定要退出吗?")) {
qApp->quit();
}
});
turnLabel = new QLabel("当前轮到黑方下棋", this);
turnLabel->setGeometry(500, 300);
blackCountLabel = new QLabel("黑方棋子数:0", this);
blackCountLabel->setGeometry(500, 350);
whiteCountLabel = new QLabel("白方棋子数:0", this);
whiteCountLabel->setGeometry(500, 400);
}
void MainWindow::startGame()
{
reset(); // 重置游戏
startButton->setEnabled(false); // 开始游戏后禁用开始按钮
}
void MainWindow::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
drawBoard(painter); // 绘制棋盘
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COL; j++) {
if (board[i][j] != 0) {
drawPiece(painter, i, j); // 绘制棋子
}
}
}
}
void MainWindow::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) { // 左键点击
int x = event->x();
int y = event->y();
if (x >= 20 && x <= 580 && y >= 20 && y <= 580) { // 在棋盘内点击
int row = (y - 20) / HEIGHT;
int col = (x - 20) / WIDTH;
if (board[row][col] == 0) { // 当前位置没有棋子
board[row][col] = turn; // 下棋
if (checkWin(row, col)) { // 检查是否胜利
gameOver();
} else {
turn = turn == 1 ? 2 : 1; // 切换玩家
backButton->setEnabled(true); // 开启悔棋按钮
}
update(); // 重新绘制
}
}
}
}
void MainWindow::drawBoard(QPainter &painter)
{
painter.setPen(QPen(Qt::black, 2));
for (int i = 0; i < ROW; i++) {
painter.drawLine(20, 20 + i * HEIGHT, 20 + (ROW - 1) * WIDTH, 20 + i * HEIGHT);
painter.drawLine(20 + i * WIDTH, 20, 20 + i * WIDTH, 20 + (COL - 1) * HEIGHT);
}
}
void MainWindow::drawPiece(QPainter &painter, int row, int col)
{
if (board[row][col] == 1) { // 黑方棋子
painter.setBrush(QBrush(Qt::black));
} else if (board[row][col] == 2) { // 白方棋子
painter.setBrush(QBrush(Qt::white));
}
painter.drawEllipse(QPoint(col * WIDTH + 20, row * HEIGHT + 20), WIDTH / 2, HEIGHT / 2);
}
bool MainWindow::checkWin(int row, int col)
{
int i, j, k, count;
// 横向
count = 1;
for (i = col - 1; i >= 0; i--) { // 向左
if (board[row][i] == turn) {
count++;
} else {
break;
}
}
for (i = col + 1; i < COL; i++) { // 向右
if (board[row][i] == turn) {
count++;
} else {
break;
}
}
if (count >= 5) {
return true;
}
// 纵向
count = 1;
for (i = row - 1; i >= 0; i--) { // 向上
if (board[i][col] == turn) {
count++;
} else {
break;
}
}
for (i = row + 1; i < ROW; i++) { // 向下
if (board[i][col] == turn) {
count++;
} else {
break;
}
}
if (count >= 5) {
return true;
}
// 斜向(左上到右下)
count = 1;
for (i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) { // 向左上
if (board[i][j] == turn) {
count++;
} else {
break;
}
}
for (i = row + 1, j = col + 1; i < ROW && j < COL; i++, j++) { // 向右下
if (board[i][j] == turn) {
count++;
} else {
break;
}
}
if (count >= 5) {
return true;
}
// 斜向(左下到右上)
count = 1;
for (i = row + 1, j = col - 1; i < ROW && j >= 0; i++, j--) { // 向左下
if (board[i][j] == turn) {
count++;
} else {
break;
}
}
for (i = row - 1, j = col + 1; i >= 0 && j < COL; i--, j++) { // 向右上
if (board[i][j] == turn) {
count++;
} else {
break;
}
}
if (count >= 5) {
return true;
}
return false;
}
void MainWindow::gameOver()
{
isGameOver = true;
backButton->setEnabled(false); // 禁用悔棋按钮
QString message = turn == 1 ? "黑方胜利!" : "白方胜利!";
QMessageBox::information(this, "游戏结束", message);
startButton->setEnabled(true); // 开启开始按钮
}
void MainWindow::reset()
{
memset(board, 0, sizeof(board)); // 清空棋盘
turn = 1; // 黑方先手
blackCount = 0;
whiteCount = 0;
isGameOver = false;
backButton->setEnabled(false); // 禁用悔棋按钮
update(); // 重新绘制
}
```
在.pro文件中添加:
```pro
QT += widgets
```
编译运行即可看到五子棋界面。
C++基于qt 的五子棋悔棋代码
以下是基于Qt的五子棋悔棋代码示例:
(1)在mainwindow.h中添加如下代码:
```
private:
int chessboard[15][15]; // 用来存储棋盘信息
int player; // 玩家标志,1表示黑棋,2表示白棋
int step; // 记录步数
bool isUndo; // 是否悔棋标志
QList<QPair<int, int>> historyList; // 用来存储历史记录
```
(2)在mainwindow.cpp中添加如下代码:
```
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 初始化棋盘信息
memset(chessboard, 0, sizeof(chessboard));
player = 1;
step = 0;
isUndo = false;
// 绑定悔棋按钮点击事件
connect(ui->undoBtn, &QPushButton::clicked, this, &MainWindow::undo);
// 绑定棋盘点击事件
connect(ui->chessBoard, &ChessBoard::clicked, this, &MainWindow::playChess);
}
void MainWindow::playChess(int row, int col)
{
if (chessboard[row][col] != 0) {
QMessageBox::warning(this, tr("Warning"), tr("The position has been occupied!"));
return;
}
// 绘制棋子
ui->chessBoard->drawChess(row, col, player);
// 记录历史记录
historyList.append(qMakePair(row, col));
// 更新棋盘信息
chessboard[row][col] = player;
step++;
// 判断是否有胜者
if (ui->chessBoard->isWin(row, col)) {
QMessageBox::information(this, tr("Congratulations"), tr("Player %1 wins!").arg(player == 1 ? tr("Black") : tr("White")));
ui->chessBoard->setEnabled(false);
return;
}
// 判断是否平局
if (step == 225) {
QMessageBox::information(this, tr("Tie"), tr("Tie game!"));
ui->chessBoard->setEnabled(false);
return;
}
// 切换玩家
player = player == 1 ? 2 : 1;
}
void MainWindow::undo()
{
if (step == 0) {
QMessageBox::warning(this, tr("Warning"), tr("There is no step to undo!"));
return;
}
// 获取历史记录中的最后一步
QPair<int, int> lastStep = historyList.last();
int row = lastStep.first;
int col = lastStep.second;
// 悔棋
ui->chessBoard->undoChess(row, col);
// 更新棋盘信息
chessboard[row][col] = 0;
step--;
// 切换玩家
player = player == 1 ? 2 : 1;
// 删除历史记录中的最后一步
historyList.removeLast();
}
```
(3)在chessboard.cpp中添加如下代码:
```
void ChessBoard::drawChess(int row, int col, int player)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setPen(Qt::NoPen);
if (player == 1) {
painter.setBrush(Qt::black);
} else {
painter.setBrush(Qt::white);
}
painter.drawEllipse(QPointF((col + 0.5) * gridSize(), (row + 0.5) * gridSize()), gridSize() / 2 - 2, gridSize() / 2 - 2);
}
bool ChessBoard::isWin(int row, int col)
{
int count = 1; // 连续棋子的数量
// 判断横向是否有五个棋子相连
for (int i = col - 1; i >= 0; i--) {
if (m_chessboard[row][i] != m_chessboard[row][col]) {
break;
}
count++;
}
for (int i = col + 1; i < 15; i++) {
if (m_chessboard[row][i] != m_chessboard[row][col]) {
break;
}
count++;
}
if (count >= 5) {
return true;
}
// 判断纵向是否有五个棋子相连
count = 1;
for (int i = row - 1; i >= 0; i--) {
if (m_chessboard[i][col] != m_chessboard[row][col]) {
break;
}
count++;
}
for (int i = row + 1; i < 15; i++) {
if (m_chessboard[i][col] != m_chessboard[row][col]) {
break;
}
count++;
}
if (count >= 5) {
return true;
}
// 判断左上到右下是否有五个棋子相连
count = 1;
for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
if (m_chessboard[i][j] != m_chessboard[row][col]) {
break;
}
count++;
}
for (int i = row + 1, j = col + 1; i < 15 && j < 15; i++, j++) {
if (m_chessboard[i][j] != m_chessboard[row][col]) {
break;
}
count++;
}
if (count >= 5) {
return true;
}
// 判断左下到右上是否有五个棋子相连
count = 1;
for (int i = row + 1, j = col - 1; i < 15 && j >= 0; i++, j--) {
if (m_chessboard[i][j] != m_chessboard[row][col]) {
break;
}
count++;
}
for (int i = row - 1, j = col + 1; i >= 0 && j < 15; i--, j++) {
if (m_chessboard[i][j] != m_chessboard[row][col]) {
break;
}
count++;
}
if (count >= 5) {
return true;
}
return false;
}
void ChessBoard::undoChess(int row, int col)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setPen(QPen(Qt::black, 2));
painter.setBrush(Qt::NoBrush);
painter.drawRect(col * gridSize(), row * gridSize(), gridSize(), gridSize());
if (m_chessboard[row][col] == 1) {
painter.setPen(QPen(Qt::black, 1));
painter.setBrush(Qt::black);
} else {
painter.setPen(QPen(Qt::white, 1));
painter.setBrush(Qt::white);
}
painter.drawEllipse(QPointF((col + 0.5) * gridSize(), (row + 0.5) * gridSize()), gridSize() / 2 - 2, gridSize() / 2 - 2);
m_chessboard[row][col] = 0;
}
```
以上代码实现了基于Qt的五子棋悔棋功能,可以参考编写。
阅读全文