一、主要目标:

1.1:鼠标控制。

1.2:各棋子按照象棋规则移动

1.3:判断双方胜负

注:本设计使用vs-2017运行。需要下载graphics.h库。

二、基本流程

2.1 棋牌展示

直接输出棋盘背景图片,包含方格线、“楚河”、“汉界”等,代码如下:

loadimage(&img, "C:/Users/ASUS/Desktop/shess/5.jpg");
    putimage(0, 0, &img);//输出棋盘

该地址下放如图所示2.1所示图片充当背景。

图2.1 棋盘背景图片

2.3.2 棋子展示

按照象棋棋子的摆法,在指定坐标出画出棋子(先画圆圈,再写字,每个棋子都如此)。

2.3.3 各棋子子移动

俥,马,象,士,炮,将,兵分别写移动规则(根据起始坐标和目的坐标判断是否可以移动)。

2.3.4 判断胜负

棋盘信息没改变一次就扫描一次棋盘,如果一方的将被覆盖(被对方所吃),则输出另一方获胜。游戏结束。

完整代码:

#include<stdio.h>
#include<graphics.h>
#include<math.h>
void execute(int a, int b, int c, int d);
bool jiang(int a, int b, int  c, int d);
bool pao(int a, int b, int c, int d);
bool ma(int a, int b, int c, int d);
IMAGE img;
#define distance  35//窗口线与棋盘边界线的距离
#define   longth  65//棋盘方格的长
#define   high   61//棋盘方格的宽
struct movecoordinate
{long x;long y;
};
struct  Chesscoordinate//棋子综合信息
{int x;int y;DWORD type;  //颜色bool river;//是否过河int id;
};
enum pieces
{SPACE = -1,車, 馬, 象, 士, 将, 炮, 卒,车, 马, 相, 仕, 帥, 砲, 兵,BEGIN, END,};
enum pieces redchess[] = { 車,馬,象,士,将,炮,卒, };
enum pieces blackchess[] = { 车,马,相,仕,帥,砲,兵, };
enum pieces state = BEGIN;
struct move {  //鼠标选中的棋子int beginx;int beginy;int endx;int endy;int state;
}moving = { -1,-1,-1,-1,BEGIN };
const char* chessname[] = { "車","馬","象","士","将","炮","卒","车","马","相","仕","帥","砲","兵", };
struct Chesscoordinate  map[9][10];//坐标
struct Chesscoordinate  AImap[9][10];//坐标
movecoordinate begin = { -1,-1 }, end = { -1,-1 };
int  xx(int a)//数组下标转换成坐标
{a = distance + longth * a;return a;
}
int  yy(int a)
{a = distance + high * a;return a;
}
void begining()
{loadimage(&img, "C:/Users/ASUS/Desktop/shess/66.jpg");initgraph(img.getwidth(), img.getheight(), 1);putimage(0, 0, &img);//输出开始界面;}
void  qiban()
{loadimage(&img, "C:/Users/ASUS/Desktop/shess/5.jpg");initgraph(img.getwidth(), img.getheight(), 1);putimage(0, 0, &img);//输出棋盘
}
void  coord()//棋子信息赋值
{loadimage(&img, "C:/Users/ASUS/Desktop/shess/5.jpg");putimage(0, 0, &img);//输出棋盘for (int i = 0; i <= 8; i++){for (int j = 0; j <= 9; j++)//遍历二维数组{enum pieces chessid = SPACE;//先把全部位置的id赋值为SAPCEDWORD  chesstype;//定义颜色中间变量if (j <= 4){chesstype = BLACK;//黑方if (j == 0){if (i <= 4){chessid = blackchess[i];//}else{chessid = blackchess[8 - i];}}if (j == 2 && (i == 1 || i == 7)){chessid = blackchess[5];}if (j == 3 && (i == 0 || i == 2 || i == 4 || i == 4 || i == 6 || i == 8)){chessid = blackchess[6];}}else{chesstype = RED;//红方if (j == 6 && (i == 0 || i == 2 || i == 4 || i == 6 || i == 8)){chessid = redchess[6];}if (j == 7 && (i == 1 || i == 7)){chessid = redchess[5];}if (j == 9){if (i <= 4){chessid = redchess[i];}else{chessid = redchess[8 - i];}}}//依次赋值map[i][j].id = chessid;map[i][j].river = false;map[i][j].type = chesstype;map[i][j].x = distance + longth * i;map[i][j].y = distance + high * j;}}for (int i = 0; i <= 8; i++){for (int j = 0; j <= 9; j++){if (map[i][j].id == SPACE){map[i][j].type = YELLOW;}}}}
void getbackground() //画棋子
{int x_start, y_start;x_start = distance;y_start = distance;settextstyle(30, 0, "黑体");//棋子大小颜色setbkmode(0);for (int i = 0; i <= 8; i++){for (int j = 0; j <= 9; j++){if (map[i][j].id != SPACE)//在棋盘上输出{setfillcolor(RGB(253, 216, 161));//    setlinestyle(BLACK);settextcolor(map[i][j].type);fillcircle(map[i][j].x, map[i][j].y, 24);fillcircle(map[i][j].x, map[i][j].y, 18);outtextxy(map[i][j].x - 13, map[i][j].y - 13, chessname[map[i][j].id]);}}}}
void movechess(int a, int b, int c, int d)//移动棋子,改变其坐标
{map[c][d].id = map[a][b].id;map[c][d].river = map[a][b].river;map[c][d].type = map[a][b].type;map[c][d].x = xx(c);map[c][d].y = yy(d);map[a][b].id = SPACE;map[a][b].type = YELLOW;}void MouseControl()//获取鼠标点击信息并完响应
{//getbackground();if (MouseHit()){float beginrow, beginrol, endrow, endrol;//第一次按下时的坐标int intbeginrow, intbeginrol, intendrow, intendrol;//第二次按下时的坐标MOUSEMSG msg = GetMouseMsg();if (msg.uMsg == WM_LBUTTONDOWN){//获取鼠标点击的数组的下标//    printf("(%d,%d)", msg.x, msg.y);beginrow = (float)(msg.x - distance) / longth;beginrol = (float)(msg.y - distance) / high;intbeginrow = round(beginrow);intbeginrol = round(beginrol);if (moving.state == BEGIN){moving.state = END;moving.beginx = intbeginrow;moving.beginy = intbeginrol;//    printf("(%d,%d)  \n", moving.beginx, moving.beginy);}else if (moving.state == END){moving.state = BEGIN;moving.endx = intbeginrow;moving.endy = intbeginrol;execute(moving.beginx, moving.beginy, moving.endx, moving.endy);}}}}int  win()
{int redgeneral = 0;int blackgeneral = 0;for (int i = 0; i <= 8; i++){for (int j = 0; j <= 9; j++){if (map[i][j].id == blackchess[4]){blackgeneral++;}else if (map[i][j].id == redchess[4]){redgeneral++;}else{blackgeneral = blackgeneral;redgeneral = redgeneral;}}}//printf("%d %d\n", blackgeneral, redgeneral);if (blackgeneral == 0){return 0;}else if (redgeneral == 0){return 1;}else{return 2;}}
bool jiang(int a, int b, int  c, int d)//判断是否只移动了一格(将军、兵的规则)
{float h;h = sqrt(abs(d - b)*abs(d - b) + abs(c - a)*abs(c - a));if (b < 4 && c > 2 && c < 6 && d < 3){if (h == 1 && map[c][d].type != map[a][b].type)return true;elsereturn false;}if (b > 4 && c > 2 && c < 6 && d >6){if (h == 1 && map[c][d].type != map[a][b].type)return true;elsereturn false;}else{return false;}}
bool bing(int a, int b, int c, int d)
{float h;h = sqrt(abs(d - b)*abs(d - b) + abs(c - a)*abs(c - a));if (map[a][b].type == BLACK){if (map[a][b].river == false){if (d == b + 1 && h == 1 && map[c][d].type != map[a][b].type){return true;}else{return false;}}else{if (d >= b && h == 1 && map[c][d].type != map[a][b].type){return true;}else{return false;}}}else if (map[a][b].type == RED){if (map[a][b].river == false){if (d == b - 1 && h == 1 && map[c][d].type != map[a][b].type){return true;}else{return false;}}else{if (d <= b && h == 1 && map[c][d].type != map[a][b].type){return true;}else{return false;}}}else{return false;}
}
bool pao(int a, int b, int c, int d)//炮的移动
{if (c == a && d != b){int time = 0;int max = d > b ? d : b;int min = b < d ? b : d;for (int i = min; i <= max; i++){if (map[c][i].id != SPACE){time++;}}//    printf("%d\n", time);if (map[c][d].id == SPACE){if (time == 1)return  true;elsereturn false;}if (map[c][d].id != SPACE){if (time != 3){return false;}else{if (map[c][d].type == map[a][b].type){return false;}else{return true;}}}}else if (d == b && c != a){int time = 0;int max = a > c ? a : c;int min = c < a ? c : a;for (int i = min; i <= max; i++){if (map[i][d].id != SPACE){time++;}}//    printf("%d\n", time);if (map[c][d].id == SPACE){if (time == 1)return  true;elsereturn false;}if (map[c][d].id != SPACE){if (time != 3){return false;}else{if (map[c][d].type == map[a][b].type){return false;}else{return true;}}}}else{return false;}
}
bool che(int a, int b, int c, int d)
{if (c == a && d != b)//是否为直线{int time = 0;int max = d > b ? d : b;int min = b < d ? b : d;for (int i = min; i <= max; i++)//遍历路径{if (map[c][i].id != SPACE){time++;}}//    printf("%d", time);if (time == 1)//车移动不吃棋子{return true;}if (time == 2)//车移动并且吃目的坐标的棋子{if (map[c][d].type == map[a][b].type)//如果是目的坐标是自己的棋子,则返回false{return false;}if (map[c][d].type == YELLOW){return false;}else{return true;}}else{return false;}}else    if (d == b && c != a){int time = 0;int max = c > a ? c : a;int min = a < c ? a : c;for (int i = min; i <= max; i++)//遍历路径{if (map[i][d].id != SPACE){time++;}}//    printf("%d", time);if (time == 1)//车是否车跳棋{return true;}else if (time == 2){if (map[c][d].type == map[a][b].type){return false;}if (map[c][d].type == YELLOW){return false;}else{return true;}}else{return false;}}else{return 0;}
}
bool ma(int a, int b, int c, int d)
{float h;h = sqrt(abs(d - b)*abs(d - b) + abs(c - a)*abs(c - a));//    printf("%f", h);if (h <= 2 || h >= 2.5)//根号8=2.8.根号5=2.2{//    printf("太远了!\n");return  false;}else{int xx, yy, max, min;//关键点的坐标和中间值max = abs(d - b) > abs(c - a) ? abs(d - b) : abs(c - a);min = abs(c - a) < abs(d - b) ? abs(c - a) : abs(d - b);//printf("max\min:(%d,%d)", max, min);if (max == abs(d - b)){yy = b + (d - b) / 2;xx = a;}else{xx = a + (c - a) / 2;yy = b;}//    printf("xx\yy:(%d,%d)\n", xx, yy);if (map[xx][yy].id == SPACE){if (map[c][d].type != map[a][b].type){//    printf("目的坐标(%d,%d)\n", c, d);//    printf("那是你自己的棋子!\n");return true;}else{//    printf("那是你的棋子!\n");return false;}}else{//    printf("关键位置有棋子!\n");return false;}}
}
bool xiang(int a, int b, int c, int d)
{float h;h = sqrt(abs(d - b)*abs(d - b) + abs(c - a)*abs(c - a));if (b <= 4){if (d > 4){return false;}else{if (h<2.4 || h>2.9){return false;}else{int xx = (a + c) / 2;int yy = (b + d) / 2;if (map[xx][yy].id == SPACE){if (map[c][d].type == map[a][b].type){return false;}else{return true;}}else{return false;}}}}else{if (d < 5){return false;}else{if (h<2.4 || h>2.9){return false;}else{int xx = (a + c) / 2;int yy = (b + d) / 2;if (map[xx][yy].id == SPACE){if (map[c][d].type == map[a][b].type){return false;}else{return true;}}else{return false;}}}}}
bool shi(int a, int b, int c, int d)
{float h = sqrt(abs(d - b)*abs(d - b) + abs(c - a)*abs(c - a));//  printf("%f", h)if (b < 5){if (c >= 3 && c <= 5 && d <= 2){if (1.2 < h &&h < 1.5){if (map[c][d].type != map[a][b].type)return true;elsereturn false;}else{return false;}}else{return false;}}else if (b > 5){if (c >= 3 && c <= 5 && d >= 7){if (1.2 < h &&h < 1.5){if (map[c][d].type != map[a][b].type)return true;elsereturn false;}else{return false;}}else{return false;}}elsereturn false;
}
void execute(int a, int b, int c, int d)//行棋
{if (map[a][b].id == blackchess[4])//黑方将{if (jiang(a, b, c, d)){movechess(a, b, c, d);}else{printf("你不能这样做\n");}}else if (map[a][b].id == redchess[4])//红方将{if (jiang(a, b, c, d)){movechess(a, b, c, d);}else{printf("你不能这样做!\n");}}else if (map[a][b].id == blackchess[6])//黑方兵{if (map[a][b].river == false){if (bing(a, b, c, d)){movechess(a, b, c, d);if (d > 4){map[c][d].river = true;}}else{printf("你不可以这样做!\n");}}else{if (bing(a, b, c, d) && d >= b){movechess(a, b, c, d);}else{printf("你不可以这样做\n");}}}else if (map[a][b].id == redchess[6])//红方兵{if (map[a][b].river == false){if (bing(a, b, c, d)){movechess(a, b, c, d);if (d < 5){map[c][d].river = true;}}else{printf("你不可以这样做!\n");}}else{if (bing(a, b, c, d) && d <= b){movechess(a, b, c, d);}else{printf("你不可以这样做!\n");}}}else if (map[a][b].id == blackchess[5] || map[a][b].id == redchess[5]){if (pao(a, b, c, d)){movechess(a, b, c, d);}else{printf("你不能这样做!\n");}}else if (map[a][b].id == blackchess[0] || map[a][b].id == redchess[0]){if (che(a, b, c, d)){movechess(a, b, c, d);}else{printf("你不可以这样做!\n");}}else if (map[a][b].id == blackchess[1] || map[a][b].id == redchess[1]){if (ma(a, b, c, d)){movechess(a, b, c, d);}else{printf("你不能这样做!\n");}}else if (map[a][b].id == blackchess[2] || map[a][b].id == redchess[2]){if (xiang(a, b, c, d)){movechess(a, b, c, d);}elseprintf("你不能这样做!\n");}else if (map[a][b].id == blackchess[3]){if (shi(a, b, c, d)){movechess(a, b, c, d);}elseprintf("你不能这样做!");}else if (map[a][b].id == redchess[3]){if (shi(a, b, c, d)){movechess(a, b, c, d);}elseprintf("你不能这样做!");}
}
int main()
{begining();while (1){coord();//输出棋盘win();BeginBatchDraw();while (win() == 2){win();putimage(0, 0, &img);getbackground();//输出棋子MouseControl();//鼠标更改数据FlushBatchDraw();}putimage(0, 0, &img);getbackground();//输出棋子MouseControl();//鼠标更改数据FlushBatchDraw();if (win() == 0){printf("红方胜!\n");}else if (win() == 1){printf("黑方胜!\n");}}getchar();return 0;
}

注意:由于棋子是根据所选棋盘图片的大小、在指定位置画棋子。棋盘的不一样会导致棋子位置不正确。读者可直接将该棋盘复制,将图片修改成和我一样的比例,如图2.2.

图2.2 棋盘背景图片大小

读者也可以自己选择背景图片,根据图片大小,更改该代码宏定义处的distance、longth、high的值,保证棋子落在正确的位置上。另外包含人机部分的代码已上传到我的另一篇博客,请需要的自提。

基于c语言的象棋游戏相关推荐

  1. c语言五子棋学年论文,基于c语言五子棋小游戏生本科论文.doc

    基于c语言五子棋小游戏生本科论文 五子棋小游戏 需求分析 现在有越来越多的人使用电脑,而且五子棋的受众广泛但实体棋操作较为繁琐且平时较难实现,所以电脑版的五子棋游戏应运而生.大家对于这个小游戏的需求如 ...

  2. 基于c语言的小游戏,--基于C语言的小游戏设计.doc

    --基于C语言的小游戏设计.doc 级丌 密公 本科生毕业(学位)论文 基于c语言的爪游软设计 李俊佶 (2009061322) TOC \o "1-5" \h \z 指导教师姓名 ...

  3. c语言语音控制游戏文献,C语言课程设计-基于C语言推箱子游戏设计-毕业论文文献.doc...

    gd工程职业技术学院毕业论文 基于C语言的推箱子游戏设计 Design of the push box Based on Combined Language 作者姓名: 学科专业: 应用电子技术 学院 ...

  4. 基于Python语言的PUBG游戏数据可视化分析系统

    [success]写于2019年大作业[/success] 博客链接:https://www.iamzlt.com/?p=299 代码链接请到博客链接内查看. 摘要 随着网络技术的兴起和普及,网络游戏 ...

  5. 基于Java的中国象棋游戏的设计与实现

    技术:Java等 摘要: 近些年,Java技术日趋成熟,它的跨平台性,健壮性以及使用人数的增多都表明了它的受欢迎程度不断攀升,因此选用了Java语言作为中国象棋游戏的开发语言.并且中国象棋文化源远流长 ...

  6. android象棋游戏,基于安卓的中国象棋游戏app

    [实例简介] 很详尽完整的一份安卓象棋游戏app源码.可直接在eclipse+jdk+sdk的开发环境中运行,界面做的也还不错. [实例截图] [核心代码] Chess_DJB └── Chess_D ...

  7. python编写格斗游戏_基于C++语言编程格斗游戏毕业设计正文

    摘 要 游戏自古至今都伴随并影响着人们的生活.截至 2013 年,中国游戏用户达 3.45 亿人, 游戏产业链的发展给游戏开发带来了无限的商机, 是未来信息产品的重要深化 方向之一.格斗游戏是出现的比 ...

  8. 基于C语言的五子棋游戏设计与实现 课程报告+项目源码及可执行exe文件

    资源下载地址:https://download.csdn.net/download/sheziqiong/85680476 资源下载地址:https://download.csdn.net/downl ...

  9. c语言五子棋对局结果存储,基于C语言五子棋小游戏总结.doc

    五子棋小游戏 需求分析 现在有越来越多的人使用电脑,而且五子棋的受众广泛但实体棋操作较为繁琐且平时较难实现,所以电脑版的五子棋游戏应运而生.大家对于这个小游戏的需求如下:首先,设计这个游戏最基本的就是 ...

最新文章

  1. Linux挂载iscsi存储
  2. php事件和行为,Yii框架组件和事件行为管理详解
  3. memcache中的add和set方法区别
  4. Google Go:初级读本
  5. poj1163 数字三角形 (动态规划)
  6. IOS的UIPickerView 和UIDatePicker
  7. Unity3d打开的时候,卡在loading界面白屏的解决方法
  8. linux如何更新数据包up,Linux更新(update/upgrade) 修改更新源
  9. (转)mysql 无法设置外键的原因总结
  10. 用 Rust 开发 Linux,可行吗?
  11. delphi 检测网络是否连通_WebRTC:连接建立过程的网络穿透
  12. iphone 开发内存管理 心得
  13. PDF密码可以破解吗?有没有PDF解密的方法
  14. coherence mysql_Coherence Step by Step 第三篇 缓存(四) 缓存数据源(翻译)
  15. 三年java不会线程_Java后端开发三年多线程你都懂,问你异步编程你说你没听过???...
  16. 【金猿人物展】龙盈智达首席数据科学家王彦博:量子科技为AI大数据创新发展注入新动能...
  17. 关于CRC校验的一些总结
  18. 兰博基尼推出全新混动超跑Revuelto
  19. jquery遍历对象list拼接
  20. [c++]CodeBlocks中去掉下划线的方法

热门文章

  1. C# 中的Event EventArgs和Delegate(转载)
  2. 学习计算机网络必看的书
  3. 【JMS】JMS支持的模式讲解
  4. 【LeetCode - 159】至多包含两个不同字符的最长子串
  5. ES6入门--let的基本使用
  6. MapX学习基本教程
  7. cookie详解,即什么是cookie。
  8. SecureCRT标签显示IP地址
  9. Hexo+valine评论微信通知
  10. c盘java文件误删_C盘误删文件如何恢复?