1.结点类,InWhere
定义如下:
定义如下:
class InWhere
{
public:
int boat; //船的位置,开始没有加这个,后来发现因为没有人在左边时候船在右边的话
//
//
BOOL Test();//测试是否能符合结点条件
int father;//爸爸
int mother;//妈妈
int plice;//警察
int son1;//儿子1
int son2;//儿子2
int daughter1;//女儿1
int daughter2;//女儿2
int shife;//土匪(CS打多了,称号改不过来了)
//重载操作符,很重要.
InWhere & operator =(const InWhere &other);
BOOL operator ==(const InWhere &other);
BOOL operator !=(const InWhere &other);
InWhere();
virtual ~InWhere();
};
BOOL InWhere::Test()
{
//测试符合场景状况的结点状态
//必须要有个会驾船的和船在一边
if(father !=boat && mother !=boat && plice !=boat)
return FALSE;
//如果有人在船上那么船必须为2
//船上最多有2个人而且必须有个m_bCanDriver = TRUE的
int i = 0;
if(daughter1 == 2) i++;
if(daughter2 == 2) i++;
if(son1 == 2) i++;
if(son2 == 2) i++;
if(father == 2) i++;
if(mother == 2) i++;
if(plice == 2) i++;
if(shife == 2) i++;
if(i>2) return FALSE;
if(i != 0 && boat != 2)
return FALSE;
//警察和小偷不在一起时候,小偷会伤害家人
if(shife != plice)
{
if(daughter1 == shife || daughter2 == shife ||
son1 == shife || son2 == shife ||
father == shife || mother == shife)
return FALSE;
}
//当爸爸妈妈不在一起时,妈妈骂儿子,爸爸骂女儿
if(mother != father)
{
if(daughter1 == father || daughter2 == father ||
son1 == mother || son2 == mother)
return FALSE;
}
return TRUE;
}
2.MOVE类
BOOL Move::Test(CArray<InWhere, InWhere>& p_Ain)
{
//测试某2点是否能够通过
InWhere a = p_Ain.GetAt(m_nNow);
InWhere b = a;
InWhere c = p_Ain.GetAt(m_nNext);
InWhere d = c;
int num(0);
//如果是开始在船上的话
if(a.boat == 2)
{
++num;
}
if(c.boat == 2)
{
++num;
}
//头和尾只能有且有一个在船上
if(num != 1)
return FALSE;
//只要在船上的状态等于岸边的状态就表示此路是行的通的
//从船上到岸上的
if(a.boat == 2)
{
//---*--->*
if(a.daughter1 == 2)
a.daughter1 = 3;
if(a.daughter2 == 2)
a.daughter2 = 3;
if(a.father == 2)
a.father = 3;
if(a.mother == 2)
a.mother = 3;
if(a.plice == 2)
a.plice = 3;
if(a.shife == 2)
a.shife = 3;
if(a.son1 == 2)
a.son1 = 3;
if(a.son2 == 2)
a.son2 = 3;
a.boat =3;
if(a == p_Ain.GetAt(m_nNext))
return TRUE;
//*<----*-----
if(b.daughter1 == 2)
b.daughter1 = 1;
if(b.daughter2 == 2)
b.daughter2 = 1;
if(b.father == 2)
b.father = 1;
if(b.mother == 2)
b.mother = 1;
if(b.plice == 2)
b.plice = 1;
if(b.shife == 2)
b.shife = 1;
if(b.son1 == 2)
b.son1 = 1;
if(b.son2 == 2)
b.son2 = 1;
b.boat =1;
if(b == p_Ain.GetAt(m_nNext))
return TRUE;
}
//从岸到船上
if(c.boat == 2)
{
//----*<---*
if(c.daughter1 == 2)
c.daughter1 = 3;
if(c.daughter2 == 2)
c.daughter2 = 3;
if(c.father == 2)
c.father = 3;
if(c.mother == 2)
c.mother = 3;
if(c.plice == 2)
c.plice = 3;
if(c.shife == 2)
c.shife = 3;
if(c.son1 == 2)
c.son1 = 3;
if(c.son2 == 2)
c.son2 = 3;
c.boat =3;
if(c == p_Ain.GetAt(m_nNow))
return TRUE;
//*---->*----
if(d.daughter1 == 2)
d.daughter1 = 1;
if(d.daughter2 == 2)
d.daughter2 = 1;
if(d.father == 2)
d.father = 1;
if(d.mother == 2)
d.mother = 1;
if(d.plice == 2)
d.plice = 1;
if(d.shife == 2)
d.shife = 1;
if(d.son1 == 2)
d.son1 = 1;
if(d.son2 == 2)
d.son2 = 1;
d.boat =1;
if(d == p_Ain.GetAt(m_nNow))
return TRUE;
}
return FALSE;
}
3,遍历
void CRiverDlg::OnRiver()
{
// TODO: Add your control notification handler code here
UpdateData();
if(m_nGoEnd > m_wheres.GetSize()-1)
{
MessageBox("填入数字错误,这种情况不存在");
return;
}
m_bEndFlag = FALSE; //重置结束标志
m_ListStep.DeleteAllItems();
m_ListStep.SetRedraw(FALSE);
int i(0);
int nItem(0);
CString strInfo;
//声明结点访问标志
BOOL *Visited = new BOOL[m_wheres.GetSize()];
for(i = 0 ; i<m_wheres.GetSize(); i++)
Visited[i] = FALSE;
//初始化道路
CArray<int, int> Road;
//遍历找到结点
GoRiver(Road, m_nGoBegin, m_nGoEnd, m_MoveAll, Visited);
CString saMessage[3] = {"左岸","船上","右岸"};
nItem = 0;
for(i = 0; i<Road.GetSize(); i++)
{
strInfo.Format("第%d步", i+1);
nItem = m_ListStep.InsertItem(nItem, strInfo);
m_ListStep.SetItemText(nItem, 0, strInfo);
m_ListStep.SetItemText(nItem, 1, saMessage[m_wheres.GetAt(Road.GetAt(i)).father-1]);
m_ListStep.SetItemText(nItem, 2, saMessage[m_wheres.GetAt(Road.GetAt(i)).mother-1]);
m_ListStep.SetItemText(nItem, 3, saMessage[m_wheres.GetAt(Road.GetAt(i)).daughter1-1]);
m_ListStep.SetItemText(nItem, 4, saMessage[m_wheres.GetAt(Road.GetAt(i)).daughter2-1]);
m_ListStep.SetItemText(nItem, 5, saMessage[m_wheres.GetAt(Road.GetAt(i)).son1-1]);
m_ListStep.SetItemText(nItem, 6, saMessage[m_wheres.GetAt(Road.GetAt(i)).son2-1]);
m_ListStep.SetItemText(nItem, 7, saMessage[m_wheres.GetAt(Road.GetAt(i)).plice-1]);
m_ListStep.SetItemText(nItem, 8, saMessage[m_wheres.GetAt(Road.GetAt(i)).shife-1]);
m_ListStep.SetItemText(nItem, 9, saMessage[m_wheres.GetAt(Road.GetAt(i)).boat-1]);
nItem++;
}
delete[] Visited;
m_ListStep.SetRedraw(TRUE);
m_ListStep.Invalidate();
}
void CRiverDlg::GoRiver(CArray<int,int>& p_Road, int Begin, int End, CArray<Move, Move>& p_MoveAll, BOOL *Visited)
{
//深度遍历图形算法
//此步不需要因为从设置了结束位以后就再也没调用GORIVER了
//if(m_bEndFlag) return;
int i;
Visited[Begin] = TRUE;
//讲其加入到走过的路中
p_Road.Add(Begin);
if(Begin == End)
{
m_bEndFlag = TRUE;
MessageBox("找到了从起点通往终点道路");
return;
}
for(i=0; i<p_MoveAll.GetSize(); i++)
{
if(p_MoveAll.GetAt(i).m_nNow == Begin)
{
if(Visited[p_MoveAll.GetAt(i).m_nNext] == FALSE)
{
GoRiver(p_Road, p_MoveAll.GetAt(i).m_nNext, End, p_MoveAll, Visited);
if(m_bEndFlag) return;
}
}
}
//如果遍历完了还没找到说明此路不通出栈
p_Road.RemoveAt(p_Road.GetSize()-1);
}
void CRiverDlg::OnParse()
{
//找的所有的状态结点位置及所有可以走过的路
// TODO: Add your control notification handler code here
CString strInfo;//信息提示
m_ListRoot.DeleteAllItems();//ROOT清空
m_ListMyRoad.DeleteAllItems();//MYROAD清空
m_wheres.RemoveAll(); //结点清空
InWhere where; //临时结点
m_ListRoot.SetRedraw(FALSE); //不许重绘图
int AccordNum(0); //序号
int nItem(0);
int i,j,k,l,m,n,o,p,q;
for(i=1; i<4; i++)
for(j=1; j<4; j++)
for(k=1; k<4; k++)
for(l=1; l<4; l++)
for(m=1; m<4; m++)
for(n=1; n<4; n++)
for(o=1; o<4; o++)
for(p=1; p<4; p++)
for(q = 1; q<4; q++)
{
where.daughter1 = i;
where.daughter2 = j;
where.father = k;
where.mother = l;
where.plice = m;
where.shife = n;
where.son1 = o;
where.son2 = p;
where.boat = q;
if(where.Test())
{
strInfo.Format("%d", AccordNum);
nItem = m_ListRoot.InsertItem(nItem, strInfo);
m_ListRoot.SetItemText(nItem,0,strInfo);
strInfo.Format("%d", k);
m_ListRoot.SetItemText(nItem,1,strInfo);
strInfo.Format("%d", l);
m_ListRoot.SetItemText(nItem,2,strInfo);
strInfo.Format("%d", i);
m_ListRoot.SetItemText(nItem,3,strInfo);
strInfo.Format("%d", j);
m_ListRoot.SetItemText(nItem,4,strInfo);
strInfo.Format("%d", o);
m_ListRoot.SetItemText(nItem,5,strInfo);
strInfo.Format("%d", p);
m_ListRoot.SetItemText(nItem,6,strInfo);
strInfo.Format("%d", m);
m_ListRoot.SetItemText(nItem,7,strInfo);
strInfo.Format("%d", n);
m_ListRoot.SetItemText(nItem,8,strInfo);
strInfo.Format("%d", q);
m_ListRoot.SetItemText(nItem,9,strInfo);
m_wheres.Add(where);
++AccordNum;
++nItem;
}
}
m_ListRoot.SetRedraw(TRUE);
m_ListRoot.Invalidate();
m_ListMyRoad.SetRedraw(FALSE);
strInfo.Format("一共有%d种可能状况", m_wheres.GetSize());
MessageBox(strInfo);
m_MoveAll.RemoveAll();
Move mov;
AccordNum = 0;
nItem = 0;
for(i = 0; i< m_wheres.GetSize(); i++)
for(j = 0; j< m_wheres.GetSize(); j++)
{
mov.m_nNow = i;
mov.m_nNext = j;
if(i != j && mov.Test(m_wheres))
{
strInfo.Format("%d", AccordNum);
nItem = m_ListMyRoad.InsertItem(nItem, strInfo);
m_ListMyRoad.SetItemText(nItem,0,strInfo);
strInfo.Format("%d->%d", i,j);
m_ListMyRoad.SetItemText(nItem,1,strInfo);
m_MoveAll.Add(mov);
++AccordNum;
++nItem;
}
}
m_ListMyRoad.SetRedraw(TRUE);
m_ListMyRoad.Invalidate();
strInfo.Format("一共有%d种可能移动状况", m_MoveAll.GetSize());
MessageBox(strInfo);
GetDlgItem(IDC_RIVER)->EnableWindow();
GetDlgItem(IDC_GOEND)->EnableWindow();
GetDlgItem(IDC_GOBEGIN)->EnableWindow();
//设默认值为起点0终点最后m_wheres的最后个
//设置默认的起点和终点
m_nGoBegin = 0;
m_nGoEnd = m_wheres.GetSize()-1;
UpdateData(FALSE);
}