📄 a8dlg.cpp
字号:
// A8Dlg.cpp : implementation file
//
#include "stdafx.h"
#include "A8.h"
#include "A8Dlg.h"
#include "intput.h"
#include "searchpos.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CA8Dlg dialog
CA8Dlg::CA8Dlg(CWnd* pParent /*=NULL*/)
: CDialog(CA8Dlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CA8Dlg)
m_nowstate = _T("");
m_timecost = 0.0;
m_nodesum = 0;
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CA8Dlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CA8Dlg)
DDX_Control(pDX, IDC_SUANFA, m_ctrlsize);
DDX_Control(pDX, IDC_PROGRESS1, m_progress);
DDX_Control(pDX, IDOK, m_bsearch);
DDX_Text(pDX, IDC_STATIC_NOWSTATE, m_nowstate);
DDX_Text(pDX, IDC_EDIT5, m_timecost);
DDX_Text(pDX, IDC_EDIT6, m_nodesum);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CA8Dlg, CDialog)
//{{AFX_MSG_MAP(CA8Dlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_CTLCOLOR()
ON_BN_CLICKED(IDC_FORE, OnFore)
ON_BN_CLICKED(IDC_LAST, OnLast)
ON_BN_CLICKED(IDC_SUANFA, OnSuanfa)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CA8Dlg message handlers
BOOL CA8Dlg::OnInitDialog()
{
CDialog::OnInitDialog();
GetWindowRect(&m_rectFull); // 保存初始尺寸
m_rectHalf = m_rectFull;
// 折半
CRect rect;
m_ctrlsize.GetWindowRect(&rect);
m_rectHalf.right = rect.right+10;
// 锁定尺寸
ToggleSize();
// 设置主标题的字体和大小
m_font.CreatePointFont(160,"黑体",NULL);
((CStatic *)GetDlgItem(IDC_STATIC_TITILE))->SetFont(&m_font, true);
// 初始化进度条
m_progress.SetRange(0,100);
m_progress.SetPos(0);
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
// 初始化原始状态图,末状图和当前节点搜索图
CWnd *pWnd0 = (CWnd *)GetDlgItem(IDC_PIC_INIT);
pDCInit = pWnd0->GetDC();
CWnd *pWnd1 = (CWnd *)GetDlgItem(IDC_PIC_LAST);
pDCObj = pWnd1->GetDC();
CWnd *pWnd2 = (CWnd *)GetDlgItem(IDC_PIC_NOWSTATE);
pDCCur = pWnd2->GetDC();
m_bsearch.EnableWindow(false); // 关闭搜索按钮
m_binitdown = false; // 关闭初始节点图
m_bobjdown = false; // 关闭末节点图
// TODO: Add extra initialization here
//初始化当前系统状态
m_nowstate.Format("欢迎使用本程序,系统已经准备就绪!");
UpdateData(FALSE);
return TRUE; // return TRUE unless you set the focus to a control
}
void CA8Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CA8Dlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CA8Dlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
//执行搜索命令函数
void CA8Dlg::OnOK()
{
// 计时,搜索节点数,进度条清零
m_timecost = 0.0;
m_nodesum = 0;
m_progress.SetPos(0);
// 报告系统状态
m_nowstate.Format("正在搜索中,请稍候......");
UpdateData(false);
UpdateWindow();
// 判断是否有解(用八数码逆序列的奇偶性来判断)
if (m_jiugong.ComputeJO(&(m_jiugong.StateInit))
!= m_jiugong.ComputeJO(&(m_jiugong.StateObj)))
{
m_progress.SetPos(100);
// 报告系统状态
m_nowstate.Format("很遗憾,两个状态之间无解,请重新输入");
UpdateData(false);
return;
}
m_bsearch.EnableWindow(false); // 关闭搜索按钮
m_ctrlsize.EnableWindow(false); // 关闭算法流程图按钮
m_pdlg = new Csearchpos; // 显示进度条指示
m_pdlg->Create(IDD_DIALOG_SEARCHPOS,this);
m_pdlg->ShowWindow(SW_SHOW);
m_pdlg->CenterWindow();
m_pdlg->UpdateWindow();
clock_t Starttime, Endtime; // 设置计时
Starttime = clock(); // 计时开始
// 调用SEARCH()函数计算
if (TRUE == m_jiugong.Search(m_pdlg))
{
m_pdlg->m_searchpos.SetPos(100);
Endtime = clock(); // 计时结束
Sleep(1000); // 设置延时
m_pdlg->DestroyWindow();
UpdateWindow();
delete m_pdlg; // 释放内存
// 搜索耗时
m_timecost = (double)(Endtime - Starttime)/CLOCKS_PER_SEC;
// 搜索节点总数
m_nodesum = m_jiugong.OpenList.size()+m_jiugong.OpenList.size();
m_nowstate.Format("恭喜恭喜,搜索成功,总共需要走 %d 步"
,m_jiugong.ResultList.size()-1);
UpdateData(false);
UpdateWindow();
// 执行节点动态运行图
m_nstep = 0;
int stepsum = m_jiugong.ResultList.size(); // 需要走的总步数
double nowstep; // 现在运行的步数
int progress; // 进度条变量
for (int i = 0; i <= m_jiugong.ResultList.size(); i++)
{
if ((m_nstep == 0) && (m_jiugong.ResultList.empty() == false))
{
DrawJiuGong(pDCCur,m_jiugong.ResultList.begin()->state);
m_nowstate.Format("总共需要走 %d 步,当前是起始状态"
,m_jiugong.ResultList.size()-1);
UpdateData(false);
m_nstep++;
}
else if (m_nstep < (m_jiugong.ResultList.size()-1))
{
list<JGState>::iterator ite;
for (ite = m_jiugong.ResultList.begin();
ite != m_jiugong.ResultList.end();
++ite)
{
DrawJiuGong(pDCCur,ite->state);
m_nowstate.Format("总共需要走 %d 步,当前是第 %d 步"
,m_jiugong.ResultList.size()-1, m_nstep);
UpdateData(false);
nowstep = m_nstep;
progress = int((nowstep/stepsum)*100); // 计算当前进度
m_progress.SetPos(progress); // 进度条显示
m_nstep++;
Sleep(300); // 每步的延迟时间
}
}
else
{
m_nowstate.Format("总共需要走 %d 步,已经到达目标状态"
,m_jiugong.ResultList.size()-1);
UpdateData(false);
DrawJiuGong(pDCCur,m_jiugong.ResultList.end()->state);
m_progress.SetPos(100);
}
}//end for
m_bsearch.EnableWindow(true); // 开放搜索按钮
m_ctrlsize.EnableWindow(true); // 开放算法流程图按钮
m_nowstate.Format("运算已经全部完成,系统重新准备就绪!");
UpdateData(false);
}
else
{
Endtime = clock(); // 计时结束
m_timecost = (double)(Endtime - Starttime)/CLOCKS_PER_SEC; // 搜索耗时
//搜索节点总数
m_nodesum = m_jiugong.CloseList.size()+m_jiugong.OpenList.size();
m_pdlg->DestroyWindow();
m_bsearch.EnableWindow(true);//开放搜索按钮
m_ctrlsize.EnableWindow(true);//开放算法流程图按钮
UpdateWindow();
delete m_pdlg;
DrawJiuGong(pDCCur,m_jiugong.StateInit.state);
UpdateData(false);
//报告节点超标状态
m_nowstate.Format("很遗憾,搜索的节点超过了设定的范围,请重新输入");
UpdateData(false);
}//end search()函数
}
// 设置当前系统状态显示字体的颜色
HBRUSH CA8Dlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
if (pWnd->GetDlgCtrlID() == IDC_STATIC_NOWSTATE)
{
pDC->SetTextColor(RGB(255,0,0));//显示红色
}
// TODO: Return a different brush if the default is not desired
return hbr;
}
//输入原始状态数据采集
void CA8Dlg::OnFore()
{
// 报告系统状态
m_nowstate.Format("正在输入初始状态");
UpdateData(false);
// 调用数据输入对话框
Cintput inputdlg;
if (inputdlg.DoModal() == IDOK)
{
// 赋值
m_jiugong.StateInit.state[0][0] = inputdlg.m_int00;
m_jiugong.StateInit.state[0][1] = inputdlg.m_int01;
m_jiugong.StateInit.state[0][2] = inputdlg.m_int02;
m_jiugong.StateInit.state[1][0] = inputdlg.m_int10;
m_jiugong.StateInit.state[1][1] = inputdlg.m_int11;
m_jiugong.StateInit.state[1][2] = inputdlg.m_int12;
m_jiugong.StateInit.state[2][0] = inputdlg.m_int20;
m_jiugong.StateInit.state[2][1] = inputdlg.m_int21;
m_jiugong.StateInit.state[2][2] = inputdlg.m_int22;
// 检查输入初始状态数据的合法性
if (CheckData(m_jiugong.StateInit.state) == false)
{
// 报告错误
m_nowstate.Format("输入的初始状态数据不合法,请重新输入!!!");
UpdateData(false);
m_binitdown = false;
m_bsearch.EnableWindow(false);
return;
}
DrawJiuGong(pDCInit,m_jiugong.StateInit.state); // 在初始状态图上画图
DrawJiuGong(pDCCur,m_jiugong.StateInit.state); // 在当前节点状态图上画图
if (m_bobjdown == true)
{
m_nowstate.Format("初始状态数据输入完毕,系统准备就绪!!!");
UpdateData(false);
}
if (m_bobjdown == false)
{
m_nowstate.Format("系统未采集到末状态或刚才末状态输入不合法,请输入末状态!");
UpdateData(false);
}
m_nstep = 0;
m_binitdown = true;
if ((m_binitdown == true) && (m_bobjdown == true))
{
m_bsearch.EnableWindow(true); // 开放执行搜索按钮
}
}
else
{
m_nowstate.Format("您取消了数据的输入,系统重新准备就绪!!!");
UpdateData(false);
}
}
//输入末状态数据采集函数
void CA8Dlg::OnLast()
{
m_nowstate.Format("正在输入末状态数据!!!");
UpdateData(false);
// 调用数据输入对话框
Cintput inputdlg;
if (inputdlg.DoModal() == IDOK)
{
// 赋值
m_jiugong.StateObj.state[0][0] = inputdlg.m_int00;
m_jiugong.StateObj.state[0][1] = inputdlg.m_int01;
m_jiugong.StateObj.state[0][2] = inputdlg.m_int02;
m_jiugong.StateObj.state[1][0] = inputdlg.m_int10;
m_jiugong.StateObj.state[1][1] = inputdlg.m_int11;
m_jiugong.StateObj.state[1][2] = inputdlg.m_int12;
m_jiugong.StateObj.state[2][0] = inputdlg.m_int20;
m_jiugong.StateObj.state[2][1] = inputdlg.m_int21;
m_jiugong.StateObj.state[2][2] = inputdlg.m_int22;
//检查输入末状态数据的合法性
if (CheckData(m_jiugong.StateObj.state) == false)
{
m_nowstate.Format("输入的末状态数据不合法,请重新输入!!!");
UpdateData(false);
m_bobjdown = false;
m_bsearch.EnableWindow(false);
return;
}
DrawJiuGong(pDCObj,m_jiugong.StateObj.state); // 在末状态图上画图
if(m_binitdown == true)
{
m_nowstate.Format("末状态数据输入完毕,系统准备就绪!!!");
UpdateData(false);
}
else
{
m_nowstate.Format("未采集到初状态或刚才初状态输入不合法,请重新输入初状态!");
UpdateData(false);
}
m_nstep = 0;
m_bobjdown = true;
if ((m_binitdown == true) && (m_bobjdown == true))
{
m_bsearch.EnableWindow(true); // 开放搜索按钮
}
}
else
{
m_nowstate.Format("您取消了数据的输入,系统重新准备就绪!!!");
UpdateData(false);
}
}
// 画出原始状态图,末状图和当前节点搜索图函数
void CA8Dlg::DrawJiuGong(CDC *pDC, int state[3][3])
{
CBitmap bitmap[9];
CDC dcMemory;
CRect rc;
int width;
int height;
bitmap[0].LoadBitmap(IDB_BITMAP_NULL);
bitmap[1].LoadBitmap(IDB_BITMAP1);
bitmap[2].LoadBitmap(IDB_BITMAP2);
bitmap[3].LoadBitmap(IDB_BITMAP3);
bitmap[4].LoadBitmap(IDB_BITMAP4);
bitmap[5].LoadBitmap(IDB_BITMAP5);
bitmap[6].LoadBitmap(IDB_BITMAP6);
bitmap[7].LoadBitmap(IDB_BITMAP7);
bitmap[8].LoadBitmap(IDB_BITMAP8);
dcMemory.CreateCompatibleDC(pDC);
pDC->GetWindow()->GetWindowRect(&rc);
width = rc.Width();
height = rc.Height();
for (int i=0; i<3; i++)
{
for (int j=0; j<3; j++)
{
if ((state[i][j] >= 0) && (state[i][j] < 9))
{
dcMemory.SelectObject(&bitmap[state[i][j]]);
pDC->BitBlt((j*2+1)*width/6-20,(i*2+1)*height/6-20,60,60,&dcMemory,0,0,SRCCOPY);
}
}
}
}
// 检查输入数据的合法性函数
bool CA8Dlg::CheckData(int state[3][3])
{
int count[9];
int i, j;
for (i=0; i < 9; i++)
{
count[i] = 0;
}
for (i=0; i < 3; i++)
{
for (j=0; j < 3; j++)
{
if ((state[i][j] < 0) || (state[i][j] > 8))
return false;
count[state[i][j]]++;
}
}
for (i=0; i < 9; i++)
{
if (count[i] == 0)
return false;
}
return true;
}
// 展开对话框,显示A*算法流程图
void CA8Dlg::OnSuanfa()
{
ToggleSize();//调用锁定尺寸函数
}
//锁定尺寸函数
void CA8Dlg::ToggleSize()
{
CRect rect;
CString str;
if(m_bToggleSize)
{
str = "A*算法流程图>>";
rect = m_rectHalf;
}
else
{
str = "<<返回";
rect = m_rectFull;
}
SetWindowPos(NULL,0,0,rect.Width(),rect.Height(),SWP_NOZORDER|SWP_NOMOVE);
m_ctrlsize.SetWindowText(str);
m_bToggleSize = !m_bToggleSize;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -