Algorytmy z powrotami - skoczek

0

Jako że dzięki mojemu ostatniemu postowi :
Jak poprawić mój kod? nauczyłem się jak korzystać z wektorów to zachęcony tą pomocą znów zwracam się z prośbą do osób bardziej ogarniętych w temacie.

Mianowicie chce nauczyć się rekurencji i algorytmów z powrotami. Czytam Wirtha i doszedłem do problemu drogi skoczka szachowego.

Próbowałem to zaklepać samodzielnie jednak nie potrafie sobie poradzić z powrotami.

Oto kod (mniej ważne pierdoły na górze, część gdzie powinny być powroty zaraz nad mainem):

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;


void wypelnij(int ** tab,int N)
{

    for(int i = 0; i<N; i++)
    {

        for(int k = 0; k<N; k++)
        {
            tab[i][k] = 0;
        }
    }
}

void wypisz(int ** tab,int N)
{

    for(int i = 0; i<N; i++)
    {

        for(int k = 0; k<N; k++)
        {
            cout<<tab[i][k]<<" ";
        }
        cout<<endl;
    }
}


bool poprawnosc_ruchu(int x,int y,int N,int ** szachownica)          // WIADOMO - NIE MOZEMY WYJSC POZA TABLICE ANI ODWIEDZIC MIEJSCA JUZ ODWIEDZONEGO
{
    if(x>=0 && x<N && y < N && y>0 && szachownica[x][y]==0) return true;
    else return false;
}




bool ruch_mozliwy(int &wspx,int &wspy,int wariant_ruchu,int N,int ** szachownica)
{
    switch(wariant_ruchu)
    {

    case 1 :
        if (poprawnosc_ruchu(wspx+2,wspy+1,N,szachownica))
        {
            wspx = wspx + 2;
            wspy = wspy + 1;
            break;
        }

    case 2 :
        if (poprawnosc_ruchu(wspx-2,wspy-1,N,szachownica) )
        {
            wspx = wspx - 2;
            wspy = wspy - 1;
            break;
        }

    case 3 :
        if (poprawnosc_ruchu(wspx+2,wspy-1,N,szachownica) )
        {
            wspx = wspx + 2;
            wspy = wspy - 1;
            break;
        }

    case 4 :
        if (poprawnosc_ruchu(wspx-2,wspy+1,N,szachownica) )
        {
            wspx = wspx - 2;
            wspy = wspy + 1;
            break;
        }

    case 5 :
        if (poprawnosc_ruchu(wspx+1,wspy+2,N,szachownica) )
        {
            wspx = wspx + 1;
            wspy = wspy + 2;
            break;
        }


    case 6 :
        if (poprawnosc_ruchu(wspx-1,wspy-2,N,szachownica) )
        {
            wspx = wspx - 1;
            wspy = wspy - 2;
            break;
        }


    case 7 :
        if (poprawnosc_ruchu(wspx+1,wspy-2,N,szachownica) )
        {
            wspx = wspx + 1;
            wspy = wspy - 2;
            break;
        }


    case 8 :
        if (poprawnosc_ruchu(wspx-1,wspy+2,N,szachownica) )
        {
            wspx = wspx - 1;
            wspy = wspy + 2;
            break;
        }


    default :
        return false;
    }

    return true;

}







void konik(int ** szachownica,int wspx,int wspy,int nr_ruchu,int N)
{


    if(nr_ruchu == N*N - 1)
    {
        wypisz(szachownica,N);
        return;
    }
    szachownica[wspx][wspy] = nr_ruchu;

    for(int i = 1; i<=8; i++)
    {
        if(ruch_mozliwy(wspx,wspy,i,N,szachownica))
        {
            nr_ruchu++;
            szachownica[wspx][wspy] = nr_ruchu;
            konik(szachownica,wspx,wspy,nr_ruchu,N);
        }


        // Tutaj powinien nastapic powrot, czyli jak skoczek nie ma się gdzie już ruszyć to aby próbował z miejsca wczesniej - jednak nie wiem jak to zrobić


    }

    return;

}





int main()
{
    srand(time(NULL));

    cout<<"Jak duza ma byc szachownica ? "<<endl;
    int N;
    cin>>N;


    int **szachownica = new  int * [N];

    for(int i = 0; i<N; i++)
    {
        szachownica[i] = new int [N];
    }

    wypelnij(szachownica,N);



    konik(szachownica,0,0,1,N);

    wypisz(szachownica,N);

    return 0;
}

Prośba do osób którym chce się pomóc :

  1. Czy mógłby ktoś w przystępny sposób wytłumaczyć mi jak użyć tutaj tego powrotu , tak aby konik się nie ścinał gdy znajdzie się w ślepym zaułku tylko się cofnął?

  2. Czy mógłby ktoś polecić jakieś źródło gdzie w sposób prosty i przystępny jest wytłumaczona rekurencja? ( nie chcę gotowców ani banalnych przykładów z silnią- wiem że jest ich pełno).

0

googluj, i zrozum te banalne przykłady najpierw, a tak przy okazji -> gdzie te vectory? :)

0

no tak - googluj, dzięki :)
Mam to zrobić na tablicy N x N.

0

Ok poprawiłem ten kod i działa :D

Btw dzięki za link do wykladu o .... rekurencyjnej silni :P

Co prawda jestem zadowolony bo wreszcie program działa ale złożoność obliczeniowa ogromna dlatego też bardzo bym prosił - jesli ktoś ma jakieś pomysły jak ją polepszyć byłbym wdzięczny.

Póki co sprawnie się oblicza dla szachownicy o maksymalnej , jakże imponującej wielości 6x6.

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;


void fill_chessboard(int ** tab,int N)
{

    for(int i = 0; i<N; i++)
    {

        for(int k = 0; k<N; k++)
        {
            tab[i][k] = 0;
        }
    }
}

void print_the_chessboard(int ** tab,int N)
{

    for(int i = 0; i<N; i++)
    {

        for(int k = 0; k<N; k++)
        {
            cout<<tab[i][k]<<" ";
        }
        cout<<endl;
    }
}

bool is_move_possible(int option,int &nx,int &ny,int x,int y,int ** chessboard,int N){

switch(option){
case 1 : nx = x + 2;ny = y + 1;break;
case 2 : nx = x - 2;ny = y - 1;break;
case 3 : nx = x + 2;ny = y - 1;break;
case 4 : nx = x - 2;ny = y + 1;break;  // Sprawdzam wszystkie 8 ruchów które są możliwe dla skoczka
case 5 : nx = x + 1;ny = y + 2;break;
case 6 : nx = x - 1;ny = y - 2;break;
case 7 : nx = x + 1;ny = y - 2;break;
case 8 : nx = x - 1;ny = y + 2;break;
}
if(nx>=0 && nx<N && ny>=0 && ny<N && chessboard[nx][ny] == 0){return true;}
return false;
}


bool knight(int cordx,int cordy,int move_counter,int ** chessboard,int N){
chessboard[cordx][cordy] = move_counter;
int nx,ny;

if(move_counter == N*N){print_the_chessboard(chessboard,N);return true;}
else{

for(int i = 1;i<=8;i++)
if(is_move_possible(i,nx,ny,cordx,cordy,chessboard,N)==true){  // Sprawdzam wszystkie 8 ruchów które są możliwe dla skoczka
if(knight(nx,ny,move_counter+1,chessboard,N)==true){return true;}} 
chessboard[cordx][cordy] = 0; // Tutaj jest to cofnięcie z którym miałem problem

}
return false;

}


int main()
{
    srand(time(NULL));
    cout<<"Enter the size of a chessboard  "<<endl;
    int N;
    cin>>N;

    int **chessboard = new  int * [N];

    for(int i = 0; i<N; i++)
    {
        chessboard[i] = new int [N];
    }

    fill_chessboard(chessboard,N);
    knight(0,0,1,chessboard,N); // Przekazuje początkowe kordy i numer ruchu 
    return 0;
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1