/ /
// Construction/Destruction
/ /
/* 功能描述:
* Queen有3中动作模式:
* (1) 单步模式
* (2) 自动演示模式
* (3) 自动求解最终答案模式
* 接口:
* MoveNext() 尝试往下移动,更新StepSaver内容,同时更新lastrow、lastcol,为下一步作准备
* Solve() 求解主函数
* MoreSolve() 更多解的求解调用入口
*/
Queen::Queen( int n, int delay)
{
if (n < 1 || n > 32 )
{
AfxMessageBox(_T( " 请选择2~32之间的数,当前n被强制设为32 " ));
n = 32 ;
}
N = n;
lastcol = ( 0 ),lastrow = ( 0 ),PlayDelay = (delay);
SampleSolve = new StepSaver(N);
}
Queen:: ~ Queen()
{
delete SampleSolve;
// necessary?
SampleSolve = 0 ;
lastrow = lastcol = 0 ;
}
int Queen::Solve()
{
int ret;
int count = 0 ;
do {
ret = NextStep();
if (ret == FIND_ONE_SOLUTION)
count ++ ;
} while (ret != END_OF_SEARCH);
return count;
}
int Queen::MoreSolve()
{
if ( ! SampleSolve) return false ;
SampleSolve -> UnSet(lastrow,lastcol);
if (lastcol >= N - 1 && lastrow >= N - 1 )
return false ;
lastcol = lastcol + 1 ;
if (lastcol >= N)
lastrow += 1 ;
return Solve();
}
// 单步演示,如论成功与否,每一步都要走
int Queen::NextStep()
{
int row = lastrow; // 行
int col = lastcol; // 列
// 先做出失败的假设,在return false之前置好初值
lastrow = lastcol = N;
if (row >= N || col >= N)
return END_OF_SEARCH; // 没有更多解了
// 演示
Place(row,col);
// 计算下一个待演示的位置
// 当前是一个局部可用解,需要跳到下一行安排新的皇后,形成大一些的局部解
// 若不是可用解,继续尝试在当前行安排当前皇后,或者退回到上一行接着上次的地方尝试。
// 如果发现没有退路了,返回false
if (SampleSolve -> IsCompatiable(row,col))
{
// 标记当前可放位置
SampleSolve -> Set(row,col);
// 寻找下一个位置
row ++ ; // next line
/ //
/// BUG ! Fix me!
/ /
/// if(row >= N)
/// return false;
/// col=0
// //
/// Fixed:
if (row >= N) // 已经找到一个解。并且,需要寻找下一个解的初始出发点。
{
// row--;
col ++ ;
while ( row >= N || (row >= 1 && col >= N ) ){ // 需要退格
row -- ;
col = SampleSolve -> GetCol(row);
SampleSolve -> UnSet(row,col); // 先取消此行的摆放标记
col ++ ; // 得到待尝试格的col
}
// 更新lastrow, lastcol
lastrow = row;
lastcol = col;
if ( row <= 0 && col >= N ) // 已经退到了顶部之外,失败
return END_OF_SEARCH | FIND_ONE_SOLUTION;
return FIND_ONE_SOLUTION; //
} else {
col = 0 ;
}
} else {
ASSERT(row >= 0 );
col ++ ; // “一般情况”下的下一个位置
while ( row >= 1 && col >= N ){ // 需要退格
row -- ;
col = SampleSolve -> GetCol(row);
SampleSolve -> UnSet(row,col); // 先取消此行的摆放标记
col ++ ; // 得到待尝试格的col
}
if ( row <= 0 && col >= N ) // 已经退到了顶部之外,失败
return END_OF_SEARCH;
}
// 更新lastrow, lastcol
lastrow = row;
lastcol = col;
return HAVE_NEXT_STEP;
}
BOOL Queen::Place( int x, int y)
{
if (PlayDelay != 0 ){
SampleSolve -> TempSet(x,y);
((CQueenDlg * )((CQueenDlg * )AfxGetApp() -> m_pMainWnd)) -> UpdateCanvas();
// Sleep(PlayDelay);
SampleSolve -> TempUnSet(x,y);
}
if ( ! SampleSolve -> IsCompatiable(x,y))
return false ;
return true ;
}
标签:return,SampleSolve,Test,lastcol,lastrow,col,row
From: https://blog.51cto.com/u_16162111/6492450