Qt中国象棋四——显示棋子可移动位置/项目完成
点击上方蓝字可关注公众号,方便下次阅读~
先看段视频!
经过上次的介绍,剩下的只是一些逻辑的调整。距离基本版的完成已经比较接近了。
在介绍显示棋子可移动区域前,先介绍下棋子 的可移动位置算法。
1.棋子“马”算法简要分析
棋子“马”的计算可移动区域算法简介:
1,求出8个待选位置,8个位置的偏移是(-2,-1)(-2,1)(2,-1)(2,1)
(1,-2)(1,2)(-1,-2)(-1,2)存在关系:|x|+|y|=3
2,判断待选位置是否在棋盘内
3,判断中间是否有卡位的棋子
4,位置上是否已存在同色棋子
算法实现过程如下,注释比较详细:
Item newItem; for (int i = -2; i<=2; i++) { for(int j = -2; j<=2; j++) { if (qAbs(i) + qAbs(j) == 3) { QPoint newPoint = item.m_pt + QPoint(i,j); //当该点在棋盘内,可继续搜索 if (newPoint.x() >= 0 && newPoint.x() <= 8 && newPoint.y()>=0 && newPoint.y() <= 9) { ; } else { continue; } //求该方向行走路线的 卡位元素位置 //相对当前点4个卡位位置计算 QPoint ptDirect(0,0); if (qAbs(i) > qAbs(j)) { if (i>0) { ptDirect = QPoint(1,0); } else { ptDirect = QPoint(-1,0); } } else { if (j>0) { ptDirect = QPoint(0,1); } else { ptDirect = QPoint(0,-1); } } //在棋盘中马的卡位元素位置 QPoint ptHit = item.m_pt + ptDirect; //目标点卡位位置有棋子 if (findItemAtLogicPoint(ptHit,newItem)) { //卡位 continue; } //目标点卡位位置无棋子,但是目标点是同色棋子 if (findItemAtLogicPoint(newPoint ,newItem) && item.m_color == newItem.m_color) { //有本组item continue; } moveableArea.append(newPoint); } } }
2. 绘制棋子可移动位置:
要绘制出棋子可移动位置其实就是将之前moveableArea中的QPoint标记出来。
QVector<QPoint> moveableArea; //获取已选择棋子的可移动区域getMoveableArea(m_selectedItem,moveableArea);
绘制棋子可移动位置与绘制棋子类似,可参考Qt 中国象棋第二节的绘制棋子部分,文末附有链接。
void MainWindow::drawMoveableArea(QPainter &painter, const QVector<QPoint> moveableArea)
{ for(int i = 0; i < moveableArea.size(); i++) { QRect rcTarget( START_X + moveableArea[i].x()*55.5, START_Y + moveableArea[i].y()*56, 53,50); painter.drawPixmap(rcTarget,m_moveableAreaImage); }
}
效果如下:
3. 其他逻辑调整
鼠标事件这里是整个业务的核心;添加定时器事件,用于将选中的棋子进行提示。
//鼠标点击,走棋、吃棋等逻辑
void MainWindow::mousePressEvent(QMouseEvent *e)
{ //获得鼠标点击位置所对应的棋子 QPoint pt; pt.setX( (e->pos().x() - START_X ) / RECT_WIDTH); pt.setY( (e->pos().y() - START_Y ) / RECT_HEIGHT); //是否有选中的棋子 if(m_bExistSelectedItem) { //再次点击已经选择的棋子,什么也不做 if (pt == m_selectedItem.m_pt) { return; } //点击其它棋子 Item clickedItem; if (findItemAtLogicPoint(pt,clickedItem)) { //点击的同色的另外一个棋子,改选 if ( (m_bIsRedTurn && clickedItem.m_color == COLOR_RED) || (!m_bIsRedTurn && clickedItem.m_color != COLOR_RED)) { //改选棋子后,清除原有的落子提示 m_moveableArea.clear(); update(); setItemShow(m_selectedItem, true); m_selectedItem = clickedItem; //获取已选择棋子的可移动区域 getMoveableArea(m_selectedItem,m_moveableArea); update(); return; } } //绘制落子提示 getMoveableArea(m_selectedItem,m_moveableArea); //获取已选择棋子的可移动区域 update(); //点击的异色棋子,判断是否能走能吃 QVector<QPoint> moveableArea; getMoveableArea(m_selectedItem,moveableArea); //获取已选择棋子的可移动区域 if(moveableArea.contains(pt)) { //包含当前鼠标点中的棋子,则能吃 bool bDeleteSHUAI = false; deleteItemAtLogicPoint(pt,bDeleteSHUAI); //吃掉 changeItemLogicPoint(m_selectedItem.m_pt,pt); //绘制新的棋子位置 m_moveableArea.clear(); //清除落子提示
// update(); //发送重新绘图事件 if(bDeleteSHUAI) { QString str = m_bIsRedTurn?QStringLiteral("红方胜利!"):QStringLiteral("黑方胜利!"); QMessageBox::information(NULL, "GAME OVER ",str, QMessageBox::Yes , QMessageBox::Yes); newGame(); return ; } m_bExistSelectedItem = false; m_bIsRedTurn = !m_bIsRedTurn; update(); return ; } } else //当前没有选中棋子 { Item clickedItem; if(findItemAtLogicPoint(pt,clickedItem)) //知道了我是谁、我在哪 { if( (m_bIsRedTurn && clickedItem.m_color == COLOR_RED) || (!m_bIsRedTurn && clickedItem.m_color == COLOR_BLACK)) { m_selectedItem = clickedItem; m_bExistSelectedItem = true; getMoveableArea(m_selectedItem,m_moveableArea); //获取已选择棋子的可移动区域 update(); return; } } }
} void MainWindow::timerEvent(QTimerEvent *)
{ for (int i = 0; i<m_items.size(); i++) { if (m_items[i].m_pt == m_selectedItem.m_pt) { m_items[i].m_bShow = !m_items[i].m_bShow; } }
}
后记总结:
这一个小项目在参考源码的情况下陆陆续续写了近两周,有些惭愧啊。
个人技能的增长需要不断去学习新的知识并将学到的东西不断提炼和总结,最后变成自己的东西才算是真正的学会,不然就像【知道了那么多道理却依然过不好这一生一样!】
之前项目文章回顾:
Qt中国象棋四——显示棋子可移动位置/项目完成相关推荐
- Qt实现中国象棋:(四)棋子绘制的实现
一.棋子图片的简要介绍 上图就是所要使用到的棋子图片,以"r"开头命名的均为红棋,以"b"开头命名的是黑棋:其中带有红色边框的棋子表示将要被移动的棋子(被选中的 ...
- Qt中国象棋之棋子的实现
一.添加棋子类 添加新文件 -> C++ -> C++ Class,类名ChessPieces 棋子头文件chesspieces.h #ifndef CHESSPIECES_H #defi ...
- Qt中国象棋之棋子的移动
通过鼠标事件实现棋子移动(还没实现每个棋子的移动规则,所以可以随便移动,随便吃棋子,只要轮到走棋的话) 1.判断鼠标左键点击的位置是否为棋盘合法位置 2.只有在棋盘的行.列交叉点为中心的圆圈(刚好是处 ...
- java中国象棋棋盘放置棋子,Qt中国象棋二——棋盘与棋子的绘制
上次和大家分享了Qt的2D绘图基础知识,这样可以更好地理解象棋中一些关于绘图的程序.这次要和大家分享的则是棋盘与棋子的绘制,也可以说是Qt 2D绘图的一些具体应用. 源程序是我在网上找的,而且是下载了 ...
- Qt中国象棋二——棋盘与棋子的绘制
上次和大家分享了Qt的2D绘图基础知识,这样可以更好地理解象棋中一些关于绘图的程序.这次要和大家分享的则是棋盘与棋子的绘制,也可以说是Qt 2D绘图的一些具体应用. 源程序是我在网上找的,而且是下载了 ...
- Qt中国象棋一—— Qt 2D 绘图入门
最近想用Qt写一个中国象棋的项目,在网上找了几个例子后,发现关于绘图部分基础为0 ,于是根据项目需要学习一下.查了一些网上的资料,在此总结一下:我比较喜欢的方式是用到什么学什么,或者自己想做一个东西, ...
- java中国象棋棋盘放置棋子,JAVA简易文字版中国象棋
大二时制作的JAVA简易文字版中国象棋,现在放出,希望大家喜欢! // Java core packages import java.awt.*; import java.awt.event.*; / ...
- C++ QT中国象棋项目讲解(四) 简单的人机对战
人机对战实战用SingleGame.h #ifndef SINGLEGAME_H #define SINGLEGAME_H#include "Board.h" #include & ...
- 用java定义中国象棋的棋子_java大神 求帮忙 我坐的中国象棋怎样移动棋子
我的象棋棋子都是标签,都添加了事件监听,我怎样实现棋子的移动啊packageQizi.b;importjava.awt.Component;importjava.awt.event.MouseAdap ...
最新文章
- 【整理】JDK MacOS X
- modelsim与debussy联调环境的搭建
- PS摩棒工具如何选中自己想要的区域
- 【Tree】Prim算法思想与步骤
- 大话设计模式读书笔记--6.原型模式
- 波卡生态项目Polkalokr将在Polkastarter进行IDO
- pythonmatplot可视化_python:matplotlib基础数据可视化,pythonmatplotlib
- 计算机绘图自考知识点,全国自考机械制图一试题2004.04
- iOS安全系列之一:HTTPS
- JS调用webservice的两种方式
- ai作诗——分享好用人工智能作诗工具
- 叩丁狼学院Java入门 项目代码
- 【学习打卡02】可解释机器学习笔记之ZFNet
- 【OpenCV-Python】教程:5-3 光流
- python中对数字降序和升序_该程序查找在Python中按升序或降序排列数字的最低成本...
- java实现词法分析器
- matlab解方程、方程组
- electron 应用程序updater实现热更新
- 我爸的电脑中了勒索病毒……
- MVC与三层架构之间的关系
热门文章
- java 商品类目 递归
- libc_hidden_def、libc_hidden_weak、libc_hidden_proto
- 《MacWorld》杂志关于MacBook Air的FAQ
- word中不同英文字体的区别(笔记)
- 大数据云计算——shell组件
- 用alert、confirm、prompt与if语句的配合使用来完成一个简单的问答效果
- Mac实用技巧(一)—— 快捷键
- 同文输入法 android,同文输入法无障碍版
- 题外话:关于广东有线电视机顶盒WIFI密码修改的问题
- android 9.0 c7Pro,三星C7 Pro和C9 Pro哪个好?三星C9 Pro和C7 Pro区别对比