#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
m_boardSize = 20; // 20*20
// 初始化棋盘
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
m_chessArr[i][j].isExist = false;
}
}
m_columnWidth = this->height()/(m_boardSize*1.05);
// 初始化按钮位置
ui->pushButton_back->move(m_columnWidth*(m_boardSize+2),m_columnWidth*(m_boardSize/2));
ui->pushButton_restart->move(m_columnWidth*(m_boardSize+2),m_columnWidth*(m_boardSize/3));
// 电脑下棋
srand(time(NULL));
connect(&timer, &QTimer::timeout, [=]()
{
// 电脑下棋
if (m_gameOver)
{
return ;
}
int x = 0;
int y = 0;
AI(&x, &y);
m_chessArr[x][y].chessType = m_playerReturn;
m_chessArr[x][y].isExist = true;
m_curChess.x = x;
m_curChess.y = y;
m_curChess.isExist = true;
m_curChess.value = 0;
m_curChess.chessType = m_playerReturn;
m_BackList.push_back(m_curChess);
timer.stop();
m_playerReturn = !m_playerReturn;
if (judgeVictory(x , y))
{
update();
QMessageBox::information(this, "胜负已定", "很遗憾,挑战失败!");
m_gameOver = true;
}
update();
});
}
Widget::~Widget()
{
delete ui;
}
void Widget::resizeEvent(QResizeEvent *event)
{
m_columnWidth = this->height()/(m_boardSize*1.05);
ui->pushButton_back->move(m_columnWidth*(m_boardSize+2),m_columnWidth*(m_boardSize/2));
ui->pushButton_restart->move(m_columnWidth*(m_boardSize+2),m_columnWidth*(m_boardSize/3));
}
void Widget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
// 画网格线
for (int i = 1; i <= m_boardSize; i++)
{
if (i == 1 || i == m_boardSize)
{
painter.setPen(QPen(Qt::black,3));
}
else
{
painter.setPen(QPen(Qt::black,1));
}
// 画横线
painter.drawLine(m_columnWidth, i*m_columnWidth, m_boardSize*m_columnWidth, i*m_columnWidth);
// 画竖线
painter.drawLine(i*m_columnWidth, m_columnWidth, i*m_columnWidth, m_boardSize*m_columnWidth);
}
// 画棋子
painter.setPen(QPen(Qt::black,1));
for (int i = 1; i <= m_boardSize; i++)
{
for (int j = 1; j <= m_boardSize; j++)
{
if (m_chessArr[i][j].isExist == true)
{
if (m_chessArr[i][j].chessType == true)
{
painter.setBrush(Qt::white);
painter.drawEllipse(i*m_columnWidth - m_columnWidth/2, j*m_columnWidth - m_columnWidth/2, m_columnWidth/1.2, m_columnWidth/1.2);
}
else if (m_chessArr[i][j].chessType == false)
{
painter.setBrush(Qt::black);
painter.drawEllipse(i*m_columnWidth - m_columnWidth/2, j*m_columnWidth - m_columnWidth/2, m_columnWidth/1.2, m_columnWidth/1.2);
}
}
}
}
if (m_curChess.isExist)
{
if (m_chessArr[m_curChess.x][m_curChess.y].chessType == true)
{
painter.setBrush(Qt::white);
}
else if (m_chessArr[m_curChess.x][m_curChess.y].chessType == false)
{
painter.setBrush(Qt::black);
}
QPen pen;
pen.setColor(Qt::red);
pen.setWidth(3);
painter.setPen(pen);
painter.drawEllipse(m_curChess.x*m_columnWidth - m_columnWidth/2, m_curChess.y*m_columnWidth - m_columnWidth/2, m_columnWidth/1.2, m_columnWidth/1.2);
}
painter.end();
}
void Widget::mouseReleaseEvent(QMouseEvent *event)
{
if (m_playerReturn == false || m_gameOver == true)
{
return ;
}
if (event->button() == Qt::LeftButton)
{
// 计算落子位置
int xPos = event->x();
int yPos = event->y();
for (int i = 1; i <= m_boardSize; i++)
{
for (int j = 1; j <= m_boardSize; j++)
{
if (((xPos - i*m_columnWidth) < m_columnWidth/2) && ((yPos - (j*m_columnWidth)) < m_columnWidth/2))
{
if (m_chessArr[i][j].isExist == true)
{
return ;
}
// 玩家下棋
m_chessArr[i][j].chessType = m_playerReturn;
m_chessArr[i][j].isExist = true;
m_curChess;
m_curChess.x = i;
m_curChess.y = j;
m_curChess.isExist = true;
m_curChess.chessType = m_playerReturn;
m_curChess.value = 0;
m_BackList.push_back(m_curChess);
m_playerReturn = !m_playerReturn;
if (judgeVictory(i , j))
{
// qDebug() << m_playerReturn << "获胜";
update();
QMessageBox::information(this, "胜负已定", "恭喜你,挑战成功!");
m_gameOver = true;
}
// 电脑准备下棋
timer.start(2000);
update();
return ;
}
}
}
}
return ;
}
bool Widget::judgeVictory(int x,int y)
{
for(int i=1,j=y; i<=m_boardSize; i++) //锁定列,扫描同一列上的元素是否相等
{
if((m_chessArr[i][j].isExist == true && m_chessArr[i+1][j].isExist == true && m_chessArr[i+2][j].isExist == true && m_chessArr[i+3][j].isExist == true && m_chessArr[i+4][j].isExist == true)
&& (m_chessArr[i][j].chessType == !m_playerReturn && m_chessArr[i+1][j].chessType == !m_playerReturn && m_chessArr[i+2][j].chessType == !m_playerReturn && m_chessArr[i+3][j].chessType == !m_playerReturn && m_chessArr[i+4][j].chessType == !m_playerReturn))
{
return true;
}
}
for(int i=x,j=1; j<=m_boardSize; j++) //锁定行,扫描同一行上的元素是否相等
{
if((m_chessArr[i][j].isExist == true && m_chessArr[i][j+1].isExist == true && m_chessArr[i][j+2].isExist == true && m_chessArr[i][j+3].isExist == true && m_chessArr[i][j+4].isExist == true)
&& (m_chessArr[i][j].chessType == !m_playerReturn && m_chessArr[i][j+1].chessType == !m_playerReturn && m_chessArr[i][j+2].chessType == !m_playerReturn && m_chessArr[i][j+3].chessType == !m_playerReturn && m_chessArr[i][j+4].chessType == !m_playerReturn))
{
return true;
}
}
//找到左下最后一个元素的行标,扫描落子所在正对角线
for(int i=x+y-1,j=1; i>=1; i--,j++)
{
if((m_chessArr[i][j].isExist == true && m_chessArr[i-1][j+1].isExist == true && m_chessArr[i-2][j+2].isExist == true && m_chessArr[i-3][j+3].isExist == true && m_chessArr[i-4][j+4].isExist == true)
&& (m_chessArr[i][j].chessType == !m_playerReturn && m_chessArr[i-1][j+1].chessType == !m_playerReturn && m_chessArr[i-2][j+2].chessType == !m_playerReturn && m_chessArr[i-3][j+3].chessType == !m_playerReturn && m_chessArr[i-4][j+4].chessType == !m_playerReturn))
{
return true;
}
}
//先找到左上第一个元素的列标,扫描落子所在副对角线上
for(int i=x-y+1,j=1; j<=m_boardSize; i++,j++)
{
if((m_chessArr[i][j].isExist == true && m_chessArr[i+1][j+1].isExist == true && m_chessArr[i+2][j+2].isExist == true && m_chessArr[i+3][j+3].isExist == true && m_chessArr[i+4][j+4