Entwickler-Ecke
Sonstiges (Delphi) - Brauhce Hilfe beim Programmieren von schiffeversenken
4r4k1s - Mo 04.12.06 12:49
Titel: Brauhce Hilfe beim Programmieren von schiffeversenken
Ich brauche hilfe ich soll für die schule schiffe versenken programmieren ich habe aber keine ahnung wie ich das anstellen soll und meine abschlussnote hängt dvon ab.
Ich habe ca 200 pannels (2 spielfelder 10*10)
ein start und einen beenden button und eine spielanleitung.
Das einzigste was bisher geht ist der beenden knopf und die anleitung kann mir da wer weiterhelfen ??
greetz 4r4k1s
Moderiert von
Christian S.: Topic aus Wünsche, Anregungen & Kritik verschoben am Mo 04.12.2006 um 11:57
mkinzler - Mo 04.12.06 12:53
Zitat: |
ein start und einen beenden button und eine spielanleitung. |
Das ist ja schon was! :mrgreen:
Definiere mal genauer, womit du Probleme hast.
BTW. eine Musterlösung wird dir hier keiner geben.
Christian S. - Mo 04.12.06 12:58
Hallo,
bitte ändere den Titel des Topics, da er wenig über das eigentlich Thema verrät. Hier der entsprechende Absatz aus den
Richtlinien [
http://www.entwickler-ecke.de/richtlinien.html]:
1.2 Beiträge: |
Bitte formuliere den Betreff Deiner Beiträge so, dass andere Mitglieder anhand dieser bereits das eigentliche Thema festmachen können. Beiträge wie etwa "Eine Anfängerfrage" oder "Weiß jemand, wie das geht?" lassen den Leser im Unklaren darüber, was das Thema der Diskussion ist.[...] |
Einfach oben bei Deinem ersten Beitrag auf

klicken und den Titel ändern. Danke Dir!
Viele Grüße,
Christian S.
4r4k1s - Mo 04.12.06 13:02
Schiffe versenken
Schiffe versenken ist ein Spiel was jeder kennt
Sie spielen gegen einen Computergegner der Ihre Flotte zerstören will.
Abwechselnd schießen Sie und der Computer auf das jeweils feindliche Spielfeld um die Schiffe des Gegners zu versenken.
Ihr Spielfeld ist auf der linken Seite des Bildschirms und Sie müssen die Schiffe des Computers im rechten Feld suchen
Ist ein Schiff getrofen wird das feld rot makiert ist der Schuss in kein Ziel getroffen wird das feld weiß.
Wird ein Schiff versenkt so färbt sich das versenkte Schiff Schwarz.
Das Spielfeld ist 10 x 10 Felder groß und es gibt 5 schiffarten
Die Schiffgrößen sind wie folgt:
Flugzeugträger 5 Felder
Zerstörer 4 Felder
Kreuzer 3 Felder
U-Boot 2 Felder
Schnellboot 1 Feld
Ich wünsche viel Spaß beim Spielen
^^ das ist die spielanleitung und womit ich probleme habe ist so ziemlich alles ich weiß weder wie ich die schiffe auf die felder setzten soll noch wie ich die farben entsprechend änder bei treffer oder nicht treffer.
Ich weiß auch nicht wie ich die agnzen Pannels programmieren soll bin einfach ein blutiger anfänger
4r4k1s - Mo 04.12.06 13:10
ok ich versuche es mal :) wenn es nicht klappt habt ihr mich wieder am hals ;)
Popov - Mo 04.12.06 15:44
In welche Klasse gehst du? Wie viel Stunden hast du bereits Delphi? Was erwarten man von euch? Soll der Computer selbstständig Schiffe positionieren (senkrecht/wagerecht) und auch selbst deine Schiffe suchen? Denn wenn man es richtig macht, dann bracht man schon paar Stunden dafür. Und ich kann mir nicht vorstellen, daß man Anfängern eine komplizierte Aufgabe stellt.
4r4k1s - Mo 04.12.06 16:22
ich gehe in die 13te klasse vom berufskolleg opladen haben in der 12 angefangen mit delphi nur halt nicht solche programme in FORM sonder nur kleine console application sowas halt.
wir haben 90 min delphi / woche
nein will keinen computer gegner sollen 2 Spieler sein erstmal ads mit dem computer kann man ja nachträglich noch reinschreiben denke ich mal
Popov - Mo 04.12.06 16:34
Sollen die Schiffe senkrecht und waagerecht angeordnet werden oder reicht nur waagerecht?
4r4k1s - Mo 04.12.06 23:55
man soll einstellen können ob senkrecht oder waagerecht
Popov - Di 05.12.06 01:49
Ich hab das aus Spaß mal programmiert, da ich noch nie Schiffeversenken programmiert habe. Das ganze hat mich knapp eine Stunde gekostet und ich muß sagen, daß Panels die schlechteste alle Möglichkeiten ist. Vielleicht denkst du dir, daß es mit Panels einfacher ist, aber bei Panels mußt du 200 Objekte koordinieren, wobei sie auch noch in zwei Lager geteilt werden. Viel einfacher wäre es über zwei image Komponenten auf denen die Felder gezeichnet würden und die Mausposition über Berechnung die x/y ermittelt würde. Hört sich kompliziert an, aber 200 Panels zu managen ist komplizierter. Dementsprechend sieht auch der Code aus. Es ist eher zusammen geschußtert. Ich weiß nicht ob du es gebrauchen kannst, da ich hier und da mit paar Tricks gearbeitet habe und ich nicht weiß ob du das deinem Lehrer verkaufen kannst.
Ok, was macht dieses Programm? Als erstes brauchst du keine 200 Panels anzulegen. Das Programm macht es für dich. Das einzige was du brauchst sind zwei Panels auf einem LEEREN Formular (Form1):
Panel1 (Name: Panel1)
und
Panel2 (Name: Panel2)
Beide Panels sollten eine Höhe und Breite haben die bei einer Division durch 10 keine Nachkommastellen hat. Ich empfehle dir für beide Panele eine Höhe und Breite von je 300. Nach dem Start werden Panel1 und Panel2 mit je 100 Panelen gefüllt. Dann brauchst du noch ein Button. Beim Klick auf den Button werden auf beiden Feldern Schiffe angelegt. Da hier alles mit Text läuft wird Schiff welches aus 5 Feldern besteht durch die Zahlen 5 angezeigt, 4'er durch 4 usw. Beim Klick auf ein Feld das eine Zahl hat wird das Feld rot markiert. Sind alle Felder eines Schiffes rot, dann werden sie schwarz.
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: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls;
type TForm1 = class(TForm) Panel1: TPanel; Panel2: TPanel; Button1: TButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); private procedure PanelClick(Sender: TObject); procedure ErstelleFelder(Panel: TPanel; MatrixNr: Integer); procedure AufPanelMatrixAnzeigen(Panel: String; MatrixNr: Integer); public end;
type TSchiffeMatrix = record xy: array[0..9, 0..9] of Shortint; end;
var Form1: TForm1; Matrix: array[1..2] of TSchiffeMatrix;
implementation
{$R *.DFM}
procedure TForm1.PanelClick(Sender: TObject); var l, x, y, i, z: Integer; s: String; p: Byte; begin l := Length(TPanel(Sender).Name); s := TPanel(Sender).Name; x := StrToInt(s[l-1]); y := StrToInt(s[l]);
p := TPanel(Sender).Tag; if Matrix[p].xy[x, y] > 0 then begin TPanel(Sender).Color := clRed; Matrix[p].xy[x, y] := -Matrix[p].xy[x, y]; end;
for i := -1 downto -5 do begin z := 0;
for x := 0 to 9 do for y := 0 to 9 do if Matrix[p].xy[x, y] = i then inc(z);
if z = Abs(i) then for x := 0 to 9 do for y := 0 to 9 do if Matrix[p].xy[x, y] = -z then with TPanel(FindComponent('Panel'+IntToStr(p))) do TPanel(FindComponent('Panel'+IntToStr(p)+intToStr(x)+IntToStr(y))).Color := clBlack; end;
end;
procedure TForm1.ErstelleFelder(Panel: TPanel; MatrixNr: Integer); var x, y: Integer; h, w: Integer; begin w := Panel.Width div 10; h := Panel.Height div 10;
for y := 0 to 9 do for x := 0 to 9 do begin with TPanel.Create(Panel) do begin Parent := Panel; Width := h; Height := w; Left := x * Width; Top := y * Height; Name := TPanel(Panel).Name + IntToStr(x) + IntTostr(y); Caption := ''; Tag := MatrixNr; OnClick := PanelClick; end; end; end;
procedure SchiffZufaelligPositionieren(Schifflaenge: Integer; MatrixNr: Integer); var Gesetzt: Boolean; Neustart: Boolean; x, y, ix, iy, Richtung: integer; begin Randomize;
repeat Richtung := Random(1 + 1); Gesetzt := False; Neustart := False;
case Richtung of 0: begin x := Random(9 + 1 - Schifflaenge); y := Random(9 + 1);
for ix := x to x + Schifflaenge-1 do if Matrix[MatrixNr].xy[ix, y] <> 0 then Neustart := True; if Neustart then Continue;
for ix := x to x + Schifflaenge-1 do Matrix[MatrixNr].xy[ix, y] := Schifflaenge;
Gesetzt := True; end; 1: begin x := Random(9 + 1); y := Random(9 + 1 - Schifflaenge);
for iy := y to y + Schifflaenge-1 do if Matrix[MatrixNr].xy[x, iy] <> 0 then Neustart := True; if Neustart then Continue;
for iy := y to y + Schifflaenge-1 do Matrix[MatrixNr].xy[x, iy] := Schifflaenge;
Gesetzt := True; end; end; until Gesetzt;
end;
procedure TForm1.AufPanelMatrixAnzeigen(Panel: String; MatrixNr: Integer); var x, y: integer; sName: String; begin with TPanel(FindComponent(Panel)) do for x := 0 to 9 do for y := 0 to 9 do begin sName := Panel + IntToStr(x) + IntToStr(y);
if Matrix[MatrixNr].xy[x, y] = 0 then TPanel(FindComponent(sName)).Caption := '' else TPanel(FindComponent(sName)).Caption := IntToStr(Matrix[MatrixNr].xy[x, y]); end; end;
procedure PanelMatrix(Panel: String; MatrixNr: Integer); var x, y, Schifflaenge: integer; begin for x := 0 to 9 do for y := 0 to 9 do with Form1, TPanel(FindComponent(Panel)) do TPanel(FindComponent(Panel+IntToStr(x)+IntToStr(y))).Color := clBtnFace;
Randomize;
for x := 0 to 9 do for y := 0 to 9 do Matrix[MatrixNr].xy[x, y] := 0;
for Schifflaenge := 5 downto 1 do SchiffZufaelligPositionieren(Schifflaenge, MatrixNr);
Form1.AufPanelMatrixAnzeigen(Panel, MatrixNr); end;
procedure PanelMatrix1; begin PanelMatrix('Panel1', 1); end;
procedure PanelMatrix2; begin PanelMatrix('Panel2', 2); end;
procedure TForm1.FormCreate(Sender: TObject); begin ErstelleFelder(Panel1, 1); ErstelleFelder(Panel2, 2); end;
procedure TForm1.Button1Click(Sender: TObject); begin PanelMatrix1; Sleep(10); PanelMatrix2; end;
end. |
Ich empfehle dir es nicht mit Panelen zu machen, da du dann Chaos in Code hast. Ich werde dir hier nicht automatisch weiter helfen. Wenn ich da bin, bin ich da. Wenn nicht, dann nicht. Mal sehen ob die Anderen es verbessern oder was besseres liefern. Ich hoffe das Zweite.
alzaimar - Di 05.12.06 08:48
Als Alternative würde ich eine TDrawGrid, oder um es ganz einfach zu gestalten, ein TStringGrid vorschlagen.
Im TStringGrid schreibst Du 'X' für Deine Schiffe, 'O' für die des Gegners. ein '.' für abgefragte Zellen komplettiert dein minimalistisches Layout. Dann kannst Du dich zunächst nur um die Umsetztung des Spiels kümmern. Später tauschst Du das TStringGrid durch die Lösung von popov aus.
Noch besser wäre es allerdings, wenn Du GUI und Logik trennst: Programmiere das Spiel mit Hilfe eines Arrays:
Delphi-Quelltext
1:
| Array [0..9,0..9] Of Char; |
Wenn Ihr schon mit ordinalen Typen gearbeitet habt, kannst Du auch die verwenden:
Delphi-Quelltext
1: 2: 3:
| Type TZelle = (zeUnbekannt, zeWasser, zeSchiffRot, zeSchiffSchwarz); TSpielfeld = Array [0..9,0..9] of TZelle; |
4r4k1s - Di 05.12.06 17:44
wie sieht das aus beim stringgrid mit fraben kann cih da felder wo ein schiff ist mit rot versehen oder blau oder was anderes ??
Bzw. hab ich mir das so vorgestellt das ich das stringgrid zuerst komplett blau habe dann wo ich die schiffe platziert habe grün treffer rot fehlschüsse weiß
geht das auch ?? und das das dann nich X und O ist sondern die felder einfach ausgemalt werden
alzaimar - Di 05.12.06 17:49
Ein Stringgrid ist nur für Strings, also Text. Dafür ist es aber auch einfacher. Ich gehe mal davon aus, das Du Anfänger bist. Womit willst Du den anfangen? Zeichnen oder das Spiel programmieren?
freak4fun - Di 05.12.06 18:15
4r4k1s hat folgendes geschrieben: |
wie sieht das aus beim stringgrid mit fraben kann cih da felder wo ein schiff ist mit rot versehen oder blau oder was anderes ??
Bzw. hab ich mir das so vorgestellt das ich das stringgrid zuerst komplett blau habe dann wo ich die schiffe platziert habe grün treffer rot fehlschüsse weiß
geht das auch ?? und das das dann nich X und O ist sondern die felder einfach ausgemalt werden |
Zum Beispiel jede zweite Reihe Rot. ;)
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState); begin with Stringgrid1 do begin if ARow mod 2 = 0 then begin Canvas.Brush.Color := clRed; Canvas.TextRect(Rect, Rect.Left + 2, Rect.Top + 2, Cells[Acol, Arow]); end; end; end; |
MfG
freak
Popov - Di 05.12.06 18:20
@k&/$Nds87E&
Tut mit k&/$Nds87E&, aber wer solche komischen Nicks hat wie du, der muß es sich gefallen lassen, daß man ich auch mal als k&/$Nds87E& anspricht ;)
Ok 4r4k1s, jetzt mal Klartext. Wie man sieht bist du mit der Aufgabe überfordert. Also entweder hast du nicht aufgepaßt oder man hat euch eine zu schwere Aufgabe gestellt. Du stellst hier Fragen und wenn dir eine Lösung zu schwer ist, dann stellst du weiter die Fragen. Also gut, sag was du kannst, dann können wir vielleicht mit dem was du kannst bei der Lösung helfen.
4r4k1s - Di 05.12.06 22:13
was biste direkt so agro ?
nein die sache ist die aufgabe wurde uns nciht gestellt wir sollten uns ein spiel aussuchen um zu programmieren mir is halt schiffeversenken eingefallen hab nu aber gemerkt das das voll schwer ist ich komme da vorne und hinten nicht weiter.
was ich kann ..... weiß nicht genau zumindest der exit knopf geht schonmal und die spielbeschreibung habe ich auch in eine form 2 gepackt wo dann nen memo geöffnet wird aber das ist ja auch das einfachste von dem ganzen mist der da noch kommt denke ich
ConditionZero - Di 05.12.06 22:43
Weiß dein Lehrer die entscheidung von dir welches spiel du proggn willst, weil wenn nein würde ich dir einfach empfehlen auf was einfaches umzusteigen wie z.B. ein StringSpiel, also ein spiel komplett ohne grafikq gedings wo einfach ein bischen logik gefragt ist...:
eine idee hätte ich da müsste auf für ein anfänger gut machbar sein:
Man hat eine Zahl, nehmen wir mal die 35.
Dann hat man drei buttons auf einem steht ne eins auf dem 2. eine 2 und auf dem 3. eine 3
dann ist spieler eins dran: jetzt kann er per buttonklick entweder eine 1 eine 2 oder eine 3 auswählen nd von der aktuellen zahl also in dem fall 35 noch am anfang abzieht. dann spieler zwei usw.
spiel des ziels ist es das der gegenspieler eine Zahl klicken muss, sodass die nächste zahl 0 oder im negativen bereich liegt. am besten noch wenn man keine 1 zur möglichkeit des abziehens hat also dann so 3,5 und 7 wie du eben lustig bist.
LG
Popov - Mi 06.12.06 00:58
Ich hab aus Spaß es nochmal programmiert. Dieses mal habe ich zwei Image Komponenten genommen. Außerdem habe ich es auf drei Units geteilt.
Die erste ist die Formular Unit. In Create werden erstmal beide Felder gezeichnet. Nach Buttonklick werden die Felder gefüllt und gezeichnet. Dann nur noch in die Felder klicken.
Die zweite Unit beschäftigt sich nur mit der Matrix. Die Matrix ist eine 2'er Array bestehend aus 10 x 10 Feldern.
Die dritte Unit beschäftigt sich mit dem Zeichen der Felder. Hier wird alles in eine Bitmap gezeichnet. Auch wenn es nach 10 x 10 Buttons aussieht, alles ist gezeichent. Wo geklickt wurde, d.h. welches Feld, wird über eine Berechnung der X/Y Position des Mauszeigers gemacht.
Auch wenn sich alles jetzt kompliziert anhört, ist das ganze Programm normale Delphi Hausmannskost. Wenn man sich etwas damit beschäftigt und hier und da fragt wieso das so und so gemacht wurde, kann man das Programm verstehen. Ich habe es versucht sehr leicht lesbar zu programmieren. Auch du als Anfänger müßtest es nach einer Zeit verstehen.
Und unter der Betrachtung, daß ich bisher der einzige bin der ein Code geliefert, wäre es nett, wenn deine Reaktion auf ein Beispiel nicht >keine Reaktion< ist und du lediglich dann fragst ob es mit Stringgrid leichter geht. Denn dann kannst du den Rest alleine machen.
Hier die drei Teile des Programms nach Units.
Formular-Unit:
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:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls;
type TForm1 = class(TForm) Image1: TImage; Image2: TImage; Button1: TButton; procedure Button1Click(Sender: TObject); procedure Image1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure FormCreate(Sender: TObject); procedure Image2MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); private public end;
var Form1: TForm1;
implementation
{$R *.DFM}
uses uAllgemeinTeil, uFeld, uMatrix;
procedure TForm1.FormCreate(Sender: TObject); begin ZweiLeereAnfangsFelderZeichnen(Image1, Image2); end;
procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin FeldKlicksAuswerten(Image1.Picture.Bitmap, 1, x, y); end;
procedure TForm1.Image2MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin FeldKlicksAuswerten(Image2.Picture.Bitmap, 2, x, y); end;
procedure TForm1.Button1Click(Sender: TObject); begin SpielNeu(Image1, Image2);; end;
end. |
Allgemein-Teil
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:
| unit uAllgemeinTeil;
interface
uses extctrls;
procedure ZweiLeereAnfangsFelderZeichnen(Image1, Image2: TImage); procedure SpielNeu(Image1, Image2: TImage);
implementation
uses uMatrix, uFeld;
procedure ZweiLeereAnfangsFelderZeichnen(Image1, Image2: TImage); begin MatrixLeeren(1); MatrixLeeren(2);
with Image1.Picture do begin Bitmap.Width := Image1.Width; Bitmap.Height := Image1.Height; FelderNachMatrixZeichen(Bitmap, FELDER_X, FELDER_Y, True, 1); end;
with Image2.Picture do begin Bitmap.Width := Image2.Width; Bitmap.Height := Image2.Height; FelderNachMatrixZeichen(Bitmap, FELDER_X, FELDER_Y, True, 2); end; end;
procedure SpielNeu(Image1, Image2: TImage); begin BeideMatrixFelderMitSchiffenFuellen;
FelderNachMatrixZeichen(Image1.Picture.Bitmap, FELDER_X, FELDER_Y, True, 1); FelderNachMatrixZeichen(Image2.Picture.Bitmap, FELDER_X, FELDER_Y, True, 2); end;
end. |
Matrix-Unit:
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: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174:
| unit uMatrix;
interface
uses Windows;
procedure MatrixLeeren(MatrixNr: Integer); procedure FeldInVirtuellenZehnerMatrixErmitteln(var a: Integer; var b: Integer; x, y, BmpWidth, BmpHeight: Integer); procedure PruefenObSchiffGetroffenWurde(MatrixNr, MatrixX, MatrixY: Integer); function GesunkeneSchiffeErmitteln(MatrixNr: Integer): Boolean; procedure FuenfSchiffeInMatrixZufaelligPositionieren(MatrixNr: Integer); procedure BeideMatrixFelderMitSchiffenFuellen;
const FELDER_X = 15; FELDER_Y = 15;
type TSchiffeMatrix = record xy: array[0..FELDER_X-1, 0..FELDER_Y-1] of Shortint; end;
var Matrix: array[1..2] of TSchiffeMatrix;
implementation
procedure MatrixLeeren(MatrixNr: Integer); var x, y: Integer; begin for x := 0 to FELDER_X - 1 do for y := 0 to FELDER_Y - 1 do Matrix[MatrixNr].xy[x, y] := 0; end;
procedure FeldInVirtuellenMatrixErmitteln(var a: Integer; var b: Integer; x, y, BmpWidth, BmpHeight, FelderX, FelderY: Integer); begin a := (x * FelderX div BmpWidth) - 1; if ((x * FelderX) mod BmpWidth) > 0 then Inc(a);
b := (y * FelderY div BmpHeight) - 1; if ((y * FelderY) mod BmpHeight) > 0 then Inc(b); end;
procedure FeldInVirtuellenZehnerMatrixErmitteln(var a: Integer; var b: Integer; x, y, BmpWidth, BmpHeight: Integer); begin FeldInVirtuellenMatrixErmitteln(a, b, x, y, BmpWidth, BmpHeight, FELDER_X, FELDER_Y);; end;
procedure PruefenObSchiffGetroffenWurde(MatrixNr, MatrixX, MatrixY: Integer); begin if Matrix[MatrixNr].xy[MatrixX, MatrixY] > 0 then Matrix[MatrixNr].xy[MatrixX, MatrixY] := -Matrix[MatrixNr].xy[MatrixX, MatrixY]; end;
function GesunkeneSchiffe(MatrixNr, FelderX, FelderY: Integer): Boolean; var i, x, y, z: Integer; begin for i := -1 downto -5 do begin z := 0;
for x := 0 to FelderX - 1 do for y := 0 to FelderY - 1 do if Matrix[MatrixNr].xy[x, y] = i then inc(z);
if z = Abs(i) then begin for x := 0 to FelderX - 1 do for y := 0 to FelderY - 1 do if Matrix[MatrixNr].xy[x, y] = -z then Matrix[MatrixNr].xy[x, y] := Matrix[MatrixNr].xy[x, y] -10; end; end;
Result := False; end;
function GesunkeneSchiffeErmitteln(MatrixNr: Integer): Boolean; begin Result := GesunkeneSchiffe(MatrixNr, FELDER_X, FELDER_Y); end;
procedure EinSchiffInMatrixZufaelligPositionieren(FelderX, FelderY: Integer; Schifflaenge: Integer; MatrixNr: Integer); var Gesetzt: Boolean; Neustart: Boolean; x, y, x2, y2, Richtung: integer; begin Randomize;
repeat Richtung := Random(1 + 1); Gesetzt := False; Neustart := False;
case Richtung of 0: begin x := Random((FelderX - 1) + 1 - Schifflaenge); y := Random((FelderY - 1) + 1);
for x2 := x to x + Schifflaenge-1 do if Matrix[MatrixNr].xy[x2, y] <> 0 then Neustart := True; if Neustart then Continue;
for x2 := x to x + Schifflaenge-1 do Matrix[MatrixNr].xy[x2, y] := Schifflaenge;
Gesetzt := True; end; 1: begin x := Random((FelderX - 1) + 1); y := Random((FelderY - 1) + 1 - Schifflaenge);
for y2 := y to y + Schifflaenge-1 do if Matrix[MatrixNr].xy[x, y2] <> 0 then Neustart := True; if Neustart then Continue;
for y2 := y to y + Schifflaenge-1 do Matrix[MatrixNr].xy[x, y2] := Schifflaenge;
Gesetzt := True; end; end; until Gesetzt; end;
procedure FuenfSchiffeInMatrixZufaelligPositionieren(MatrixNr: Integer); var Schifflaenge: integer; begin MatrixLeeren(MatrixNr);
for Schifflaenge := 5 downto 1 do EinSchiffInMatrixZufaelligPositionieren(FELDER_X, FELDER_Y, Schifflaenge, MatrixNr); end;
procedure BeideMatrixFelderMitSchiffenFuellen; begin FuenfSchiffeInMatrixZufaelligPositionieren(1); Sleep(100); FuenfSchiffeInMatrixZufaelligPositionieren(2); end;
end. |
Grafik-Unit:
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: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98:
| unit uFeld;
interface
uses Graphics, Dialogs;
procedure FelderNachMatrixZeichen(Bitmap: TBitmap; xm, ym: Integer; Cl3D: Boolean; MatrixNr: Integer); function FeldKlicksAuswerten(Bitmap: TBitmap; MatrixNr, x, y: Integer): Boolean;
implementation
uses uMatrix;
procedure EinFeldZeichen(Bmp: TBitmap; w, h: Integer; Col: TColor; Cl3D: Boolean); begin Bmp.Width := w; Bmp.Height := h; with Bmp.Canvas do begin Brush.Color := Col; Brush.Style := bsSolid;
if not Cl3D then begin Pen.Color := clBlack; Rectangle(0, 0, w, h); end else begin FillRect(ClipRect); Pen.Color := $00454545; MoveTo(w-1, 0); LineTo(w-1, h-1); MoveTo(0, h-1); LineTo(w, h-1); Pen.Color := clWhite; MoveTo(0, 0); LineTo(w, 0); MoveTo(0, 0); LineTo(0, h); end; end; end;
procedure FelderNachMatrixZeichen(Bitmap: TBitmap; xm, ym: Integer; Cl3D: Boolean; MatrixNr: Integer); var w, h, x, y: Integer; a: Shortint; Bmp: TBitmap; begin w := Bitmap.Width div xm; h := Bitmap.Height div ym;
for x := 0 to xm - 1 do for y := 0 to ym - 1 do begin Bmp := TBitmap.Create; try a := Matrix[MatrixNr].xy[x, y];
case a of 0: EinFeldZeichen(Bmp, w, h, clBtnFace, Cl3D); 1: EinFeldZeichen(Bmp, w, h, $00FF8080, Cl3D); 2: EinFeldZeichen(Bmp, w, h, $00C08000, Cl3D); 3: EinFeldZeichen(Bmp, w, h, $00FF8000, Cl3D); 4: EinFeldZeichen(Bmp, w, h, $00C08080, Cl3D); 5: EinFeldZeichen(Bmp, w, h, clBlue, Cl3D); -5..-1: EinFeldZeichen(Bmp, w, h, clRed, Cl3D); -15..-11: EinFeldZeichen(Bmp, w, h, clBlack, Cl3D); end; Bitmap.Canvas.Draw(x * w, y * h, Bmp); finally Bmp.Free; end; end; end;
function FeldKlicksAuswerten(Bitmap: TBitmap; MatrixNr, x, y: Integer): Boolean; var a, b: Integer; begin FeldInVirtuellenZehnerMatrixErmitteln(a, b, x, y, Bitmap.Width, Bitmap.Height); PruefenObSchiffGetroffenWurde(MatrixNr, a, b); Result := GesunkeneSchiffeErmitteln(MatrixNr); FelderNachMatrixZeichen(Bitmap, FELDER_X, FELDER_Y, True, MatrixNr); end;
end. |
Wie schon in der ersten Antwort gesagt, ist es nicht das komplette Programm. Es ist nur die Engine. Das drumherum usw. mußt du eventuell noch programmieren.
//EDIT:
Drei kleine Änderungen: zuerst zwei Matrix und Grafik Prozeduren in die dafür vorgesehene Units verschoben. Da passen die besser hin. Dann noch eine Allgemein-Unit erstellt um wichtige Prozeduren und Funktionen gesondert anbieten zu können. Somit ist die Haupt-Unit ziemlich leer geworden und dient nur noch für Ereignisse. Zumindest ist es so übersuchtlicher.
Jetstream - Mi 06.12.06 03:25
Popov hat folgendes geschrieben: |
Und unter der Betrachtung, daß ich bisher der einzige bin der ein Code geliefert, wäre es nett, wenn deine Reaktion auf ein Beispiel nicht >keine Reaktion< ist und du lediglich dann fragst ob es mit Stringgrid leichter geht. Denn dann kannst du den Rest alleine machen. |
Du solltest nicht zu viel Dank erwarten. Das hier ist wieder der typische "Hilfe Hilfe ich brauch ganz schnell meine Hausaufgaben fertig in 1a Qualität sonst fall ich durch" Thread. Ihr werdet noch nen ganzen Tag aneinander vorbeireden, du wirst dann genervt das fertige Programm hochladen, er wird Danke sagen und es unverändert abgeben.
Wie wärs, wenn du keinen fertigen Quelltext anbietest, sondern eher ein paar nützliche Links, wo er sich das benötigte Wissen selbst zusammensuchen kann? Gibt doch genügend Topics im Forum übers Zeichnen mit Canvas.
hansa - Mi 06.12.06 04:19
4r4k1s hat folgendes geschrieben: |
was biste direkt so agro ?
nein die sache ist die aufgabe wurde uns nciht gestellt wir sollten uns ein spiel aussuchen um zu programmieren mir is halt schiffeversenken eingefallen... |
Als ca. 18-jähriges Roh-Weichei sollte man auch besser gar nicht erst fragen. 8) Nicht aussprechbare oder wie hier schwer merkbare/buchstabierbare "coole" Hacker-Nick-Names : selber Schuld. Habe einen wie Dich auch in der Obhut (11. Klasse Gymn.). Der käme allerdings nie auf die Idee mich in die Nähe der Landwirtschaftspolitik als Agrarheini zu stellen. :mrgreen:
Zum Thema : Schiffe versenken ist IMHO schon zu kompliziert. Popov hat es jetzt zweimal ziemlich komplett programmiert. Ohne Erfolg. :mrgreen: Für den Fragesteller wohlgemerkt. Zum Dank erhält er dann von dem noch Beschwerden. Er soll sich ein leichteres Spiel ausdenken. Oder eigenes Spiel. Wer zuerst zusammen die 6 würfelt, der hat gewonnwn. Bei 3 Würfeln oder so. Das könnte auch im Pisa-Zeitalter gelingen. 8)
Popov - Mi 06.12.06 11:50
@Jetstream und hansa
Das Spiel ist noch nicht fertig, denn es ergibt keinen Sinn zwei Felder zu sehen in dem man alle Schiffe sieht ;) Aber es ist eine Engine mit der man das Spiel programmieren kann. Sie macht die internen Berechnungen, sie reagiert auf Klicks, sie wertet aus und erkennt ob Schiffe getroffen wurden, sie zeichnet alles. Was allerdings noch fehlt, daß ist der Sinn des Spiels, d.h. es muß noch zum Spiel gemacht werden. Den Teil werde ich nicht programmieren. Und wenn er ein richtiges Spiel haben will, dann hat er noch etwas zu programmieren. Nur ich fürchte, daß auch das zu schwer für ihn ist.
4r4k1s - Mi 06.12.06 14:00
Ersteinmal danke für die vielen antworten
und zu dem spiel ja mein lehrer weiß das leider schon und wechseln dürfen wir auch nicht soweit ich weiß.
Und nein will kein komplettes games hier haben ich will das scon auch bissl selber dran arbeiten ich versuche gearde die ganzen befehle die in dem quelltext stehen zu verstehen und was die bewirken.
Zu meinem NICK name mein Nick Name ist Arakis in JEDEM forum da der hier vergeben war bin ich halt 4r4k1s ist Arakis in zahlen geschrieben is halt kein name auf die schnelle eingefallen
greetz Arakis (4r4k1s)
Popov - Mi 06.12.06 18:04
Kleiner Tipp am Rande. Wie du siehst habe ich in der zweiten Version die Grafik und Matrix vom Rest getrennt. Somit kann man sehr schön sehen welchen Anteil der jeweilige Part am Programm hat. Und falls du immer noch mit dem Gedanken Spiels ob es mit Buttons, Grids oder Panels leichter ist, guck dir vorher die Unit uMatrix an. Egal womit du das Spiel machst, ein Matrix Teil (also ein Teil der alles auswertet) wirst du immer brauchen. Und so wie es aussieht ist es der größte Teil des Programms. Der Rest ist der Grafik Teil der lediglich alles zeichnet. Das ist kaum der Rede wert.
Mein Vorschlag ist also: grübele nicht weiter nach womit du es machst. Der sichtbare Teil ist bei Images nur zwei Prozeduren groß. Das wirst du mit nichts unterbieten können. Also fange mit Analyse der uMatrix Unit an, dann uFeld und dann den Rest.
ConditionZero - Mi 06.12.06 19:48
Ehrlich gesagt finde ich das ein bisschen kompliziert für eien Anfänger,
da selbst wenn er es versteht er es immer noch seinem Lehrer präsentieren muss (glaub ich zumidest mal ^^)
Also wenn ich da der Lehrer weär hätte ich schon so meine Zweifel, dass das selber geproggt ist....
coder62 - Mi 06.12.06 23:25
als anfänger hätte ich defintiv tic tac toe genommen, das macht kaum arbeit und ist auch nicht wirklich schwer.
und kenne das aus meiner schulzeit von wegen programmieren im unterricht, da lernt man im grunde genommen so gut wie gar nix. in der regel sind meist kleinere projekt für die bewertung auch besser, um so grösser es wird um so mehr findet ne lehrer nur zum meckern und die note sinkt. da kann es schnell passieren, das jemand mit ne mini projekt ne 1 kriegt und jemand mit ne riesenprojekt und viel mühe reingesteckt ne 4 z.b.
sind meine eigenen erfahrungswerte.
Popov - Do 07.12.06 22:24
Ich glaube auch, daß er damit nicht klar kommt. In der Zwischenzeit hätten schon zig Verständnisfragen kommen müssen. In der Zwischenzeit könnte er den Code schon verstehen können. Aber ich glaube er versucht jetzt Plan B. Plan B ist, wenn man etwas nicht versteht, irgendwo anders unter einem anderen Namen nochmal die gleiche Frage zu stellen und zu hoffen, daß die nächste Antwort einfacher ausfallen wird ;)
4r4k1s - Fr 08.12.06 16:17
nein stelle nie 2 mal die gleichen fragen ich trete ma mit meinem lehrer in verhandlung ob ich was anderes machen kann das ich da net kla komme.
Erstmal danke für eure hilfe war sehr hilfreich ich versuche es nochmal und das mit der martix verstehe ich :)
Ich tue mein bestes mehr kann ich nicht machen wenn das nicht hinhaut muss ich mir was anderes überlegen.
Nochmal danke für eure hilfe ich denke mal ihr habt mich nicht das letzte mal hier gesehen
greetz Arakis
4r4k1s - Mi 13.12.06 17:24
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| var
schiffe :array [1..200] of tpanel;
procedure TForm1.button1click (sender: tobject); var i:integer begin for i:= 1 to 10 do begin schiffe [i] :=tpanel.create(self); schiffe[i].top:=10+20*i; schiffe[i].color:=clred; schiffe[i].parent:= self end; end. |
so habe ich das bisher gemacht damit habe ich gaaaantz viele pannels erzeugt beim klick auf start nur wie bekomme ich das hin das 2 Felder von 10 mal 10 mannels rauskommen ??
Bei den befehlen oben gehen die nur in einer reihe nach unten.
Greetz Arakis
Moderiert von
Christian S.: Delphi-Tags hinzugefügt
4r4k1s - So 24.12.06 03:06
*up*
Narses - So 24.12.06 03:43
Moin!
4r4k1s hat folgendes geschrieben: |
stelle nie 2 mal die gleichen fragen |
4r4k1s hat folgendes geschrieben: |
*up* |
:zwinker: ;)
Du brauchst eine verschachtelte Schleife, so wird das nix:
4r4k1s hat folgendes geschrieben: |
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| var schiffe :array [1..200] of tpanel;
procedure TForm1.button1click (sender: tobject); var i:integer begin for i:= 1 to 10 do begin schiffe [i] :=tpanel.create(self); schiffe[i].top:=10+20*i; schiffe[i].color:=clred; schiffe[i].parent:= self end; end. | |
Du mußt doch wohl eher 2x 10x 10 Panels anlegen, oder? ;)
cu
Narses
Popov - So 24.12.06 03:53
@4r4k1s
Was erwartest du? Doch nicht eine Antwort. Und wenn man bedenkt, daß es hier im Thread bereits ein Beispiel gibt das Panelfelder erzeugt, dann ist deine Frage geradezu unverschämt. Du fragst und fragst und fragst und guckst dir anscheinend die Antworten garnicht an. Mach es dieses mal schön alleine.
Und schon mal überlegt wie du zum beispiel das Feld A7 oder D5 ansprichst? Oder willst du nur Felder zeichnen? *lol*
jaenicke - So 24.12.06 13:55
Popov hat folgendes geschrieben: |
@4r4k1s
Was erwartest du? Doch nicht eine Antwort. Und wenn man bedenkt, daß es hier im Thread bereits ein Beispiel gibt das Panelfelder erzeugt, dann ist deine Frage geradezu unverschämt. Du fragst und fragst und fragst und guckst dir anscheinend die Antworten garnicht an. Mach es dieses mal schön alleine. |
Genau das hab ich auch gedacht, als ich den Thread gestern gesehen habe...
Wenn es mehr Leute sagen, dann glaubst du es vielleicht mal, deshalb sage ich das explizit auch noch...
Wenn du gegebene Beispiele nicht verstehst, dann frag nach! Aber so ist das einfach nur
dreist...
Ich gebe dir sogar einen Link auf den Beitrag, wo
Popov das mit den Panels bereits programmiert hat:
http://www.delphi-forum.de/viewtopic.php?t=67298#404744
Aber solange du dich nicht wenigstens damit beschäftigst,
wenn du schon nicht die wesentlich bessere und (meiner Meinung nach) einfachere Lösung, die dir ebenfalls geschrieben wurde, benutzen willst, kannst du doch wohl nicht ernsthaft erwarten, dass dir hier noch jemand hilft.
Und um die Stelle zu finden, wo die Panels erzeugt werden, muss man nur deutsch können, nichtmal Delphi. Denn die Namen der Prozeduren können eindeutiger ja kaum sein...
Und wenn dir die absoluten Grundlagen in Delphi fehlen, dann sieh dir erstmal ein paar Tutorials an!
Die wurden dir ja bereits verlinkt:
http://www.delphi-forum.de/viewtopic.php?t=67298#404526
Ansonsten war das alles, was ich hier sagen werde. Wenn du dich ernsthaft mit dem geposteten Quelltext auseinandersetzt (das erkennen wir an Verständnisfragen, denn dass du alles sofort verstehst erwartet hier gar keiner...), dann werde ich vielleicht auch noch weiter helfen, ansonsten war das alles von meiner Seite.
4r4k1s - So 24.12.06 13:56
nein will die natürlich auch ansprechen aber erstma will ich 2mal 10x10 felder hinbekommen
Narses - So 24.12.06 15:30
Moin!
Ich denke, wir haben hier sicher Verständnis dafür, wenn du einen bestimmten Lösungsweg einschlagen möchtest (bzw. sollst). Allerdings kommst du nicht gerade so rüber, dass man sich darum "reißt", dir zu helfen... :?
4r4k1s hat folgendes geschrieben: |
nein will die natürlich auch ansprechen aber erstma will ich 2mal 10x10 felder hinbekommen |
Du hast Tipps genug, zeig deinen Code und wenn er nicht funktioniert, zeig uns die Stelle, an der das Problem auftritt und gib eine brauchbare Problembeschreibung oder sag uns, WAS du nicht verstehst.
Es wird dir hier keiner ein Programm nach deinen Angaben maßschneidern - sowas kannst du gerne unter Jobangebote loswerden. ;)
cu
Narses
jaenicke - So 24.12.06 16:02
Narses hat folgendes geschrieben: |
4r4k1s hat folgendes geschrieben: | nein will die natürlich auch ansprechen aber erstma will ich 2mal 10x10 felder hinbekommen |
Du hast Tipps genug, zeig deinen Code und wenn er nicht funktioniert, zeig uns die Stelle, an der das Problem auftritt und gib eine brauchbare Problembeschreibung oder sag uns, WAS du nicht verstehst. |
Naja, das hat er ja gemacht... Das ist hier ausnahmsweise (bezogen aufs Forum allgemein bei vielen Fragen ;-)) nicht das Problem... Das Problem ist doch, dass der entsprechende Quelltext schon gepostet wurde und er gar nicht reingesehen hat. Denn dann hätte er gesehen, dass er statt seiner einen Schleife deren zwei benötigt. Und die korrekte Array-Deklaration ist dort auch zu sehen.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!