Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members  

eight_queens.cc

00001 /*
00002 *  Name:      eight_queens.cc
00003 *  Author:    Rafael Jesus Alcantara Perez
00004 *  Summary:   Test for base algorithm
00005 *  Date:      $Date: 2003/04/14 00:18:36 $
00006 *  Revision:  $Revision: 1.1 $
00007 *
00008 *  Copyright (C) 1994-2002  Rafael Jesus Alcantara Perez <rafa@dedalo-ing.com>
00009 *
00010 *  This program is free software; you can redistribute it and/or modify
00011 *  it under the terms of the GNU General Public License as published by
00012 *  the Free Software Foundation; either version 2 of the License, or
00013 *  (at your option) any later version.
00014 *
00015 *  This program is distributed in the hope that it will be useful,
00016 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 *  GNU General Public License for more details.
00019 *
00020 *  You should have received a copy of the GNU General Public License
00021 *  along with this program; if not, write to the Free Software
00022 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00023 *  MA 02111-1307, USA.
00024 */
00025 
00026 #include <cstdlib>
00027 #include <cstring>
00028 #include <iostream>
00029 #include <mpcl/test.h>
00030 #include <vector>
00031 
00032 
00033 #define MAX_QUEENS   (8)
00034 #define MAX_ROWS     (8)
00035 #define MAX_COLUMNS  (8)
00036 
00037 
00038 class TQueen
00039 {
00040 
00041   public:
00042 
00043     int   iX;
00044     int   iY;
00045 
00046 
00047   public:
00048 
00049     TQueen (void) :
00050       iX (0)      ,
00051       iY (0)      {}
00052 
00053     bool isKillingTo (const TQueen& rktSOURCE_QUEEN) const;
00054     bool operator == (const TQueen& rktSOURCE_QUEEN) const;
00055 
00056     //
00057     //  S T R E A M   F U N C T I O N S
00058     //
00059     friend std::basic_ostream<char>& operator << (std::basic_ostream<char>& rtOUTPUT_OSTREAM, const TQueen& rktSOURCE_QUEEN);
00060 
00061 };  // class TQueen
00062 
00063 typedef std::vector<TQueen>        TArrayQueen;
00064 typedef std::vector<TArrayQueen>   TArrayArrayQueen;
00065 
00066 
00067 class TRecursiveApproachAlgorithm
00068 {
00069 
00070   public:
00071 
00072     TArrayArrayQueen*   ptSolutionsArray;
00073 
00074 
00075   public:
00076 
00077     void execute (TArrayArrayQueen& rtSOLUTIONS_ARRAY);
00078 
00079 
00080   private:
00081 
00082     bool areKillingEachOther ( const TQueen&      rktQUEEN              ,
00083                                const TArrayQueen& rktSOURCE_QUEEN_ARRAY ) const;
00084     bool tryFor (int iROW, TArrayQueen& rtQUEEN_ARRAY);
00085 
00086 };  // class TRecursiveApproachAlgorithm
00087 
00088 
00089 bool TQueen::isKillingTo (const TQueen& rktSOURCE_QUEEN) const
00090 {
00091 
00092   return ( ( abs (iX - rktSOURCE_QUEEN.iX) == abs (iY - rktSOURCE_QUEEN.iY) ) ||
00093            ( iX == rktSOURCE_QUEEN.iX )                                       ||
00094            ( iY == rktSOURCE_QUEEN.iY )                                        );
00095 
00096 }  // TQueen::isKillingTo()
00097 
00098 
00099 bool TQueen::operator == (const TQueen& rktSOURCE_QUEEN) const
00100 {
00101 
00102   return ( ( iX == rktSOURCE_QUEEN.iX ) && ( iY == rktSOURCE_QUEEN.iY ) );
00103 
00104 }  // TQueen::operator ==()
00105 
00106 
00107 std::basic_ostream<char>& operator << (std::basic_ostream<char>& rtOUTPUT_OSTREAM, const TQueen& rktSOURCE_QUEEN)
00108 {
00109 
00110   rtOUTPUT_OSTREAM << rktSOURCE_QUEEN.iX;
00111   rtOUTPUT_OSTREAM << ",";
00112   rtOUTPUT_OSTREAM << rktSOURCE_QUEEN.iY;
00113   return rtOUTPUT_OSTREAM;
00114 
00115 }  // friend operator << ()
00116 
00117 
00118 void TRecursiveApproachAlgorithm::execute (TArrayArrayQueen& rtSOLUTIONS_ARRAY)
00119 {
00120 
00121   TArrayQueen   tTemporalQueenArray;
00122 
00123   //
00124   //  Warning:  We know that there are solutions. If we shouldn't know that, 
00125   //            this wouldn't be an algorithm, because it could not find a
00126   //            solution.
00127   //
00128   ptSolutionsArray = &rtSOLUTIONS_ARRAY;
00129 
00130   tryFor (0, tTemporalQueenArray);
00131 
00132 }  // TRecursiveApproachAlgorithm::execute()
00133 
00134 
00135 bool TRecursiveApproachAlgorithm::areKillingEachOther ( const TQueen&      rktQUEEN       ,
00136                                                         const TArrayQueen& rktQUEEN_ARRAY ) const
00137 {
00138 
00139   bool   gKills = false;
00140 
00141   for (size_t J = 0; ( J < rktQUEEN_ARRAY.size() ) ;++J)
00142   {
00143     if ( rktQUEEN_ARRAY [J].isKillingTo (rktQUEEN) )
00144     {
00145       gKills = true;
00146       break;
00147     }
00148   }
00149   return gKills;
00150 
00151 }  // TRecursiveApproachAlgorithm::areKillingEachOther()
00152 
00153 
00154 bool TRecursiveApproachAlgorithm::tryFor (int iROW, TArrayQueen& rtQUEEN_ARRAY)
00155 {
00156 
00157   bool   gSuccess = true;
00158 
00159   if ( ( rtQUEEN_ARRAY.size() < MAX_QUEENS ) && ( iROW < MAX_ROWS ) )
00160   {
00161 
00162     TQueen   tNewQueen;
00163 
00164     gSuccess     = false;
00165     tNewQueen.iY = iROW;
00166     for (size_t J = 0; ( J < MAX_COLUMNS ) ;++J)
00167     {
00168       tNewQueen.iX = J;
00169       if ( !areKillingEachOther (tNewQueen, rtQUEEN_ARRAY) )
00170       {
00171         rtQUEEN_ARRAY.push_back (tNewQueen);
00172         if ( tryFor (iROW + 1, rtQUEEN_ARRAY) )
00173         {
00174           gSuccess |= true;
00175           if ( rtQUEEN_ARRAY.size() == MAX_QUEENS )
00176           {
00177             ptSolutionsArray->push_back (rtQUEEN_ARRAY);
00178           }
00179         }
00180         //
00181         //  Back-tracking.
00182         //
00183         rtQUEEN_ARRAY.erase (rtQUEEN_ARRAY.end() - 1);
00184       }
00185     }
00186   }
00187   return gSuccess;
00188 
00189 }  // TRecursiveApproachAlgorithm::tryFor()
00190 
00191 
00192 //
00193 //  L O C A L   F U N C T I O N S
00194 //
00195 
00196 static void _DisplaySolutionsGraphicly (const TArrayArrayQueen& rktSOLUTIONS_ARRAY)
00197 {
00198 
00199   using std::cout;
00200   using std::endl;
00201 
00202   //
00203   //  Warning:  This function supposes that queens are sorted, and
00204   //            the table is dimension 8x8.
00205   //
00206   for (size_t J = 0; ( J < rktSOLUTIONS_ARRAY.size() ) ;++J)
00207   {
00208     cout << "Queens Solution [" << J << "]" << endl;
00209     cout << "+---+---+---+---+---+---+---+---+" << endl;
00210     for (long int K = rktSOLUTIONS_ARRAY[J].size() - 1; ( K >= 0 ) ;K--)
00211     {
00212       for (int L = 0; ( L < rktSOLUTIONS_ARRAY [J][K].iX ) ;++L)
00213       {
00214         cout << "|   ";
00215       }
00216       cout << "| Q ";
00217       for (size_t M = rktSOLUTIONS_ARRAY [J][K].iX + 1; ( M < MAX_COLUMNS ) ;++M)
00218       {
00219         cout << "|   ";
00220       }
00221       cout << "|" << endl;
00222       cout << "+---+---+---+---+---+---+---+---+" << endl;
00223     }
00224   }
00225 
00226 }  // _DisplaySolutionsGraphicly()
00227 
00228 
00230 int main (int argc, char** argv)
00231 {
00232 
00233   using std::strcmp;
00234 
00235   TEST_INIT ("tests for TBaseAlgorithm (implements eight queens solution)");
00236 
00237   TArrayArrayQueen              tSolutionsArray;
00238   TRecursiveApproachAlgorithm   tRecursiveApproachAlgorithm;
00239 
00240   if ( argc > 1 )
00241   {
00242     if ( !strcmp (argv[1], "-g") || !strcmp (argv[1], "--graphic") )
00243     {
00244       _DisplaySolutionsGraphicly (tSolutionsArray);
00245     }
00246     else
00247     {
00248       TEST_WRITE_INFO ("%s", "eight_queens: unrecognized option(s)");
00249       TEST_WRITE_INFO ("%s", "Usage: eight_queens [{-g|--graphic}]");
00250       TEST_FAIL;
00251     }
00252   }
00253   else
00254   {
00255     tRecursiveApproachAlgorithm.execute (tSolutionsArray);
00256     TEST_NUMBERS (92, tSolutionsArray.size());
00257     if ( !TEST_IN_SILENT_MODE )
00258     {
00259       for (size_t J = 0; ( J < tSolutionsArray.size() ) ;++J)
00260       {
00261         for (size_t K = 0; ( K < tSolutionsArray[J].size() ) ;++K)
00262         {
00263           fprintf ( hptTestTargetFile           ,
00264                     "#Queen [%d][%d]: %d, %d\n" ,
00265                     J                           ,
00266                     K                           ,
00267                     tSolutionsArray [J][K].iX   ,
00268                     tSolutionsArray [J][K].iY   );
00269         }
00270       }
00271     }
00272   }
00273 
00274   TEST_MEMORY_STATUS;
00275   TEST_RETURN_CODE;
00276 
00277 }  // main()

Generated on Mon Oct 13 02:35:23 2003 for MPCL by doxygen1.2.18