![]() |
4gewinnt
Guten Tag allerseits,
ich bräuchte dringend hilfe beim programmieren von 4gewinnt (mit Shapes und Buttons). Leider versteh ich gerade nicht warum bei mir die Shapes sich nicht färben. Kann sich das jemand mal ansehen? Danke im vorraus:)
Code:
unit Unit1;
{$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls; type { TForm1 } TForm1 = class(TForm) Button1: TButton; Button10: TButton; Button2: TButton; Button3: TButton; Button4: TButton; Button5: TButton; Button6: TButton; Button7: TButton; Button8: TButton; Button9: TButton; Panel1: TPanel; Panel2: TPanel; S1: TShape; S10: TShape; S11: TShape; S12: TShape; S13: TShape; S14: TShape; S15: TShape; S16: TShape; S17: TShape; S18: TShape; S19: TShape; S2: TShape; S20: TShape; S21: TShape; S22: TShape; S23: TShape; S24: TShape; S25: TShape; S26: TShape; S27: TShape; S28: TShape; S29: TShape; S3: TShape; S30: TShape; S31: TShape; S32: TShape; S33: TShape; S34: TShape; S35: TShape; S36: TShape; S37: TShape; S38: TShape; S39: TShape; S4: TShape; S40: TShape; S41: TShape; S42: TShape; S5: TShape; S6: TShape; S7: TShape; S8: TShape; S9: TShape; Timer1: TTimer; procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure SelectS(col:integer;player:integer); private { private declarations } public { public declarations } arrayInt: array[1..6,1..7] of integer; list:array[1..42] of TShape; end; var Form1: TForm1; implementation {$R *.lfm} { TForm1 } procedure TForm1.Button2Click(Sender: TObject); begin end; procedure TForm1.Button3Click(Sender: TObject); begin close; end; procedure TForm1.Button4Click(Sender: TObject); var i,j,x:integer; begin SelectS(1,1); for i:=1 to 6 do for j:=1 to 7 do if arrayInt[i,j]=1 then list[i*j].Brush.Color:=clred else if arrayInt[i,j]=2 then list[i*j].Brush.color:=clblue; end; procedure TForm1.FormCreate(Sender: TObject); var i,j:integer; begin for i:=1 to 6 do for j:=1 to 7 do arrayInt[i,j]:=0; timer1.enabled:=true; timer1.Interval:=10; list[1]:=S1; list[2]:=S2; list[3]:=S3; list[4]:=S4; list[5]:=S5; list[6]:=S6; list[7]:=S7; list[9]:=S8; list[10]:=S9; list[11]:=S10; list[12]:=S11; list[13]:=S12; list[14]:=S13; list[15]:=S14; list[16]:=S15; list[17]:=S16; list[18]:=S17; list[18]:=S18; list[19]:=S19; list[20]:=S20; list[21]:=S21; list[22]:=S22; list[23]:=S23; list[24]:=S24; list[25]:=S25; list[26]:=S26; list[27]:=S27; list[28]:=S28; list[29]:=S29; list[30]:=S30; list[31]:=S31; list[32]:=S32; list[33]:=S33; list[34]:=S34; list[35]:=S35; list[36]:=S36; list[37]:=S37; list[38]:=S38; list[39]:=S39; list[40]:=S40; list[41]:=S41; list[42]:=S42; end; procedure TForm1.SelectS(col:integer;player:integer); //wählt bei buttonclick das shape aus, welches der player färbt. var i,x:integer; begin repeat i:=1; x:=0; if arrayInt[i,col] = 0 then begin arrayInt[1,col]:=player; x:=1; end; i:=i+1; until x=1 end; end. |
AW: 4gewinnt
hab dir leider noch keine noch nicht DIE antwort (edit: doch hab ihn, einfach weiter lesen und am besten diesen tipp hier auch befolgen :D) aber schau mal bei FormCreate wo du versuchst die shapes in das array zu speichern hast du paar mal nen kleinen fehler gemacht mit den zahlen z.B. da:
Delphi-Quellcode:
ich empfehle dir eine schleife zu machen, so kannst du nichts falsch machen, der code ist veil kleiner und übersichtlicher und du wiederholst dich nicht 42 mal :D
list[6]:=S6;
list[7]:=S7; list[9]:=S8; list[10]:=S9; .... list[16]:=S15; list[17]:=S16; list[18]:=S17; list[18]:=S18; list[19]:=S19; schau mal so, du kannst den namen der komponente auch über ein string suchen anstatt direkt das objekt an die arrray items zu übergeben:
Delphi-Quellcode:
du siehst also dafür brauchst du gerade mal 3-4 zeilen und falsch machen kannst du da fast nichts :D
for c := 1 to 42 do
begin // erklärung // nehmen wir an die schleife fängt gerade an also ist c = 1 !!!!! list[c] := (FindComponent('S'+IntToStr(c)) as TShape) // also da c = 1 ist setzen wir das erste element von dem array list... // zu dem komponenten welches wir mit dem namen und "FindComponent" suchen mit dem namen "S" und dann noch die zahl, wäre beim ersten durchlaufen der schleife also "S1". Nun müsst du noch angeben das diese komponente ein TShape ist und kein TButton oder ähnliches, machst du ganz einfach mit as TShape und am bestren ne klammer drum herum :) end; ---------------------------------------- achtung: habe gerade bemerkt das ich hier bei meinen beispielen die anzahl verkehrt gemacht habe verglichen zu dir, also i mit 7 und j mit 6, hab das bei der formel nochmal angemerkt aber hoffe du verstehst dann selbst was der fehler war :D Dann noch bei "Button4Click" scheint mir die berechnung der index falsch zu sein was auch der grund sein könnte warum nicht gefärbt wird
Delphi-Quellcode:
wenn du einfach multiplizierst kommst du ja rein theoretisch schon nicht mal auf alle zahlen, wie willst du z.B. oder 17 oder 31 (und noch viele andere) aus zwei ganzen zahlen multiplizieren? geht ja nicht :)
list[i*j].Brush.Color:=clred
und list[i*j].Brush.color:=clblue; also nehmen wir an dein feld ist so aufgebaut
Code:
1 2 3 4 5 6 7
1 x x x x x x x 2 x x x x x x x 3 x x x x x x x 4 x x x x x x x 5 x x x x x x x 6 x x x x x x x x = feld zahlen auf der linken seite sind deine i koordinate zahlen auf der rechten seite sind deine j koordinate wichtig ist das alle shapes auch in der richtigen reihenfolge sind damit das klappt also hier die oberen 2 reihen meines beispiel felds welches ich oben gezeichnet habe aber mit den namen anstatt den X 1 2 3 4 5 6 7 1 S1 S2 S3 S4 S5 S6 S7 1 S8 S9 .. .. .. .. .. <- geht weiter mit 10 11 12 13 14 ... 3 .. .. .. .. .. 16 17 18 19 20 21 22 und so weiter 4 geht so weiter... was du jetzt gemacht hast ist einfach i und j multiplizieren aber das stimmt ja nicht einfach so. die formeln müssten so aussehen:
Delphi-Quellcode:
so wird die i und j koordinaten korrent von den positionen zum index berechnet und das war der fehler bin mir ziemlich sicherlist[i*7+j +1].Brush.Color:=clred // mal 7 weil bei mir die i reihe 7 items hat, plus 1 weil du bei 1 mit dem zählen beginnst :D und list[i*7+j +1].Brush.color:=clblue; // mal 7 weil bei mir die i reihe 7 items hat, plus 1 weil du bei 1 mit dem zählen beginnst :D |
AW: 4gewinnt
Zitat:
Ob du weißt wofür H+ da ist, davon gehe ich mal nicht aus. Machst halt typische Anfängerfehler, die man immer bei Schulprojekten sieht. Falls es ein Schulprojekt ist: das Forum ist leider nicht dafür da, dass andere deine Hausaufgaben machen. |
AW: 4gewinnt
Zitat:
|
AW: 4gewinnt
Hallo Wega
du solltest dir überlegen, die Shapes dynamisch zu erzeugen (eventuell auch, ob du effektiv Shapes verwenden willst oder nicht besser selbst etwas zeichnen willst). Mit Shapes könntest du es so tun:
Delphi-Quellcode:
unit Unit95;
interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls; type TForm4Gewinnt = class(TForm) procedure FormCreate(Sender: TObject); procedure FormPaint(Sender: TObject); procedure ShapeMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure FormResize(Sender: TObject); private { Private-Deklarationen } FWerIstDran : integer; SColor : array[0..2] of TColor; FShapes : array[1..7,1..6] of TShape; FWerte : array[1..7, 1..6] of integer; public { Public-Deklarationen } procedure NeuesSpiel; procedure ZeigeSpielFeld; end; var Form4Gewinnt: TForm4Gewinnt; implementation {$R *.dfm} procedure TForm4Gewinnt.ZeigeSpielFeld; var feldgroesse, dx, size, br, ho, x, y: Integer; begin br := clientwidth div 7; ho := clientheight div 6; if br < ho then feldgroesse := br else feldgroesse := ho; size := round(0.8*feldgroesse); dx := (feldgroesse-size) div 2; for x := 1 to 7 do for y := 1 to 6 do begin FShapes[x,y].Width := size; FShapes[x,y].Height := size; FShapes[x,y].Left := (x-1)*feldgroesse+dx; FShapes[x,y].Top := (y-1)*feldgroesse+dx; FShapes[x,y].Brush.Color := SColor[FWerte[x,y]]; end; end; procedure TForm4Gewinnt.FormCreate(Sender: TObject); var x, y : integer; begin SColor[0] := clwhite; SColor[1] := clred; SColor[2] := clblue; for x := 1 to 7 do for y := 1 to 6 do begin FShapes[x,y] := TShape.Create(Self); FShapes[x,y].Parent := Self; FShapes[x,y].Shape := stCircle; FShapes[x,y].Tag := x*10+y; // Wir weisen jedem Shape eine Nummer zu FShapes[x,y].OnMouseDown := ShapeMouseDown; end; NeuesSpiel; end; procedure TForm4Gewinnt.FormPaint(Sender: TObject); begin ZeigeSpielFeld; end; procedure TForm4Gewinnt.FormResize(Sender: TObject); begin ZeigeSpielFeld; end; procedure TForm4Gewinnt.NeuesSpiel; var x, y : integer; begin for x := 1 to 7 do for y := 1 to 6 do FWerte[x,y] := 0; FWeristDran := 1; ZeigeSpielFeld; end; procedure TForm4Gewinnt.ShapeMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var zeile, spalte, nr : integer; begin if Sender is TShape then begin nr := ( Sender as TShape ).Tag; spalte := nr div 10; for zeile := 6 downto 1 do if ( FWerte[spalte,zeile] = 0 ) then begin FWerte[spalte,zeile] := FWerIstDran; if FWerIstDran = 1 then FWerIstDran := 2 else FWerIstDran := 1; ZeigeSpielFeld; break; end; end; end; end. ZeigeSpielFeld; Zeigt das Spielfeld neu an FormCreate Die Farben der Spielsteine werden gesetzt, die Shapes werden erzeugt; wir weisen dabei jedem Shape eine Nummer (Tag) zu. Tag nutzen wir weiter unten im ShapeMouseDown. NeuesSpiel wird aufgerufen FormPaint Wenn das Formular neu gezeichnet werden soll... FormResize Wenn der User die Formulargrösse ändert... NeuesSpiel Zurücksetzen des Spielfelds auf 0. Wählen, wer beginnt. Spielfeld anzeigen. ShapeMouseDown User klickt auf ein Shape. Wir bestimmen anhand der Tagnummer des angeklickten Shapes die Spalte, in welche geklickt wurde. Wir prüfen von unten nach oben, ob noch ein Feld frei ist. Wenn Ja, dann setzen wir den Spielstein, der andere Spieler ist dran, wir zeigen das Spielfeld an. Du kannst den Code 1:1 verwenden - Neues Projekt öffnen - Formname anpassen, unit Name anpassen - und weiter programmieren ;-). Du könntest zum Beispiel ein weiteres Shape W definieren. Wenn ein Spieler einen neuen Spielstein in Spalte S setzt, dann lässt du W in Spalte S von oben nach unten fallen. Wie erwähnt: Du könntest die ganze Sache ohne Shapes wesentlich schöner bauen. Aber eine gute Taktik ist sicher spannender. (Du weisst ja sicher, dass 4gewinnt schwach gelöst ist.) |
AW: 4gewinnt
Aber dann bitte nicht innerhalb der Methoden auf die globale Form-Variable zugreifen, sondern besser stattdessen "Self" benutzen.
|
Dieses Thema wurde am "20. May 2017, 23:38 Uhr" von "Luckie" aus dem Forum "Fragen / Anregungen zur DP" in das Forum "Object-Pascal / Delphi-Language" verschoben.
|
AW: 4gewinnt
Danke DH - hab's korrigiert.
|
AW: 4gewinnt
Und noch ein Tipp: Die Forensuche. Auf meine nonVCL Version weise ich jetzt mal besser nicht hin. Ach ja: soll das ganze auch eine KI bekommen? Ich hoffe mal nicht, denn das wäre etwas zu viel verlangt vom Lehrer, so es denn ein Schulprojekt ist.
|
AW: 4gewinnt
Zuerstmal vielen vielen dank an die Hilfestellungen. Michael II:Ich kann leider deine Vorlage nicht verwenden, da ich mit Lazarus arbeite(n muss) :/
Also hab ich an meinem ursprünglichen versucht weiterzuarbeiten. Nun kommt eine Fehlermeldung sobald ich auf meinen Button klicke (External:SIGSEGV) und es leitet mich nur zu einer stelle hin, zeigt aber nichts weiteres an.
Code:
list[i*7+j+1].Brush.Color:=clred
else if arrayInt[i,j]=2 then list[i*7+j+1].Brush.color:=clblue; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:20 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz