Autor Beitrag
F34r0fTh3D4rk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5284
Erhaltene Danke: 27

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: So 06.06.10 11:40 
Ich sag immer: Logik, Daten und Darstellung trennen. Denn was du zunächst versucht hast, war die Logik über die Darstellung zu implementieren. Das geht zwar, macht in diesem Fall aber nicht viel Sinn. Man kann Domino komplett funktionierend ohne, bzw. unabhängig von der Darstellung entwickeln und dann die Darstellung über eine Schnittstelle einbauen. So muss man, wenn man sich für eine andere Darstellungsform entscheiden sollte (3D statt 2D, text-basiert statt grafisch), nur noch den Code für die Darstellung, aber nicht die eigentliche Logik des Spiels umschreiben.

Dazu vielleicht ganz hilfreich: Model View Controller (Für Domino vielleicht etwas übertrieben, aber hier wird das Prinzip deutlich)
und: Beobachter
Bergmann89
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1742
Erhaltene Danke: 72

Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
BeitragVerfasst: So 06.06.10 19:03 
Hey,

@F34r0fTh3D4rk: in gewisserweiße sind die Daten, Logik un Darstellung getrennt. Die Daten liegen alle in dem Array. Wenn der User eine Eingabe macht, bzw. wenn die KI einen Steni legen soll, werden die Daten im Array geändert (Logik) und zum Schulss greift die OnPaint-Methode des PaintBox auf das Array zu und zeichnet alles (Darstellung). Wozu würdest du den Observer einsetzten? Bsp.: Das der Datenbereich dem Observer sagt das sich die Daten geändert haben un der dann der Darstellung sagt, das neu gezeichnet werden muss?!

@galagher: für die KI (wenn man es so nennen kann) würd ich sowas wie nen BruteForce machen:
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
Punkt auf 0,0 setzen (oben links)
while not CheckDomino do
  drehe stein 
  wenn 4 mal gedreht wurde, dan...
    verschiebe Position um ein Feld nach rechts
    wenn Position auserhalb des spielfeldes, dann...
      setze X-Position auf 0
      setze Y-Position in die nächste Zeile


so würde die KI die Steine immer erst versuchen oben links anzulegen. Man könnte das ganze auch auf Random umbauen, da muss man dann aber noch paar Tests einbauen, dass das auch wirklich zum Ende kommt.

MfG Bergmann

_________________
Ich weiß nicht viel, lern aber dafür umso schneller^^
galagher Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2556
Erhaltene Danke: 45

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: So 06.06.10 20:18 
user profile iconF34r0fTh3D4rk hat folgendes geschrieben Zum zitierten Posting springen:
Ich sag immer: Logik, Daten und Darstellung trennen.
Das versuche ich bei jedem Programm, schaffe es aber nicht immer wirklich konsequent!

@Bergmann89:
Nochmals Dank! Einen Code nach diesem Beispiel werde ich einbauen und sehen, wie weit ich komme! Die Anzahl der Möglichkeiten ist ja nicht unbegrenzt, und daher werden Anweisungen nach deinem Vorschlag sicher auch in akzeptabler Zeit ausgeführt.

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19322
Erhaltene Danke: 1749

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 06.06.10 20:29 
user profile iconBergmann89 hat folgendes geschrieben Zum zitierten Posting springen:
warum man globale Variablen nur ur Nt verwenden sollte weiß ich eig auch nich geanz genau^^ Warscheinlich der Übersicht halber, bzw um Ressourcen zu sparen, denn globale Variablen belegen immer Speicher, Objekt-Variablen nur dann, wenn das Objekt daszu exestiert.
Damit hat das weniger zu tun, ist aber natürlich auch richtig.

Aber stell dir einmal z.B. ein dynamisch erstelltes Formular in einem Editor vor. Du erstellst davon jetzt zwei, weil zwei Dateien parallel geöffnet werden. So, jetzt schreibst du den Dateinamen aber in eine globale Variable. Davon gibt es aber nur eine. Wie willst du dadrin also zwei Dateinamen unterbringen?

Globale Variablen gehören eben nicht zu einem bestimmten Objekt, sondern zu der Unit, in der die Klasse, also der Konstruktionsplan der Objekte, steht. Dementsprechend darf man auch nicht versuchen objektbezogene Dinge darin abzulegen. Was zu einem Objekt, also einer von ggf. mehreren Instanzen der Klasse, gehört, gehört auch in die Klasse.

Das ist auch der Grund weshalb man nicht Form1.Caption oder so schreiben sollte sondern Self.Caption oder nur Caption. Denn sonst greift man ggf. plötzlich auf eine falsche oder nicht existierende Instanz eines Formulars zu. Und noch öfter passiert das bei eigenen Klassen, denn bei denen gibt es natürlich sehr oft mehrere Instanzen.

Zusätzlich sind globale Variablen nicht gerade übersichtlich, sagtest du ja schon, und objektorientiert schon gar nicht.
galagher Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2556
Erhaltene Danke: 45

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: So 06.06.10 20:53 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Aber stell dir einmal z.B. ein dynamisch erstelltes Formular in einem Editor vor.
Das war einmal einer meiner Anfangsfehler - plötzlich hat dar Editor glatt unter einem falschen Dateinamen gespeichert! Hier ist es mir seitdem klar. Ansonsten ist es wohl einfach Gewohnheit oder Bequemlichkeit. :oops:
Werde künftig versuchen, ohne globale Variablen auszukommen, gleich mal im Domino-Projekt!

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
galagher Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2556
Erhaltene Danke: 45

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: Mo 07.06.10 17:38 
Im Moment suche noch ich den Stein für das Programm aus. Wenn er irgendwo passt, funktioniert es, wenn nicht, rechnet sich das Programm den Speicher wund:
ausblenden volle Höhe 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:
var
  i, tmp: Integer;
begin
(*
Punkt auf 0,0 setzen (oben links)
while not CheckDomino do
  drehe stein
  wenn 4 mal gedreht wurde, dan...
    verschiebe Position um ein Feld nach rechts
    wenn Position auserhalb des spielfeldes, dann...
      setze X-Position auf 0
      setze Y-Position in die nächste Zeile
*)


 Domino.X := 0;
 Domino.Y := 0;
 while not CheckDomino(Domino) do
 begin
 //drehe stein
  for i := 0 to 3 do
  begin
    if Domino.Dir = diVert then begin
      tmp       := Domino.P1;
      Domino.P1 := Domino.P2;
      Domino.P2 := tmp;
      Domino.Dir := diHorz;
    end else Domino.Dir := diVert;
  end;

  //wenn 4 mal gedreht wurde, dan...
  //verschiebe Position um ein Feld nach rechts
  Inc(Domino.X);

  //wenn Position auserhalb des spielfeldes, dann...
  if Domino.X > Board.Width then
  begin
   Domino.X := 0;  //setze X-Position auf 0
   Inc(Domino.Y);  //setze Y-Position in die nächste Zeile
  end;
 end;

 //Und zeichne das Ganze!
 Board.Canvas.Draw(Domino.X * iStoneWidth, Domino.Y * iStoneWidth, imgStein.Picture.Graphic);
end;
 iStoneWidth, imgStein.Picture.Graphic);
end;

Wo ist / sind meine Fehler? Kann man aus mehreren möglichen Plätzen per Random einen auswählen? Das würde das Spiel interessanter machen.

//Edit: Es funktioniert auch dann nicht immer, wenn der Stein passt!

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
Bergmann89
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1742
Erhaltene Danke: 72

Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
BeitragVerfasst: Di 08.06.10 00:35 
Hey,

geh mal Schritt für Schritt mit dem Debuger durch. Der Sinn der Sache war ja, das abwechselnd geprüft und dann was geändert wird. Also müsste er nach jedem Drehen, einmal in den While-Kopf spingen, wo das CheckDomino steht.
Damit er die Schleife auch verlässt, wenn kein Stein passt, musst du gucken wann die Y Position außerhalb des Feldes ist und dann setzt du einfach ein break;, das beendet die Schleife.
Das mit dem random-Wert geht auch, dazu musst du nur alle Positionen des Feldes abschreiten (3 for-Schleifen: X, Y, Drehen) und gucken ob der Stein passt. wenn ja schreibst du ihn - ähnlich wie beim CheckDomino - in ein Array. Dazu musst du die CheckDomino-Funktion aber ändern, bzw. ne 2. machen, da die jetzige den Stein ja gleich hinlegt, und die neue soll ja nur gucken ob er passt. Dann hast du alle möglichen Stellen in dem Array un kannst dir eine raussuchen.

MfG Bergmann.

_________________
Ich weiß nicht viel, lern aber dafür umso schneller^^
galagher Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2556
Erhaltene Danke: 45

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: Di 08.06.10 17:42 
user profile iconBergmann89 hat folgendes geschrieben Zum zitierten Posting springen:
Der Sinn der Sache war ja, das abwechselnd geprüft und dann was geändert wird. Also müsste er nach jedem Drehen, einmal in den While-Kopf spingen, wo das CheckDomino steht.
Macht der Code ja, es klappt aber nicht richtig. ZB. legt wird der Stein immer dann horizontal hingelegt, wenn ich ihn zuvor drehe. Ist er vertikal, wird er vertikal gelegt. Passen zB. 5 Punkte, wenn diese unten sind, dann legt er den Stein nur dann ab, wenn ich ihm vorher die Punkte nach unten drehe. Irgendwie wirkt sich das Drehen nicht aus...

user profile iconBergmann89 hat folgendes geschrieben Zum zitierten Posting springen:
Damit er die Schleife auch verlässt, wenn kein Stein passt, musst du gucken wann die Y Position außerhalb des Feldes ist und dann setzt du einfach ein break;, das beendet die Schleife.
Ok, klar: if Domino.Y > Board.Height then break;

user profile iconBergmann89 hat folgendes geschrieben Zum zitierten Posting springen:
Das mit dem random-Wert geht auch
Solange es nicht mal so klappt, ist das vorläufig egal!

Ich habe also 2 Versionen gebastelt, beide funktionieren, aber eben nur wie oben beschrieben:
ausblenden volle Höhe 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:
//So: -----------------------------------------------------------------
 Domino.X := 0;
 Domino.Y := 0;

 repeat
  for i := 0 to 3 do
  begin
    if Domino.Dir = diVert then begin
      tmp       := Domino.P1;
      Domino.P1 := Domino.P2;
      Domino.P2 := tmp;
      Domino.Dir := diHorz;
    end else Domino.Dir := diVert;
  end;

  //wenn 4 mal gedreht wurde, dan...
  //verschiebe Position um ein Feld nach rechts
  Inc(Domino.X);

  //wenn Position auserhalb des spielfeldes, dann...
  if Domino.X > Board.Width then
  begin
   Domino.X := 0;  //setze X-Position auf 0
   Inc(Domino.Y);  //setze Y-Position in die nächste Zeile
  end;

 until (CheckDomino(Domino)) or (Domino.Y > Board.Height);



//Oder so: -----------------------------------------------------------------
 Domino.X := 0;
 Domino.Y := 0;

 while not CheckDomino(Domino) do
 begin
 //drehe stein
  for i := 0 to 3 do
  begin
    if Domino.Dir = diVert then begin
      tmp       := Domino.P1;
      Domino.P1 := Domino.P2;
      Domino.P2 := tmp;
      Domino.Dir := diHorz;
    end else Domino.Dir := diVert;
  end;

  //wenn 4 mal gedreht wurde, dan...
  //verschiebe Position um ein Feld nach rechts
  Inc(Domino.X);

  //wenn Position auserhalb des spielfeldes, dann...
  if Domino.X > Board.Width then
  begin
   Domino.X := 0;  //setze X-Position auf 0
   Inc(Domino.Y);  //setze Y-Position in die nächste Zeile
  end;
  if Domino.Y > Board.Height then break;
 end;

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
galagher Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2556
Erhaltene Danke: 45

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: Di 08.06.10 20:26 
Jetzt funktioniert es, aber es ist langsam, weil ich das Image mitdrehen muss. Habe versucht, einen Integer t zu verwenden und den Stein vor dem Zeichnen t-Mal zu drehen, das klappt aber nicht. Also muss ich etwas finden, das den gelichen Effekt hat wie die Prozedur Drehen90Grad.

Das Programm spielt jetzt und dreht und legt die Steine richtig! :lol: :D
ausblenden volle Höhe 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:
var
  i, n, t, tmp: Integer;
begin
(*
Punkt auf 0,0 setzen (oben links)
while not CheckDomino do
  drehe stein
  wenn 4 mal gedreht wurde, dan...
    verschiebe Position um ein Feld nach rechts
    wenn Position auserhalb des spielfeldes, dann...
      setze X-Position auf 0
      setze Y-Position in die nächste Zeile
*)


 Domino.X := 0;
 Domino.Y := 0;
 n := 0;
 while not CheckDomino(Domino) do
 begin
 //drehe stein
//  for i := 0 to 3 do
  begin
   Drehen90Grad(imgStein.Picture.Bitmap);
//   Inc(t);
    if Domino.Dir = diVert then begin
      tmp       := Domino.P1;
      Domino.P1 := Domino.P2;
      Domino.P2 := tmp;
      Domino.Dir := diHorz;
    end else Domino.Dir := diVert;
  end;

  Inc(n);

  if n = 3 then
  begin
  //wenn 4 mal gedreht wurde, dan...
  //verschiebe Position um ein Feld nach rechts
  Inc(Domino.X);
  n := 0;
//  t := 0;
  end;

  //wenn Position auserhalb des spielfeldes, dann...
  if Domino.X > Board.Width then
  begin
   Domino.X := 0;  //setze X-Position auf 0
   Inc(Domino.Y);  //setze Y-Position in die nächste Zeile
  end;
  if Domino.Y > Board.Height then break;
 end;

 //Und zeichne das Ganze!
// for i := 0 to t do Drehen90Grad(imgStein.Picture.Bitmap);
 Board.Canvas.Draw(Domino.X * iStoneWidth, Domino.Y * iStoneWidth, imgStein.Picture.Graphic);
end;

Das kann man aber sicher noch optimieren.

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Di 08.06.10 20:49 
Moin!

user profile icongalagher hat folgendes geschrieben Zum zitierten Posting springen:
Jetzt funktioniert es, aber es ist langsam, weil ich das Image mitdrehen muss. Habe versucht, einen Integer t zu verwenden und den Stein vor dem Zeichnen t-Mal zu drehen, das klappt aber nicht. Also muss ich etwas finden, das den gelichen Effekt hat wie die Prozedur Drehen90Grad.
Naja, die Images werden ja nicht jeweils mehrere MB haben, oder? :? Einfach 4 ImageListen nehmen, für jede Himmelsrichtung eine. :nixweiss:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
galagher Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2556
Erhaltene Danke: 45

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: Di 08.06.10 20:58 
user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
Naja, die Images werden ja nicht jeweils mehrere MB haben, oder? :? Einfach 4 ImageListen nehmen, für jede Himmelsrichtung eine. :nixweiss:Narses
Ich will nicht auch noch jeden Stein 4x im Programm haben, 1x genügt!
Elegant hat es ja user profile iconBergmann89 in seinem Programm gelöst, da wird jeder Stein aus wenigen Bildteilen sozusagen zusammengesetzt.

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Di 08.06.10 21:00 
Moin!

user profile icongalagher hat folgendes geschrieben Zum zitierten Posting springen:
Ich will nicht auch noch jeden Stein 4x im Programm haben, 1x genügt!
Du kannst ja beim Programmstart die 3 berechenbaren aus einer gespeicherten ableiten. :idea: Klar, muss man nicht 4x statisch ablegen. :nixweiss:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Bergmann89
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1742
Erhaltene Danke: 72

Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
BeitragVerfasst: Mi 09.06.10 13:24 
Hey,

es würde auch helfen, wenn man das Zeichnen, während der Suche der passenden Stelle einfach weg lässt ;) Also nur die Daten manipulieren und am Ende zeichnen, so sollte es schnell genug sein, das der User es kaum mitbekommt. Kleinen Schönheitsfehler hab ich noch gefunden: if Domino.Y > Board.Height then break; ist nich ganz richtig, da du ja bei 0 anfängst zu Zählen muss die Schleife beendet werden, wenn die Position größer oder gleich der Feldhöhe ist...

MfG Bergmann.

_________________
Ich weiß nicht viel, lern aber dafür umso schneller^^
galagher Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2556
Erhaltene Danke: 45

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: Mi 09.06.10 17:52 
user profile iconBergmann89 hat folgendes geschrieben Zum zitierten Posting springen:
es würde auch helfen, wenn man das Zeichnen, während der Suche der passenden Stelle einfach weg lässt ;) Also nur die Daten manipulieren und am Ende zeichnen
Wenn ich das Drehen während der Suche weglasse, wird der Stein falsch hingelegt! Habe schon versucht, je einen Integer für diVert und diHorz mitzählen zu lassen und danach, vor dem Zeichnen, den Stein entsprechend oft zu Drehen - klappt alles nicht. Die meisten Steine liegen dann falsch.

user profile iconBergmann89 hat folgendes geschrieben Zum zitierten Posting springen:
if Domino.Y > Board.Height then break; ist nich ganz richtig, da du ja bei 0 anfängst zu Zählen muss die Schleife beendet werden, wenn die Position größer oder gleich der Feldhöhe ist...

Also muss es heissen: if Domino.Y >= Board.Height then break; und auch if Domino.X >= Board.Width then?

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
Bergmann89
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1742
Erhaltene Danke: 72

Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
BeitragVerfasst: Mi 09.06.10 19:07 
Hey,

wieso sollte das mit dem nicht Zeichnen nicht gehen? Du hast doch, wenn die while-Schleife verlassen wird noch dein n, und das gibt an wie oft du die Image drehen musst, also einfach ne For-Schleife von 0 bis n-1 un da das Drehen90Grad rein. Danach bloß noch zeichnen. Fertig ;)
user profile icongalagher hat folgendes geschrieben Zum zitierten Posting springen:
Also muss es heissen: if Domino.Y >= Board.Height then break; und auch if Domino.X >= Board.Width then?
rischtisch :)

MfG Bergmann.

_________________
Ich weiß nicht viel, lern aber dafür umso schneller^^
galagher Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2556
Erhaltene Danke: 45

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: Mi 09.06.10 19:18 
Hallo!

user profile iconBergmann89 hat folgendes geschrieben Zum zitierten Posting springen:
wieso sollte das mit dem nicht Zeichnen nicht gehen? Du hast doch, wenn die while-Schleife verlassen wird noch dein n,
Das n wird aber nach je 4x Drehen wieder auf 0 gesetzt!

Nun möchte ich noch, dass das Programm aus mehreren Möglichkeiten eine auswählt.

Hab's jetzt so gelöst, läuft scnhell und korrekt:
ausblenden volle Höhe 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:
 while not CheckDomino(Domino) do
 begin
 //drehe stein
  if Domino.Dir = diVert then begin
     tmp       := Domino.P1;
     Domino.P1 := Domino.P2;
     Domino.P2 := tmp;
     Domino.Dir := diHorz;
   end else
   begin
    Domino.Dir := diVert;
    Inc(h);  //Zähler für horizontal
   end;

  {Zähler für Drehen erhöhen}
  Inc(n);

  if n = 3 then
  begin
   //wenn 4 mal gedreht wurde, dan...
   //verschiebe Position um ein Feld nach rechts
   Inc(Domino.X);
   n := 0;
  end;

  //wenn Position auserhalb des spielfeldes, dann...
  if Domino.X  >= Board.Width then
  begin
   Domino.X := 0;  //setze X-Position auf 0
   Inc(Domino.Y);  //setze Y-Position in die nächste Zeile
  end;
  if Domino.Y >= Board.Height then break;
 end;


 //Und zeichne das Ganze!
 {Den Stein 1x drehen, wenn er horizontal abgelegt werden soll}
 if Domino.Dir = diHorz then Drehen90Grad(imgStein.Picture.Bitmap);
 {Den Stein noch 3x drehen, wenn der Zähler h eine ungerade Zahl ist, dadurch}
 {wird er so gedreht, dass die Punktezahl auf der richtigen Seite ist.}
 if Odd(h) then
 begin
  Drehen90Grad(imgStein.Picture.Bitmap);
  Drehen90Grad(imgStein.Picture.Bitmap);
 end;

 {Den Stein zeichen}
 Board.Canvas.Draw(Domino.X * iStoneWidth, Domino.Y * iStoneWidth, imgStein.Picture.Graphic);

 {Den Stein (imgStein) ggf. wieder vertikal stellen}
 if Domino.Dir = diHorz then Drehen90Grad(imgStein.Picture.Bitmap);

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
Bergmann89
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1742
Erhaltene Danke: 72

Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
BeitragVerfasst: Mi 09.06.10 19:23 
Hey,

so geht das natürlich auch, aber im endeffekt is es das gleiche was ich grad gesagt hab^^ Wenn das Proggi dann eine random-Stelle auswählen soll, musst du den n eben mit speichern, wenn du dir das Array mit den möglichen Stellen zusammen bastelst. Musst du ja jetzt mit deinem h auch bloß machen.

MfG Bergmann.

_________________
Ich weiß nicht viel, lern aber dafür umso schneller^^
galagher Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2556
Erhaltene Danke: 45

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: Do 10.06.10 17:37 
Hallo!

user profile iconBergmann89 hat folgendes geschrieben Zum zitierten Posting springen:
Wenn das Proggi dann eine random-Stelle auswählen soll, musst du den n eben mit speichern, wenn du dir das Array mit den möglichen Stellen zusammen bastelst.
:nixweiss: Ok, ich habe vor, die Funktion CheckDomino um einen bool'schen Parameter zu erweitern: False bedeutet, es wird der erste Platz genommen, an dem der Stein passt, True bedeutet, es werden zuerst alle Möglichkeiten gesammelt und dann mit Random eine ausgewählt.

Also soll der Aufruf so aussehen, wenn zB. der Spieler einen Stein setzt: CheckDomino(Domino, False)
und so, wenn das Programm einen setzen soll: CheckDomino(Domino, True)

Kannst du mir Tipps geben, was ich an CheckDomino abändern muss? Ich denke, die Prüfung der angrenzenden Steine bleibt gleich, aber ich will ja nicht sofort etwas ins Array eintragen und True zurückgeben und damit den Stein schon ablegen, sondern erst alle Möglichkleiten erfassen, und erst dann ablegen.

ausblenden Delphi-Quelltext
1:
2:
  SetLength(DominoList, Length(DominoList) + 1); //Array um 1 Element erweitern
  DominoList[High(DominoList)] := d; //Stein in Letztes Element eintragen

Was muss ich hier ändern?

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
Bergmann89
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1742
Erhaltene Danke: 72

Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
BeitragVerfasst: Do 10.06.10 17:41 
Hey,

das ist eine schlechte Idee, ich würd's so machen: Das eintragen der Steine von CheckDomino in eine Extra Prozedur auslagern (z.B. PlaceDomino). dann Würd ich ne Prozedur machen, die alle Möglichkeiten durchprobiert, und wenn CheckDomino TRUE ist, dann wird ne Proezur aufgerufen, die die mögliche Position in das Array einträgt (z.B. AddPosiblePos). Am Ende kannst du dann mit random die Position bestimmten, mit PlaceDomino den Stein ablegen und mit Paint neu zeichnen...

MfG Bergmann

_________________
Ich weiß nicht viel, lern aber dafür umso schneller^^
galagher Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2556
Erhaltene Danke: 45

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: Do 10.06.10 19:05 
user profile iconBergmann89 hat folgendes geschrieben Zum zitierten Posting springen:
das ist eine schlechte Idee, ich würd's so machen: Das eintragen der Steine von CheckDomino in eine Extra Prozedur auslagern (z.B. PlaceDomino).
Das war einfach! :mrgreen:
Der ganze Rest nicht.

Ja, ich verstehe, was du meinst, ist ja auch verständlich, aber wie giesse ich das in Quellcode?

user profile iconBergmann89 hat folgendes geschrieben Zum zitierten Posting springen:
dann Würd ich ne Prozedur machen, die alle Möglichkeiten durchprobiert, und wenn CheckDomino TRUE ist, dann wird ne Proezur aufgerufen, die die mögliche Position in das Array einträgt (z.B. AddPosiblePos).
Jedesmal, wennn CheckDomino TRUE ist, soll genau was in welches Array eingetragen werden?
Also: Die Prozedur, die das tut, heisst AddPosiblePos, und sie trägt wo was ein? Dieses Array kann ja nicht DominoList sein?

user profile iconBergmann89 hat folgendes geschrieben Zum zitierten Posting springen:
Am Ende kannst du dann mit random die Position bestimmten, mit PlaceDomino den Stein ablegen und mit Paint neu zeichnen...
So in etwa:
ausblenden Delphi-Quelltext
1:
2:
3:
 i := -1;
 while i = -1 do
  i := Random(High(DominoPossiblePos));  //alles, was nicht -1 ist, ist eine Position


Nie wieder ein Programm, bei dem auch das Programm etwas tun soll! :motz:


//Edit:
Das zB. tut gar nichts:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure TForm1.CheckDominos(d: TDomino);
var
  x, y: Integer;
begin
 for x := 0 to Board.Width do
  for y := 0 to Board.Height do
   if CheckDomino(d) then
    memo1.Lines.Add('A');  //natürlich nur zum Testen!
end;

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!