五子棋是个简单的小游戏,尝试使用Qt将他做出来,学习时的练习demo。
成果展示
需求分析
五子棋:在棋盘上,黑棋先行,交替下棋,五子练成直线获取胜利。
实现过程
1.棋盘绘制:下棋的第一步肯定是绘制棋盘
这里使用for循环画了15*15个格子数
//画棋盘
void MainWindow::DrawChessboard()
{
QPainter painter(this);//创建一个QPainter对象
//设置抗锯齿 用于平滑图形的边缘
painter.setRenderHint(QPainter::HighQualityAntialiasing, true);
//设置画刷的颜色 用于填充图形的内部
painter.setBrush(Qt::darkYellow);
//设置画笔的颜色与宽度 黑色,宽度为2
painter.setPen(QPen(QColor(Qt::black),2));
//for循环画棋盘 15*15个格子
for(int i = 0;i<CHESS_COLUMES; i++)
{
for (int j = 0; j<CHESS_ROWS; j++)
{
//画一个格子 横坐标 纵坐标 宽 高
painter.drawRect( (i+0.5)*RECT_WIDTH,(j+0.5)*RECT_HEIGHT,RECT_WIDTH,RECT_HEIGHT);
}
}
}
2.画棋子:棋子是椭圆的,这里是循环将所有下的棋子画在棋盘上,
//画棋子
void MainWindow::DrawItems()
{
QPainter painter(this);//创建一个QPainter对象
painter.setPen(QPen(QColor(Qt::transparent)));//设置画笔的颜色为透明
//循环绘制棋子
for (int i = 0; i<mItems.size(); i++)
{
Item item = mItems[i];
if (item.mBlack)
{
painter.setBrush(Qt::black);//下黑棋时设置成黑色
}
else
{
painter.setBrush(Qt::white);//下白棋是设置成白色
}
DrawChessAtPoint(painter,item.mPt);
}
}
//在点击的位置下棋
void MainWindow::DrawChessAtPoint(QPainter& painter,QPoint& pt)
{
//painter.drawRect( (pt.x()+0.5)*RECT_WIDTH,(pt.y()+0.5)*RECT_HEIGHT,RECT_WIDTH,RECT_HEIGHT);
//圆心的位置 格子的中心
QPoint ptCenter((pt.x()+0.5)*RECT_WIDTH,(pt.y()+0.5)*RECT_HEIGHT);
//绘制椭圆 也就是棋子
painter.drawEllipse(ptCenter,RECT_WIDTH / 2,RECT_HEIGHT / 2);
}
3.下棋并且判断输赢,这里是重写的鼠标点击事件
这里判断输赢不能便利整个棋盘,而是以下下去的那个点为中心,判断四个方向是否能够练成五个子。
void MainWindow::mousePressEvent(QMouseEvent * e)
{
//求鼠标点击处的棋子点pt
QPoint pt;
pt.setX( (e->pos().x() ) / RECT_WIDTH);
pt.setY( (e->pos().y() ) / RECT_HEIGHT);
//如果已存在棋子,就什么也不做
for (int i = 0; i<mItems.size(); i++)
{
Item item = mItems[i];
if (item.mPt == pt)
{
//已有棋子
return;
}
}
//不存在棋子,就下一个
Item item(pt,mIsBlackTurn);
mItems.append(item);
//统计4个方向是否五子连 以下棋的那个子为中心
int nLeft = CountNearItem(item,QPoint(-1,0));
int nLeftUp = CountNearItem(item,QPoint(-1,-1));
int nUp = CountNearItem(item,QPoint(0,-1));
int nRightUp = CountNearItem(item,QPoint(1,-1));
int nRight = CountNearItem(item,QPoint(1,0));
int nRightDown = CountNearItem(item,QPoint(1,1));
int nDown = CountNearItem(item,QPoint(0,1));
int nLeftDown = CountNearItem(item,QPoint(-1,1));
//本身下了一个棋子
if ( (nLeft + nRight) >= 4 ||
(nLeftUp + nRightDown) >= 4 ||
(nUp + nDown) >= 4 ||
(nRightUp + nLeftDown) >= 4 )
{
QString str = mIsBlackTurn?"Black":"White";
QMessageBox::information(NULL, "GAME OVER",str, QMessageBox::Yes , QMessageBox::Yes);
mItems.clear();
//NewGame();
return;
}
//该另一方下棋了
mIsBlackTurn = !mIsBlackTurn;
}
int MainWindow::CountNearItem(Item item,QPoint ptDirection)
{
int nCount = 0;
item.mPt += ptDirection;//移动item的位置
//从下棋的点往8个放向移动
while (mItems.contains(item))//包含
{
//颜色相同 数目+1 且朝着相同的方向在移动一个
nCount++;
item.mPt += ptDirection;
}
return nCount;
}
以上就是简易的qt五子棋,这是人人,并没有增加人工智能,后续会开发,应该是使用贪心算法。