#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPushButton>
#include <QLabel>
#include <QVector>
const int colorWhite = 1;
const int colorBlack = 2;
const int lineMaxNumber = 19;
struct DropPosition
{
int X;
int Y;
int color;
};
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
int startPointX = 50;
int startPointY = 50;
int lineDistance = 20;
int starRadius = 6;
int pieceRadius = 18;
int fontSize = 6;
int buttonWidth = 80;
int buttonHeight = 50;
int buttonDistance = 30;
bool blackOrWhite = false;
bool isDisplayNumber = false;
int number = 1;
int points[lineMaxNumber][lineMaxNumber];
int checkPoints[lineMaxNumber][lineMaxNumber];
QVector<DropPosition> *vector;
QPushButton *clearPushButton;
QPushButton *passPushButton;
QPushButton *undoPushButton;
QPushButton *displayPushButton;
QPushButton *savePushButton;
QLabel *stepLabel;
void mousePressEvent(QMouseEvent *event);
void paintEvent(QPaintEvent *event);
void eat(int xnum, int ynum, int color);
void clean(int xnum, int ynum, int color);
int ifthere(int xnum, int ynum, int color);
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "qpainter.h"
#include "qlabel.h"
#include "QMouseEvent"
#include "qdebug.h"
#include "qpixmap.h"
#include "qrect.h"
#include "qdatetime.h"
#include "qstring.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
setFixedSize(700,800);
setWindowTitle("go game");
startPointX = 50;
startPointY = 50;
lineDistance = (this->width()-100)/18;
starRadius = lineDistance / 3;
pieceRadius = lineDistance - 2;
fontSize = pieceRadius / 3;
memset(points,0,sizeof(points));
vector = new QVector<DropPosition>;
stepLabel = new QLabel(this);
stepLabel->setText("Wait for Black to move ...");
stepLabel->resize(300,50);
stepLabel->move((this->width()-stepLabel->width())/2,this->height()-stepLabel->height());
clearPushButton = new QPushButton(this);
clearPushButton->setText("clear");
clearPushButton->resize(buttonWidth,buttonHeight);
clearPushButton->move((this->width()-buttonWidth*5-buttonDistance*4)/2,this->height()-buttonHeight-50);
connect(clearPushButton,&QPushButton::clicked,this,[=](){
for(int i=0;i<lineMaxNumber;i++)
{
for(int j=0;j<lineMaxNumber;j++)
{
points[i][j] = 0;
}
}
number = 1;
blackOrWhite = false;
vector->clear();
QString str = QString("clearPushButton pressed");
stepLabel->setText(str);
update();
});
undoPushButton = new QPushButton(this);
undoPushButton->setText("undo");
undoPushButton->resize(buttonWidth,buttonHeight);
undoPushButton->move((this->width()-buttonWidth*5-buttonDistance*4)/2+buttonWidth+buttonDistance,this->height()-buttonHeight-50);
connect(undoPushButton,&QPushButton::clicked,this,[=](){
if(vector->length() > 0)
{
int x = vector->at(vector->length()-1).X;
int y = vector->at(vector->length()-1).Y;
if (vector->at(vector->length()-1).color == colorBlack)
{
blackOrWhite = false;
}
else if (vector->at(vector->length()-1).color == colorWhite)
{
blackOrWhite = true;
}
points[x][y] = 0;
number = number - 1;
vector->remove(vector->length()-1);
if(vector->length() > 0)
{
for(int i=0;i<vector->length();i++)
{
points[vector->at(i).X][vector->at(i).Y]=vector->at(i).color;
eat(vector->at(i).X,vector->at(i).Y,vector->at(i).color);
}
}
}
QString str = QString("undoPushButton pressed");
stepLabel->setText(str);
update();
});
passPushButton = new QPushButton(this);
passPushButton->setText("pass");
passPushButton->resize(buttonWidth,buttonHeight);
passPushButton->move((this->width()-buttonWidth*5-buttonDistance*4)/2+buttonWidth*2+buttonDistance*2,this->height()-buttonHeight-50);
connect(passPushButton,&QPushButton::clicked,this,[=](){
blackOrWhite = blackOrWhite == true ? false : true;
DropPosition point;
point.X = -1;
point.Y = -1;
point.color = 0;
vector->append(point);
number = number + 1;
QString str = QString("passPushButton pressed");
stepLabel->setText(str);
});
displayPushButton = new QPushButton(this);
displayPushButton->setText("display");
displayPushButton->resize(buttonWidth,buttonHeight);
displayPushButton->move((this->width()-buttonWidth*5-buttonDistance*4)/2+buttonWidth*3+buttonDistance*3,this->height()-buttonHeight-50);
connect(displayPushButton,&QPushButton::clicked,this,[=](){
isDisplayNumber = isDisplayNumber == true ? false : true;
update();
});
savePushButton = new QPushButton(this);
savePushButton->setText("save");
savePushButton->resize(buttonWidth,buttonHeight);
savePushButton->move((this->width()-buttonWidth*5-buttonDistance*4)/2+buttonWidth*4+buttonDistance*4,this->height()-buttonHeight-50);
connect(savePushButton,&QPushButton::clicked,this,[=](){
QPixmap pixmap = this->grab(QRect(startPointX-lineDistance,startPointY-lineDistance,(lineMaxNumber+1)*lineDistance,(lineMaxNumber+1)*lineDistance));
QDateTime dateTime = QDateTime::currentDateTime();
QString str = dateTime.toString("yyyy-MM-dd HH:mm:ss") + ".png";
pixmap.save(str,"png");
});
}
MainWindow::~MainWindow()
{
}
void MainWindow::mousePressEvent(QMouseEvent *event)
{
int x = (event->x() - startPointX)/lineDistance;
if (event->x() - startPointX - lineDistance*x > lineDistance/2)
{
x = x+1;
}
int y = (event->y() - startPointY)/lineDistance;
if (event->y() - startPointY - lineDistance*y > lineDistance/2)
{
y = y+1;
}
if ((x < 0 || x > lineMaxNumber) || (y < 0 || y > lineMaxNumber)) return;
if (points[x][y]) return;
if (blackOrWhite)
{
points[x][y] = colorWhite;
number = number + 1;
blackOrWhite = false;
eat(x,y,colorWhite);
DropPosition point;
point.X = x;
point.Y = y;
point.color = colorWhite;
vector->append(point);
QString str = QString("White drop position:X:%1,Y:%2").arg(x).arg(y);
stepLabel->setText(str);
}
else
{
points[x][y] = colorBlack;
number = number + 1;
blackOrWhite = true;
eat(x,y,colorBlack);
DropPosition point;
point.X = x;
point.Y = y;
point.color = colorBlack;
vector->append(point);
QString str = QString("Black drop position:X:%1,Y:%2").arg(x).arg(y);
stepLabel->setText(str);
}
update();
}
void MainWindow::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
//painter.setRenderHint(QPainter::HighQualityAntialiasing);
QPixmap pix;
pix.load(":/background.png");
painter.drawPixmap(startPointX-lineDistance,startPointY-lineDistance,(lineMaxNumber+1)*lineDistance,(lineMaxNumber+1)*lineDistance,pix);
for(int i=0;i<lineMaxNumber;i++)
{
painter.drawLine(startPointX + i*lineDistance, startPointY, startPointX + i*lineDistance, startPointY + (lineMaxNumber-1)*lineDistance);
painter.drawLine(startPointX, startPointY + i*lineDistance, startPointX + (lineMaxNumber-1)*lineDistance, startPointY + i*lineDistance);
if ((i == 3) || (i == 9) || (i == 15))
{
painter.setBrush(QBrush(Qt::black,Qt::SolidPattern));
painter.drawEllipse(startPointX + i*lineDistance - starRadius / 2,startPointY + 3*lineDistance - starRadius / 2, starRadius, starRadius);
painter.drawEllipse(startPointX + i*lineDistance - starRadius / 2,startPointY + 9*lineDistance - starRadius / 2, starRadius, starRadius);
painter.drawEllipse(startPointX + i*lineDistance - starRadius / 2,startPointY + 15*lineDistance - starRadius / 2, starRadius, starRadius);
}
}
for(int i=0;i<lineMaxNumber;i++)
{
for(int j=0;j<lineMaxNumber;j++)
{
if (points[i][j])
{
if (points[i][j] == colorWhite)
{
// painter.setBrush(QBrush(Qt::white,Qt::SolidPattern));
// painter.drawEllipse(startPointX + i*lineDistance - pieceRadius / 2,startPointY + j*lineDistance - pieceRadius / 2, pieceRadius, pieceRadius);
pix.load(":/white.png");
painter.drawPixmap(startPointX + i*lineDistance - pieceRadius / 2,startPointY + j*lineDistance - pieceRadius / 2, pieceRadius, pieceRadius, pix);
}
else if (points[i][j] == colorBlack)
{
// painter.setBrush(QBrush(Qt::black,Qt::SolidPattern));
// painter.drawEllipse(startPointX + i*lineDistance - pieceRadius / 2,startPointY + j*lineDistance - pieceRadius / 2, pieceRadius, pieceRadius);
pix.load(":/green.png");
painter.drawPixmap(startPointX + i*lineDistance - pieceRadius / 2,startPointY + j*lineDistance - pieceRadius / 2, pieceRadius, pieceRadius, pix);
}
}
}
}
if (isDisplayNumber)
{
for(int i=0;i<vector->length();i++)
{
if ((vector->at(i).X>=0) && (vector->at(i).Y>=0) && (points[vector->at(i).X][vector->at(i).Y]))
{
QFont font("Helvetica", fontSize, QFont::Bold, true);
painter.setFont(font);
if (points[vector->at(i).X][vector->at(i).Y] == colorBlack)
{
painter.setPen(QColor(Qt::white));
}
else if (points[vector->at(i).X][vector->at(i).Y] == colorWhite)
{
painter.setPen(QColor(Qt::black));
}
QRectF rect(startPointX + vector->at(i).X*lineDistance - pieceRadius / 2,startPointY + vector->at(i).Y*lineDistance - pieceRadius / 2, pieceRadius, pieceRadius);
painter.drawText(rect,Qt::AlignCenter,QString::number(i+1));
}
}
}
}
//吃棋总逻辑
void MainWindow::eat(int X, int Y, int color)
{
if (X - 1 >= 0)
{
if ((points[X - 1][Y] != color)&&(points[X-1][Y]))
{
memset(checkPoints, 0, lineMaxNumber * lineMaxNumber * sizeof(int));
if (!ifthere((X - 1), Y, points[X - 1][Y]))
{
clean((X - 1), Y, points[X - 1][Y]);
}
}
}
if (X + 1 < lineMaxNumber)
{
if ((points[X+1][Y] != color) && (points[X+1][Y]))
{
memset(checkPoints, 0, lineMaxNumber * lineMaxNumber * sizeof(int));
if (!ifthere((X+1), Y, points[X +1][Y]))
{
clean((X+1), Y, points[X+1][Y]);
}
}
}
if (Y + 1 < lineMaxNumber)
{
if ((points[X][Y+1] != color) && (points[X][Y+1]))
{
memset(checkPoints, 0, lineMaxNumber * lineMaxNumber * sizeof(int));
if (!ifthere(X, (Y+1), points[X][Y+1]))
{
clean(X, (Y+1), points[X][Y+1]);
}
}
}
if (Y - 1 >= 0)
{
if ((points[X][Y-1] != color) && (points[X][Y-1]))
{
memset(checkPoints, 0, lineMaxNumber * lineMaxNumber * sizeof(int));
if (!ifthere(X, (Y-1), points[X][Y-1]))
{
clean(X, (Y-1), points[X][Y-1]);
}
}
}
}
//清除逻辑
void MainWindow::clean(int X, int Y, int color)
{
points[X][Y] = 0;
if (X - 1 >= 0)
{
if (points[X - 1][Y] == color)
clean((X - 1), Y, color);
}
if (X + 1 < lineMaxNumber)
{
if (points[X+1][Y] == color)
clean((X+1), Y, color);
}
if (Y - 1 >= 0)
{
if (points[X][Y-1] == color)
clean(X,(Y-1), color);
}
if (Y + 1 < lineMaxNumber)
{
if (points[X][Y+1] == color)
clean(X, (Y+1), color);
}
return;
}
//判断棋是否存活
int MainWindow::ifthere(int X, int Y, int color)
{
checkPoints[X][Y] = 1;
int ret = 0;
if (X + 1 < lineMaxNumber)
{
if (points[X+1][Y] == 0)
{
return 1;
}
if (points[X+1][Y] == color)
{
if (!checkPoints[X+1][Y])
ret = ret + ifthere((X+1), Y, color);
}
}
if (X - 1 >= 0)
{
if (points[X-1][Y] == 0)
{
return 1;
}
if (points[X-1][Y] == color)
{
if (!checkPoints[X-1][Y])
ret = ret + ifthere((X-1), Y, color);
}
}
if (Y + 1 <lineMaxNumber)
{
if (points[X][Y+1] == 0)
{
return 1;
}
if (points[X][Y+1] == color)
{
if (!checkPoints[X][Y+1])
ret = ret + ifthere(X, (Y+1), color);
}
}
if (Y - 1 >= 0)
{
if (points[X][Y-1] == 0)
{
return 1;
}
if (points[X][Y-1] == color)
{
if (!checkPoints[X][Y-1])
ret = ret + ifthere(X, (Y-1), color);
}
}
if (ret > 0)
return 1;
else
return 0;
}