Programming Resources
For Fun and Learning
Charles Cusack
Computer Science
Hope College
main

Python

C++


JAVA
PHP
SQL
Alice

Queens


queens.cpp

// Queens class implementation
//
//---------------------------------------------------------------------------
#include "queens.h"
//---------------------------------------------------------------------------
Queens::Queens(int n)
{
     BoardSize=n;
     Board=NULL;
     NewBoard(BoardSize);    
     ClearBoard();
}
//---------------------------------------------------------------------------
Queens::~Queens()
{
    DeleteBoard();
}
//---------------------------------------------------------------------------
Queens::Queens(const Queens &Q)
{
    Board=NULL; // This is done because we know Board can't point to anything
                // valid, since it hasn't been created yet, but we aren't
                // sure Board doesn't have some other value in it.
    CopyBoard(Q);
}
//---------------------------------------------------------------------------
Queens& Queens::operator=(const Queens& Q)
{
    if(this!=&Q)
    {
       CopyBoard(Q);  // This also takes care of deleting any dynamic 
                      // memory allocated in the old board.
    }
    return *this;
}
//---------------------------------------------------------------------------
void Queens::CopyBoard(const Queens &Q)
{
     if(BoardSize!=Q.BoardSize)
     {
         // If the boards are not the same size,
         // de-allocate and re-allocate dynamic memory.
         DeleteBoard();
         BoardSize=Q.BoardSize;
         NewBoard(BoardSize);
     }

     // Copy the values from Q to this.
     for(int i=0;i<BoardSize;i++)
        for(int j=0;j<BoardSize;j++)
           Board[i][j]=Q.Board[i][j];  
}
//---------------------------------------------------------------------------
void Queens::NewBoard(int n)
{
     if(Board!=NULL) // Prevents memory leaks.
         DeleteBoard();  
     BoardSize=n;
     Board=new square*[BoardSize];  // We make Board point to an array of
                                    // pointers to squares.  
     // NOTE: Board is of type square **. That is, it is a pointer to a
     // pointer to a square.  Thus it can point to a pointer to a square
     // or an array of pointers to squares. In this case, we make it point
     // to an array of pointers to squares.  That is why the "square*" is
     // present.  By saying
     //       new square*[BoardSize]
     // we are saying we want to allocate an array of BoardSize pointers to
     // squares.

      
     for(int i=0;i<BoardSize;i++)  // Make each pointer point to an array 
                                   // of squares.
        Board[i]=new square[BoardSize];
         // NOTE:  Here, we want each pointer to a square to point to an
         // array of squares.  This is why here we use "square", not 
         // "square*".  You only use a * if you wand a pointer to something,
         // and here we don't.
}
//---------------------------------------------------------------------------
void Queens::DeleteBoard()
{
    if(Board!=NULL) 
    {
         for(int i=0;i<BoardSize;i++)
            if(Board[i]!=NULL)  delete []Board[i];
         delete []Board;
         Board=NULL;
         BoardSize=0;
    }
}
//---------------------------------------------------------------------------
void Queens::ClearBoard()
{
     for(int i=0;i<BoardSize;i++)
        for(int j=0;j<BoardSize;j++)
           Board[i][j]=empty;
}
//---------------------------------------------------------------------------
void Queens::SetQueen(int Row,int Column)
{
     Board[Row][Column]=queen;
}
//---------------------------------------------------------------------------
void Queens::RemoveQueen(int Row,int Column)
{
     Board[Row][Column]=empty;
}
//---------------------------------------------------------------------------
bool Queens::IsUnderAttack(int Row,int Column)
{
    if(Row<0 || Row>=BoardSize || Column<0 || Column>=BoardSize)
      return false;
    for(int i=0;i<Column;i++)
       if(Board[Row][i]==queen)  
            return true;
    int i=1;
    while(Row-i>=0 && Column-i>=0)
    {
         if(Board[Row-i][Column-i]==queen) 
               return true;
         i++;
    }
    i=1;
    while(Row+i<BoardSize && Column-i>=0)
    {
         if(Board[Row+i][Column-i]==queen) 
                return true;
         i++;
    }
    return false;
}
//---------------------------------------------------------------------------
int Queens::PlaceQueens(int Column)
{
if(Column<BoardSize) 
{
   int Row = 0;
   while ( Row < BoardSize )                               // Try every row
   {
      if(!IsUnderAttack(Row,Column))     // If the spot is not under attack
      {
          SetQueen(Row,Column);                     // Place queen on board
          if (PlaceQueens(Column+1)) // Continue placing in the next column
          { 
                return true;           // If it was successful, return true
          }  
          else
          {                       // If no queen is possible in next column
             RemoveQueen(Row, Column);       // remove queen placed earlier
             Row++;                            // try next square in column
          }  
      } 
      else
      {
         Row++;          // If square can be attacked consider next square 
      }
   } 
   return false;
} 
else
{
   return true;
}
}  
//---------------------------------------------------------------------------
void PrintLine(int n)
{
  cout<<"|";
  for(int i=0;i<4*n-1;i++) 
     cout<<"-";
  cout<<"|\n";
  }
//---------------------------------------------------------------------------
void Queens::DisplayBoard()
{
  PrintLine(BoardSize);
  for(int i=0;i<BoardSize;i++)
{
      cout<<"|";
      for(int j=0;j<BoardSize;j++)
{
         if(Board[i][j]==empty)
{
            cout<<"   |";
          }
         else {
            cout<<" Q |";
          } 
       }
      cout<<"\n";
      PrintLine(BoardSize);
    }
   cout<<"\n";
 }
//---------------------------------------------------------------------------