⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eightnumberview.cpp

📁 人工智能中的八数码难题,人工智能中的八数码难题
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// EightNumberView.cpp : implementation of the CEightNumberView class
//

#include "stdafx.h"
#include "EightNumber.h"

#include "EightNumberDoc.h"
#include "EightNumberView.h"

#include "ExplainGame.h"
#include "EditDlg.h"
#include "MainFrm.h"
//#include "AboutDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

int di[4]={0,-1,1,0};
int dj[4]={-1,0,0,1};
//int zeroi,zeroj;
/////////////////////////////////////////////////////////////////////////////
// CEightNumberView
UINT MultiThread(LPVOID param);

IMPLEMENT_DYNCREATE(CEightNumberView, CFormView)

BEGIN_MESSAGE_MAP(CEightNumberView, CFormView)
	//{{AFX_MSG_MAP(CEightNumberView)
	ON_WM_PAINT()
	ON_BN_CLICKED(IDC_BUTTON_STEPRUN, OnButtonSteprun)
	ON_BN_CLICKED(IDC_BUTTON_RUN, OnButtonRun)
	ON_WM_TIMER()
	ON_WM_CANCELMODE()
	ON_BN_CLICKED(IDC_BUTTON_ONOK, OnButtonOnok)
	ON_WM_LBUTTONDOWN()
	ON_WM_KEYDOWN()
	ON_BN_CLICKED(IDC_BUTTON_START, OnButtonStart)
	ON_BN_CLICKED(IDC_BUTTON_EXPLAIN, OnButtonExplain)
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CFormView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CFormView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CFormView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CEightNumberView construction/destruction

CEightNumberView::CEightNumberView()
	: CFormView(CEightNumberView::IDD)
{
	//{{AFX_DATA_INIT(CEightNumberView)
	//}}AFX_DATA_INIT
	// TODO: add construction code here
	start[0][0]=2;
	start[0][1]=8;
	start[0][2]=3;
	start[1][0]=1;
	start[1][1]=0;
    start[1][2]=4;
	start[2][0]=7;
	start[2][1]=6;
	start[2][2]=5;



    goal[0][0]=1;
	goal[0][1]=2;
	goal[0][2]=3;
	goal[1][0]=8;
	goal[1][1]=0;
	goal[1][2]=4;
	goal[2][0]=7;
	goal[2][1]=6;
	goal[2][2]=5;
	
	
	

	//totalcount=0;
	
	cellwidth=160;
	cellheight=160;
    ni=1;
	nj=1;
    depth=0;
	//open=1;
	//closed=0;
//	k=0;
	count=-1;
    AutoPlay=false;

	for (int i=0; i<3; i++)
		for (int j=0; j<3; j++)
		{
			zerosite.ch[i][j]=start[i][j];
			if (start[i][j]==0)
			{
             zerosite.si=i;
			 zerosite.sj=j;
			}
		}
     	
   m_pThread=NULL;
}

CEightNumberView::~CEightNumberView()
{
	//DeleteObject(bitmap);
	//for (int i=0; i<3; i++)
     //for (int j=0; j<3; j++)
         DeleteObject(bitmap);
		// DeleteObject(map);

}

void CEightNumberView::DoDataExchange(CDataExchange* pDX)
{
	CFormView::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CEightNumberView)
	DDX_Control(pDX, IDC_BUTTON_EXPLAIN, m_Explain);
	DDX_Control(pDX, IDC_STATIC_SHOWSTATE, m_ShowState);
	DDX_Control(pDX, IDC_BUTTON_START, m_Start);
	DDX_Control(pDX, IDC_BUTTON_ONOK, m_OnOK);
	DDX_Control(pDX, IDC_BUTTON_STEPRUN, m_SepRun);
	DDX_Control(pDX, IDC_BUTTON_RUN, m_RunToStop);
	//}}AFX_DATA_MAP
}

BOOL CEightNumberView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CFormView::PreCreateWindow(cs);
}

void CEightNumberView::OnInitialUpdate()
{
	CFormView::OnInitialUpdate();
	GetParentFrame()->RecalcLayout();
	ResizeParentToFit();
    //GetRand();
   
	//m_pThread=AfxBeginThread(MultiThread,0);
	Run();
    if (ftot)
	{
     m_SepRun.EnableWindow(TRUE);
	 m_RunToStop.EnableWindow(TRUE);
     m_ShowState.SetWindowText(String);
	}
     else
	 {
       m_SepRun.EnableWindow(FALSE);
	   m_RunToStop.EnableWindow(FALSE);
	   m_ShowState.SetWindowText("初始化失败!非常遗憾此状态无解\n\n   禁止使用自动运行和单步运行\n\n      只能使用鼠标或键盘方向键移动");
	 }
   
    //m_ShowState.EnableWindow(FALSE);
}

void CEightNumberView::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	AfxGetMainWnd()->SetWindowText("八数码游戏[作者:李少辉]");
	// TODO: Add your message handler code here
      //ItoBitmap();
	  //DrawStation();
	  /*for (int i=0;i<3; i++)
		  for (int j=0; j<3; j++)
		  {
             temp.si=i;
			 temp.sj=j;
			 drawd(temp,1);
		  }*/
	int i,j;
	  for (i=0; i<3; i++)
		  for ( j=0; j<3; j++)
		  {
			  drawd(i,j,start[j][i]);
		  }
	  DrawGraphics();
	  DrawStoA();

	  //目标状态
    CPen newPen,*oldPen;
	newPen.CreatePen(PS_SOLID,3,RGB(128,0,0));
	oldPen=dc.SelectObject(&newPen); 
	for(i=0;i<=3;i++)
	{
		dc.MoveTo(540+240,40+40*i);
		dc.LineTo(540+360,40+40*i);
	}
	for(j=0;j<=3;j++)
	{
		dc.MoveTo(540+240+40*j,40);
		dc.LineTo(540+240+40*j,160);
	}
	CFont newFont,*oldFont;
	newFont.CreateFont(20,20,0,0,700,FALSE,FALSE,FALSE,ANSI_CHARSET,
		OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,PROOF_QUALITY,FF_ROMAN,"Times New Roman");
	oldFont=dc.SelectObject(&newFont);
	dc.SetBkColor(RGB(212,208,200));
	CString str;
	//显示目标状态
	for(i=0;i<3;i++)
		for(j=0;j<3;j++)
		{
			str.Format("%i",goal[i][j]);
			dc.TextOut(540+240+40*j+10,40+40*i+10,str);
			
		}
	newPen.DeleteObject();
	newFont.DeleteObject();
	dc.SelectObject(oldPen);
	dc.SelectObject(oldFont);
	// Do not call CFormView::OnPaint() for painting messages
}

/////////////////////////////////////////////////////////////////////////////
// CEightNumberView printing

BOOL CEightNumberView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CEightNumberView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CEightNumberView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

void CEightNumberView::OnPrint(CDC* pDC, CPrintInfo* /*pInfo*/)
{
	// TODO: add customized printing code here
}

/////////////////////////////////////////////////////////////////////////////
// CEightNumberView diagnostics

#ifdef _DEBUG
void CEightNumberView::AssertValid() const
{
	CFormView::AssertValid();
}

void CEightNumberView::Dump(CDumpContext& dc) const
{
	CFormView::Dump(dc);
}

CEightNumberDoc* CEightNumberView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CEightNumberDoc)));
	return (CEightNumberDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CEightNumberView message handlers

BOOL CEightNumberView::Dupe(struct record a, struct record b)//检查是否与已有状态重复
{
   BOOL buf=TRUE;
	for(int i=0;i<3;i++)
		for(int j=0;j<3;j++)
			if(a.ch[i][j]!=b.ch[i][j])
				buf=FALSE;
	return buf;
}

BOOL CEightNumberView::Check(int k)//检查空格向第k个方向移动是否出棋盘
{
    BOOL check;
	newnode.ni=temp.si+di[k];
	newnode.nj=temp.sj+dj[k];
	if(newnode.ni>=0 && newnode.ni<=2 && newnode.nj>=0 && newnode.nj<=2)
		check=TRUE;
	else
	{
		check=FALSE;
		newnode.ni=newnode.ni-di[k];
		newnode.nj=newnode.nj-dj[k];
	}
	return check;
}

BOOL CEightNumberView::Goals(struct record g)//检查是否为目标
{
	BOOL gl=TRUE;
	for(int i=0;i<3;i++)
		for(int j=0;j<3;j++)
		{
			if(g.ch[i][j]!=goal[i][j])
				gl=FALSE;
		}
	return gl;

}

void CEightNumberView::Run()
{
    int preopen;
	m_SepRun.EnableWindow(FALSE);
	m_RunToStop.EnableWindow(FALSE);
	//String=""; 
	open=1;
	closed=0;
	CString str;
	BOOL tt=TRUE;
	ftot=false;
	for(int i=0;i<3;i++)
		for(int j=0;j<3;j++)
			data[1].ch[i][j]=start[i][j];
	data[1].si=ni;
	data[1].sj=nj;
//	CString ss;
//	ss.Format("%i",data[1].si);
//	MessageBox(ss);
	data[1].pnt=0;
	data[1].dep=0;
	while(open>closed && tt && open<100000)
	{
		closed=closed+1;   //出队一个元素
		temp=data[closed];
		depth=temp.dep;
		newnode=temp;
		for(k=0;k<=3;k++)
		{
			if(Check(k))
			{
				open=open+1;
				data[open]=newnode;
				//原空格赋新位置的值,新空格置为零
				data[open].ch[ data[open].si ][ data[open].sj ]=data[open].ch[ data[open].ni ][ data[open].nj ];
				data[open].ch[ data[open].ni ][ data[open].nj ]=0;
				//新空格的位置赋给原空格
				data[open].si=data[open].ni;
				data[open].sj=data[open].nj;

				data[open].pnt=closed;
				data[open].dep=depth+1;
			}
            /*if (open>10000)
			{
				MessageBox("内存不足,或本组数据不能够到达目标状态\n\n     可以使用鼠标进行移动\n\n  要重新开始,请单击‘开始游戏’","初始化失败",MB_OK|MB_ICONINFORMATION);
				//MessageBox("恭喜你,你已赢得这局,’","八数码游戏",MB_OK|MB_ICONINFORMATION);
				exit(1);
				//continue;
				//goto failed;
			}*/
			preopen=open-1;
			struct record temnode;
			temnode=data[open];
			for(i=1;i<=preopen;i++)
			{
				if(Dupe(temnode,data[i]))
					open=open-1;

			}
			//ShowStatus(data[open-1].ch);
			if(Goals(data[open]))
			{
				tt=FALSE;
                ftot=true;
			}
			if(tt==FALSE)
				break;
		}
//failed: break;
	}
    
	if(tt==FALSE && open<100000)
	{
		//记下深度
		depth=data[open].dep;
		//把直接移动的状态用output数组记下来
		struct record temnode;
		int temi,temdepth;
		temdepth=depth;
		temnode=data[open];
		output[0]=data[1];
		output[temdepth]=data[open];
		while(temnode.pnt!=1)
		{
			temi=temnode.pnt;
			output[--temdepth]=data[temi];
			temnode=data[temi];
		}
		//output数组赋值完毕

		//使单步运行按钮有效
		//m_cButtonStepRun.EnableWindow(TRUE);

		//输出提示信息
		CString count;
		count.Format("%i",open-1);
		//CString std;
	    //std.Format("%d",open);
	    //MessageBox(std);
		//MessageBox("    运行成功!\n\n共产生"+count+"个状态(包括目标状态,但不包括初始状态)");
		String="      初始化成功!\n\n    共产生"+count+"个状态\n\n可以使用自动运行和单步运行\n\n也可以使用鼠标或键盘方向键进行移动\n\n";
	}
  //else
	 //MessageBox("Failed!");
	if (open>=100000 && tt==TRUE)
	{
     //CString std;
	 //std.Format("%d",open);
	 //MessageBox(std);
	 MessageBox("内存不足,或本组数据不能够到达目标状态\n\n     可以使用鼠标或键盘方向键进行移动\n\n  要重新开始,请单击‘开始游戏’","初始化失败",MB_OK|MB_ICONINFORMATION);
				//MessageBox("恭喜你,你已赢得这局,’","八数码游戏",MB_OK|MB_ICONINFORMATION);
				//exit(1);
				//continue;
				//goto failed;
	  ftot=false;
	}
	

  
}

void CEightNumberView::DrawGraphics()
{
    int i;
	CDC *pDC=GetDC();
	for(i=0;i<=3;i++)
	{
		pDC->MoveTo(i*160+20,20);
		pDC->LineTo(i*160+20,480+20);
	}
	for(i=0;i<=3;i++)
	{
		pDC->MoveTo(20,i*160+20);
		pDC->LineTo(480+20,i*160+20);
	}
	pDC->DeleteDC();
	return;
}

void CEightNumberView::GetRand()
{
   srand(time(NULL));
   int aa[9];
   int i,j;
   //&start[0][0]=aa;
   CString str,string="",st;
//   int dat;
  // aa[0]=rand()%9;
     for (i=0; i<9;i++)
	 {
		 aa[i]=rand()%9;
		 for(j=0; j<i;j++)
		 {
			 if (aa[i]==aa[j])
			 {
               
			  do
			  {

				aa[i]=rand()%9;
				
			  } while (aa[i]==aa[j]);
            
			 }
			
		 }
		 //str.Format("%d",aa[i]);
		//	MessageBox(str);
	
	 }
   st="012345678";
   int ab[9];
   int a,t;
   for (i=0; i<9; i++)
	   ab[i]=11;
   for (j=1; j<10; j++)
   {
	   a=0;
	   t=atoi(substr(st,j,1));
	   for (i=0; i<9; i++)
	   {
		   //t=atoi(substr(st,j,1));
		   if (t==aa[i])
		   {
			   a=a+1;
		       if (a>1)
			    aa[i]=9;
		   }
	   }
	   if (a==0)
	   {
			   //aa[i]=10;
			   ab[j-1]=t;
	   }
	   
	   //str.Format("%d",aa[i]);
	   //MessageBox(str);
   }
   /*CString std="";
   for (i=0; i<9; i++)
   {
	   str.Format("%d",aa[i]);
	   std=std+"  "+str; 
   }
   MessageBox(std);
for (i=0; i<9; i++)
   {
	   str.Format("%d",ab[i]);
	   std=std+"  "+str; 
   }
   MessageBox(std);*/
   for (i=0; i<9; i++)
   {
	   if (aa[i]==9)
	   {
		   for (j=0; j<9; j++)
		   {
			   if (ab[j]!=11)
			   {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -