Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - Matrice sferica (!)
Forum - C/C++ - Matrice sferica (!)

Avatar
Luca90 (Normal User)
Newbie


Messaggi: 8
Iscritto: 27/11/2009

Segnala al moderatore
Postato alle 20:24
Mercoledì, 09/12/2009
Ciao a tutti!Scusatemi, sto cercando di scrivere il gioco Life con C; ora, dovendo contare i "vivi" della matrice, sorge il problema degli estremi: quando si arriva ai limiti della matrice, come potrei fare per contare i vivi dall'altro lato della matrice? Come se fosse una griglia sferica? Avevo pensato a cicli while a catena, però mi son incartato...Potreste darmi qualche dritta?

PM Quote
Avatar
TheKaneB (Member)
Guru^2


Messaggi: 1792
Iscritto: 26/06/2009

Segnala al moderatore
Postato alle 21:27
Mercoledì, 09/12/2009
ciao, ci sono varie soluzioni al problema... una che mi viene in mente è questa:
Codice sorgente - presumibilmente C++

  1. #include <stdio.h>
  2.  
  3. #define MAX_X 5
  4. #define MAX_Y 8
  5.  
  6. int myMatrix[MAX_X][MAX_Y];
  7.  
  8. #define         SIDE_NONE       0
  9. #define         SIDE_RIGHT      1
  10. #define         SIDE_LEFT       2
  11. #define         SIDE_UP         4
  12. #define         SIDE_DOWN       8
  13. // La negazione di 0 corrisponde alla parola con tutti i bit settati a 1
  14. // Non uso la forma 0xFFFFFFFF per evitare assunzioni sulla lunghezza della parola macchina
  15. #define         SIDE_ALL        (~0)
  16.  
  17. // Versione NON ottimizzata
  18. int getX(int side, int x)
  19. {
  20.     int _x = x;
  21.  
  22.     // Attenzione: Considero la X crescente verso destra e la Y crescente verso il basso (convenzione comune in computer graphics)
  23.     if (side & SIDE_LEFT)       _x -= 1;
  24.     if (side & SIDE_RIGHT)      _x += 1;
  25.  
  26.     // Mi riporto nel campo dei numeri positivi
  27.     while (_x < 0) { _x += MAX_X; }
  28.  
  29.     // Rientro nel campo dei valori ammissibili per x e y
  30.     _x %= MAX_X;
  31. }
  32.  
  33. int getY(int side, int y)
  34. {
  35.     int _y = y;
  36.  
  37.     if (side & SIDE_UP)         _y -= 1;       
  38.     if (side & SIDE_DOWN)       _y += 1;
  39.  
  40.     while (_y < 0) { _y += MAX_Y; }
  41.  
  42.     _y %= MAX_Y;
  43. }
  44.  
  45. int getValue(int side, int x, int y)
  46. {
  47.     int sphericalX = getX(side, x);
  48.     int sphericalY = getY(side, y);
  49.    
  50.     return myMatrix[sphericalX][sphericalY];
  51. }
  52.  
  53. void setValue(int side, int x, int y, int value)
  54. {
  55.     int sphericalX = getX(side, x);
  56.     int sphericalY = getY(side, y);
  57.    
  58.     myMatrix[sphericalX][sphericalY] = value;
  59. }
  60.  
  61. int main(int argc, char **argv)
  62. {
  63.     // Inizializzo myMatrix
  64.     // [...] codice "a piacere"
  65.     int i,j;
  66.     printf(">>>\n");
  67.     for (j = 0; j < MAX_Y; j++)
  68.     {
  69.         printf("|");
  70.         for (i = 0; i < MAX_X; i++)
  71.         {
  72.             myMatrix[i][j] = i + MAX_X * j;
  73.             printf("%d\t", myMatrix[i][j]);
  74.         }
  75.         printf("|\n");
  76.     }
  77.     printf(">>>\n");
  78.     // [...] FINE codice "a piacere"
  79.  
  80.     int a = getValue(SIDE_NONE, 12, -3);
  81.     int b = getValue(SIDE_RIGHT, 11, -3);
  82.  
  83.     if (a == b) printf("Yeah!\n");
  84.  
  85.     // Ottengo il valore della casella in alto a sinistra rispetto alle coordinate 0,0, cioè ottengo lo spigolo opposto della matrice
  86.     a = getValue(SIDE_LEFT + SIDE_UP, 0, 0);
  87.     b = getValue(SIDE_NONE, MAX_X - 1, MAX_Y - 1);
  88.  
  89.     if (a == b) printf("Oh Yeah 2 - la vendetta\n");
  90.  
  91.     return 0;
  92. }



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 ;)

PM Quote
Avatar
TheKaneB (Member)
Guru^2


Messaggi: 1792
Iscritto: 26/06/2009

Segnala al moderatore
Postato alle 21:29
Mercoledì, 09/12/2009
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!

PM Quote
Avatar
Luca90 (Normal User)
Newbie


Messaggi: 8
Iscritto: 27/11/2009

Segnala al moderatore
Postato alle 16:50
Giovedì, 10/12/2009
Prima di tutto ti ringrazio per aver perso tempo con la mia richiesta:)e mi scuso se non ti ho risposto subito, ma non ho potuto..comunque, non riesco a rispondere alla tua domanda di "assert":k:,perchè non ho capito cosa fa la tilde quando definisci SIDE_ALL.Perchè ((Non so come scrive la tilde)0)?

PM Quote
Avatar
Luca90 (Normal User)
Newbie


Messaggi: 8
Iscritto: 27/11/2009

Segnala al moderatore
Postato alle 16:53
Giovedì, 10/12/2009
Ah ma è 0 negato???? La negazione non si scrive tipo (!0)?

PM Quote
Avatar
TheKaneB (Member)
Guru^2


Messaggi: 1792
Iscritto: 26/06/2009

Segnala al moderatore
Postato alle 17:21
Giovedì, 10/12/2009
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).


PM Quote
Avatar
TheKaneB (Member)
Guru^2


Messaggi: 1792
Iscritto: 26/06/2009

Segnala al moderatore
Postato alle 17:26
Giovedì, 10/12/2009
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 :)

PM Quote
Avatar
Luca90 (Normal User)
Newbie


Messaggi: 8
Iscritto: 27/11/2009

Segnala al moderatore
Postato alle 12:33
Venerdì, 11/12/2009
Sono arrivato alla fine a questo codice, ma su linux dopo la prima printf mi da Segmentation fault..Che tipo di errore è?

Codice sorgente - presumibilmente C++

  1. #include <stdio.h>
  2. #define X 80
  3. #define Y 30
  4.  
  5. //clear the screen from not wanted chars
  6. void blackScreen(char screen[Y][X],int max_x, int max_y){
  7.         int i,j;
  8.         for(i=0; i<max_y;i++){
  9.                 for(j=0; j<max_x; ++j){
  10.                         screen[i][j]=' ';
  11.                 }
  12.         }
  13. }
  14.  
  15. // print the screen
  16. void printScreen(char screen[Y][X],int max_x, int max_y){
  17.         int i, j;
  18.         for(i=0;i<max_y;++i){
  19.                 printf("\n");
  20.                 for(j=0;j<max_x;++j){
  21.                         printf("%c",screen[i][j]);
  22.                 }
  23.         }              
  24. }
  25.  
  26. //copy a screen to the new one
  27. void copyScreen(char target[Y][X],char source[Y][X],int max_x, int max_y){
  28.         int i,j;
  29.         for(i=0; i<max_y; ++i){
  30.                 for(j=0; j<max_x; ++j){
  31.                         target[i][j]=source[i][j];     
  32.                 }
  33.         }
  34. }
  35.  
  36. // new generation of population
  37. void epoch(char new[Y][X],char old[Y][X],int max_x, int max_y){
  38.         int i,j;
  39.         for(i=0; i<max_y; ++i){
  40.                 for(j=0; j<max_x; ++j){
  41.                         switch(contaVicini(old[i][j], max_x, max_y)){
  42.                                 case 2:
  43.                                         new[i][j]=old[i][j];
  44.                                         break;
  45.                                 case 3:
  46.                                         new[i][j]= '+';
  47.                                         break;
  48.                                 default:
  49.                                         new[i][j]= ' ';
  50.                                         break;
  51.                         }      
  52.                 }      
  53.         }      
  54. }
  55. //count the neighbor
  56. int contaVicini(char screen[Y][X],int x,int y, int max_x, int max_y){
  57.         int i,j,cont=0,flag=0;
  58.                
  59.                 //Eccezioni per i quattro angoli; conta manualmente gli 8 vicini, pensando la matrice come una sfera
  60.                 if(y == 0){
  61.                        
  62.                         //Angolo: AltoSx
  63.                         if(x == 0){
  64.                                 while(flag <= 3){
  65.                                         if(screen[y][max_x]=='+')++cont;
  66.                                         if(screen[y][1]=='+')++cont;
  67.                                         ++flag;
  68.                                         if(screen[y+1][0]=='+')++cont;
  69.                                         if(screen[y+1][1]=='+')++cont;
  70.                                         if(screen[y+1][max_x]=='+')++cont;
  71.                                         ++flag;
  72.                                         if(screen[max_y][0]=='+')++cont;
  73.                                         if(screen[max_y][1]=='+')++cont;
  74.                                         if(screen[max_y][max_x]=='+')++cont;
  75.                                         ++flag;
  76.                                 }      
  77.                                
  78.                         }
  79.                        
  80.                         //Angolo: AltoDx
  81.                         if(x == max_x){
  82.                                 while(flag <= 3){
  83.                                         if(screen[y][max_x-1]=='+')++cont;
  84.                                         if(screen[y][0]=='+')++cont;
  85.                                         ++flag;
  86.                                         if(screen[y+1][max_x]=='+')++cont;
  87.                                         if(screen[y+1][max_x-1]=='+')++cont;
  88.                                         if(screen[y+1][0]=='+')++cont;
  89.                                         ++flag;
  90.                                         if(screen[max_y][max_x]=='+')++cont;
  91.                                         if(screen[max_y][max_x-1]=='+')++cont;
  92.                                         if(screen[max_y][0]=='+')++cont;
  93.                                         ++flag;
  94.                                 }      
  95.                                
  96.                         }
  97.                 }
  98.                
  99.                 if(y == max_y){
  100.                
  101.                         //Angolo: BassoSx
  102.                         if(x == 0){
  103.                                 while(flag <= 3){
  104.                                         if(screen[y][max_x]=='+')++cont;
  105.                                         if(screen[y][1]=='+')++cont;
  106.                                         ++flag;
  107.                                         if(screen[0][0]=='+')++cont;
  108.                                         if(screen[0][1]=='+')++cont;
  109.                                         if(screen[0][max_x]=='+')++cont;
  110.                                         ++flag;
  111.                                         if(screen[max_y-1][0]=='+')++cont;
  112.                                         if(screen[max_y-1][1]=='+')++cont;
  113.                                         if(screen[max_y-1][max_x]=='+')++cont;
  114.                                         ++flag;
  115.                                 }
  116.                         }
  117.                        
  118.                         //Angolo: BassoDx
  119.                         if(x==max_x){
  120.                                 while(flag <= 3){
  121.                                         if(screen[y][max_x-1]=='+')++cont;
  122.                                         if(screen[y][0]=='+')++cont;
  123.                                         ++flag;
  124.                                         if(screen[y-1][max_x]=='+')++cont;
  125.                                         if(screen[y-1][max_x-1]=='+')++cont;
  126.                                         if(screen[y-1][0]=='+')++cont;
  127.                                         ++flag;
  128.                                         if(screen[0][max_x]=='+')++cont;
  129.                                         if(screen[0][max_x-1]=='+')++cont;
  130.                                         if(screen[0][0]=='+')++cont;
  131.                                         ++flag;
  132.                                 }      
  133.                                
  134.                         }      
  135.                                
  136.                 }
  137.                
  138.         //Eccezioni per le righe estreme: matrice vista come una sfera
  139.        
  140.         //Riga 0
  141.         if(y == 0){
  142.                 if(x != (0 & max_x)){
  143.                         while(flag <= 3){
  144.                                         if(screen[y][x-1]=='+')++cont;
  145.                                         if(screen[y][x+1]=='+')++cont;
  146.                                         ++flag;
  147.                                         if(screen[max_y][x]=='+')++cont;
  148.                                         if(screen[max_y][x-1]=='+')++cont;
  149.                                         if(screen[max_y][x+1]=='+')++cont;
  150.                                         ++flag;
  151.                                         if(screen[y+1][x]=='+')++cont;
  152.                                         if(screen[y+1][x-1]=='+')++cont;
  153.                                         if(screen[y+1][x+1]=='+')++cont;
  154.                                         ++flag;
  155.                         }              
  156.                 }
  157.         }
  158.        
  159.         //Riga max_y
  160.         if(y == max_y){
  161.                 if(x != (0 & max_x)){
  162.                         while(flag <= 3){
  163.                                                 if(screen[y][x-1]=='+')++cont;
  164.                                                 if(screen[y][x+1]=='+')++cont;
  165.                                                 ++flag;
  166.                                                 if(screen[0][x]=='+')++cont;
  167.                                                 if(screen[0][x-1]=='+')++cont;
  168.                                                 if(screen[0][x+1]=='+')++cont;
  169.                                                 ++flag;
  170.                                                 if(screen[y-1][x]=='+')++cont;
  171.                                                 if(screen[y-1][x-1]=='+')++cont;
  172.                                                 if(screen[y-1][x+1]=='+')++cont;
  173.                                                 ++flag;
  174.                         }
  175.                 }
  176.         }
  177.        
  178.         //Colonna 0
  179.         if(x == 0){
  180.                 if(y != (0 & max_y)){
  181.                         while(flag <= 3){
  182.                                         if(screen[y][max_x]=='+')++cont;
  183.                                         if(screen[y][x+1]=='+')++cont;
  184.                                         ++flag;
  185.                                         if(screen[y-1][max_x]=='+')++cont;
  186.                                         if(screen[y-1][0]=='+')++cont;
  187.                                         if(screen[y-1][1]=='+')++cont;
  188.                                         ++flag;
  189.                                         if(screen[y+1][max_x]=='+')++cont;
  190.                                         if(screen[y+1][0]=='+')++cont;
  191.                                         if(screen[y+1][1]=='+')++cont;
  192.                                         ++flag;
  193.                         }
  194.                 }
  195.         }
  196.        
  197.        
  198.         //Colonna max_x
  199.         if(x == max_x){
  200.                 if(y != (0 & max_y)){
  201.                         while(flag <= 3){
  202.                                         if(screen[y][max_x-1]=='+')++cont;
  203.                                         if(screen[y][0]=='+')++cont;
  204.                                         ++flag;
  205.                                         if(screen[y-1][max_x]=='+')++cont;
  206.                                         if(screen[y-1][max_x-1]=='+')++cont;
  207.                                         if(screen[y-1][0]=='+')++cont;
  208.                                         ++flag;
  209.                                         if(screen[y+1][max_x]=='+')++cont;
  210.                                         if(screen[y+1][max_x-1]=='+')++cont;
  211.                                         if(screen[y+1][0]=='+')++cont;
  212.                                         ++flag;
  213.                         }
  214.                 }
  215.         }
  216.        
  217.         //Tutto il resto       
  218.                 for(i=y-1; i<y+2;++i){
  219.                         for(j=x-1; j<x+2; ++j){
  220.                                 if(screen[i][j]=='+'){
  221.                                         ++cont;
  222.                                 }
  223.                         }
  224.                 }
  225.  
  226. return cont;
  227. }
  228.  
  229.  
  230. int main(){
  231. int x,y;
  232.  
  233.         printf("Inserisci i valori di Y (verticale) - MAX 30\n>");
  234.         scanf("%d", &y);       
  235.                 while(y>Y){
  236.                         printf("Errore. Valore eccessivo. Reimmettere MAX 30\n> ");
  237.                         scanf("%d", &y);
  238.                 }
  239.         printf("Inserisci i valori di X (orizzontale) - MAX 80\n>");
  240.         scanf("%d", &x);
  241.                 while(x>X){
  242.                         printf("Errore. Valore eccessivo. Reimmettere MAX 80\n> ");
  243.                         scanf("%d", &x);
  244.                 }
  245.  
  246.  
  247.         char newScreen[Y][X];
  248.  
  249.         char screen[Y][X]={
  250.         "   +                                       ",
  251.         "                                           ",
  252.         "                              +            ",
  253.         "                            + +            ",
  254.         "               ++         ++             ++",
  255.         "              +    +      ++             ++",
  256.         "   ++        +       +    ++               ",
  257.         "   ++        +    +  + +    + +            ",
  258.         "             +       +        +            ",
  259.         "              +    +                       ",
  260.         "               ++                          ",
  261.         };
  262.  
  263. /*
  264.         char screen[Y][X]={
  265.         "                                      ",
  266.         "        +  +                          ",
  267.         "       +                              ",
  268.         "       +   +                          ",
  269.         "       ++++                           ",
  270.         "                                      ",
  271.         "                                      ",
  272.         };
  273. */
  274.  
  275. int a=-1;
  276.  
  277. while(a!=0){
  278. printScreen(screen, x,y);
  279. printf("Print Ok --------------------------------------------------------------------------------------\n");
  280. epoch(newScreen, screen, x,y);
  281. printf("Epoch Ok ---------------------------------------------------------------------------------------\n");
  282. copyScreen(screen, newScreen, x,y);
  283. }
  284.  
  285.        
  286.        
  287.        
  288.  
  289.        
  290. return 0;
  291. }


PM Quote
Avatar
TheKaneB (Member)
Guru^2


Messaggi: 1792
Iscritto: 26/06/2009

Segnala al moderatore
Postato alle 13:22
Venerdì, 11/12/2009
non ho eseguito il codice, ma ad una prima analisi trovo una cosa stranissima...

Codice sorgente - presumibilmente C++

  1. int contaVicini(char screen[Y][X],int x,int y, int max_x, int max_y)



ha 5 parametri in input

mentre qui:
Codice sorgente - presumibilmente C/C++

  1. switch(contaVicini(old[i][j], max_x, max_y)){
  2.                 case 2:
  3.                     new[i][j]=old[i][j];
  4.                     break;
  5.                 case 3:
  6.                     new[i][j]= '+';
  7.                     break;
  8.                 default:
  9.                     new[i][j]= ' ';
  10.                     break;
  11.             }



gliene passi soltanto 3!

Possono accadere 2 cose, in teoria:
1 - Il compilatore si incaxxa come una bestia e non compila
2 - Il compilatore è magnanimo e se ne esce con un semplice warning.

Il secondo caso non va comunque ignorato, perchè gli ultimi 2 parametri, in questo caso max_x e max_y, sarebbero spazzatura nello stack, quindi andresti a toccare locazioni di memoria fuori dall'array, provocando un crash, un bug logico o altri danni assortiti. Il segmentation fault è un errore tipico, ti indica che hai tentato di accedere ad un segmento di memoria fuori dallo spazio assegnato alla tua virtual memory, quindi probabilmente da qualche parte si accede ad un elemento dell'array con indice superiore alla dimensione massima dell'array.

PM Quote