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

#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

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值