五子棋是个简单的小游戏,尝试使用Qt将他做出来,学习时的练习demo。
成果展示
需求分析
五子棋:在棋盘上,黑棋先行,交替下棋,五子练成直线获取胜利。
实现过程
1.棋盘绘制:下棋的第一步肯定是绘制棋盘
这里使用for循环画了15*15个格子数
//画棋盘
void MainWindow::DrawChessboard()
{QPainter painter(this);//创建一个QPainter对象//设置抗锯齿 用于平滑图形的边缘painter.setRenderHint(QPainter::HighQualityAntialiasing, true);//设置画刷的颜色 用于填充图形的内部painter.setBrush(Qt::darkYellow);//设置画笔的颜色与宽度 黑色,宽度为2painter.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)
{//求鼠标点击处的棋子点ptQPoint 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五子棋,这是人人,并没有增加人工智能,后续会开发,应该是使用贪心算法。