基于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;
			}
		}

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

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
二、 算法思想: 采用回溯法解决八皇后问题。从第一行开始,放第一个皇后,放好皇后以后,她所在的行,列和对角线上的每一个位置就是她的管辖范围,别的皇后没有权利干涉,否则死无藏身之地。 然后,第二个皇后,从第二行的第一列开始判断所在的位置是否是别的皇后的管辖范围,找到第一个还没有被占据的位置,则将其占为己有。暂时,该皇后停在该位置。然后,第三个到第八个皇后依次从第三行,第四行,… ,到第八行的第一列开始寻求自己的位置。假如到第i个皇后时,已经没有任何位置可选,则第i-1个皇后必须往后移动进行协调,同样,假如第i-1个皇后往后移动时没有找到空位置,则第i-2个皇后必须往后移动,进行协调,当找到空位置时,暂时停下,将下一个皇后重新从第一列开始寻找空位置。重复上述过程,直到所有皇后都停下来。则得到了第一个解。要想产生所有的解,则当产生第一个解以后,第八个皇后往后移动,找下一个可以利用的空位置,找不到,则第七个皇后必须往后移动,若找到空位置则停下,第八个皇后从第八行第一列重新试探,找到空位置。一直这样,直到第一个皇后将第一行遍历完。得到的解就是所有解。 三、 概要设计: ***************类型及相关变量定义***************** //位置信息类型 typedef struct { int row; int col; }PosType; //皇后类型 typedef struct Queen{ PosType pos; int number; //第几号皇后 }QueenType; //栈节点类型 typedef struct Note{ QueenType queen; struct Note *next; }NoteType; //棋盘,某一位置chessboard[i][j]上有皇后,则该位的值变为皇后序号。同样,该皇后的势 //力范围内的位置上的值全部变为该皇后的序号。 int chessboard[8][8]; //结果集,共92种解,每一种解中记录8个位置信息。 PosType ResultSet[92][8]; //定义一个栈,保存信息 Typedef struct{ NoteType head; Int size; }QueenStack; //定义一个栈,存放皇后信息 QueenStack qstack; *************相关操作**************** //初始化棋盘,开始时每个位置上都没有皇后,值全为0;并给8个皇后编号。 void initChessboard(); //回溯求八皇后问题的所有解,皇后协调算法 void queenCoordinate(); //输出所有解 void printResult();
首先,需要在EasyX中创建一个窗口,用于作为管理员登录的界面。在窗口中添加相应的控件,例如用户名输入框、密码输入框、登录按钮等。接下来,需要编写C语言代码实现管理员登录的功能。 以下是一个简单的管理员登录示例代码: ```c #include <graphics.h> #include <conio.h> #include <stdio.h> #include <string.h> #define USERNAME "admin" // 管理员用户名 #define PASSWORD "123456" // 管理员密码 int main() { initgraph(640, 480); // 创建窗口 // 创建用户名标签和输入框 settextstyle(20, 0, "宋体"); outtextxy(200, 200, "用户名:"); char username[20] = {0}; inputbox_getline(username, 20, "请输入用户名:"); // 创建密码标签和输入框 outtextxy(200, 250, "密 码:"); char password[20] = {0}; inputbox_getline(password, 20, "请输入密码:", true); // 判断用户名和密码是否正确 if (strcmp(username, USERNAME) == 0 && strcmp(password, PASSWORD) == 0) { cleardevice(); settextcolor(GREEN); outtextxy(250, 250, "登录成功!"); } else { cleardevice(); settextcolor(RED); outtextxy(250, 250, "用户名或密码错误!"); } getch(); // 等待用户按任意键关闭窗口 closegraph(); return 0; } ``` 在这个示例中,我们使用了EasyX提供的一些函数来创建窗口、绘制控件和文字等。在登录按钮被点击时,我们判断用户输入的用户名和密码是否正确,并根据判断结果显示相应的提示信息。 需要注意的是,在实际开发中,管理员用户名和密码应该存储在数据库或配置文件中,而不是硬编码在代码中。此外,还应该对密码进行加密存储,以保证安全性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值