您的位置:首页 > 编程语言 > C语言/C++

八皇后问题 回溯法 C++ 含迭代器

2013-11-26 09:41 387 查看
#ifndef POSITION
#define POSITION

class Position
{
    protected:
        int row,column;

    public:
        Position();
        Position (int row, int column);
        int getRow() const;
        int getColumn() const;
int getnum_of_queen() const;
void setPosition(int newRow,int newColumn);
}; // class Position

#endif

#ifndef BACKTRACK
#define BACKTRACK
#include "Application.h";
#include "Position.h";
class BackTrack  
{
    public:
        BackTrack (const Application& app);
        bool tryToSolve (Position pos);
    protected:
        Application app;
}; // class BackTrack
#endif

#ifndef APPLICATION
#define APPLICATION
#include <iostream>
#include "Position.h"
using namespace std;
class Application
{
    friend ostream& operator<<(ostream& stream, Application& app);
    public:
        // Postcondition: the initial state for this Application has been
        //                generated -- from input or assignments -- and
        //                the start position has been returned.
        Position generateInitialState();
        // Postcondition: true has been returned if pos can be on the path
        //                to a goal.  Otherwise, false has been returned.
        bool valid (const Position& pos);

        // Precondition: pos represents a valid position.
        // Postcondition: pos has been recorded as a valid position.

        void record (const Position& pos);

        // Postcondition: true has been returned if pos is the final
        //                position for this application.  Otherwise, false
        //                has been returned.

        bool done () const;

        // Postcondition: pos has been marked as not being on the path to
        //                a goal.
        void undo (const Position& pos);      
    class Iterator
    {
protected:
            void* fieldPtr;
        public:
            // Postcondition: this Iterator has been initialized to
            //                iterate from pos.
            Iterator (const Position& pos);

            // Postcondition: the next position for this Iterator has
            //                been returned.
            Position operator++ (int);

            // Postcondition: this Iterator cannot iterate any further.
            bool atEnd();

    }; // class Iterator
}; // class Application
#endif

///主要部分

#include "Application.h"
#include "Position.h"
#include <iostream>
#include <string>
#include <Math.h>

const short QUEEN= 9;
const short ROWS = 8;
const short COLUMNS = 8;
const short TRIED = 2;
short ChessBoard[8][8];
short NUM_OF_QUEEN=0;

//int newRow=0;


Position start;

using namespace std;

struct itrFields
{
int row,column,direction_x,direction_y;
};//itrFields

Position Application::generateInitialState()
{
for(int i=0;i<8;i++)
{

for(int j=0;j<8;j++)
{
ChessBoard[i][j]=0;
cout<<ChessBoard[i][j]
    <<" ";
if(j==7) cout<<endl;

}
}//初始化棋盘并输出整个棋盘

    const string START_PROMPT =
        "Please enter the start row and start column: ";

    int row,column;
cout<<"请输入第一个皇后的位置(纵坐标1~8,横坐标1~8):";
cin>>row>>column;

    start.setPosition (row-1, column-1);
cout<<endl<<endl;
    return start;//获取并返回第一个皇后的位置

} // method generateInitialState


bool Application::valid (const Position& pos)
{
bool flag=true;
if(pos.getRow()+1>8||pos.getRow()+1<1||pos.getColumn()+1>8||
pos.getColumn()+1<1)
flag=false;
if(flag)
for(int i=0;i<8;i++)
{
if(i==pos.getColumn()) continue;
if(ChessBoard[pos.getRow()][i]==9)  {flag=false;break;}

}//检查横行是否有皇后
if(flag)
for(int j=0;j<8;j++)
{
if(j==pos.getRow()) continue;
if(ChessBoard[j][pos.getColumn()]==9) {flag=false;break;}

}//检查竖行是否有皇后
if(flag)
for(int r=0;r<8;r++)
{
for(int c=0;c<8;c++)
{
if(r==pos.getRow()&&c==pos.getColumn()) continue;
if(abs(r-pos.getRow())==abs(c-pos.getColumn()))
{
if(ChessBoard[r][c]==9) {flag=false;break;}
}
}
if(!flag) break;
}//检查左斜,右斜有没有皇后

//
if(flag) newRow++;

return flag;
}

//标记皇后
void Application::record(const Position& pos)
{
ChessBoard[pos.getRow()][pos.getColumn()]=QUEEN;
NUM_OF_QUEEN++;
}
// 判断八个皇后是否已经都摆上
bool Application::done () const
{
//
cout<<NUM_OF_QUEEN;

return NUM_OF_QUEEN==8;
}

void Application::undo(const Position& pos)
{
if(ChessBoard[pos.getRow()][pos.getColumn()]==9) 
    NUM_OF_QUEEN--;
ChessBoard[pos.getRow()][pos.getColumn()]=0;
}

ostream& operator<<(ostream& stream, Application& app)
{
cout<<endl;
for(int row=0;row<ROWS;row++)
{
for(int column=0;column<COLUMNS;column++)
cout<<ChessBoard[row][column]<<" ";
cout<<endl;
}//outfor
return stream;
}//operation <<


Application::Iterator::Iterator(const Position& pos)
{

itrFields* itrPtr=new itrFields;
itrPtr->row=pos.getRow();
itrPtr->column=pos.getColumn();
itrPtr->direction_x=pos.getRow();
itrPtr->direction_y=0;
fieldPtr=itrPtr;
}//constructor

Position Application::Iterator::operator ++(int)
{
itrFields* itrPtr=(itrFields*)fieldPtr;
int nextRow = itrPtr -> row,
        nextColumn = itrPtr -> column;

switch(itrPtr->direction_x)
{
case 0:nextRow=0;break;
case 1:nextRow=1;break;
case 2:nextRow=2;break;
case 3:nextRow=3;break;
case 4:nextRow=4;break;
case 5:nextRow=5;break;
case 6:nextRow=6;break;
case 7:nextRow=7;break;
}
    switch(itrPtr -> direction_y++)
{
case 0:nextColumn=0;break;
case 1:nextColumn=1;break;
case 2:nextColumn=2;break;
case 3:nextColumn=3;break;
case 4:nextColumn=4;break;
case 5:nextColumn=5;break;
case 6:nextColumn=6;break;
case 7:nextColumn=7;break;
}
//cout<<nextRow<<nextColumn<<" ";

Position next(nextRow+1,nextColumn);
return next;

}//operator++

bool Application::Iterator::atEnd()
{
if(((itrFields*)fieldPtr)->direction_x>7||
((itrFields*)fieldPtr)->direction_y>7)
     return true;
return false;
}


#include "Position.h"

Position::Position()
{
    row = 0;
    column = 0;
} // default constructor

Position::Position (int row, int column)
{
    this -> row = row;
    this -> column = column;
} // constructor

void Position::setPosition(int newRow,int newColumn)
{
this->row=newRow;
this->column=newColumn;
}


int Position::getRow() const
{
    return row;
} // method getRow()


int Position::getColumn() const
{
    return column;
} // method getColumn()

#include <iostream>
#include <string>
#include "BackTrack.h"
#include "Application.h"
#include "Position.h"

 
using namespace std;

int main()
{
    Application app;

BackTrack b(app);

cout<<"初始化棋盘:\n";
Position start=app.generateInitialState();

if(!app.valid(start))
cout<<"您的输入有误!"<<endl;
else
{
app.record(start);
if(app.done() || b.tryToSolve(start))
cout<<"八个皇后已经正确摆放!"<<endl<<app;
else
{
cout<<app<<endl;
app.undo(start);
cout<<"八个皇后没有正确摆放!"<<endl;
}
}
cout<<endl<<endl;

system("pause");

return 0;
}

#include "BackTrack.h"

BackTrack::BackTrack (const Application& app)

{

    this -> app = app;

} // constructor

bool BackTrack::tryToSolve (Position pos)

{

    bool success = false;

    Application::Iterator itr (pos);

    while (!success && !itr.atEnd())

    {

        pos = itr++;

        if (app.valid (pos))

        {

            app.record (pos);

            if (app.done ())

                success = true;

            else

            {

                success = tryToSolve (pos);

//if(!success) cout<<1;

if (!success)

{   

app.undo(pos); 

}

            } // not done

        }

    } // while

    return success;

} // method tryToSolve
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: