Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Schiffe versenken, Platzierung (https://www.delphipraxis.net/151288-schiffe-versenken-platzierung.html)

m2zer0 11. Mai 2010 14:39


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 :)

stho 11. Mai 2010 15:04

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...

m2zer0 11. Mai 2010 19:13

Re: Schiffe versenken, Platzierung
 
Delphi-Quellcode:
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;
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...

m2zer0 24. Mai 2010 11:07

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.

patti 24. Mai 2010 11:46

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:
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;
(ungetestet, nur hier schnell im Beitrags-Editor getippt, können Tippfehler drin sein :-) )

Hoffe, das hilft dir schonmal einbisschen weiter ;-)

mfg
Patti

m2zer0 24. Mai 2010 12:50

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

m2zer0 26. Mai 2010 23:13

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?

m2zer0 27. Mai 2010 17:16

Re: Schiffe versenken, Platzierung
 
soooo :)
Mit dem Platzieren der eigenen Schiffe bin ich endlich fertig :)
Der Quelltext sieht nun so aus:

Delphi-Quellcode:
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;
Wie könnte ich recht simpel einen "Neues Spiel" button machen, ohne das ich manuell alle variablen auf anfangsstatus setzen muss?

shmia 27. Mai 2010 17:30

Re: Schiffe versenken, Platzierung
 
Das grundsätzliche Problem steckt hier:
Delphi-Quellcode:
arr2:array[0..9,0..9] of boolean;
Damit lässt sich nur erkennen ob an einer bestimmten Stelle Schiff oder Wasser ist.
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:
arr2:array[0..9,0..9] of char;
Hier eine Spielkarte mit drei Schiffen aaa (3-er Schiff), bBbbb (5-er Schiff mit einem Treffer), cccc (4-er Schiff)
*-chen bedeutet Wasser
Bei einem Treffer wird ein Kleinbuchstabe zu einem Grossbuchstaben.
Code:
**********
*aaa******
*b********
*B********
*b********
*b********
*bcccc****
**********
**********
**********

m2zer0 27. Mai 2010 18:39

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 :)

shmia 27. Mai 2010 18:59

Re: Schiffe versenken, Platzierung
 
Zitat:

Zitat von m2zer0
..bin noch ein Anfänger was Delphi angeht

Ein "Char" ist ein einzelnes Zeichen und natürlich darf man damit ebenso wie mit "Boolean" ein- oder mehrdimensionale Arrays aufbauen.
Grundlagentutorial

m2zer0 27. Mai 2010 19:20

Re: Schiffe versenken, Platzierung
 
Mhh..
Char zu benutzen wäre auf jedenfall intelligenter, da hast du recht.
Nur hab ich noch nie damit gearbeitet, deswegen weiß ich zB. nicht wie ich meinen Quelltext daran anpassen kann.

Nehmen wir mal

Delphi-Quellcode:
 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;
Diese Abfrage setzt ja Boolean voraus, wie sieht sie unter Verwendung von Char aus?

:)

fui-tak 27. Mai 2010 19:55

Re: Schiffe versenken, Platzierung
 
Das müsste dann so gehen:
Delphi-Quellcode:
begin
      with sender as TDrawgrid do
        begin
          if not(arr2[acol,arow] = '*') //wenn hier kein * ist, dann wird ... clRed ausgeführt
            then canvas.brush.color := clred
            else canvas.brush.color := clwhite;
           canvas.fillrect(rect);
        end;
end;

m2zer0 27. Mai 2010 21:24

Re: Schiffe versenken, Platzierung
 
Hat geklappt danke :)
Hab jetzt fast alles umgeschrieben damit array of char akzeptiert wird, nur der Teil mit dem TRect macht mir noch Probleme.

Delphi-Quellcode:
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;

  gueltig:=true;

  for iX := r.Left to r.Right do                       //Hier müsste
    for iY := r.Top to r.Bottom do                     //noch etwas geändert
      if (arr2[iX,iY]='k') then gueltig := false;      //werden, nur was?
Es ist das Feld um das Schiff, damit man die Schiffe nicht direkt aneinander oder ineinander Platzieren kann.
Die Platzierung wird in eine If-Abfrage gesetzt (if gueltig then), nur im Moment bin ich ein klein wenig verwirrt. :^)

IceBube 27. Mai 2010 22:51

Re: Schiffe versenken, Platzierung
 
Hallo!

Mir war langweilig :), und dachte ich schreib dir schnell meine Variante dazu..

Delphi-Quellcode:
type
  //Schiff Typ (Size, Senkrecht?)
  TTypus = Record
    Size     : Integer;
    Senkrecht : Boolean;
  end;

  //Form
  TForm1 = class(TForm)
    DrawGrid1: 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);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

  //NewGame
  procedure NewGame();

var
  Form1: TForm1;

  //Schiffm Typen (0=Unbesetz, 1=Besetzt, 2=Treffer)
  Ships : Array[0..25, 0..20] of Integer;
  Typen : Array[0..2] of TTypus;

  //Aktiv - Gesetzt Schiff-typ
  Aktiv : Integer;

  //State - 0 = Setzen, 1=Play..
  State : Integer;

implementation

{$R *.dfm}

procedure NewGame();
var
  X, Y : Integer;
begin
  //----
  //Neues Spiel
  //----
  for Y := 0 to 20 do
    for X := 0 to 25 do
      Ships[X, Y] := 0;

  //
  Form1.DrawGrid1.Repaint;
end;


procedure TForm1.DrawGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
  //----
  //DrawCell - TDrawGrid
  //----
  with Sender as TDrawGrid do
  begin
    //
    case Ships[aCol, aRow] of
      0: Canvas.Brush.Color := clWhite; //Frei
      1: Canvas.Brush.Color := clRed;  //Besetzt
      2: Canvas.Brush.Color := clBlue; //Treffer
    end;

    //
    canvas.fillrect(rect);
  end;

end;

procedure TForm1.DrawGrid1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  Row, Col : Integer;
  I, iX, iY  : Integer;
  Typ      : TTypus;
  //------------------
  Collision : Boolean;
begin
  //----
  //Setze ein Schiff
  //----
  DrawGrid1.MouseToCell(X, Y, Col, Row);

  //
  if State = 1 then
  begin
    //Treffer
    if Ships[Col, Row] = 1 then
      Ships[Col, Row] := 2
    else
      ShowMessage('Kein Treffer!');

    //Alle gefunden?
    Collision := True;

    for iY := 0 to 20 do
      for iX := 0 to 25 do
        if Ships[iX,iY] = 1 then Collision := False;

    //
    if Collision then
      //Gewonnen
      ShowMessage('Sie haben gewonnen!');

    Exit;
  end;

  //Typ
  Typ := Typen[Aktiv];

  //Prüfen
  Collision := False;
  if not Typ.Senkrecht then
    for I := -1 to Typ.Size do
    begin
      if Ships[Col+I, Row] = 1 then Collision := True;

      //Auf den Seiten?
      if Ships[Col+I, Row+1] = 1 then Collision := True;
      if Ships[Col+I, Row-1] = 1 then Collision := True
    end
  else
    for I := -1 to Typ.Size do
    begin
      if Ships[Col, Row+I] = 1 then Collision := True;
      //Auf den Seiten?
      if Ships[Col+1, Row+I] = 1 then Collision := True;
      if Ships[Col-1, Row+I] = 1 then Collision := True;
    end;

  //Collision?
  if Collision then
  begin
    ShowMessage('Sie können hier kein Schiff setzen!');
    Exit;
  end;

  //
  if not Typ.Senkrecht then
    for I := 0 to Typ.Size-1 do
      Ships[Col+I, Row] := 1
  else
    for I := 0 to Typ.Size-1 do
      Ships[Col, Row+I] := 1;

  //
  DrawGrid1.Repaint;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  //--------
  //Form Create
  //--------

  //Typen
  //--------------------------
  //5er Schiff Waagrecht
  Typen[0].Size      := 5;
  Typen[0].Senkrecht := False;

  //3er Schiff Senkrecht
  Typen[1].Size      := 3;
  Typen[1].Senkrecht := True;

  //2er Schiff Senkrecht
  Typen[2].Size      := 2;
  Typen[2].Senkrecht := True;
  //--------------------------

  //Aktives Schiff (0-2)
  Aktiv := 2;

  //
  State := 0;
end;
Hoffe das hilft dir :)

lg

Edit : Spielmode hinzugefügt...
Edit2: Dachte man kann die Schiffe auch nebeinander bauen :S
Jetzt aber nicht mehr :)

m2zer0 28. Mai 2010 13:12

Re: Schiffe versenken, Platzierung
 
Vielen, vielen Dank :)
Es gibt nicht mehr viele Leute die so hilfsbereit sind wie du :)
Aber ich hab das Gefühl das nahezu alle hier in der DP unglaublich nett sind :)

Ich werd mir das alles morgen genauer anschauen, da ich heute im Stress bin.

Mit freundlichen Grüßen m2zer0 :)

fui-tak 28. Mai 2010 22:19

Re: Schiffe versenken, Platzierung
 
Zitat:

Zitat von m2zer0
Delphi-Quellcode:
...

  gueltig:=true;

  for iX := r.Left to r.Right do                       //Hier müsste
    for iY := r.Top to r.Bottom do                     //noch etwas geändert
      if (arr2[iX,iY]='k') then gueltig := false;      //werden, nur was?
Es ist das Feld um das Schiff, damit man die Schiffe nicht direkt aneinander oder ineinander Platzieren kann.
Die Platzierung wird in eine If-Abfrage gesetzt (if gueltig then), nur im Moment bin ich ein klein wenig verwirrt. :^)



Ich weiß nicht ob ich dich richtig verstehe, aber ich glaube du hättest gerne sowas:
Delphi-Quellcode:
...
  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; //wenn auf dem Feld ein Schiff irgendeiner Art ist (in deinem Beispiel gingen nur k-Schiffe), wird gueltig auf false gesetzt

IceBube 28. Mai 2010 22:35

Re: Schiffe versenken, Platzierung
 
Zitat:

Zitat von fui-tak
Delphi-Quellcode:
(...)
 ... //wenn auf dem Feld ein Schiff irgendeiner Art ist (in deinem Beispiel gingen nur k-Schiffe), wird gueltig auf false gesetzt

Hmm, wieso? Das ist ja bei "Schiffe versenken" egal, oder nicht?

Bei meinem Code erkennt man nicht ob ein ganzes Schiff versenkt worden ist

Tipp:
Verwende statt "Integer" einen eigenen Typ!

z.B.:
Delphi-Quellcode:
type
 TShip = Record
    Typ    : TTypus;
    Treffer : array[0..10] of Boolean; //Wahr = Treffer, max. 11 
 end;

 //..
 Ships : Array[-1..20, -1..25] of TShip;
 

 //Prüfen ob ganzes Schiff versenkt!
 var
   iX, iY, I : Integer;
 
 for iY := 0 to 20 do
   for iX := 0 to 25 do
   begin
     Collision := True;    
     
     for I := Low(Ships[iX, iY].Treffer) to High(Ships[iX, iY].Treffer) do    
       if not Ships[iX, iY].Treffer[I] then Collision := False;


     //Versenkt?
     if Collision then
      ShowMessage('Schiff Position (X, Y): ' + inttostr(iX)+', ' + inttostr(iY) +^J+ 'Wurde versenkt!');
   end;
lg

m2zer0 28. Mai 2010 22:54

Re: Schiffe versenken, Platzierung
 
Da ich auch gerne Anzeigen lassen würde welches Schiff versenkt würde, benutze ich lieber, wie mir einige posts zuvor gesagt wurde:
Array of Char;

Das hat recht viele Vorteile, nur mein Problem ist, dass ich nicht weiß wie ich die Schleife, die dafür sorgte, dass Schiffe nicht an/ineinander liegen, passend für Array of Char umschreibe.

Edit: Ok, das Problem hat sich grad von allein gelöst^^ ich hätte nur einmal nachdenken sollen. Vielleicht ist es schon ein wenig zu spät.. :^)

m2zer0 29. Mai 2010 00:20

Re: Schiffe versenken, Platzierung
 
So :)
Nun brauche ich einen Computergegner. Er muss keine Taktik haben, es reicht wenn seine Schiffe zufällig platziert werden und seine Schüsse auch zufällig sind. Die Platzierung sollte jedoch unter den gleichen Richtlinien wie die des Spielers ablaufen.

Die Frage ist nur wie? :)

Naja, es ist spät und ich brauche Schlaf. Bis morgen dann ;)

m2zer0.

m2zer0 31. Mai 2010 14:56

Re: Schiffe versenken, Platzierung
 
Was kann man denn am besten für die Platzierung der Computer Schiffe benutzen?

Ich mach mir schon seit Tagen Gedanken darüber, nur ich komm nicht darauf wie ich es anstelle ohnen einen Quelltext von einem gigantischen Ausmaß zu bekommen.. :(

m2zer0 1. Jun 2010 17:56

Re: Schiffe versenken, Platzierung
 
Die Platzierung hab ich nun auch gemeister. Nun kommt das Schießen :)
Da der Com nur zufällig schießen muss, muss ich es hinbekommen das ein Zufälliges Feld, das noch nicht beschossen wurde, beschossen wird. Wie kann ich das überprüfen? Geht das mithilfe eines Arrays?

patti 1. Jun 2010 17:59

Re: Schiffe versenken, Platzierung
 
Naja, das ist eigentlich ganz einfach. Mit Hilfe von "random" erzeugst du dir zwei Zufalls-Zahlen von 0 bis 9, eine für die x-Richtung und eine für die y-Richtung. Dann überprüfst du in deinem Array mit den Feldern, ob das Feld bereits "beschossen" wurde. Wenn ja --> nochmal neue Zufallszahlen erzeugen (das ganze in einer Schleife, bis das Feld, das rauskommt, noch nicht beschossen wurde), wenn nein --> "schießen".

mfg

m2zer0 1. Jun 2010 18:13

Re: Schiffe versenken, Platzierung
 
habe ich bereits versucht, nur irgendwann ist die Wahrscheinlichkeit so gering das eine passende Zahl getroffen wird, das das Programm sich an der Schleife aufhängt.

idefix2 2. Jun 2010 22:50

Re: Schiffe versenken, Platzierung
 
Delphi-Quellcode:
var
NochNichtBeschossen: array[1..m,1..n] of integer; // m*n spielfeldgrösse, alle noch nicht beschossenen Felder enthalten true
AnzahlNochNichtBeschossen: integer;

procedure zielsuchen (var x,y: integer);
var i,j,z,h: integer;
begin
z := trunc(random(AnzahlNochNichtBeschossen))+1;
h := 0;
for i := 1 to m do
for j := 1 to n do
  if NochNichtBeschossen [i,j]
  then begin inc(h);
       if h=z then begin x:=i; y:=j; exit end;
       end;
end;
Vielleicht in etwa so?

m2zer0 2. Jun 2010 23:26

Re: Schiffe versenken, Platzierung
 
Könntest du die procedure noch einmal kurz erklären?
Müsste es nicht ein array of boolean sein?

Vielen Dank schonmal für die Hilfe :)

idefix2 3. Jun 2010 15:56

Re: Schiffe versenken, Platzierung
 
entschuldige, natürlich boolean, im Kommentar steht ja auch: alle noch nicht beschossenen Felder enthalten true

Die Idee ist die: Wenn Du noch x nicht beschossene Felder hast, erzeugst Du eine Zufallsszahl n zwischen 1 und x und gehst dann im Feld zum n-ten noch nicht beschossenen Feld, die schon beschossenen Felder werden einfach übersprungen, ohne dass etwas passiert. Also bei jedem noch nicht beschossenen Feld den Zähler um 1 erhöhen, wenn Du bei n angelngt bist, die Prozedur (und die Schleife) verlassen.

freak4fun 3. Jun 2010 16:04

Re: Schiffe versenken, Platzierung
 
Delphi-Quellcode:
NochNichtBeschossen: array[1..m,1..n] of integer;
Finde ich besser. Hast du dir um die Zustände eines Feldes gedanken gemacht? Oder hälst du meherer Arrays vom Spielfeld?
Mir würden auf anhieb 4 Zustände einfallen: Boot getroffen, Boot nichtgetroffen, Wasser nicht beschossen, Wasser beschossen :gruebel:

m2zer0 3. Jun 2010 17:30

Re: Schiffe versenken, Platzierung
 
Ich benutze, wie bereits aus den vorherigen posts hervorgehend, ein Array of Char. Jedes Bot hat seinen eigenen Buchstaben, welcher sich nach dem Beschuss ändert. Gleiches gilt für das Wasser.

idefix2 3. Jun 2010 17:41

Re: Schiffe versenken, Platzierung
 
Zitat:

Oder hälst du meherer Arrays vom Spielfeld?
Ich möchte ja nicht das ganze Spiel programmmieren, sondern nur einen Vorschlag für das konkret formulierte Problem machen. Dafür ist boolean ausreichend.
Natürlich kann man die verschiedenen Zustände der Feldelemente in einer integer variablen oder sogar besser in einer Variablen vom Typ set of Aufzähltyp halten, und aufzähltyp ist dann etwas wie (IstWasser, IstBeschossen, IstAbgeschossen ....) und was auch immer noch an binären Zuständen benötigt wird.

Aber wie er m2zer0 seine Daten sonst organisiert, möchte ich ganz ihm überlassen (solange er nicht explizit danach fragt :) )

Ob es sinnvoll ist, in dem Feld jedem Boot einen anderen Buchstaben zuzuordnen, kann ich nicht sagen, weil ich mich mit dem Gesamtprogramm nicht beschäftigt habe, aus dem Bauch heraus würde ich sagen, eher nein, das schaut mir nicht nach einem sauberen Datenmodell aus, aber das muss letztlich der Programmierer entscheiden.

freak4fun 3. Jun 2010 21:20

Re: Schiffe versenken, Platzierung
 
Alles klar! Ich wollte auch nur darauf hinweisen. Ich habe selbst mal Bomberman versucht zu programmieren und da bin ich auf ähnliche Probleme gestoßen, daher die ANregung. ;)

idefix2 3. Jun 2010 21:43

Re: Schiffe versenken, Platzierung
 
@ Freak4fun

Prinzipiell hast Du sicher Recht. Ich denke, ich würde auch eher alle möglichen Zustände der einzelnen Felder des Spielfeld in einem einzigen zweidimensionalen array abspeichern.

m2zer0 8. Jun 2010 19:18

AW: Schiffe versenken, Platzierung
 
Edit: Ich hatte grad nen Geistesblitz
Mit ner Repeat Until Schleife war das ganze schnell gelöst^^

Trotzdem vielen Dank


So, ich bin fast fertig. :)
Ich hab gehofft ich schaffe den Rest allein, aber ein Problem habe ich noch.
Die Platzierung der gegnerischen Schiffe. Diese soll unter den gleichen Konditionen wie die Spielerschiffe-Platzierung ablaufen.
Also:
-4 Schiffe (2er,3er,4er,5er)
-Um ein Schiff herum darf kein 2. sein.
Code:
1)          2)
  11###        1####
  ##222        1####
  #####        #####
  #####        #222#
 so nicht  das würde gehen
(Im Programm ist es ein 10*10 Feld)
-Schiffe sollen zufällig Vertikal oder Horizontal sein

Alles was ich bisher versucht habe klappte zum Teil. Die Schiffe wurden platziert, haben aber das Feld um das andere Schiff gekonnt ignoriert.(Siehe Code bsp. 1)

Meine Überlegung war ein Rect um das Schiff zu legen und Reihe und Spalte so oft zufällig zu bestimmen bis Spalte und Zeile ein freies Feld erwischen.

m2zer0 8. Jun 2010 19:46

AW: Schiffe versenken, Platzierung
 
"Lösch mich"


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:07 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz