///////////////////////////////////////// // LoadData:载入数据 // 生成当前操作状态 // 并将当状态加入搜索树中 ///////////////////////////////////////// BOOL CMain::LoadData(BOOL Adv) { if(Adv == false) { CInitDialog InitDlg; if(InitDlg.DoModal()==IDOK) { CDisplay *DispItem;DispItem = new CDisplay; m_CurrentG = 0; for(int i=0; i<MaxItem; i++) for(int j=0; j<MaxItem; j++) { this->m_Desc[i][j] = InitDlg.GetDescData(i,j); this->m_Data[i][j] = InitDlg.GetSrcData(i,j); DispItem->LoadData(m_Data[i][j],i,j); } DispItem->SetNoteType(AlReady); DispItem->SetThisIsAAnswer(); DispItem->SetCurrentG(m_CurrentG); DispItem->SetCurrentCount(0); m_CurOpItem = DispItem; m_DispList.AddTail(DispItem); return TRUE; } else return FALSE; } else { CInputAdvDlg InitDlg; if(InitDlg.DoModal()==IDOK) { CDisplay *DispItem;DispItem = new CDisplay; m_CurrentG = 0; for(int i=0; i<MaxItem; i++) for(int j=0; j<MaxItem; j++) { this->m_Desc[i][j] = InitDlg.GetDescData(i,j); this->m_Data[i][j] = InitDlg.GetSrcData(i,j); DispItem->LoadData(m_Data[i][j],i,j); } DispItem->SetNoteType(AlReady); DispItem->SetThisIsAAnswer(); DispItem->SetCurrentG(m_CurrentG); DispItem->SetCurrentCount(0); m_CurOpItem = DispItem; m_DispList.AddTail(DispItem); return TRUE; } else return FALSE; } }
/////////////////////////////////////////// // FindBestMoveFlag:寻找最佳移动方式 并移动之 // 入口: GenerateChild(); // 参数:子节点集 // 返回值:错误代码 ////////////////////////////////////////// UINT CMain::FindBestMoveFlag(List *pList) { //计算移动后是否有重复项 重复项不参加最佳选择运算 IsReadyExist(pList); //在没有出现过移动结果中选择最佳解 POSITION Pos = pList->GetHeadPosition(); int H[4]={65535,65535,65535,65535},i=0,Min = 65535; POSITION MinPos; while(Pos) { POSITION CurPos = Pos; CDisplay *Item = (CDisplay *)pList->GetNext(Pos); if(Item->GetNoteType() == AlReady) {i++;continue;} H[i] = CaculateH(Item); if(Min>H[i]) {Min=H[i];MinPos = CurPos;} i++; } if(Min == 65535) {/* //没有找到最佳方法 表示这个结点所有子项都已扩展。要回溯 //但在本程序中 由于输入值一定有解,可以不要回溯 for(int CurrentG = this->m_CurrentG;CurrentG>0;CurrentG--) if(FindOtherNote(CurrentG)) return NoError;//找到了另一个未扩展的结点返回 */ return ErrorCode;//没有未扩展的结点了 本题无解 } //标记最佳解 Pos = pList->GetHeadPosition(); while(Pos) { POSITION CurPos = Pos; CDisplay *Item = (CDisplay *)m_DispList.GetNext(Pos); if(CurPos == MinPos) { Item->SetThisIsAAnswer();//是解 Item->SetNoteType(AlReady);//被扩展 m_CurOpItem = Item; } m_DispList.AddTail(Item); } return NoError; }
////////////////////////////////// //GenerateChild: 生成子节点 // 返回值:生成子节点过程中的错误代码 ////////////////////////////////// UINT CMain::GenerateChild() { List ChildList; int m=0; for(int k=0; k<4; k++) { if(m_iMoveFlag[k] == false) continue; CDisplay *Tmp;Tmp = new CDisplay; for(int i=0; i<MaxItem; i++) for(int j=0; j<MaxItem; j++) Tmp->LoadData(m_CurOpItem); Tmp->SetCurrentG(m_CurrentG); Tmp->SetCurrentCount(m++); Tmp->SetNoteType(NotYet); Tmp->MoveBlank(k); ChildList.AddTail(Tmp); } return FindBestMoveFlag(&ChildList); }
////////////////////////////////////// // IsReadyExist: 是否已经存在 // 如果已经存在则设标记为已存在 // 入口: FindBestMoveFlag() // 参数:子节点集起始位置指针 ////////////////////////////////////// void CMain::IsReadyExist(List *pList) { POSITION PosSrc = pList->GetHeadPosition(); while(PosSrc) { POSITION CurPos = PosSrc; CDisplay *ItemSrc = (CDisplay *)pList->GetNext(PosSrc); POSITION PosDesc = m_DispList.GetHeadPosition(); while(PosDesc) { CDisplay *ItemDesc = (CDisplay *)m_DispList.GetNext(PosDesc); if(ItemSrc->IsEqual(ItemDesc)) {//已经存在于第i个结果上 ItemSrc->SetNoteType(Cannot); m_DispList.AddTail(ItemSrc); pList->RemoveAt(CurPos); break; } } } }