基于c语言的象棋游戏

article/2025/9/20 15:59:27

一、主要目标:

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的值,保证棋子落在正确的位置上。另外包含人机部分的代码已上传到我的另一篇博客,请需要的自提。

 

 


http://chatgpt.dhexx.cn/article/NcJhvUvB.shtml

相关文章

【Unity连载】斗兽棋—棋类游戏开发演示(1)

序言 “黄梅时节家家雨&#xff0c;青草池塘处处蛙。有约不来过夜半&#xff0c;闲敲棋子落灯花。” “象棋终日乐悠悠&#xff0c;苦被严亲一旦丢。兵卒坠河皆不救&#xff0c;将军溺水一齐休。马行千里随波去&#xff0c;象入三川逐浪游。炮响一声天地震&#xff0c;忽然惊…

简单的象棋开发

我们需要准备的知识是c语言基础和easyx图形: easyx官网&#xff1a; https://easyx.cn/ 首先头文件少不了: #include<stdio.h>(c语言的头文件) #include<graphics.h>&#xff08;easyx的&#xff09; #include<mmsystem.h>&#xff08;音乐播放的&#x…

Java游戏开发 —— 五子棋

引言&#xff1a; 五子棋的代码实现很简单&#xff0c;难的是计算机的AI算法&#xff0c;在网上找了很多资料&#xff0c;费了好半天劲才弄明白其实现的原理&#xff0c;真的挺开阔思路的&#xff0c;很有意思&#xff01; 思路&#xff1a; 1、创建主窗口&#xff0c;加载菜单…

编程小游戏之三子棋

三子棋是一个民间的益智小游戏&#xff0c;游戏分为双方对战&#xff0c;双方依次在9宫格棋盘上摆放棋子&#xff0c;率先将自己的三个棋子连成一条线的一方则视为胜利者。下面将说明如何利用C语言在我们的计算机上简单的实现三子棋。 1.逻辑框架设计 在vs上创建两个.c文件test…

【C语言】三子棋游戏的实现(玩家VS玩家 or 玩家VS电脑)

目 录 一、三子棋游戏介绍 二、游戏功能函数分析 1 菜单显示函数 2 菜单选择函数 3 选择确认函数 4 显示当前棋盘状态函数 5 棋盘初始化函数 6 玩家下棋函数 7 电脑下棋函数 8 棋局状态判断函数 三、游戏功能函数的整合 四、三子棋游戏的实现 五、游戏…

安卓做的棋类游戏

大方大斜 前言一、直接上图二、游戏主要代码1.界面绘制代码2.游戏触摸事件代码 最后 前言 安卓制作棋类游戏&#xff0c;小时候和发小在地上画棋盘&#xff0c;有树叶或者树枝做棋子。 一、直接上图 二、游戏主要代码 1.界面绘制代码 双人界面绘制&#xff0c;主要代码代码如…

基于java的五子棋游戏设计

技术&#xff1a;Java、JSP等摘要&#xff1a;随着互联网迅速的发展&#xff0c;网络游戏已经成为人们普遍生活中不可或缺的一部分&#xff0c;它不仅能使人娱乐&#xff0c;也能够开发人的智力&#xff0c;就像本文所主要讲的五子棋游戏一样能挖掘人们聪明的才干与脑袋的机灵程…

自己设计的棋类游戏

1、构思&#xff1a; 象棋、国际象棋、井字棋等 我一开始的设计是这个样的&#xff1a;一个5x5的棋盘&#xff08;之后变成7x7&#xff09;&#xff0c;所有棋子摆成一个井字 棋子有两种&#xff0c;一种兵一种王&#xff0c;中间用中立的棋子&#xff0c;就叫box来隔开他们 …

Java围棋游戏的设计与实现

技术&#xff1a;Java等 摘要&#xff1a; 围棋作为一个棋类竞技运动&#xff0c;在民间十分流行&#xff0c;为了熟悉五子棋规则及技巧&#xff0c;以及研究简单的人工智能&#xff0c;决定用Java开发五子棋游戏。主要完成了人机对战和玩家之间联网对战2个功能。网络连接部分为…

【国际象棋】棋盘游戏-微信小程序开发流程详解

与中国象棋类似的&#xff0c;还有国际象棋&#xff0c;知道有人爱玩&#xff0c;于是凭着好奇心&#xff0c;网上研究了一下&#xff0c;跟中国象棋有相似之处&#xff0c;玩法是有些许不一样&#xff0c;不知道象棋最早出于谁之手呢&#xff0c;抽空做一做&#xff0c;最终完…

利用C语言巧妙实现棋类游戏——三子棋

小游戏&#xff1a;三子棋用C语言实现 你是否学完了C语言的函数、数组、选择结构、循环结构苦于没有实战小项目巩固自己所学的知识呢&#xff0c;今天小程序猿就给大家带来了一个游戏的小游戏——三子棋&#xff0c;利用C语言实现的&#xff0c;希望对大家能有所帮助。 我们大家…

基于C#的五子棋游戏设计

目 录 一、 毕业设计内容 3 二、 毕业设计目的 3 三、 工具/准备工作 3 四、 设计步骤和方法 3 &#xff08;一&#xff09; 总体设计 3 1&#xff0e; 总体设计思路及设计图 3 2&#xff0e; 界面设计 4 3&#xff0e; 全局变量设计 4 &#xff08;二&#xff09; 详细设计 5 …

【Unity连载】斗兽棋-棋类游戏开发演示(2)

第四章 游戏操作与指令 如同养育一个婴儿&#xff0c;父母总会一步步引领孩子成长&#xff0c;从蹒跚学步到来去如风&#xff1b;我们对游戏功能的开发&#xff0c;也无疑应当从走出第一步棋开始。现在&#xff0c;我们已经构建出了棋盘、棋子等基本的游戏逻辑对象&#xff1b…

Java游戏开发——中国象棋联机版

游戏介绍&#xff1a; 中国象棋是起源于中国的一种棋戏&#xff0c;属于二人对抗性游戏的一种&#xff0c;在中国有着悠久的历史。由于规则简单&#xff0c;趣味性强&#xff0c;成为流行极为广泛的棋类游戏。 中国象棋使用方形格状棋盘及红黑二色圆形棋子进行对弈&#xff0c…

【论文】word中三线表的快速简单制作

【论文】word中三线表的快速简单制作 首先&#xff0c;打开word点击插入→表格&#xff0c;选择需要插入表格的行列数&#xff0c;行列数没有关系&#xff0c;因为你插入后可以随意添加行列。 则插入了一下表格&#xff1a; 把你所需要的数据放进去&#xff1a; 之后&#…

如何在word中制作线宽不同的三线表

在word中难免会插入特定的三线表&#xff0c;那就现场给给大家演示一遍 1、打开word&#xff0c;点击插入&#xff0c;点击表格&#xff0c;至于插入几行几列看自己的需求哈。 2、右键点击表格&#xff0c;然后点击表格属性 3、点击边框和底纹&#xff0c;对表格去除相关边线 …

论文中的三线表绘制(word)

步骤 1、选中表格&#xff08;点击下图中的红框部分选中&#xff09; 2、右击表格选择“表格属性” 3、点击边框和底纹&#xff0c;再选择无边框&#xff08;先不要点确定&#xff09; 4、设置三线表的上下边框&#xff08;1.5磅&#xff09;&#xff0c;完成下图之后点击确定-…

word三线表标题两条线之间如何出现空白间隔(论文必备)

为了写论文&#xff0c;我需要把以上的标题转换成下图所示的样子 所实现的步骤如下&#xff1a; 1、把标题内容回车 放在下一行 2、加一条绘制表格的线 3、选中第一行对应位置的两格&#xff0c;合并单元格 并填入内容 可以看到单纯的加上边框&#xff0c;两条线之间是没有空…

Word 2016表格三线表制作

1、打开word&#xff0c;点击插入&#xff0c;插入一个表格。 2、选中表格&#xff0c;点击设计&#xff0c;在边框中的笔画粗细选择1.5磅&#xff0c;然后在边框下拉框先选择无框线&#xff0c;再选择上框线和下框线。然后笔画粗细选择0.5磅&#xff0c;选中第一行后&#x…

三线表的制作

目录 前言参考过程 前言 最近在写些东西的时候&#xff0c;需要用到三线表&#xff0c;上网查了一下&#xff0c;将方法记录下来。 参考 三分钟快速制作论文三线表 过程 (1) 先插入一个表格&#xff0c;然后新建一个表格样式 (2) 如下图所示更改 (3) 点击第二步中的格式&a…