Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
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?
ciao, ci sono varie soluzioni al problema... una che mi viene in mente è questa:
Codice sorgente - presumibilmente C++
#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");
return0;
}
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).
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?
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)?
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).
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
non ho eseguito il codice, ma ad una prima analisi trovo una cosa stranissima...
Codice sorgente - presumibilmente C++
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++
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;
}
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.