Newsgroup: it.comp.lang.delphi
Titolo: Algoritmo Matrice

Salve ragazzi, ho una matrice 4x4 di tspeedbutton (creati a runtime).
Di questi tspeedbutton devo controllare il velore della proprietà visible
(true o false).
Vorrei in pratica che se clicco su uno mi dica il valore degli otto che lo
circondano (tranne agli angoli dove sono tre i bottoni che circondano quello
nell'angolo) e ai lati dove sono 5.
01 02 03 04
05 06 07 08
09 10 11 12
13 14 15 16
Per esempio nella "figura" sopra il 6, 7, 10 e 11 hanno vicino 8 caselle, il
2, 3, 8, 12, 14, 15, 5, 9 ne hanno 5 circostanti e 1, 4, 13, 16 ne hanno
solo 3.
Il mio problema è proprio capire se mi trovo su un bottone che ha 3, 5 o 8
circostanti e capire quali sono i circostanti.
Ovviamente non posso basarmi sul loro nome (sennò lo avrei già fatto) perchè
nella matrice non sono in ordine come in figura sopra ma sono sparsi (quindi
se l'1 si trova al centro non ha 3 tasselli circostanti ma 8, etc.)
Chi sa darmi una dritta per controllare in che posizione sono, cioè che mi
dia le coordinate x e y della posizione nella matrice?
Grazie.
-- 
Karletto
chiamac...@tiscalinet.it
http://www.carletto.cjb.net

 dia le coordinate x e y della posizione nella matrice?
Il metodo piu semplice potrebbe essere di assegnare al tag un valore
progressivo da 1 a 16.
Testandolo nell'evento che ti interessa dovresti poter ricavare facilmente
la posizione nella griglia.
Ciao.
Gianluca

Hai senz'altro due indici, uno di riga (i) e uno di colonna (j) che ti
dicono che elemento stai consideando
Inoltre dai che i e j vanno da 1 ad un massimo
Ora hai tutto!
Ci sono 3 casi:
1) i=1, j=1; i=1,j=max; i=max,j=1; i=max,j=max sono i 4 angoli e hai 3
quadrati intorno;
2) i=1,1<j<max; i=max,1<j<max; 1<i<max,j=1, 1<i<max,j=max e sono i 'lati'
con 5 quadrati attorno
3)  1<i<max, 1<j<max e sei in mezzo con 8 'vicini'
Fai sti test in degli if innestati e vai che č un amore
--
_________________________________________
Edmondo Di Tucci 
snar...@tin.it
guarda i miei lavori su: 
www.powernetsi.it/edmondo

 --
Era proprio questo che volevo evitare... Pensavo che esistesse una procedura
pronta che mi controllasse se si č sui "margini" della matrice oppure no.
Tutto questo perchč il mio prof. dice che dopo 3 if siamo nella merda
pura...
Cmq mi sa che alla fine lo mando a quel paese e lo faccio con gli if.
Mi ricordo i miei primi programmi dove misi 10 if per fare un
assegnazione...
Il codice era il seguente:
//---CODICE---//
Var
  a: array [1..10] of byte;
  x: byte;
Begin
If a[j]=1 then x:=1;
If a[j]=2 then x:=2;
If a[j]=3 then x:=3;
If a[j]=4 then x:=4;
If a[j]=5 then x:=5;
If a[j]=6 then x:=6;
If a[j]=7 then x:=7;
If a[j]=8 then x:=8;
If a[j]=9 then x:=9;
If a[j]=10 then x:=10;
End.
Mentre ovviamente bastava fare:
x:=a[j];
In quel caso gli ho dato ragione ma secondo me se 10 if in un programma
vanno messi per forza, come fa lui a dire che siamo nella merda?
Bho, ditemi voi.
Ciao
P.S. Se esiste una funzione che mi dice se sono su un bordo di una matrice
gradirei saperlo.
Ciao

Io intendevo solo 3 o 4 if innestati
Certo che quella fesseria dei 10 if...
Comunque a livello computazionale i confronti e le assegnazioni impiegano
(nella teoria) un tempo cmputazionale nullo (trascurabile), l'unica
diffioltà è nellamanutenzione del codice


circondano 
Mi ricorda il gioco "campo minato"... se cerchi in rete
qualceh clone con seorgenti forse la risposta si trova li'....
ciao
Morde.
morde [at] programmer [.] net

> Il mio problema è proprio capire se mi trovo su un bottone che ha 3,
5 o 8 circostanti e capire quali sono i circostanti. Ovviamente non
posso basarmi sul loro nome (sennò lo avrei già fatto) perchè nella
matrice non sono in ordine come in figura sopra ma sono sparsi (quindi
se l'1 si trova al centro non ha 3 tasselli circostanti ma 8, etc.) Chi
sa darmi una dritta per controllare in che posizione sono, cioè che mi
dia le coordinate x e y della posizione nella matrice? <<
Mi pare che i problemi siano 2:
a) i 16 oggetti sono in una matrice e possono pero' essere ordinati in
modo qualunque: vuoi sapere come trovare riga, colonna in cui si trova
l'oggetto i-esimo;
b) vuoi essere in grado, per ciascun oggetto, di avere una lista degli
adiacenti.
Lasciando perdere un attimo i TButton, mi pare ti possa essere utile una
cosa come:
type
  TTessera = class; // forward
  TScacchiera = class(TObject)
  private
    fTessere: TList;
    fSize: integer;
    fFreePos: TPoint;    // solo per il gioco del 15
  public
    constructor Create(Size: integer); // Size e' la dimensione
scacchiera
    constructor Random(Size: integer);
    constructor LoadPartita(aFile: TFilename);
    destructor Delete; override;
    function PosOfTessera(aTess: TTessera): TPoint;
    function VicinoA(aPos: TPoint; bPos: TPoint): boolean; overload;
    function VicinoA(aPos: TPoint; bTess: TTessera): boolean; overload;
    function VicinoA(aTess: TTessera; bPos: TPoint): boolean; overload;
    function VicinoA(aTess: TTessera; bTess: TTessera): boolean;
overload;
    function TesseraFromPos(aPos: TPoint): TTessera;
    procedure Muovi(aTess: TTessera; da, a: TPoint);
  end;
  TTessera = class(TObject)
  private
    fId: integer;
    fPosition: TPoint;
    fScacchiera: TScacchiera;
    procedure SetPostion(Value: TPoint);
  public
    constructor Create(Id: integer; aPoint: TPoint);
    destructor Delete; override; // in cui eventualmente staccarsi dalla
scacchiera
    property Position: TPoint read fPosition write SetPosition;
    property Id: Integer read fId;
  end;
una possibile implementazione di VicinoA:
// returns True if bPos is close to aPos;
function TScacchiera.VicinoA(aPos: TPoint; bPos: TPoint): boolean;
var hDist, vVist: integer;
begin
  hDist := (bPos.x - aPos.x) * (bPos.x - aPos.x);  // 1, 4, 9...
  vDist := (bPos.y - aPos.y) * (bPos.y - aPos.y);
  Result := (hDist + vDist) < 4;
end;
Da cui e' facile, ciclando su fTessere, determinare la lista di quelle
vicine a una qualunque.
(ovviamente, il modello e' piu' comodo per il gioco del 15 che per la
dama: il campo Id, infatti, e' stato introdotto per quello; come Muovi,
che dovrebbe sollevare un'eccezione se la nuova posizione non e'
valida).
Per il collegamento ai TButton puoi usare la proprieta' Tag.
Se proprio ti serve sapere se una tessera e' borderline o in un vertice:
function TScacchiera.IsXOnBorder(aTess: TTessera): boolean;
begin
  Result := (aTess.Position.x = 0) or (aTess.Position.x = fSize-1);
end;
function TScacchiera.IsYOnBorder(aTess: TTessera): boolean;
begin
  Result := (aTess.Position.y = 0) or (aTess.Position.y = fSize-1);
end;
function TScacchiera.IsVertex(aTess: TTessera): boolean;
begin
  Result := IsYOnBorder(aTess) and IsXOnBorder(aTess);
end;
Saluti
Paolo Arosio