n皇后问题MFC人机界面课程设计Word文件下载.docx
- 文档编号:21800178
- 上传时间:2023-02-01
- 格式:DOCX
- 页数:12
- 大小:74.25KB
n皇后问题MFC人机界面课程设计Word文件下载.docx
《n皇后问题MFC人机界面课程设计Word文件下载.docx》由会员分享,可在线阅读,更多相关《n皇后问题MFC人机界面课程设计Word文件下载.docx(12页珍藏版)》请在冰豆网上搜索。
这里我们选择使用回溯法即经典的递归法来求解n皇后问题,这个算法将在棋盘上一列一列地放置皇后直到n个皇后在不相互攻击的情况下都被摆放在棋盘上,算法便终止。
当一个新加入的皇后因为与已经存在的皇后之间相互攻击而不能被摆在棋盘上时,算法便发生回溯。
一旦发生这种情况,就试图把最后放在棋盘上的皇后移动到其他地方。
这样做是为了让新加入的皇后能够在不与其它皇后相互攻击的情况下被摆放在棋盘的适当位置上。
如图所示是两种满足要求摆放皇后的图。
四、设计流程
1打开visualC++新建一个MFCAPPwizrd(exe)工程,由于该n皇后问题是由8皇后问题衍变而来的,我们为了纪念高斯这位伟大的数学家,我们把工程命名为EightQueen。
2按如图为窗体放置相应的组件,将窗体的名称改成“皇后问题”并按以下表格设置好相关的ID和属性
3
标题
ID
属性
分组框
开始
IDC_START
暂停/单步
IDC_PAUSE
n值
IDC_BOARD_SIZE
单步
IDC_STEP_BY
不中断
IDC_NO_INT
继续
IDC_CONTINUE
停止
IDC_STOP
Queen_panel
IDC_QUEEN_PANEL
关于
IDC_ABOUT
按Ctrl+W为IDC_QUEEN_PANEL添加一个Type为QueenPanel的成员变量m_panel
4为组件画板新建一个名为QueenPanel的类,并添加以下成员:
public
private
QueenPanel();
voidDrawBoard(CDC*pDC,intsize,intcell);
QueenPanel(intsize);
int*queen;
virtual~QueenPanel();
intn;
voidSetSize(intsize);
HANDLEqueen_mutex;
voidSetQueen(int*newq);
voidSetQueen(introw,intcol)
④为CEightQueenDlg类添加以下变量及函数
pubilc
voidUpdateUI();
staticDWORDWINAPIThreadGo(LPVOIDlpParam);
voidWINAPIGo();
voidUpdateQPanel(int*queen);
virtualvoidOnOK();
voidUpdateQPanel(introw,intcol);
virtualvoidOnCancel();
voidDoPause();
voidWINAPIStep(inti);
BOOLEANm_step,m_no_int;
intcount;
BOOLEAN*rk;
BOOLEAN*lk;
BOOLEAN*mk;
BOOLEANstep,no_int;
HANDLEpause_event,this_mutex;
BOOLEANcanceling,running,pausing;
五、程序代码:
①为单步单选框控件添加BN_CLICKED消息映射,代码如下:
CButton*step=(CButton*)GetDlgItem(IDC_STEP_BY);
m_step=(step->
GetCheck()==BST_CHECKED)?
TRUE:
FALSE;
if(m_step){
CButton*autoBtn=(CButton*)GetDlgItem(IDC_NO_INT);
autoBtn->
SetCheck(FALSE);
m_no_int=FALSE;
}
②为不中断单选框控件添加BN_CLICKED消息映射,代码如下:
CButton*autoBtn=(CButton*)GetDlgItem(IDC_NO_INT);
m_no_int=(autoBtn->
if(m_no_int){
CButton*step=(CButton*)GetDlgItem(IDC_STEP_BY);
step->
m_step=FALSE;
③为开始按钮控件添加BN_CLICKED消息映射,代码如下:
DWORDdwThreadId;
HANDLEhThread;
CStringstr;
GetDlgItem(IDC_BOARD_SIZE)->
GetWindowText(str);
intnewn=atoi(str);
if(newn<
=3){
MessageBox("
大小不能小于4"
"
警告"
MB_OK);
return;
else{
n=newn;
m_panel.SetSize(n);
step=m_step;
no_int=m_no_int;
running=TRUE;
pausing=canceling=FALSE;
UpdateUI();
hThread=CreateThread(
NULL,
0,
ThreadGo,
this,
&
dwThreadId);
if(hThread==NULL)
{
MessageBox(NULL,"
CreateThreadfailed."
MB_OK);
}
DWORDWINAPICEightQueenDlg:
:
ThreadGo(LPVOIDlpParam)
{
CEightQueenDlg*dlg=(CEightQueenDlg*)lpParam;
dlg->
Go();
return0;
④为暂停/单步按钮控件添加BN_CLICKED消息映射,代码如下:
WaitForSingleObject(this_mutex,INFINITE);
step=TRUE;
if(pausing){
SetEvent(pause_event);
ReleaseMutex(this_mutex);
⑤为继续按钮控件添加BN_CLICKED消息映射,代码如下WaitForSingleObject(this_mutex,INFINITE);
step=FALSE;
ReleaseMutex(this_mutex);
⑥为停止按钮控件添加BN_CLICKED消息映射,代码如下
WaitForSingleObject(this_mutex,INFINITE);
canceling=TRUE;
⑦为QueenPanel.cpp添加如下代码
QueenPanel:
QueenPanel()
{
this->
queen=NULL;
n=0;
queen_mutex=CreateMutex(NULL,FALSE,NULL);
QueenPanel(intsize)
SetSize(size);
~QueenPanel()//析构函数,释放空间
if(queen!
=NULL)
free(queen);
BEGIN_MESSAGE_MAP(QueenPanel,CWnd)
//{{AFX_MSG_MAP(QueenPanel)
ON_WM_PAINT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
QueenPanelmessagehandlers
voidQueenPanel:
OnPaint()
CPaintDCdc(this);
//devicecontextforpainting
if(n==0||queen==NULL){
return;
}
RECTrect;
GetWindowRect(&
rect);
CDCMemDC;
//定义一个显示设备对象
CBitmapMemBitmap;
//定义一个位图对象
WaitForSingleObject(queen_mutex,INFINITE);
intw=rect.right-rect.left;
inth=rect.bottom-rect.top;
intboard=w>
=h?
h:
w;
board=board-board%n;
intcell=board/n;
//System.out.println("
w:
"
+w+"
h:
+h+"
x:
"
+x+"
y:
+y+"
cell:
+
//cell+"
board:
+board+"
rl:
+rl);
intcount=0;
inti;
CPenb_pen(PS_SOLID,1,RGB(0,0,255));
CPenr_pen(PS_SOLID,1,RGB(255,0,0));
CBrushy_brush,b_brush;
y_brush.CreateSolidBrush(RGB(255,255,0));
b_brush.CreateSolidBrush(RGB(255,255,255));
MemDC.CreateCompatibleDC(&
dc);
//建立兼容的内存显示设备
MemBitmap.CreateCompatibleBitmap(&
dc,w,h);
//建立一个兼容的位图
CBitmap*pOldBit=MemDC.SelectObject(&
MemBitmap);
MemDC.FillRect(CRect(0,0,w,h),&
b_brush);
if(cell<
7){
MemDC.TextOut(0,h/2,"
太大,画不下了!
);
else{
DrawBoard(&
MemDC,n,cell);
MemDC.SelectObject(b_pen);
MemDC.SelectObject(y_brush);
for(i=0;
i<
n;
i++){
if(queen[i]>
=0){
MemDC.Ellipse(queen[i]*cell+cell/6,i*cell+cell/6,
queen[i]*cell+cell/6+cell*2/3,
i*cell+cell/6+cell*2/3);
count++;
}
}
ReleaseMutex(queen_mutex);
dc.BitBlt(0,0,w,h,&
MemDC,0,0,SRCCOPY);
DrawBoard(CDC*pDC,intsize,intcell){
inti,j;
CBrushw_brush,b_brush;
b_brush.CreateSolidBrush(RGB(0,0,0));
w_brush.CreateSolidBrush(RGB(255,255,255));
for(i=0;
i<
size;
i++){
for(j=0;
j<
j++){
if((i+j)%2==0){
pDC->
FillRect(CRect(i*cell,j*cell,(i+1)*cell-1,(j+1)*cell-1),&
}
else{
w_brush);
}
CPenb_pen(PS_SOLID,1,RGB(0,0,0));
intboard=cell*size;
pDC->
SelectObject(b_pen);
MoveTo(0,0);
LineTo(0,board-1);
LineTo(board-1,board-1);
LineTo(board-1,0);
LineTo(0,0);
SetSize(intsize){
WaitForSingleObject(queen_mutex,INFINITE);
if(size>
n){
if(queen!
free(queen);
queen=(int*)malloc(size*sizeof(int));
for(inti=0;
i<
i++)
queen[i]=-1;
n=size;
RedrawWindow();
SetQueen(int*newq)
for(i=0;
queen[i]=newq[i];
SetQueen(introw,intcol)
queen[row]=col;
⑧在CEightQueenDlg.cpp中的顶部添加如下代码#include"
QueenPanel.h"
将QueenPanel.h包含进来
六、测试与结论
七、设计过程遇到的问题、思考及解决方法
本程序主要的重点是主要是为“开始”组建添加的子程序,还有对“画板”组建类的定义和实现。
开始时在对画板就行操作时遇到了些问题,黑白两色不能按要求画好,之后调整了函数的参数就可以了。
八、心得体会
通过为期一周的课程设计,让我进一步了解到了visualc++中MFC的知识,掌握了运用C++来实现一些基本的功能软件,和在实现一个程序时所需做的准备,应先把整体框架理出来,设定适当的变量和函数。
在编写程序的时候要细心,有时候虽然是简单的小程序,但由于疏忽还是会照成一些错误产生。
在老师给出的实验要求和目的的基础上,我们小组对其进行了一些扩充,我们最终实现的是基于人机界面可视化窗口,这个可视化界面主要的功能分为以下几部分:
第一、增加了暂停\单步调试的功能,能一个一个的放置皇后,在程序运行时让我们更好的理解实现该皇后问问题的基本原理即经典的回溯法。
第二、我们利用画板来实现皇后的放置,并且在用画板画棋盘时我们用到了黑白两色,更加直观,便于观察排错。
第三、我们在窗体中放置了一个编辑框,让我们可以随意修改n值。
第四、我们还添加了一个不中断的单选框,即我们在输入一个n值后,皇后就开始不间断的放置,直到最后一种方案,在最后会弹出一个信息框,把总共我们求得的放置皇后的方案显示出来。
通过此次实习我也认识到了在C++中算法的重要性,为今后的学习奠定了基础。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 皇后 问题 MFC 人机界面 课程设计
![提示](https://static.bdocx.com/images/bang_tan.gif)