基于EasyX实现的八皇后和马踏棋盘

EasyX是vc++的一种图形库,好像vs也是可以用的,但是我没有尝试,直接用vc++写的,下面的也是vc++的代码。
这是EasyX的下载地址:https://easyx.cn/
里面有一些大佬写的实例,可以学习学习

这是主菜单函数,大概就是建立画布,然后建立一些button用于切换到下一个界面的,我怕无聊,然后做了一个图片按钮,可以听歌的,不过就只添加了一首。

void mainMenu(){
	abcd :;
	MOUSEMSG m;
	//菜单
		initgraph(800,600);
		setbkcolor(WHITE);
		cleardevice();//刷新一次 略等于那个system(cls)
		setfillcolor(LIGHTBLUE);
		fillrectangle(105,455,305,475);//设置button背景
		fillrectangle(500,455,700,475);
	
		settextstyle(15,0,"楷体");//设置文字格式
		setbkmode(TRANSPARENT);// 去掉文字背景
		outtextxy(145,460,"进入课程设计");	
		outtextxy(540,460,"退出课程设计");

		settextcolor(BLACK);
		settextstyle(50,0,"楷体");
		outtextxy(225,530,"沐欣的课程设计");

		mciSendString("open 祝你爱我到天荒地老.mp3 alias mymusic", NULL, 0, NULL);
		while(1){
		//
		m = GetMouseMsg();
		if(m.x>=105 && m.x<= 315 && m.y >=455 && m.y<=475){
			setlinecolor(RED);
			rectangle(100,450,310,480);
			//如果点击了进入
			if(m.uMsg==WM_LBUTTONDOWN){
				Sign_in();
				goto abcd;
			}
		
		}else if(m.x>=500 && m.x<= 700 && m.y >=455 && m.y<=475){
			setlinecolor(RED);
			rectangle(495,450,705,480);
			//点击了登录
			if(m.uMsg==WM_LBUTTONDOWN){
				
				int result = MessageBox( NULL , TEXT("请点击确定按钮退出,否则点击取消") , TEXT("退出课程设计") , MB_ICONINFORMATION|MB_YESNO|MB_SYSTEMMODAL);
				switch(result)/*注意!使用Unicode应用TEXT包围字串*/
				{
					case IDYES:exit(0);break;
					case IDNO:goto abcd;break;
				}
			}
		}
		else if(m.x>=770 && m.x<= 800 && m.y >=570 && m.y<=600)
		{
			if(m.uMsg==WM_LBUTTONDOWN)
			{
				mciSendString("play mymusic", NULL, 0, NULL);
			}
		}
		else {
			setlinecolor(WHITE);
			rectangle(100,450,310,480);
			rectangle(495,450,705,480);
		}
	}
	getchar();
	closegraph();
}

登录界面没做啥,大致和主函数差不多吧,不过之前想做一个魔方的,然后懒了,丢脸丢脸
哈哈哈,快乐一下

void Sign_in(){
abcd :;  //这里使用了 goto : 是为了每次执行了功能后返回到第一步重新打印子菜单 也可以用更好的逻辑实现循环 而不用goto函数
	MOUSEMSG m;//定义鼠标变量 m
	initgraph(800,600); //定义画布大小也就是黑框大小
	setbkcolor(WHITE);//设置背景颜色
	cleardevice();//刷新一次 略等于那个system(cls)
	setfillcolor(LIGHTBLUE); //设置后面用函数画出方框的背景颜色 这里设置成了浅蓝色

	fillrectangle(200,140,600,160);	
	fillellipse(200,250,600,300);
	fillrectangle(200,380,600,400);

	fillcircle(50,550,45);
	settextstyle(15,0,"楷体");//设置文字大小 格式 
	setbkmode(TRANSPARENT);// 去掉文字背景
	//下面是输出字体 参数:(起始位置x 起始位置y “带输出的字符串”)
	outtextxy(250,142,"马踏棋盘");
	outtextxy(250,382,"魔方");
	outtextxy(10,545,"返回主菜单");
	settextstyle(20,0,"楷体");//设置文字大小 格式
	outtextxy(350,262,"八皇后");
	

    //进入触发条件的循环
	while(1){
		m = GetMouseMsg();
		if(m.x>=200 && m.x<= 600 && m.y >=140&& m.y<=160){//检测鼠标的位置 是否满足条件
			setlinecolor(RED);//满足后 设置新的边框为红色
			rectangle(190,135,610,165);//画新的边框
			//如果点击了马踏棋盘
			if(m.uMsg==WM_LBUTTONDOWN){
				horsechess();
				goto abcd;
			}
		}else if(m.x>=200 && m.x<= 600 && m.y >=260&& m.y<=280){
			setlinecolor(RED);
			ellipse(190,245,610,305);
			//点击了八皇后
			if(m.uMsg==WM_LBUTTONDOWN){
				eight_queens();
				goto abcd;
			}
		}
		else if(m.x>=200 && m.x<= 600 && m.y >=380&& m.y<=400){//
			setlinecolor(RED);
			rectangle(190,375,610,405);
			//点击了魔方
			if(m.uMsg==WM_LBUTTONDOWN){
			    int result = MessageBox( NULL , TEXT("此功能还在开发中,请按确定退出") , TEXT("魔方") , MB_ICONINFORMATION|MB_SYSTEMMODAL);
				goto abcd;
			}
		}
		//
		else if(m.x>=0 && m.x<= 100 && m.y >=500&& m.y<=600){//
			setlinecolor(YELLOW);      // 边框为黄色
	
			circle(50,550,50);
			//点击了返回
			if(m.uMsg==WM_LBUTTONDOWN){
				goto abcde;
			}


		}
		//一旦鼠标不在相应位置 将画出白色边框 覆盖之前的红色边框
		else {
			setlinecolor(WHITE);
			rectangle(190,135,610,165);	
			ellipse(190,245,610,305);
		    rectangle(190,375,610,405);

			setlinecolor(RED);
			circle(50,550,50);
		}
	}
	abcde:;//点击退出按钮 就跳转到这里退出子菜单 返回主菜单
}

八皇后界面跟上面差不多,就不发了。然后呢,八皇后主要用的是回溯法,用栈就会很简单。这是核心回溯代码。

void eight_bu(int han)
{

	if (han == 8)  //当行数达到边界时,则出现了一个没有冲突符合条件的解
	{
		num++; //记录现在满足条件解的个数
		eight_print();
		Sleep(1.2 * 1000);
		//system("pause");
		
	}
	else
	{
		for (int i = 0; i<8; i++) //循环验证在han行时,把皇后放置在第i列时
		{
			int ok = 1;//标记此行是否放置了皇后
			memset(kabc[han], 0, sizeof kabc[han]);//每次重新在此行放置皇后时,清空此行的之前放置的东西
			kabc[han][i] = 1;//标记在han行i列放置的皇后
			c[han] = i;//表示han行放置皇后的列数
			eight_push(&S, i + 1);
			
			setfillcolor(BLUE);
			solidcircle(i * 80 + 50, han * 80 + 50, 30);//并且将此时位置画上蓝色圆
			for (int j = 0; j<han; j++)//判断是否与前面的皇后位置有冲突
			{
				if (c[han] == c[j] || han - c[han] == j - c[j] || han + c[han] == j + c[j])
				{//判断是否在同一列和是否会在对角线上
					
					setfillcolor(RED);
					solidcircle(i * 80 + 50, han * 80 + 50, 30);
					
					clearcircle(i * 80 + 50, han * 80 + 50, 30);
					ok = 0;//如果出现冲突,则将此处的皇后撤掉,表示此行没有放置合适的皇后
					kabc[han][i] = 0;
					eight_pop(&S);//出栈,栈里8变7,Y为7
					eight_pop(&S);//出栈,栈里7变6,Y为7
					break;//只要出现有冲突的,则跳出判断循环,把此行的皇后放置到下一列
				}
			}
			if (ok)//若是此行已经放置好了合适的皇后
			{
				eight_bu(han + 1);//进行下一行皇后位置的寻找
				clearcircle(i * 80 + 50, curr * 80 + 50, 30);//寻找结束之后,清除上一行皇后位置
			}
		}
	}
}

接下来是马踏棋盘,主要也是回溯法,就是回的是上一个,这个运行的时间会长一些,大概有个一分钟左右吧

while(1) {//走棋盘
		n = horse_check();//试探栈顶位置坐标的8个可能选择的方向
		if((n.x != size[f].x||n.y != size[f].y)) 
		{//如果返回的坐标原来坐标不同,则该坐标为有效的坐标
			f++;
			size[f] = n;//将该存入数组中
			settextcolor(WHITE);//设置文字颜色为白
			settextstyle(40, 0, _T("宋体"));//设置字体为宋体40号
			sprintf(a, "%d", curpos+1);//将整形变量格式化为字符串,并将值存储到字符数组a中
			outtextxy(80*size[f].x-40,80*size[f].y-40,a);//将字符数组a的内容在指定位置打印输出
    
			horse_push(size[f]);//将该坐标压入栈
			Sleep(500);
			chess[size[f].x][size[f].y]=1; //将该坐标标记为1,表示已经走过
			step++;//走过的格子数加1
		}
		else 
		{
			RECT r = {0+(size[f].x-1)*80,0+(size[f].y-1)*80,80+size[f].x*80,80+size[f].y*80};//初始化一个矩形绘图区域
			setfillcolor(DARKGRAY);//设置填充颜色为白色
			fillrectangle(0+(size[f].x-1)*80,0+(size[f].y-1)*80,size[f].x*80,size[f].y*80);//用白色填充指定矩形区域
			sprintf(a, "%d", 0);//将整形变量格式化为字符串,并将值存储到字符数组a中
			//outtextxy(80*size[f].x-40,80*size[f].y-40,a);//将字符数组a的内容在指定位置打印输出
			chess[s->top->loc.x][s->top->loc.y]=0;//将该位置标记为0,表示没走过
			horse_pop();//将该坐标出栈
			//Sleep(500);
			f--;
			step--;//走过的格子数减1
		}

		
	}
	if(curpos == 64)//当走过的格子数达到64个时,马走遍整个棋盘,程序退出
		{
			int result = MessageBox( NULL , TEXT("马踏棋盘已经完成,请按确定键退出") , TEXT("马踏棋盘") , MB_ICONINFORMATION|MB_SYSTEMMODAL);
			switch(result)/*注意!使用Unicode应用TEXT包围字串*/
			{
				case IDYES:Sign_in();break;
			}
		}

主要的就这些。本人小白,望看到的大佬多多指导。
爱您

©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页