实现功能:棋子初始化及走棋规则

棋子类:

 #ifndef STONE_H
#define STONE_H #include <QString> class Stone
{
public:
Stone();
~Stone(); enum TYPE{JIANG, CHE, PAO, MA, BING, SHI, XIANG}; int _row; //棋子所在行
int _col; //棋子所在列
TYPE _type; //棋子类型(JIANG,CHE...) int _id; //棋子id(0-31)
bool _dead; //棋子是否死亡
bool _red; //是否为红方 void init(int id) //初始化棋子信息
{
struct {
int row, col;
Stone::TYPE type;
} pos[] = {
{, , Stone::CHE},
{, , Stone::MA},
{, , Stone::XIANG},
{, , Stone::SHI},
{, , Stone::JIANG},
{, , Stone::SHI},
{, , Stone::XIANG},
{, , Stone::MA},
{, , Stone::CHE}, {, , Stone::PAO},
{, , Stone::PAO},
{, , Stone::BING},
{, , Stone::BING},
{, , Stone::BING},
{, , Stone::BING},
{, , Stone::BING},
}; _id = id;
_dead = false;
_red = id<; if(id < )
{
_row = pos[id].row;
_col = pos[id].col;
_type = pos[id].type;
}
else
{
_row = -pos[id-].row;
_col = -pos[id-].col;
_type = pos[id-].type;
} } QString getText() //返回棋子类型对应的汉字,便于绘制棋面汉字
{
switch(this->_type)
{
case CHE:
return "车";
case MA:
return "马";
case PAO:
return "炮";
case BING:
return "兵";
case JIANG:
return "将";
case SHI:
return "士";
case XIANG:
return "相";
}
return "错误";
}
}; #endif // STONE_H

棋盘类:

 #ifndef BOARD_H
#define BOARD_H #include <QWidget>
#include "Stone.h" class Board : public QWidget
{
Q_OBJECT
public:
explicit Board(QWidget *parent = ); Stone _s[]; //32枚棋子
int _r; //棋子的半径
int _selectid; //记录选中的棋子id
bool _bRedTurn; //记录是否轮到红方走棋 /* 返回象棋棋盘行列对应的像素坐标 */
QPoint center(int row, int col);
QPoint center(int id); /* 返回象棋棋盘上某个坐标对应的行,列 */
bool getRowCol(QPoint pt, int& row, int& col); /* 绘制棋子*/
void drawStone(QPainter& painter, int id); void paintEvent(QPaintEvent *); /* 鼠标释放事件 */
void mouseReleaseEvent(QMouseEvent *); /* 根据要移动的棋子moveid,将要移动到的位置(row,col),将被吃掉的棋子killid判断能否走棋 */
bool canMove(int moveid, int row, int col, int killid);
/* 将 */
bool canMove1(int moveid, int row, int col, int killid);
/* 车 */
bool canMove2(int moveid, int row, int col, int killid);
bool canMove3(int moveid, int row, int col, int killid);
bool canMove4(int moveid, int row, int col, int killid);
bool canMove5(int moveid, int row, int col, int killid);
bool canMove6(int moveid, int row, int col, int killid);
bool canMove7(int moveid, int row, int col, int killid); signals: public slots: }; #endif // BOARD_H

判断走棋函数:

 bool Board::canMove(int moveid, int row, int col, int killid)
{
if(_s[moveid]._red == _s[killid]._red)//moveid和killid颜色相同)
{
//换选择
_selectid = killid;
update(); return false;
} switch(_s[moveid]._type)
{
case Stone::JIANG:
return canMove1(moveid, row, col, killid);
break;
case Stone::SHI:
return canMove2(moveid, row, col, killid);
break;
case Stone::XIANG:
return canMove3(moveid, row, col, killid);
break;
case Stone::CHE:
return canMove4(moveid, row, col, killid);
break;
case Stone::MA:
return canMove5(moveid, row, col, killid);
break;
case Stone::PAO:
return canMove6(moveid, row, col, killid);
break;
case Stone::BING:
return canMove7(moveid, row, col, killid);
break;
} return true;
}

“将” 的走棋规则说明:

 bool Board::canMove1(int moveid, int row, int col, int killid)
{
/*
1.首先目标位置在九宫内
2.移动的步长是一个格子
*/
if(_s[moveid]._red)
{
if(row > )return false;
}
else
{
if(row < )return false;
} if(col < ) return false;
if(col > ) return false; int dr = _s[moveid]._row - row;
int dc = _s[moveid]._col - col;
int d = abs(dr)* + abs(dc); // 12, 21 22 10, 1
if(d == || d == )
return true; return false;
}

判断 “将” 要移动的位置与原来位置相差一步的处理:

 int dr = _s[moveid]._row - row;
int dc = _s[moveid]._col - col;
int d = abs(dr)* + abs(dc); // 12, 21 22 10, 1
if(d == )
return true;

鼠标点击释放事件:

 void Board::mouseReleaseEvent(QMouseEvent *ev)
{
QPoint pt = ev->pos();
// 将pt转化成象棋的行列值
// 判断这个行列值上面有没有棋子
int row, col;
bool bRet = getRowCol(pt, row, col);
if(bRet == false) // 点到棋盘外
return; int i;
int clickid = -;
for(i=;i<;++i)
{
if(_s[i]._row == row && _s[i]._col == col && _s[i]._dead== false)
{
break;
}
} if(i<)
{
clickid = i;
} if(_selectid == -)
{
if(clickid != -)
{
if(_bRedTurn == _s[clickid]._red)
{
_selectid = clickid;
update();
}
}
}
else
{
if(canMove(_selectid, row, col, clickid))
{
/*走棋*/
_s[_selectid]._row = row;
_s[_selectid]._col = col;
if(clickid != -)
{
_s[clickid]._dead = true;
}
_selectid = -;
_bRedTurn = !_bRedTurn;
update();
}
}
}

效果图:

Qt版本中国象棋开发(三)的更多相关文章

  1. Qt版本中国象棋开发(四)

    内容:走法产生 中国象棋基础搜索AI, 极大值,极小值剪枝搜索, 静态估值函数 理论基础: (一)人机博弈走法产生: 先遍历某一方的所有棋子,再遍历整个棋盘,得到每个棋子的所有走棋情况(效率不高,可以 ...

  2. Qt版本中国象棋开发(一)

    开发目的:实现象棋人机对战简单AI,网络对战,移植到android中. 开发平台:windows10 + Qt5.4 for android 开发语言:C++ 开发过程:1.棋盘绘制: 方法一:重写  ...

  3. Qt版本中国象棋开发(二)

    实现功能:棋盘绘制 核心函数: void paintEvent(QPaintEvent *); //QWidget自带的虚函数,重写后使用 QPainter 类来绘制图形 QPainter paint ...

  4. 基于QT的中国象棋

    基于QT的中国象棋,可实现人人对战,人机对战,联网对战,可显示棋谱,可悔棋. 还有一些小毛病,我之后会找空把这个DEMO重新修改一下上传 链接:https://pan.baidu.com/s/1-eM ...

  5. Cocos2d-X开发中国象棋《三》開始场景的实现

    在前面两节(第一节.第二节)中介绍了中国象棋的功能和project文件.在这篇博客中将介绍中国象棋的開始场景的实现 在写代码前先理清一下实现開始场景的思路: 1.打开游戏后进入開始场景,场景上显示一个 ...

  6. Qt绘制中国象棋棋盘

    这里主要用的是#include <QPainter>里面的paintEvent void Board::paintEvent(QPaintEvent*) { QPainter painte ...

  7. Cocos2d-X开发中国象棋《二》project文件概述

    我在上一篇博客中介绍了象棋的功能.在接下来的博客中将向大家介绍使用Cocos2d-X怎样一步一步开发中国象棋 开发工具: Cocos2d-X2.2.3 VS2012 项目的文件夹: Classes:存 ...

  8. Python开发中国象棋实战(附源码)

        Pygame 做的中国象棋,一直以来喜欢下象棋,写了 python 就拿来做一个试试,水平有限,电脑走法水平低,需要在下次版本中更新电脑走法,希望源码能帮助大家更好的学习 python.总共分 ...

  9. cocos2d-x游戏开发系列教程-中国象棋02-main函数和欢迎页面

    之前两个博客讲述了象棋的规格和工程文件之后,我们继续深入的从代码开始学习cocos2dx 首先从程序入口main函数开始 main函数 int APIENTRY _tWinMain(HINSTANCE ...

随机推荐

  1. 快放弃你的管家软件吧! Part 2 强制删除

    在Windows系统中,难免会遇到用常规方法无法删除文件的情况. 经常有遇到过一些情况? 软件卸载了,有些文件夹就是删不掉,提示被占用,mmp,这时候你肯定想到了360文件粉碎机! mmp,我就删个文 ...

  2. Codeforces Round #509 (Div. 2) A. Heist 贪心

    There was an electronic store heist last night. All keyboards which were in the store yesterday were ...

  3. CF思维联系– Codeforces-988C Equal Sums (哈希)

    ACM思维题训练集合 You are given k sequences of integers. The length of the i-th sequence equals to ni. You ...

  4. C++ 重载运算符 继承 多态 (超详细)

    (一)重载运算符: (1)声明与定义格式 一般是类内声明,类外定义,虽然可以在类内定义,但 写前面堆一堆不好看!!! 类内声明: class Demo { 返回值类型 operator 运算符(形参表 ...

  5. Android 自定义View—清爽小巧灵活的多节点进度条

    前言 最近项目有一个节点进度条的小需求,完成后,想分享出来希望可以帮到有需要的同学. 真机效果图 自定义View完整代码 开箱即用~,注释已经炒鸡详细了 /** * @description: 节点进 ...

  6. 使用Golang + lua实现一个值班机器人

    我们在的项目组呢,有一项工作是,收邮件(很大程度上使用邮件是为了存个底),然后从我们的系统里边查一下相关信息,然后回复个邮件的工作.虽然工作量并不大,但是会把时间切的稀碎.为了拯救我的时间,所以做了一 ...

  7. spring的后台数据校验

    数据校验对于开发项目来说是必须的.校验一般分为前台校验和后台校验,前台校验是必须要做的,后台校验是可选的.后台校验相对前台校验来说配置起来一般更复杂.前台校验通过js做,前台校验一般非常容易绕过.sp ...

  8. Spring官网阅读(二)(依赖注入及方法注入)

    上篇文章我们学习了官网中的1.2,1.3两小节,主要是涉及了容器,以及Spring实例化对象的一些知识.这篇文章我们继续学习Spring官网,主要是针对1.4小节,主要涉及到Spring的依赖注入.虽 ...

  9. SpringCloudGateWay学习 之 从函数式编程到lambda

    文章目录 前言: 函数式编程: 什么是函数式编程: 函数式编程的特点 lambda表达式: 核心: 函数接口: 方法引用: 类型推断: 变量引用: 级联表达式跟柯里化: 前言: 这一系列的文章主要是为 ...

  10. 036_python的大文件下载以及进度条展示

    复习 1.黏包现象 粘包现象的成因: tcp协议的特点,面向流的,为了保证可靠传输,所以有很多优化的机制. 无边界 所有在连接建立的基础上传递的数据之间没有界限. 收发消息很有可能不完全相等. 缓存机 ...