![]() |
Schiffe versenken, Platzierung
Hi :)
Ich soll für die Schule das Spiel Schiffe versenken mit Delphi 5 programmieren, nur weiß ich nicht wie ich die Platzierung der Schiffe hinbekommen soll. Für das Feld will ich ein Drawgrid benutzen.Ich weiß nicht wie ich es hinbekomme, dass das Feld auf das ich klicke und das rechts daneben rot gefärbt wird. Bis jetzt wird nur das angeklickte Feld rot. Ich hoffe ihr könnt mir helfen :) |
Re: Schiffe versenken, Platzierung
du kannst dich bestimmt irgendwie die position in x und y des angeklickten Feldes heraus finden, oder?
Und dann zählst du einfach das Feld mit den Eigenschaften Y und X + 1 an ;-) Ich kenne diese komponente leider nicht... |
Re: Schiffe versenken, Platzierung
Delphi-Quellcode:
Das ist meine momentane Aushilfe für mein Problem, aber sie scheint noch stark sub-optimal zu sein, da ich von hier aus nicht wüsste wie ich dann die Schiffe mit 3/4/5 Plätzen platzieren könnte...
procedure TForm1.DrawGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState); begin with sender as TDrawgrid do begin if arr[acol,arow]or arr[acol-1,arow] then canvas.brush.color := clred else canvas.brush.color := clwhite; canvas.fillrect(rect); end; end; procedure TForm1.DrawGrid1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); Var arow,acol:integer; begin DrawGrid1.MouseToCell(X, Y,ACol, ARow); arr[acol,arow]:= not arr[acol,arow]; DrawGrid1.Repaint; end; |
Re: Schiffe versenken, Platzierung
Ich bin jetzt schon relativ weit gekommen, nur wie überprüfe ich ob die Schiffe nebeneinanderliegen? Denn das sollte ja eigentlich nicht möglich sein.
Momentan sieht der Quelltext bei mir so aus:
Delphi-Quellcode:
unit Unit1;
interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Grids, StdCtrls, ExtCtrls; type TForm1 = class(TForm) DrawGrid1: TDrawGrid; BHori: TButton; Image1: TImage; Image2: TImage; BVerti: TButton; IHori: TImage; IVerti: TImage; Image3: TImage; Image4: TImage; DrawGrid2: TDrawGrid; procedure DrawGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState); procedure DrawGrid1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure FormCreate(Sender: TObject); procedure BHoriClick(Sender: TObject); procedure BVertiClick(Sender: TObject); private arr2:array[0..9,0..9] of boolean; { Private declarations } public { Public declarations } end; var Form1: TForm1; a,b,c,d,e,f,g,h,z:integer; implementation {$R *.DFM} procedure TForm1.DrawGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState); begin begin with sender as TDrawgrid do begin if arr2[acol,arow] then canvas.brush.color := clred else canvas.brush.color := clwhite; canvas.fillrect(rect); end; end; end; procedure TForm1.DrawGrid1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); Var row,col:integer; begin DrawGrid1.MouseToCell(X, Y,Col, Row); //Mausposition auslesen if z=5 then //5er Schiff if a=1 then begin if col<6 then begin arr2[col,row] := not arr2[col,row]; arr2[col+a,row+e]:= not arr2[col+a,row+e]; arr2[col+b,row+f]:= not arr2[col+b,row+f]; arr2[col+c,row+g]:= not arr2[col+c,row+g]; arr2[col+d,row+h]:= not arr2[col+d,row+h]; image4.visible:=false; z:=z+1; end; end else if row<6 then begin arr2[col,row] := not arr2[col,row]; arr2[col+a,row+e]:= not arr2[col+a,row+e]; arr2[col+b,row+f]:= not arr2[col+b,row+f]; arr2[col+c,row+g]:= not arr2[col+c,row+g]; arr2[col+d,row+h]:= not arr2[col+d,row+h]; image4.visible:=false; z:=z+1; end; if z=4 then //4er Schiff if a=1 then begin if col<7 then begin arr2[col,row] := not arr2[col,row]; arr2[col+a,row+e]:= not arr2[col+a,row+e]; arr2[col+b,row+f]:= not arr2[col+b,row+f]; arr2[col+c,row+g]:= not arr2[col+c,row+g]; image3.visible:=false; z:=z+1; end; end else if row<7 then begin arr2[col,row] := not arr2[col,row]; arr2[col+a,row+e]:= not arr2[col+a,row+e]; arr2[col+b,row+f]:= not arr2[col+b,row+f]; arr2[col+c,row+g]:= not arr2[col+c,row+g]; image3.visible:=false; z:=z+1; end; if z=3 then //3er Schiff if a=1 then begin if col<8 then begin arr2[col,row] := not arr2[col,row]; arr2[col+a,row+e]:= not arr2[col+a,row+e]; arr2[col+b,row+f]:= not arr2[col+b,row+f]; image2.visible:=false; z:=z+1; end; end else if row<8 then begin arr2[col,row] := not arr2[col,row]; arr2[col+a,row+e]:= not arr2[col+a,row+e]; arr2[col+b,row+f]:= not arr2[col+b,row+f]; image2.visible:=false; z:=z+1; end; if z=2 then //2er Schiff if a=1 then begin if col<9 then begin arr2[col,row]:= not arr2[col,row]; arr2[col+a,row+e]:= not arr2[col+a,row+e]; image1.visible:=false; z:=z+1; end; end else if row<9 then begin arr2[col,row]:= not arr2[col,row]; arr2[col+a,row+e]:= not arr2[col+a,row+e]; image1.visible:=false; z:=z+1; end; DrawGrid1.Repaint; end; procedure TForm1.FormCreate(Sender: TObject); begin z:=2; a:=1; b:=2; c:=3; d:=4; e:=0; f:=0; g:=0; h:=0; end; procedure TForm1.BHoriClick(Sender: TObject); begin IVerti.visible:=false; //Horizontale Ausrichtung IHori.visible:=true; a:=0; b:=0; c:=0; d:=0; e:=1; f:=2; g:=3; h:=4; end; procedure TForm1.BVertiClick(Sender: TObject); begin IVerti.visible:=true; //Vertikale Ausrichtung IHori.visible:=false; a:=1; b:=2; c:=3; d:=4; e:=0; f:=0; g:=0; h:=0; end; end. |
Re: Schiffe versenken, Platzierung
Liste der Anhänge anzeigen (Anzahl: 2)
Vom Ansatz her schaut das, was du bisher hast, schon mal gar nicht so schlecht aus.
In deiner Schiff-Setzen-Routine (die ich etwas ändern würde, so ist es ziemlich umständlich und fehleranfällig) würde ich folgendes machen: Zuerst mal musst du dir überlegen, wann die Positionierung gültig ist, d.h. wann ein Setzen des Schiffs nach den Regeln erlaubt sein soll. Ein Schiff darf kein anderes Schiff irgendwo berühren, d.h. es muss um das neu zu setzende Schiff ein "Rand" von einem Feld frei sein (siehe auch Bilder im Anhang). In der Routine würde ich mir dieses Rechteck bestimmen, und zwar mit Hilfe einer Variable vom Typ TRect:
Delphi-Quellcode:
(ungetestet, nur hier schnell im Beitrags-Editor getippt, können Tippfehler drin sein :-) )
var r : TRect;
var gueltig : boolean; var iX, iY : integer; // //... // Ueberpruefung, ob innerhalb des Felds (das hast du ja schon)... // // Du weisst ja, wo das Schiff gesetzt werden soll und du weisst die Länge und die Orientierung des Schiffs. Damit kannst du schonmal die Position des Schiffs im Rect speichern: r.Left := x; r.Top := y; // if Orientierung = horizontal (* oder wie du es halt speicherst *) then begin r.Right := r.Left + Laenge -1; r.Bottom := r.Top; end else begin r.Right := r.Left; r.Bottom := r.Top + Laenge -1; end; // // Jetzt musst du das Rect auf jeder Seite noch um "1" vergoessern, dabei musst du bedenken, dass das Schiff auch an einem Rand des Felds liegen kann: // if r.Left > 0 then r.Left := r.Left -1; if r.Top > 0 then r.Top := r.Top -1; if r.Right < 9 then r.Right := r.Right +1; if r.Bottom < 9 then r.Bottom := r.Bottom +1; // // Jetzt kannst du das gesamte Rect in einer Schleife durchgehen und die Felder ueberpruefen: // gueltig := true; // for iX := r.Left to r.Right do for iY := r.Top to r.Bottom do if not(arr2[iX,iY]) then gueltig := false; // (Schleife kann man noch einbisschen optimieren) // if gueltig then begin // SETZEN end; Hoffe, das hilft dir schonmal einbisschen weiter ;-) mfg Patti |
Re: Schiffe versenken, Platzierung
Vielen dank, ich werd mir nachher wenn ich Zeit hab darüber gedanken machen :)
Aber den Grundgedanken versteh ich schon :) Falls ich das nächste mal irgendwo hängen bleibe, oder was an deinem Tipp nicht verstehe Frage ich nochmal :) Danke. M2zer0 |
Re: Schiffe versenken, Platzierung
mhh.. Ich hab reichlich rumprobiert und es klappt auch das ich auf manchen Feldern nichts mehr setzten kann, nur das schon von Anfang an. Durch das setzen von Schiffen ändert sich auch nichts an den Feldern.. ich kann sie trotzdem noch ineinander setzen. Könntest du mir deinen Quelltext noch einmal näher erklären?
|
Re: Schiffe versenken, Platzierung
soooo :)
Mit dem Platzieren der eigenen Schiffe bin ich endlich fertig :) Der Quelltext sieht nun so aus:
Delphi-Quellcode:
Wie könnte ich recht simpel einen "Neues Spiel" button machen, ohne das ich manuell alle variablen auf anfangsstatus setzen muss?
procedure TForm1.DrawGrid1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer); Var row,col:integer; begin DrawGrid1.MouseToCell(X, Y,Col, Row); //Mausposition auslesen r.Left :=Col-1; r.Top :=Row-1; if Horizontal=0 then begin r.Right:=col+z; r.Bottom:=Row+1; end else begin r.Right:=col+1; R.Bottom:=row+z; end; if r.Left = -1 then r.Left := 0; if r.Top = -1 then r.Top := 0; if r.Right =10 then r.Right := r.Right -1; if r.Bottom = 10 then r.Bottom := r.Bottom -1; LX.caption:=IntToStr(R.right); LY.caption:=IntToStr(R.left); gueltig:=true; for iX := r.Left to r.Right do for iY := r.Top to r.Bottom do if (arr2[iX,iY]) then gueltig := false; if gueltig then begin //schiffe setzen end; |
Re: Schiffe versenken, Platzierung
Das grundsätzliche Problem steckt hier:
Delphi-Quellcode:
Damit lässt sich nur erkennen ob an einer bestimmten Stelle Schiff oder Wasser ist.
arr2:array[0..9,0..9] of boolean;
Man kann aber nicht herausfinden, zu welchem Schiff ein Punkt gehört. Damit ist die Aussage "Schiff versenkt" nicht möglich. Jedes Schiff sollte eine andere Kennung haben.
Delphi-Quellcode:
Hier eine Spielkarte mit drei Schiffen aaa (3-er Schiff), bBbbb (5-er Schiff mit einem Treffer), cccc (4-er Schiff)
arr2:array[0..9,0..9] of char;
*-chen bedeutet Wasser Bei einem Treffer wird ein Kleinbuchstabe zu einem Grossbuchstaben.
Code:
**********
*aaa****** *b******** *B******** *b******** *b******** *bcccc**** ********** ********** ********** |
Re: Schiffe versenken, Platzierung
Danke für die Antwort :)
Nur ich bin noch ein Anfänger was Delphi angeht, könntest du das "Array of Char" ein wenig erklären? Das war mir bisher noch nicht bekannt. Vielen dank :) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:59 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 by Thomas Breitkreuz