Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Vier gewinnt


VerdammtVerzweifelt - Di 19.01.10 15:34
Titel: Vier gewinnt
Hallo ihr Computerfanatiker!

Wir (Sarah und Julia) müssen im Rahmen unseres Informatikunterrichts mit Hilfe des Delphi-Programms (Delphi5) ein Spiel programmieren. Ausgewählt haben wir "Vier gewinnt". Wir beide haben leider absolut keine Ahnung von Programmiersprache, StringGrid und Co. und werden wohl nie ganz hinter den Sinn der Informatik steigen. Deshalb hoffen wir auf eure Hilfe!
Folgendes Problem:

Mittlerweile haben wir (zugegebenermaßen nicht ganz ohne die Hilfe unseres Informatiklehrers!) es geschafft, die Zellen in die wir klicken mit einem farbigen Kreis zu füllen. Doch wie ist es möglich das 2 Spieler immer abwechselnd an der Reihe sind. Bitte antwortet im Quelltext, da es uns nicht gelingt Anweisungen in "unserer" Sprache in Programiersprache zu übersetzen!

Wir hoffen auf eure Hilfe und Antwort!

Mit freundlichen Grüßen
Sarah und Julia

P.S: Bitte spart euch Bemerkungen wie: "Falsche Rubrik. Es müßte ja heißen "Macht bitte meine Hausaufgaben."


Gausi - Di 19.01.10 15:41

Hallo und :welcome: in der Entwickler-Ecke,

Dann zeigt doch am besten erst einmal, was ihr schon so habt. Dann kann man da vielleicht etwas passendes einbauen. :D


VerdammtVerzweifelt - Di 19.01.10 15:46

Das ist unser bisheriger Quelltext .. wie gesagt noch ziemlich am Anfang:


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:
Unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    StringGrid1: TStringGrid;
    procedure StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
      Rect: TRect; State: TGridDrawState);
    procedure StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;
      var CanSelect: Boolean);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}
{==============================================================================}
procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
  // wenn in der gerade gezeichneten Zelle eine 1 steht, dann zeichne dort einen grünen Kreis
  if StringGrid1.Cells[ACol,ARow] = '1' then
    begin
      StringGrid1.Canvas.Brush.Color := clGreen;
      StringGrid1.Canvas.Ellipse (Rect);
    end;
  // wenn in der gerade gezeichneten Zelle eine 2 steht, dann zeichne dort einen blauen Kreis
  if StringGrid1.Cells[ACol,ARow] = '2' then
    begin
      StringGrid1.Canvas.Brush.Color := clBlue;
      StringGrid1.Canvas.Ellipse (Rect);
    end;

end;
{==============================================================================}
procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol,
  ARow: Integer; var CanSelect: Boolean);
begin
  //wenn spieler 1 dannn schreibe 1
  // StringGrid1.Cells[ACol,ARow] := '1';
  // sonst schreibe 2

KEINE AHNUNG WIE DIE SPIELER ABWECHSELND ZUM ZUG KOMMEN!
HILF UNS BITTE.
end;
{==============================================================================}
end.


:'(

Erstmal ist es uns wichtig zu wissen, wie wir nun die Spieler abwechselnd zum Zuge kommen lassen können???

Moderiert von user profile iconGausi: Delphi-Tags hinzugefügt, Beiträge zusammengefasst.


Gausi - Di 19.01.10 15:55

Eine Idee: Den Spieler in einer Variable merken und bei Klick umsetzen, also:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
// oben bei der Deklaration von Form 1
 private
    { Private-Deklarationen }
    Spieler: Integer;

// weiter unten:

procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol,
  ARow: Integer; var CanSelect: Boolean);
begin
   if Spieler = 0 then
   begin
      // code für Spieler 0
      //...
      Spieler := 1// anderer Spieler ist dran
   end else
   begin
     // ...
     Spieler := 0;
   end;
end;


Delete - Di 19.01.10 15:59

Soweit sind wir in der Delphipraxis auch schon: http://www.delphipraxis.net/post1121988.html#1121988 ;)


guinnes - Di 19.01.10 16:05

user profile iconLuckie hat folgendes geschrieben Zum zitierten Posting springen:
Soweit sind wir in der Delphipraxis auch schon: http://www.delphipraxis.net/post1121988.html#1121988 ;)

Im Delphi-Treff [http://forum.delphi-treff.de/showthread.php?t=28221] gibts auch schon Antworten


Nersgatt - Di 19.01.10 16:07

Na super, dann können wir ja hier die Bemühungen einstellen. :autsch:
@Mädels: Bitte nächstes Mal sofort auf Crossposts hinweisen. :roll:


Delete - Di 19.01.10 16:07

@Guinnes: Warum ist der Thread bei euch noch nicht geschlossen? ;)


thepaine91 - Di 19.01.10 16:08

Ich wollt erst frage wo sie copy paste gemacht haben, da dies bei Codeabschnitten nicht so funktioniert und daher gleich zu sehen war. ^^

Mein Tipp versucht erstmal die bisherigen Tipps zu verstehen und dann Fragen zu stellen.
Und egal in wieviele Foren ihr geht es sind dort zum groß Teil die selben Leute wie in anderen und daher braucht ihr das nicht in jedes Forum das ihr findet zu posten.


guinnes - Di 19.01.10 16:22

user profile iconLuckie hat folgendes geschrieben Zum zitierten Posting springen:
@Guinnes: Warum ist der Thread bei euch noch nicht geschlossen? ;)

Machen wir in so einem Fall nicht mehr, gibt nur ne Verwarnung. ( Obwohl der Effekt wohl der gleiche sein wird :wink: )


VerdammtVerzweifelt - Mi 20.01.10 14:06

Keine Ahnung was ihr hier für Informatikerspecials und Verknüpfung zu anderen Foren habt.
Wir wollten einfach nur Hilfe von möglichst vielen Leuten, damit wir dahinter steigen und unser eigenen Spiel zusammen basteln können.


JoelH - Mi 20.01.10 14:28

habt ihr ds von gausi denn schon umgesetzt?


VerdammtVerzweifelt - Mi 20.01.10 14:51

Wir arbeiten nur jeden Dienstag an unserem Projekt und zuhause haben wir das Programm nicht auf dem Rechner.
Weitere Frage werden sich sicherlich nächsten Dienstag ergeben.
Aber wir werden erstmal versuchen das so umzusetzen.
Also es funktioniert auch im Delphi5?


Gausi - Mi 20.01.10 14:55

Ja, das sollte auch in Delphi 5 gehen. Das sind absolute Basis-Elemente der Sprache. :D


VerdammtVerzweifelt - Mi 20.01.10 15:45

Vielen Lieben Dank.
Weitere spannende Aufgaben erwarten euch nächsten Dienstag ;-)


VerdammtVerzweifelt - Di 09.02.10 14:40

Soooo, nun sind wir soweit & wollen unsere Spielsteine fallen lassen.
Egal in welches Feld der Spieler klickt: der Stein soll in dieser Spalte soweit runter fallen wie es geht.
4gewinnt eben ;-)


Nersgatt - Di 09.02.10 14:44

user profile iconVerdammtVerzweifelt hat folgendes geschrieben Zum zitierten Posting springen:
Soooo, nun sind wir soweit & wollen unsere Spielsteine fallen lassen.
Egal in welches Feld der Spieler klickt: der Stein soll in dieser Spalte soweit runter fallen wie es geht.
4gewinnt eben ;-)

Na dann viel Erfolg bei dieser spannenden Aufgabe.


VerdammtVerzweifelt - Di 09.02.10 14:49

Äääähm wir würden uns sehr über Hilfe freuen!!

---Moderiert von user profile iconNarses: Beiträge zusammengefasst---

Unsere Idee ist Folgende:

if y ungleich ymaximal
solange (zelle[x,y+1]=leer) and y-1 < ymaximal
zelle [x,y+1]=1
zelle [x,y]='' (leer)

soooo & wie kriegt man das nun in einen vernünftgen Algorithmus?


Webo - Di 09.02.10 16:04

"Wenn y ungleich dem maximalen y ist, dann soll, solange die Zelle [x, y+1] leer ist und y-1 kleiner als dem maximalen y ist, in die Zelle [x, y + 1] eine 1 reingeschrieben werden und die Zelle [x,y] leer sein" ... Aber x und y ändert ihr nicht, oder ?
Ich weiss ja nicht, wie genau ihr das gedacht hattet, aber wenn das so ist, würde ja die "solange"-Bedingung (unter Delphi auch while genannt) immer "aktiv" bleiben, wenn sie denn einmal erfüllt ist, also würde ewig die gleiche Zelle 1 beinhalten. Außer ihr ändert irgendwo noch x und y ... (Kann auch sein, dass ich etwas überlesen hab)

Für weitere Überlegungen wäre Euer PseudoCode mal ganz schnell übersetzt:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
if y <> ymaximal then
begin
  while ( StringGrid.Cells[x, y + 1] = '' ) and ( y - 1 < ymaximal ) do
  begin
    StringGrid.Cells[x, y + 1] := '1';
    StringGrid.Cells[x, y] := '';  
  end;
end;


Delete - Di 09.02.10 17:13

Ich frage mich gerade, wer hier eigentlich das Programm schreibt. :roll:


Webo - Di 09.02.10 17:31

user profile iconLuckie hat folgendes geschrieben Zum zitierten Posting springen:
Ich frage mich gerade, wer hier eigentlich das Programm schreibt.

Nachdem ich mir die CrossPosts mal komplett durchgelesen habe, geht es mir ähnlich ...


guinnes - Di 09.02.10 17:47

user profile iconLuckie hat folgendes geschrieben Zum zitierten Posting springen:
Ich frage mich gerade, wer hier eigentlich das Programm schreibt. :roll:

Na, Ihr. :?
Aber dafür kriegt ihr ja auch jede Woche neue, spannende Aufgaben :wink:


VerdammtVerzweifelt - Mo 15.02.10 16:51

Vielen Dank,
wir probieren den Code morgen aus.
Hoffentlich funktioniert es :-)


Jakob_Ullmann - Mo 15.02.10 20:35

user profile iconguinnes hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconLuckie hat folgendes geschrieben Zum zitierten Posting springen:
Ich frage mich gerade, wer hier eigentlich das Programm schreibt. :roll:

Na, Ihr. :?
Aber dafür kriegt ihr ja auch jede Woche neue, spannende Aufgaben :wink:


Weißt du, das ist eigentlich das Argument. :P


VerdammtVerzweifelt - Di 16.02.10 14:28

"Operator ist auf diesen Operandentyp nicht anwendbar"

& nun?

außerdem haben wir noch das Problem, dass wieder zwischen Spieler 1 & 2 gewechselt werden muss.


Moderiert von user profile iconGausi: Versehentliches Dreifach-Posting entfernt.


Jakob_Ullmann - Di 16.02.10 14:36

Regeln -> Pushen erst nach 24h erlaubt.

Die Fehlermeldung heißt grob, dass du einen Operator verwendet hast, der nicht zum Typ passt, wenn du z. B. versuchst, zwei Strings zu multiplizieren. Tritt meistens auf, wenn du z. B. irgendwo ein StrToInt() vergessen hast (oder einen Cast). Mit anderen Worten: zeig mal deinen Quellcode.

Wie zwischen den Spielern gewechselt werden muss, habt ihr doch nun mehr als genug gehört, oder? -> Quellcode


VerdammtVerzweifelt - Di 16.02.10 14:54

1. Dieses "pushen" (wie ihr es nennt) war nicht absichtlich um das mal klar zu stellen.

2. Die Fehlermeldung hat sich gegessen.. Wir haben das Problem behoben.
Allerdings hat sich ein neues eingestellt: Die Kugeln werden immer noch nicht fallen gelassen. (Quelltext von Webo zur Hilfe genommen) Haben auch versucht "LueckeVorhanden" mit einzubauen, aber es will einfach nicht klappen..


Bergmann89 - Di 16.02.10 15:00

Hey,

das liegt daran, dass Webo in seinem Quelltext vergessen hat das y weiterzuzählen. Also muss da noch ein inc(y) rein. Wo verrat ich aber nich, das bekommt ihr sicher selbst raus ;)

MfG Bergmann


guinnes - Di 16.02.10 15:21

user profile iconBergmann89 hat folgendes geschrieben Zum zitierten Posting springen:
Hey,
das liegt daran, dass Webo in seinem Quelltext vergessen hat das y weiterzuzählen. Also muss da noch ein inc(y) rein.

Das hatte Webo auch in seinem Text geschrieben, dass es nicht gehen kann, wenn man Y oder X nicht verändert


Bergmann89 - Di 16.02.10 15:29

sry, hatte mir nur den Code angeguckt :P


VerdammtVerzweifelt - Di 16.02.10 15:30

Haben gerade unseren Lehrer mit diesem Problem konfrontiert und der hat uns den selben "Tipp" gegeben. ;)


Webo - Di 16.02.10 15:37

user profile iconguinnes hat folgendes geschrieben Zum zitierten Posting springen:
Das hatte Webo auch in seinem Text geschrieben, dass es nicht gehen kann, wenn man Y oder X nicht verändert
Jo, hatte einfach nur den PseudoCode übersetzt ;-)


user profile iconVerdammtVerzweifelt hat folgendes geschrieben Zum zitierten Posting springen:
Haben gerade unseren Lehrer mit diesem Problem konfrontiert und der hat uns den selben "Tipp" gegeben. ;)

Das ihr Y nicht verändert ? Dann wisst ihr ja jetzt, was ihr "einfach" einbauen müsst ... (siehe Bergmann89)


ffgorcky - So 21.02.10 18:12

Also wenn ich Euer Problem jetzt richtig verstanden habe, dann möchtet Ihr Euren Stein immer noch fallen lassen.
Ich würde das ganze auch mit einem Timer-Event machen, mit dem Ihr dann das in etwa so schreibt (mit einem Intervall von 100):

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
procedure TimerLassFallenOnTimer(Sender:TObject);
begin
FallenZuLassenderStein.Top:=ZuFallenLassenderStein.Top+1;
if angekommen then
    TimerLassFallen.Enabled:=false;
end;

Damit das ganze so funktioniert, müsstet Ihr vorher eine Form-Variable deklarieren
also zum Beispiel so:

Delphi-Quelltext
1:
2:
var {die Deklaration der Form-Variablen}
     FallenZuLassenderStein:TImage;

Das mit dem Image wäre aus meiner Sicht die einfachste Möglichkeit, wie ihr Eure fallen zu lassenden "Steine" bauen könntet und farbig - z.B. mit Kreisen drauf - markieren.
Und ihr müsstet den Begriff "angekommen" natürlich mit einer boolschen Abfrage ersetzen, wie sie bei Euch passt.
Ihr müsstet dann natürlich auch vorher erst mal den Start-Punkt festlegen - das fände ich am einfachsten, indem ihr da auch Buttons hinbaut, die Ihr nur anclicken braucht und damit dann den Start-Punkt festlegt - also dann so:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
FallenZuLassenderStein:=new Image(Form4Gewinnt);
if spieler1GleichTrueSpieler2GleichFalse then //also wenn Spieler 1 dran ist:
      begin
      FallenZuLassenderStein.Picture.LoadFromFile('GelberStein.bmp');
      end;
else //also wenn Spieler 2 dran ist:
      begin
      FallenZuLassenderStein.Picture.LoadFromFile('RoterStein.bmp');
      end;
FallenZuLassenderStein.Left:=TButton(Sender).Left;
FallenZuLassenderStein.Top:=TButton(Sender).Top+10//oder so, damit er nicht direkt übereinander startet.
TimerLassFallen.Enabled:=true; //Damit der Stein auch "runterfliegt".


So, ich hoffe, dass ich hier nicht gerade "irgendwelchen Murks" erzähle - ich kann es leider im Moment wieder nicht nachprüfen.


Bergmann89 - Mo 22.02.10 01:17

Hey,

muss das Ganze den grafisch Sichtbar sein? Wenn nich, dann is deine Methode ser kompilziert. Ne einfache Whileschleife tuts auch. Bsp.: wenn das Feld als Array aufgebaut ist, oben links is (0,0) und jeweils den Index des Spielers enthält, der den Stein besitzt (0 wenn kein Stein, 1 bei Spieler 1, 2 bei Spieler 2). Dann is ne while-Schleife noch die einfachste Lsg:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
var Pos: TPoint; //Position wo der Stein Positioniert wurde
var j: Integer; //Schleifenvaraibale
var Feld: array[0..90..9of Byte; //SpielfeldArray (Breite*Höhe)

j := 0;
while (j < High(Feld[Pos.X])) and (Feld[Pos.X, Pos.Y] = 0do
  dec(Pos.Y);


Jetz enthält Pos die Koordinaten des am Boden liegenden Steins...

MfG Bergmann.

p.s.: Im 1. Codeblock Zeile 3 hast du dich verschrieben ;)


VerdammtVerzweifelt - Di 23.02.10 14:41

Wie ist es möglich ein MainMenu zu erstellen in dem Neues Spiel, Spielanleitung, Highscore usw. Enthalten sind ? :shock: :?!?:


Narses - Di 23.02.10 14:44

Moin!

bitte erstelle für jede deiner Fragen ein separates Topic, da die Diskussion mehrerer Fragen in einem Topic für gewöhnlich für Verwirrung und Durcheinander sorgt. Daher:
*geschlossen*

cu
Narses