Waňov web

PB161 Jazyk C++ - 11. cvicení

Cesta jezdce po sachovnici

Úvod:

Cesta jezdce po sachovnici (Knight's Tour, Springerproblem) je jedna z klasických sachových úloh. Úkolem je najít takovou cestu, kdy jezdec projde kazdé pole sachovnice práve jednou. Príkladem takové cesty je následující obrázek:

Cesta jezdce po sachovnici

Zadání:

Vytvorte trídu Knight, která bude obsahovat algoritmus nalezení cesty jezdce po sachovnici. Jezdec musí behem své cesty navstívit kazdé pole práve jednou.

Pozadavky:

Poznámky:


Riešenie:


knight.h
#ifndef KNIGHT
#define KNIGHT
#define CHECK
#include <iostream>
#include <iomanip>
using namespace std;

class Knight
{
  private:
    int** pole;
    int velkost;
    int** presiel;
  public:
    Knight(int velkost);
    ~Knight();
    bool runTour(int ,int );
    int** getmoves();
    bool checkTour(int**, int);
    friend ostream& operator <<(ostream&, const Knight&);

};
#endif



knight.C
#include "knight.h"

//------------------------------------------------------------------------
Knight::Knight(int n):velkost(n)
   {
    if(n<1)n=1;
    pole= new int*[n];
    presiel=new int*[n*n];
    for(int i=0;i<n;i++)
      {pole[i]=new int[n];
       for(int j=0;j<n;j++)
        pole[i][j]=0;
      }
    for(int i=0;i<n*n;i++)
       presiel[i]=new int[2]; 
   }
//--------------------------------------------------------------------------
 Knight::~Knight()
   {
    for(int i=0;i<velkost;i++)
      delete[] pole[i];
      
    for(int i=0;i<velkost*velkost;i++)
       delete[] presiel[i]; 
   
    delete[] pole;
    delete[] presiel;
   }
//------------------------------------------------------------------------- 
 bool Knight::runTour(int x,int y)    // hledání cesty
   {
    const int pocet_policok=velkost*velkost;
    int i,active_X,active_Y,next_X,next_Y,obsadene=1,moznost=0;
    int* tahy=new int[velkost*velkost];
    int moznosti[8][2]={{2,1},{-2,1},{2,-1},{-2,-1},
		        {1,2},{-1,2},{1,-2},{-1,-2}};
 
    if (x<1 ||x>velkost||y<1||y>velkost) return false;

    for(i=0;i<(pocet_policok);i++)
       {tahy[i]=0;presiel[i][0]=0;presiel[i][1]=0;}

    for(i=0;i<velkost;i++)
       for(int j=0;j<velkost;j++)
         pole[i][j]=0;

    pole[x-1][y-1]=1;
    presiel[0][0]=x;
    presiel[0][1]=y;
   // ================= hlavny cyklus ==================================
    for(;;)
      {
       
       active_X=presiel[obsadene-1][0]-1;
       active_Y=presiel[obsadene-1][1]-1;

       moznost=tahy[obsadene-1];
   
       if (moznost==8) 
           {pole[active_X][active_Y]=0;
            if (obsadene!=1) obsadene--;
                else return false;           
            tahy[obsadene-1]++;
            tahy[obsadene]=0;
            continue; }
       
       next_X=active_X+moznosti[moznost][0];
       next_Y=active_Y+moznosti[moznost][1];

       if (next_X<0||next_X>=velkost||next_Y<0||next_Y>=velkost)
          {tahy[obsadene-1]++;                         //mimo sachovnicu
           continue; }    
       else 
          {if (pole[next_X][next_Y]!=0)                //uz je obsadene
              {tahy[obsadene-1]++;continue; } 
           else {
                 presiel[obsadene][0]=next_X+1;
                 presiel[obsadene][1]=next_Y+1;
                 obsadene++;                           // mozme ist
                 pole[next_X][next_Y]=obsadene;
                }
          }  
           
       if(obsadene==pocet_policok) return true;

      }

   }
 //----------------------------------------------------------------------
 int** Knight::getmoves()   // sekvence polí, tak jak je jezdec prosel 
   {
    return presiel;
   }
//---------------------------------------------------------------------
 bool Knight::checkTour(int** cesta, int pocet_krokov)
   {

    int X,Y;
    if(pocet_krokov!=velkost*velkost) return false;
    for(int i=1;i<pocet_krokov;i++)          // skace podla pravidiel ?
     {                                         
      X=cesta[i-1][0]-cesta[i][0];if (X<0) X=0-X; 
      Y=cesta[i-1][1]-cesta[i][1];if (Y<0) Y=0-Y;
      if(!(((X==1)||(X==2)) && ((Y==1)||(Y==2)) && (X!=Y)))
        return false;
     }
    int** sachovnica=new int*[velkost];
    for(int i=0;i<velkost;i++)
      {sachovnica[i]=new int[velkost];
         for(int j=0;j<velkost;j++)
           sachovnica[i][j]=0;
      }
    for(int i=0;i<pocet_krokov;i++)
     {
       if (cesta[i][0]<1 ||cesta[i][1]<1||
          cesta[i][0]>velkost||cesta[i][1]>velkost)
            return false;
       if (sachovnica[cesta[i][0]-1][cesta[i][1]-1]==0)
         sachovnica[cesta[i][0]-1][cesta[i][1]-1]=i+1;
       else
         return false;
          
     }
    return true;
   }

//--------------------------------------------------------------------- 
 ostream& operator <<(ostream& out, const Knight& jazdec)
  {
   int i,j;
   for(i=(jazdec.velkost-1);i>=0;i--)
     {out<<setw(2)<<i+1;
      for(j=0;j<jazdec.velkost;j++)
        {out<<setw(3)<<jazdec.pole[i][j];}
      out<<"\n";
     }
   out<<"  ";
   for(i=0;i<jazdec.velkost;i++)
    {out<<setw(3)<<static_cast<char>(i+97);}
   out<<endl;
   return out;
  }




Nahor