CITAZIONE
E perchè? Mica sono una divinità o l'imperatore!!
Certo, ma...insomma non ho competenze, Poi la programmazione micro e pc se pur con lo stesso linguaggio è diversa.
La tecnica che ho postato, è comoda perchè elimina gli if, si può ulteriormente migliorare, ma io avevo lasciato così.
In definitiva usa una bussola [1,1,-1-1] per le direzioni: si parte con le righe (+1), poi si scende con le colonne +1.
Poi si torna con le righe -1 e con le colonne -1.
Gli indici in quell'array li useremo per spostarci: index 1=1 (esempio)
Spiego a blocchi:
CODICE
//***************************************************
// numero die giri che deve fare in base alla forma:
// quadra è sempre n*2-1
// rettangolare varia a seconda che sia in piedi o sdraiata
// il numero varia anche se a parità di forma facciamo
// un giro antiorario. Di fatto è come se la sdraiassimo.
int test(void)
{
if (R<C && S_ORARIO==1 )
return R*2-1;
if (R>C && S_ORARIO==1 )
return C*2;
if (R<C && S_ORARIO==0 )
return R*2;
if (R>C && S_ORARIO==0 )
return C*2-1;
return R*2-1;
}
sopra stabilisco i calcoli da fare in base: matrice quadrata? Rettangolare? Rettangolare, ma senso orario o anti?
Una matrice rettangolare se la percorriamo in senso orario o antiorario, cambia.
I calcolettini me li ero fatti carta e penna.
CODICE
//***************************************************
// costruisce l'array di passi da seguire
void n_cicli(short int passi[])
{
int r=R;
int c=C;
#if (S_ORARIO==1)
int dir[2]={r,c};
#else
int dir[2]={c,r};
#endif
int tot=R*C;
int x=0;
int i=1;
int cont=0;
#if (S_ORARIO==1)
passi[0]=c;
cont=cont+c;
#else
passi[0]=r;
cont=cont+r;
#endif
while (cont<tot)
{
passi[i]=dir[x]-1;
cont=cont+passi[i];
dir[x]--;i++;
x=x^1;
}
//for (r=0; r<i; r++)
//printf ("_%d ",passi[r]);
}
Qui, creo un array dei passi che deve fare.
Ogni riga e colonna (tranne la prima riga), diminuisce di uno a ogni giro.
Es:
1,2,3
4,5,6
7,8,9
sarebbe=3,2,2,1,1
Per sapere come fare, si sfrutta il risultato della routine iniziale.
Questo array, sarà il ciclo esterno di un'altra routine.
Come notate, qui per fare righe,colonne,righe ecc...non uso nessun if:
Ma faccio uso dello XOR:
int dir[2]={r,c};
dir[x]--;i++;
x=x^1;
detta in breve: la x (indice che fa riferimento a dir), cambia ogni volta il suo valore grazie allo XOR
x=0-->righe
x=1-->colonne
Quindi mi posso girare tranquillamente senza usare if.
Una volta preparato tutto ho la stampa:
CODICE
void stampa(int array[][C],short int passi[],int n)
{
int dir[4]={1,1,-1,-1};
int d=0;
int vero=1;
int j,k,x,y;
int start_x=-1;
int start_y=0;
printf("\nSTAMPA A SPIRALE ");
#if (S_ORARIO==1)
printf ("ORARIA\n");
#else
printf ("ANTIORARIA\n");
#endif
for (j=0; j<n; j++)
{
for (k=0; k<passi[j]; k++)
{
x=start_x+(dir[d]+dir[d]*k)*vero;
y=start_y+(dir[d]+dir[d]*k)*(vero^1);
#if (S_ORARIO==1)
printf("%d " ,array[y][x]);
#else
printf("%d " ,array[x][y]);
#endif
}
d++;
start_x=x;start_y=y;d=d&3;vero=vero^1;
}
}
il for esterno segue i percorsi che ci eravamo preparati: righa 1 (es: 5 passi), colonna 1 (4 passi ecc)...
Questa invece è la bussola che dicevo:
CODICE
int dir[4]={1,1,-1,-1};
e qui avanzo sia per righe che per colonne:
CODICE
x=start_x+(dir[d]+dir[d]*k)*vero;
y=start_y+(dir[d]+dir[d]*k)*(vero^1);
Ci vorrebbe carta e penna per capire, comunque.
Sommo le direzioni in base agli indici di dir.
La variabile "vero" che se notate in y fa uno xor, serve a questo:
Quando mi muovo nelle righe, non mi devo muovere nelle colonne.
Vero, è soltanto un coefficente che va a 0 quando non mi devo muovere.
Quindi moltiplica per 0 e annulla l'operazione.
La volta dopo sarà il contrario e infatti:
(vero^1) xor ribalta tutto.
sotto:
d=d&3, è un contatore a saturazione.
Quando mi muovo nel vettore dir, devo fare in modo che arrivato in fondo ricomincio.
L'operatore AND mi fa questo:
0&3=0
1&3=1
2&3=2
ecc...
L'and non funziona con tutti i numeri per fare un contatore così.
Al massimo si può usare il modulo :100%3=1.... 5%3=2 (non si fora mai la dimensione dell'array)
e sopra ribalto la situazione iniziale.
Sembra difficile, ma carta e penna è una stupidata.
Poi, c'è anche il modo di non far calcolare i percorsi, ma io avevo lasciato perdere.
Spero di essere stato chiaro