📄 eightnumberview.cpp
字号:
// 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 + -