C语言项目实战:《国际象棋》零基础项目,200 行源代码示例

Posted 一起学编程

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言项目实战:《国际象棋》零基础项目,200 行源代码示例相关的知识,希望对你有一定的参考价值。

这篇文章主要为大家详细介绍了C语言实现——《国际象棋项目》它和中国象棋可不一样哟!文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下!

游戏介绍:

国际象棋(Chess),又称西洋棋,是一种二人对弈的棋类游戏。

棋盘为正方形,由64个黑白(深色与浅色)相间的格子组成;棋子分黑白(深色与浅色)两方共32枚,每方各16枚。虽然汉语称之为西洋棋或国际象棋,但是实际上它起源于亚洲,后由阿拉伯人传入欧洲,成为国际通行棋种。

行棋规则

国际象棋是双方对下的,一方用白棋,一方用黑棋。对局由执白者先行,每次走一步,双方轮流行棋,直到对局结束。各种棋子的一般走法如下:

王(K):横、直、斜都可以走,但每次限走一步。王是不可以送吃的,即任何被敌方控制的格子,己方王都不能走进去。否则,算“送王”犯规,三次就要判负。

(1)除易位时外,王可走到不被对方棋子攻击的任何相邻格子,而且只能走一步(着)。

(2)易位是由王和己方任何一个车一起进行的仍被视作王的一步(着)的走法。

后(Q):横、直、斜都可以走,步数不受限制,但不能越子。

车(R):横、竖均可以走,步数不受限制,不能斜走。除王车易位外不能越子。

象(B):只能斜走。格数不限,不能越子。开局时每方有两象,一个占白格,一个占黑格。

马(N):每步棋先横走或直走一格,然后再往外斜走一格;或者先斜走一格,最后再往外横走或竖走一格(即走“日”字)。可以越子,没有中国象棋中的“蹩马腿”限制。

兵(P):只能向前直走,每次只能走一格。但走第一步时,可以走一格或两格。兵的吃子方法与行棋方向不一样,它是直走斜吃,即如果兵的斜进一格内有对方棋子,就可以吃掉它而占据该格。

行棋规则大家一定要理解,因为这个关系到你实现这个国际象棋项目的规则逻辑部分!

插件:图形库插件easyX,涉及图片素材可以自行百度找也可以关注文末领取;

效果图展示

配套讲解教程:国际象棋游戏教程——哔哩哔哩https://www.bilibili.com/video/BV1bQ4y1P7fz?spm_id_from=333.999.0.0

源代码示例:

#include <graphics.h> //要先安装 easyX 到你的编译器 
#include <stdio.h>

#define SPACE  80

//记录一个棋子落点
struct MyPoint
	int x;
	int y;
;

//用来保存 单数次 鼠标左键点击  和双数次鼠标左键点击
struct MyPoint set[2];
int n = 0;//记录当前是第N次鼠标左键按下

//图片变量
IMAGE 黑棋盘img, 白棋盘img, 卒子A黑img, 卒子B黑img, 车A黑img, 车B黑img, 国王A黑img, 国王B黑img, 马A黑img, 马B黑img, 象A黑img, 象B黑img, 皇后A黑img, 皇后B黑img, 卒子A白img, 卒子B白img, 车A白img, 车B白img, 国王A白img, 国王B白img, 马A白img, 马B白img, 象A白img, 象B白img, 皇后A白img, 皇后B白img;
//枚举  为了代码容易阅读而写
enum state
	黑棋盘, 白棋盘,
	卒子A黑, 卒子B黑, 车A黑, 车B黑, 国王A黑, 国王B黑, 马A黑, 马B黑, 象A黑, 象B黑, 皇后A黑, 皇后B黑,
	卒子A白, 卒子B白, 车A白, 车B白, 国王A白, 国王B白, 马A白, 马B白, 象A白, 象B白, 皇后A白, 皇后B白
;


//1 游戏初始化  做窗口  定义图片变量  加载图片   数据
void initGame();

//2 绘制界面

//2.1 图形界面
void drawGame(int map[8][8]);
//2.2 命令行界面
void printGame(int map[8][8]);

//3 控制游戏
//3.1 鼠标控制下棋
void xiaqi(int map[8][8]);

//3.1 落子
void luozi(int map[8][8]);

int main()
	//地图
	int map[8][8] = 
		 车B白, 马B黑, 象B白, 国王B黑, 皇后B白, 象B黑, 马B白, 车B黑 ,
		 卒子B黑, 卒子B白, 卒子B黑, 卒子B白, 卒子B黑, 卒子B白, 卒子B黑, 卒子B白 ,
		 白棋盘, 黑棋盘, 白棋盘, 黑棋盘, 白棋盘, 黑棋盘, 白棋盘, 黑棋盘 ,
		 黑棋盘, 白棋盘, 黑棋盘, 白棋盘, 黑棋盘, 白棋盘, 黑棋盘, 白棋盘 ,
		 白棋盘, 黑棋盘, 白棋盘, 黑棋盘, 白棋盘, 黑棋盘, 白棋盘, 黑棋盘 ,
		 黑棋盘, 白棋盘, 黑棋盘, 白棋盘, 黑棋盘, 白棋盘, 黑棋盘, 白棋盘 ,
		 卒子A白, 卒子A黑, 卒子A白, 卒子A黑, 卒子A白, 卒子A黑, 卒子A白, 卒子A黑 ,
		 车A黑, 马A白, 象A黑, 皇后A白, 国王A黑, 象A白, 马A黑, 车A白 
	;

	initGame();

	//创建线程  实时获取鼠标情况  根据鼠标情况来修改界面

	while (1)
		drawGame(map);
		printGame(map);
		xiaqi(map); //获取鼠标的坐标  和 鼠标是否按下    getMouseMsg  阻塞
		//Sleep(20);
	



	return 0;


//1 游戏初始化  做窗口  定义图片变量  加载图片   数据
void initGame()
	//			窗口宽    窗口高     自带命令行窗口
	initgraph(8 * SPACE, 8 * SPACE, SHOWCONSOLE);
	//把素材放到和源程序文件一起(编译器运行)
	//把素材放到和可执行程序文件(*.exe)一起(直接双击运行)

	loadimage(&黑棋盘img, L"黑棋盘.bmp", SPACE, SPACE, true);
	loadimage(&白棋盘img, L"白棋盘.bmp", SPACE, SPACE, true);
	loadimage(&卒子A黑img, L"卒子A黑.bmp", SPACE, SPACE, true);
	loadimage(&卒子B黑img, L"卒子B黑.bmp", SPACE, SPACE, true);
	loadimage(&车A黑img, L"车A黑.bmp", SPACE, SPACE, true);
	loadimage(&车B黑img, L"车B黑.bmp", SPACE, SPACE, true);
	loadimage(&国王A黑img, L"国王A黑.bmp", SPACE, SPACE, true);
	loadimage(&国王B黑img, L"国王B黑.bmp", SPACE, SPACE, true);
	loadimage(&马A黑img, L"马A黑.bmp", SPACE, SPACE, true);
	loadimage(&马B黑img, L"马B黑.bmp", SPACE, SPACE, true);
	loadimage(&象A黑img, L"象A黑.bmp", SPACE, SPACE, true);
	loadimage(&象B黑img, L"象B黑.bmp", SPACE, SPACE, true);
	loadimage(&皇后A黑img, L"皇后A黑.bmp", SPACE, SPACE, true);
	loadimage(&皇后B黑img, L"皇后B黑.bmp", SPACE, SPACE, true);
	loadimage(&卒子A白img, L"卒子A白.bmp", SPACE, SPACE, true);
	loadimage(&卒子B白img, L"卒子B白.bmp", SPACE, SPACE, true);
	loadimage(&车A白img, L"车A白.bmp", SPACE, SPACE, true);
	loadimage(&车B白img, L"车B白.bmp", SPACE, SPACE, true);
	loadimage(&国王A白img, L"国王A白.bmp", SPACE, SPACE, true);
	loadimage(&国王B白img, L"国王B白.bmp", SPACE, SPACE, true);
	loadimage(&马A白img, L"马A白.bmp", SPACE, SPACE, true);
	loadimage(&马B白img, L"马B白.bmp", SPACE, SPACE, true);
	loadimage(&象A白img, L"象A白.bmp", SPACE, SPACE, true);
	loadimage(&象B白img, L"象B白.bmp", SPACE, SPACE, true);
	loadimage(&皇后A白img, L"皇后A白.bmp", SPACE, SPACE, true);
	loadimage(&皇后B白img, L"皇后B白.bmp", SPACE, SPACE, true);


//2 绘制界面

//2.1 图形界面
void drawGame(int map[8][8])
	for (int i = 0; i < 8; i++)
		for (int j = 0; j < 8; j++)
			switch (map[i][j])
			case 黑棋盘:putimage(j*SPACE, i*SPACE, &黑棋盘img);	break;
			case 白棋盘:putimage(j*SPACE, i*SPACE, &白棋盘img);	break;
			case 卒子A黑:putimage(j*SPACE, i*SPACE, &卒子A黑img);	break;
			case 卒子B黑:putimage(j*SPACE, i*SPACE, &卒子B黑img);	break;
			case 车A黑:	putimage(j*SPACE, i*SPACE, &车A黑img);	break;
			case 车B黑:	putimage(j*SPACE, i*SPACE, &车B黑img);	break;
			case 国王A黑:putimage(j*SPACE, i*SPACE, &国王A黑img);	break;
			case 国王B黑:putimage(j*SPACE, i*SPACE, &国王B黑img);	break;
			case 马A黑:	putimage(j*SPACE, i*SPACE, &马A黑img);	break;
			case 马B黑:	putimage(j*SPACE, i*SPACE, &马B黑img);	break;
			case 象A黑:	putimage(j*SPACE, i*SPACE, &象A黑img);	break;
			case 象B黑:	putimage(j*SPACE, i*SPACE, &象B黑img);	break;
			case 皇后A黑:putimage(j*SPACE, i*SPACE, &皇后A黑img);	break;
			case 皇后B黑:putimage(j*SPACE, i*SPACE, &皇后B黑img);	break;
			case 卒子A白:putimage(j*SPACE, i*SPACE, &卒子A白img);	break;
			case 卒子B白:putimage(j*SPACE, i*SPACE, &卒子B白img);	break;
			case 车A白:	putimage(j*SPACE, i*SPACE, &车A白img);	break;
			case 车B白:	putimage(j*SPACE, i*SPACE, &车B白img);	break;
			case 国王A白:putimage(j*SPACE, i*SPACE, &国王A白img);	break;
			case 国王B白:putimage(j*SPACE, i*SPACE, &国王B白img);	break;
			case 马A白:	putimage(j*SPACE, i*SPACE, &马A白img);	break;
			case 马B白:	putimage(j*SPACE, i*SPACE, &马B白img);	break;
			case 象A白:	putimage(j*SPACE, i*SPACE, &象A白img);	break;
			case 象B白:	putimage(j*SPACE, i*SPACE, &象B白img);	break;
			case 皇后A白:putimage(j*SPACE, i*SPACE, &皇后A白img);	break;
			case 皇后B白:putimage(j*SPACE, i*SPACE, &皇后B白img);	break;
			default:break;
			
		
	

//2.2 命令行界面
void printGame(int map[8][8])
	//system("cls");//清屏
	for (int i = 0; i < 8; i++)
		for (int j = 0; j < 8; j++)
			printf("%02d  ", map[i][j]);
		
		printf("\\n");
	


void xiaqi(int map[8][8])
	//点两下   //第一下 选中棋子  //第二下  落子
				//偶数次            //奇数次
	int idx = n % 2;
	MOUSEMSG msg;

	msg = GetMouseMsg();//获取鼠标信息
	if (msg.mkLButton)//鼠标左键按下
		set[idx].x = msg.x /SPACE;
		set[idx].y = msg.y / SPACE;
		printf("坐标:%d %d  下标:%d %d\\n", msg.x, msg.y, set[idx].x, set[idx].y);
		if (1 == idx)//落子
			luozi(map);
		

		n++;
	



//3.1 落子
void luozi(int map[8][8])

	
	switch (map[set[0].y][set[0].x])//判断 set[0]  位置是什么棋子    
	case 卒子A黑:
		//判断 能不能移动到  set[1]位置    如果能  就移动
		if (set[0].y - set[1].y == 1)//往上走一格
			map[set[0].y][set[0].x] = 黑棋盘;//本来位置变成黑棋盘
			map[set[1].y][set[1].x] = 卒子A白;//目的地位置变成卒子A白
		
		break;
	case 卒子A白:
		//判断 能不能移动到  set[1]位置    如果能  就移动
		if (set[0].y - set[1].y == 1)//往上走一格
			map[set[0].y][set[0].x] = 白棋盘;//本来位置变成黑棋盘
			map[set[1].y][set[1].x] = 卒子A黑;//目的地位置变成卒子A白
		
		break;
	
	


未完成的棋子代码,大家也可以自己先去想想试试,每一次的思考就是你进步的过程!

如果学习的过程中有什么问题,以及本项目有什么不懂的地方,都可以来找我交流,我来帮你!

那么今天的分享就到这里了,后续会更新更多精彩项目的,大家要好好学C语言C++哟~

写在最后:对于准备学习C/C++编程的小伙伴,如果你想更好的提升你的编程核心能力(内功)不妨从现在开始!

C语言C++编程学习交流圈子,QQ群:829164294点击进入】微信公众号:C语言编程学习基地

整理分享(多年学习的源码、项目实战视频、项目笔记,基础入门教程)

欢迎转行和学习编程的伙伴,利用更多的资料学习成长比自己琢磨更快哦!

编程学习视频分享:

 

 

以上是关于C语言项目实战:《国际象棋》零基础项目,200 行源代码示例的主要内容,如果未能解决你的问题,请参考以下文章

C语言项目实战:《扫雷游戏》零基础项目,230 行源码注释示例

C语言项目实战:《2048》零基础项目丨208 行源代码示例

C语言项目实战:《推箱子》零基础项目,270 行源码注释示例

C语言项目实战:《黄金矿工》零基础项目,180 行源代码示例

C语言项目实战:《打砖块》零基础项目丨225 行源码注释示例

C语言项目实战:《飞翔的小鸟》零基础项目,190行源代码示例