0
点赞
收藏
分享

微信扫一扫

Test


/ / 
//  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 ;    
}

举报

相关推荐

test test

test

a test

LVM test

Test Fragment

Cuda Test

sproutcore test

java test

0 条评论