09/12/09 20:27
TheKaneB
ciao, ci sono varie soluzioni al problema... una che mi viene in mente è questa:
L'ho scritta di getto, quindi non mi aspetto che funzioni a primo colpo, ma tentare una compilazione con annesso debugging richiedeva troppo sforzo fisico e mentale XD
Il codice è self explanatory, l'ho volutamente mantenuto semplice senza ottimizzare nulla (ci sarebbe molto da migliorare se ti servono tempi di calcolo brevi).
Buono studio
#include <stdio.h> #define MAX_X 5 #define MAX_Y 8 int myMatrix[MAX_X][MAX_Y]; #define SIDE_NONE 0 #define SIDE_RIGHT 1 #define SIDE_LEFT 2 #define SIDE_UP 4 #define SIDE_DOWN 8 // La negazione di 0 corrisponde alla parola con tutti i bit settati a 1 // Non uso la forma 0xFFFFFFFF per evitare assunzioni sulla lunghezza della parola macchina #define SIDE_ALL (~0) // Versione NON ottimizzata int getX(int side, int x) { int _x = x; // Attenzione: Considero la X crescente verso destra e la Y crescente verso il basso (convenzione comune in computer graphics) if (side & SIDE_LEFT) _x -= 1; if (side & SIDE_RIGHT) _x += 1; // Mi riporto nel campo dei numeri positivi while (_x < 0) { _x += MAX_X; } // Rientro nel campo dei valori ammissibili per x e y _x %= MAX_X; } int getY(int side, int y) { int _y = y; if (side & SIDE_UP) _y -= 1; if (side & SIDE_DOWN) _y += 1; while (_y < 0) { _y += MAX_Y; } _y %= MAX_Y; } int getValue(int side, int x, int y) { int sphericalX = getX(side, x); int sphericalY = getY(side, y); return myMatrix[sphericalX][sphericalY]; } void setValue(int side, int x, int y, int value) { int sphericalX = getX(side, x); int sphericalY = getY(side, y); myMatrix[sphericalX][sphericalY] = value; } int main(int argc, char **argv) { // Inizializzo myMatrix // [...] codice "a piacere" int i,j; printf(">>>\n"); for (j = 0; j < MAX_Y; j++) { printf("|"); for (i = 0; i < MAX_X; i++) { myMatrix[i][j] = i + MAX_X * j; printf("%d\t", myMatrix[i][j]); } printf("|\n"); } printf(">>>\n"); // [...] FINE codice "a piacere" int a = getValue(SIDE_NONE, 12, -3); int b = getValue(SIDE_RIGHT, 11, -3); if (a == b) printf("Yeah!\n"); // Ottengo il valore della casella in alto a sinistra rispetto alle coordinate 0,0, cioè ottengo lo spigolo opposto della matrice a = getValue(SIDE_LEFT + SIDE_UP, 0, 0); b = getValue(SIDE_NONE, MAX_X - 1, MAX_Y - 1); if (a == b) printf("Oh Yeah 2 - la vendetta\n"); return 0; }
L'ho scritta di getto, quindi non mi aspetto che funzioni a primo colpo, ma tentare una compilazione con annesso debugging richiedeva troppo sforzo fisico e mentale XD
Il codice è self explanatory, l'ho volutamente mantenuto semplice senza ottimizzare nulla (ci sarebbe molto da migliorare se ti servono tempi di calcolo brevi).
Buono studio
aaa
09/12/09 20:29
TheKaneB
ps: per verificare se hai capito la tecnica... potresti spiegarmi come mai SIDE_NONE e SIDE_ALL hanno esattamente lo stesso effetto, cioè di restituire la cella voluta?
Ciao!
Ciao!
aaa
10/12/09 15:50
Luca90
Prima di tutto ti ringrazio per aver perso tempo con la mia richiestae mi scuso se non ti ho risposto subito, ma non ho potuto..comunque, non riesco a rispondere alla tua domanda di "assert",perchè non ho capito cosa fa la tilde quando definisci SIDE_ALL.Perchè ((Non so come scrive la tilde)0)?
aaa
10/12/09 16:21
TheKaneB
la negazione di un booleano si fa con !, la negazione bitwise (cioè per ogni singolo bit) si fa con la tilde ~ (su windows premi ALT e digita 126 sul tastierino numerico, poi rilascia ALT).
aaa
10/12/09 16:26
TheKaneB
ah ovviamente ho fatto in modo che con get value tu possa interrogare le celle adiacenti senza intervenire sugli indici, così semplifichi il calcolo delle regole di Life. Lo stesso risultato si può ottenere togliendo il SIDE e agendo direttamente su x e y, tanto funziona comunque in coordinate toroidali.
Già, perchè pensandoci meglio, non è equivalende ad una sfera, ma ad un toroide! cioè una figura a forma di ciambella
Già, perchè pensandoci meglio, non è equivalende ad una sfera, ma ad un toroide! cioè una figura a forma di ciambella
aaa
11/12/09 11:33
Luca90
Sono arrivato alla fine a questo codice, ma su linux dopo la prima printf mi da Segmentation fault..Che tipo di errore è?
#include <stdio.h> #define X 80 #define Y 30 //clear the screen from not wanted chars void blackScreen(char screen[Y][X],int max_x, int max_y){ int i,j; for(i=0; i<max_y;i++){ for(j=0; j<max_x; ++j){ screen[i][j]=' '; } } } // print the screen void printScreen(char screen[Y][X],int max_x, int max_y){ int i, j; for(i=0;i<max_y;++i){ printf("\n"); for(j=0;j<max_x;++j){ printf("%c",screen[i][j]); } } } //copy a screen to the new one void copyScreen(char target[Y][X],char source[Y][X],int max_x, int max_y){ int i,j; for(i=0; i<max_y; ++i){ for(j=0; j<max_x; ++j){ target[i][j]=source[i][j]; } } } // new generation of population void epoch(char new[Y][X],char old[Y][X],int max_x, int max_y){ int i,j; for(i=0; i<max_y; ++i){ for(j=0; j<max_x; ++j){ switch(contaVicini(old[i][j], max_x, max_y)){ case 2: new[i][j]=old[i][j]; break; case 3: new[i][j]= '+'; break; default: new[i][j]= ' '; break; } } } } //count the neighbor int contaVicini(char screen[Y][X],int x,int y, int max_x, int max_y){ int i,j,cont=0,flag=0; //Eccezioni per i quattro angoli; conta manualmente gli 8 vicini, pensando la matrice come una sfera if(y == 0){ //Angolo: AltoSx if(x == 0){ while(flag <= 3){ if(screen[y][max_x]=='+')++cont; if(screen[y][1]=='+')++cont; ++flag; if(screen[y+1][0]=='+')++cont; if(screen[y+1][1]=='+')++cont; if(screen[y+1][max_x]=='+')++cont; ++flag; if(screen[max_y][0]=='+')++cont; if(screen[max_y][1]=='+')++cont; if(screen[max_y][max_x]=='+')++cont; ++flag; } } //Angolo: AltoDx if(x == max_x){ while(flag <= 3){ if(screen[y][max_x-1]=='+')++cont; if(screen[y][0]=='+')++cont; ++flag; if(screen[y+1][max_x]=='+')++cont; if(screen[y+1][max_x-1]=='+')++cont; if(screen[y+1][0]=='+')++cont; ++flag; if(screen[max_y][max_x]=='+')++cont; if(screen[max_y][max_x-1]=='+')++cont; if(screen[max_y][0]=='+')++cont; ++flag; } } } if(y == max_y){ //Angolo: BassoSx if(x == 0){ while(flag <= 3){ if(screen[y][max_x]=='+')++cont; if(screen[y][1]=='+')++cont; ++flag; if(screen[0][0]=='+')++cont; if(screen[0][1]=='+')++cont; if(screen[0][max_x]=='+')++cont; ++flag; if(screen[max_y-1][0]=='+')++cont; if(screen[max_y-1][1]=='+')++cont; if(screen[max_y-1][max_x]=='+')++cont; ++flag; } } //Angolo: BassoDx if(x==max_x){ while(flag <= 3){ if(screen[y][max_x-1]=='+')++cont; if(screen[y][0]=='+')++cont; ++flag; if(screen[y-1][max_x]=='+')++cont; if(screen[y-1][max_x-1]=='+')++cont; if(screen[y-1][0]=='+')++cont; ++flag; if(screen[0][max_x]=='+')++cont; if(screen[0][max_x-1]=='+')++cont; if(screen[0][0]=='+')++cont; ++flag; } } } //Eccezioni per le righe estreme: matrice vista come una sfera //Riga 0 if(y == 0){ if(x != (0 & max_x)){ while(flag <= 3){ if(screen[y][x-1]=='+')++cont; if(screen[y][x+1]=='+')++cont; ++flag; if(screen[max_y][x]=='+')++cont; if(screen[max_y][x-1]=='+')++cont; if(screen[max_y][x+1]=='+')++cont; ++flag; if(screen[y+1][x]=='+')++cont; if(screen[y+1][x-1]=='+')++cont; if(screen[y+1][x+1]=='+')++cont; ++flag; } } } //Riga max_y if(y == max_y){ if(x != (0 & max_x)){ while(flag <= 3){ if(screen[y][x-1]=='+')++cont; if(screen[y][x+1]=='+')++cont; ++flag; if(screen[0][x]=='+')++cont; if(screen[0][x-1]=='+')++cont; if(screen[0][x+1]=='+')++cont; ++flag; if(screen[y-1][x]=='+')++cont; if(screen[y-1][x-1]=='+')++cont; if(screen[y-1][x+1]=='+')++cont; ++flag; } } } //Colonna 0 if(x == 0){ if(y != (0 & max_y)){ while(flag <= 3){ if(screen[y][max_x]=='+')++cont; if(screen[y][x+1]=='+')++cont; ++flag; if(screen[y-1][max_x]=='+')++cont; if(screen[y-1][0]=='+')++cont; if(screen[y-1][1]=='+')++cont; ++flag; if(screen[y+1][max_x]=='+')++cont; if(screen[y+1][0]=='+')++cont; if(screen[y+1][1]=='+')++cont; ++flag; } } } //Colonna max_x if(x == max_x){ if(y != (0 & max_y)){ while(flag <= 3){ if(screen[y][max_x-1]=='+')++cont; if(screen[y][0]=='+')++cont; ++flag; if(screen[y-1][max_x]=='+')++cont; if(screen[y-1][max_x-1]=='+')++cont; if(screen[y-1][0]=='+')++cont; ++flag; if(screen[y+1][max_x]=='+')++cont; if(screen[y+1][max_x-1]=='+')++cont; if(screen[y+1][0]=='+')++cont; ++flag; } } } //Tutto il resto for(i=y-1; i<y+2;++i){ for(j=x-1; j<x+2; ++j){ if(screen[i][j]=='+'){ ++cont; } } } return cont; } int main(){ int x,y; printf("Inserisci i valori di Y (verticale) - MAX 30\n>"); scanf("%d", &y); while(y>Y){ printf("Errore. Valore eccessivo. Reimmettere MAX 30\n> "); scanf("%d", &y); } printf("Inserisci i valori di X (orizzontale) - MAX 80\n>"); scanf("%d", &x); while(x>X){ printf("Errore. Valore eccessivo. Reimmettere MAX 80\n> "); scanf("%d", &x); } char newScreen[Y][X]; char screen[Y][X]={ " + ", " ", " + ", " + + ", " ++ ++ ++", " + + ++ ++", " ++ + + ++ ", " ++ + + + + + + ", " + + + ", " + + ", " ++ ", }; /* char screen[Y][X]={ " ", " + + ", " + ", " + + ", " ++++ ", " ", " ", }; */ int a=-1; while(a!=0){ printScreen(screen, x,y); printf("Print Ok --------------------------------------------------------------------------------------\n"); epoch(newScreen, screen, x,y); printf("Epoch Ok ---------------------------------------------------------------------------------------\n"); copyScreen(screen, newScreen, x,y); } return 0; }
aaa