Entwickler-Ecke

Sonstiges (Delphi) - einzelne Zellen im StringGrid vergleichen


Ischariot - Do 07.01.10 04:01
Titel: einzelne Zellen im StringGrid vergleichen
Hey.
Ich habe mich dazu entschlossen mich in diesem Forum zu registrieren, da ich schon häufig bei Probleme hier Rat gefunden habe.
Jetzt ist jedoch so, dass ich keinen Beitrag finden kann, der sich mit meinem Problem befasst oder ich hab keinen gefunden...
Aber nun zu meinem Problem.
Ich bin dabei ein Spiel zu programmieren, soweit so gut.
Es geht um das vielleicht bekannte Spiel "Bewejeled" in einer vereinfachten Ausführung.
Dem Programm soll es möglich sein, den Inhalt von den einzelnen Zellen zu überprüfen und 2 Felder zu tauschen, per Mausklick, falls dadurch 3 Steine der selben Farbe nebeneinander gelangen. Diese 3 Felder sollen dann gelöscht werden und durch die oben liegenden ersetzt werden wodurch erreicht wird, dass die Steine von oben runterfallen und oben neue eingefügt werden.
Ich stecke nun jedoch fest, ich habe es schon geschafft, dass die Steine zufällig in meinem StringGrid angeordnet werden, jedoch stehe ich jetzt auf dem Schlauch ouch! sitze jetzt schon was länger davor und es will mir einfach nicht in Kopf kommen, wie ich weiter machen muss...
Zunächst würde es mir schon reichen, wenn mir jemand beantworten könnte:
Wie erklär ich meinem Programm, wenn 3 Zellen nebeneinander mit dem gleichen Image gefüllt sind, dass er diese löschen soll und die von oben übernimmt.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Grids, ExtCtrls, StdCtrls;

type
  TForm1 = class(TForm)
    StringGrid1: TStringGrid;
    Image1: TImage;
    Image2: TImage;
    Image3: TImage;
    Image4: TImage;
    Edit1: TEdit;
    Label1: TLabel;
    Edit2: TEdit;
    Label2: TLabel;

    procedure FormCreate(Sender: TObject);
    procedure Image4Click(Sender: TObject);
    procedure StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
      Rect: TRect; State: TGridDrawState);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Steine: TBitmap;
  acounter, bcounter: integer;

implementation

{$R *.dfm}



procedure TForm1.FormCreate(Sender: TObject);
 begin
  Screen.Cursor := crHandPoint;        //Mauszeigerdesign verändern
  Image2.Picture.LoadfromFile('Play_.bmp');    //Playimage laden
  Image3.Picture.LoadFromFile('Options_.bmp');
  Image4.Picture.LoadFromFile('Quit_.bmp');    //Beendenimage laden
  acounter:=0;
 end;


procedure TForm1.Image4Click(Sender: TObject);
 begin
  close;                                       //schließen
 end;

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
   var e: integer;
    begin
     randomize;
     e:=random(6);
     Steine:=TBitmap.Create;
     Steine.LoadfromFile(InttoStr(e)+'.bmp');                     //Edelsteine als bmp laden
     stringgrid1.Canvas.Draw(Rect.Left, Rect.Top, (steine));     //StringGrid fülle
     inc(acounter);                                             //Zähler für Anzahl der Züge zählen
     Edit1.Text:=InttoStr(132-(acounter DIV 2));                       //Ausgabe Anzahl der Züge
     if Edit1.Text ='0' then begin
     ShowMessage('Spiel vorbei!');
     StringGrid1.Destroy;                                   //Spielfeld enfernen
     Image4.Destroy;
     Image2.Destroy;
     exit;
   end;
   end;

end.


Moderiert von user profile iconNarses: Quote- durch Delphi-Tags ersetzt


JoelH - Do 07.01.10 09:48

Grob ein Denkansatz:

Ausser zum Anfang, wo alle zellen geprüft werden müssen, kann es im weiteren Verlauf nur sein, dass sich dort Reihen bilden wo sich gerade etwas verschoben hat. Wenn du also zwei Zellen tauschst, dann hast du ja deren Koordinaten im Grid. Von diesen beiden Koordinaten aus musst du nun prüfen. Einfach nach links und Rechts in den Spalten durchschauen ob gleichen Farben da sind, über einen Zähler mitzählen wieviele gefunden wurden. Sind es 3+ dann diese Felder löschen und die darüberliegenden einfach "weiterkopieren" danach wieder prüfen, durch das verrutschen könen sich ja neue Farbreihen gebildet haben. Sind alle Felder geprüft und es wurden keine neuen Farbreihen gefunden hat der Spieler wieder Zugrecht.


Bergmann89 - Do 07.01.10 12:30

Hey,

ich würd das so machen:
mach dir n 2D-Array, was genau so groß is wie dein Spielfeld, das füllst du dann per zufall mit Zahlen von 0 bis (SteinAnzahl-1) (also bei dir von 0-5). Beim zeichnen kannst du dann einfach auf das Array zugreifen, da wo du jetzt das e := random(6) hast.

Dann würd ich die Folgenden Methoden anlegen:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
CheckStones(XPosition, YPosition), Ergebnis = Integer (Anzahl der berühten Steine)
  Ergebnis ist 1
  wenn es einen Stein links neben dem Aktuellen gibt, dann
    wenn der Stein links neben dem Aktuellen Stein der gleiche ist, dann
      erhöhe das Ergebnis um den RückgabeWert von CheckStones(Parameter des linken Steins)
  wenn es einen Stein rechts neben dem aktuellen gibt, dann
    [...]
END-CheckStones



Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
DeleteStones(XPosition, YPosition)
  setze den aktuellen Stein auf "kein Stein"
  wenn es einen Stein links neben dem Aktuellen gibt, dann
    wenn der Stein links neben dem Aktuellen Stein der gleiche ist, dann  
      DeleteStones(Paramter des linken Steins)    
  wenn es einen Stein rechts neben dem aktuellen gibt, dann
    [...]
END-DeleteStones



Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
NewStones
  alle Spalten zurchzählen
    alle Steine der Spalte von unten nach oben durchzählen
      wenn der Stein gleich "kein Stein" ist, dann 
  tausche den aktuellen Stein mit dem darüber

  alle Spalten zurchzählen
    alle Steine der Spalte durchzählen
      wenn der Stein gleich "kein Stein" ist, dann
    neuer Random-Stein  
END-NewStones

Mit CheckStones kannst du jetzt die beiden Tauschpartner prüfen und ggf löschen. Dann nur ncoh mit NewStones die Steine herabfallen lassen und neue erzeugen und fertig. Wenn du das jetzt so umsetz, sollte es funktionieren...

MfG Bergmann