Delphi-PRAXiS
Seite 5 von 5   « Erste     345   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Schiffe versenken programmieren (https://www.delphipraxis.net/178499-schiffe-versenken-programmieren.html)

DeddyH 2. Mär 2014 16:23

AW: Schiffe versenken programmieren
 
Vielleicht bin ich ja nicht mehr zeitgemäß, aber ich kenne das noch so, dass die (zumindest grobe) Projektplanung abgeschlossen ist, bevor man überhaupt die IDE startet. Da hat man dann lax formuliert einen Zettel (oder eher einen Stapel davon) vor sich, auf dem das Hauptproblem in Teilprobleme und die dann wiederum in noch kleinere Teilprobleme zerlegt sind, die man nur noch in Code formulieren muss. Von PAPs oder Struktogrammen will ich erst gar nicht anfangen.

leodinho 2. Mär 2014 16:31

AW: Schiffe versenken programmieren
 
hmm.. wie soll ich das nur machen.. Nichts gegen euch aber ich finde die Programmierung einfach ******
Ich kann mich nicht reindenken und auch mit den grundlagen komm ich nicht weiter.. Ist halt nicht mein gebiet..
gebe das was ich habe ab und gut ist..
Und mein Elend als programm hat glaub immernoch keiner angeguckt?

Popov 2. Mär 2014 16:35

AW: Schiffe versenken programmieren
 
@DeddyH

Was richtig ist spielt hier zuerst keine Rolle. Außerdem dachte ich, dass der TE das schon gemacht, sie Beitrag #93. Aber um was geht es hier, wie man korrekt Projekte im Berufsleben umsetzt oder wollen wie auf biegen und brechen eine komplexe Planung für eine Hausaufgabe aufzwingen. Zurzeit ist der TE damit beschäftigt ein zweidimensionales Array mit Nullen zu löschen.

Zitat:

Zitat von leodinho (Beitrag 1250242)
Und mein Elend als programm hat glaub immernoch keiner angeguckt?

Ich hab mir das schon angeguckt, nur ist von dem Programm noch nichts zu sehen.

DeddyH 2. Mär 2014 16:40

AW: Schiffe versenken programmieren
 
Wenn man so etwas noch nie gemacht hat oder zumindest unerfahren auf dem Gebiet ist, welchen Sinn macht es da, ohne nachzudenken irgendetwas zusammenzuschreiben und ohne überhaupt zu wissen, wo man eigentlich hinwill? Falls Du Projekte im Berufsleben so umsetzt, ist das Deine Sache, ich muss das ja später zum Glück nicht debuggen.

leodinho 2. Mär 2014 16:49

AW: Schiffe versenken programmieren
 
ja toll, moralapostel helfen mir auch nicht..
ist jetzt auch egal, wäre nett gewesen wenn ich das wenigstens noch auf dem feld sichtbar gemacht hätte..
so gebe ich das halt ab und muss mit der ganzen arbeit(stunden) umsonst zufrieden sein -.-
soein programm , was man sichelich in 1h programmiert -.-

DeddyH 2. Mär 2014 16:56

AW: Schiffe versenken programmieren
 
Was hast Du denn erwartet? Dass Dir das jemand fertig auf dem Silbertablett serviert? Insbesondere Sir Rufo hat sich viel Zeit für Dein Problem genommen, nur die Umsetzung war Dein Part.

Popov 2. Mär 2014 17:05

AW: Schiffe versenken programmieren
 
DeddyH, nach allgemeiner Definition kann alles was von der normalen Tätigkeit/Routine abweicht, als Projekt bezeichnet werden. Somit ist das Brote schmieren zum Frühstück kein Projekt, auch der Kauf von Butter ist kein Projekt, weil man das immer wieder macht. Der Kauf von Frühstückstellern ist dagegen schon ein Projekt. Jedem Projekt ist eines gemeinsam: es muss geplant werden. Das bedeutet aber nicht, dass man sich für jeden Plan hinsetzen muss und es erst auf dem Papier durchplanen muss. Trotzdem benötigt ein Projekt einen Plan. Da gebe ich dir Recht. Um Frühstücksteller zu kaufen muss zuerst die Finanzierung geklärt werden, auch wenn es nur 3 Euro bei IKEA sind. Dann muss der Transport geklärt werden - nach der Arbeit im Vorbeifahren oder doch am Samstag. Personalplanung - wer macht das? Sie, er, oder doch beide. Kommen die Kinder mit? Wollen die dann auch noch was essen? Noch mehr Geld.

Ja DeddyH, ein Projekt benötigt eine Planung, aber nicht jedes muss komplex auf dem Papier geplant werden. Das kann auch so gehen: "Sie: Wir brauchen Frühstücksteller. Er: soll ich oder kaufst du die? Sie: ich bin morgen in der Nähe von IKEA, ich macht das." Projektplanung angeschlossen.

Aber ja, wenn es ein Programm in der Firma sein soll, dann wird es geplant, sogar auf dem Papier. Auch bei mir. Aber vor lauter Planung wird hier bisher eine Sache vernachlässigt: das Programm. Es wurde bisher so viel mit dem TE geplant, dass er vor lautem Plan nicht mehr durchblickt.

Ich mache dir ein Angebot: ich ziehe mich hier zurück, dann nimmst du den TE an die Hand und führst ihn zum Ziel.

leodinho 2. Mär 2014 17:09

AW: Schiffe versenken programmieren
 
hilft auch nicht..

mkinzler 2. Mär 2014 17:12

AW: Schiffe versenken programmieren
 
Zitat:

Jedem Projekt ist eines gemeinsam: es muss geplant werden. Das bedeutet aber nicht, dass man sich für jeden Plan hinsetzen muss und es erst auf dem Papier durchplanen muss. Trotzdem benötigt ein Projekt einen Plan.
In diesem Fall geht das Projekt aber über diese Komplexität hinaus. So dass sich eine geziele Planung anbieten würde; im Besonderen, da hier klar wird, dass der TE wenig Erfahrung hierin hat. Ein Profi, wie Du, wird auch von der Routine abweichende Aufgabenstellungen, live ohne Vorplanung in Code umsetzen können. Ich bezweifle aber, das der TE hirtzu im Stande ist. Deshalb finde ich es richtig, dass Detlef in darauf hingewisen hat.
Wenn du diesen Thread verfolgt hast wirst du gesehen haben, dass man hier versucht hat ihn in die richtige Richtung zu scubsen, ihm es aber an der Orientierung gefehlt hat. Deshalb wäre es für ihn ratsam, sein Vorgehen unabhängig von der Implementierung ( Code) durchzudenken.
Wenn auch "Schreibtisch-Tests" nicht mehr en vogue sind.

Popov 2. Mär 2014 17:15

AW: Schiffe versenken programmieren
 
@leodinho

Du solltes zu deinem Lehrer gehen und tatsächlich das Projekt abgeben. Die erste Prozedur sieht so aus:

Delphi-Quellcode:
//Löscht das Feld-Array mit Nullen.
procedure FeldLeeren;
var
  x, y: Integer;
begin
  for x := 0 to MaxFelder do
    for y := 0 to MaxFelder do
      Feld[x, y] := 0;
end;
Im Kommentar steht auch die Aufgabe "Löscht das Feld-Array mit Nullen". Das ist die absolut einfachste Prozedur von allen, einfach Feld mit Nullen löschen. Um das hinzukriegen muss man sich das Feld lediglich als eine zweidimensionale Matrix vorstellen, ein Schachfeld, X waagerecht, Y senkrecht. Wenn es bereits hier hapert, dann fehlt das Verständnis für die Aufgabe.

leodinho 2. Mär 2014 17:23

AW: Schiffe versenken programmieren
 
wie weiß ich jetzt aber ob ne zelle gültig ist oder nicht?
ob es im feld liegt?
also x <= maxfeld?

Sir Rufo 2. Mär 2014 17:27

AW: Schiffe versenken programmieren
 
So, ich kann mir das Elend nicht mehr mit anschauen und hier ein fertiges Schiffe Versenken in einer Konsolen-Version und ohne Highscore.

Wie man sieht bleibt vom eigentlichen Spiel nicht viel mehr als Vorbereiten und SchussAuf.
Logisch, denn die Erfassung der Schusskoordinaten und Ausgabe des Spielfeldes gehört zum User-Interface und nicht zum Spiel, denn das Spiel funktioniert auch ohne User-Interface.

Es ist bewusst rudimentär gehalten ohne viel BlinkBlink um den Blick nicht vom Wesentlichen abzulenken.
Ich habe mir erlaubt keine Kommentare zu setzen, da der Code sich im Wesentlichen selber erklärt, bzw. der TE auch noch etwas zu tun haben soll.

Hautprogramm (User-Interface)
Delphi-Quellcode:
program sv;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  SysUtils,
  SchiffeVersenken in 'SchiffeVersenken.pas';

function ZeichenFuerZelle( Wert : Integer ) : Char;
begin
  case Wert of
    Zelle_Wasser :
      Result := '.';
    Zelle_NebenSchiff :
      Result := '.';
    Zelle_Schiff :
      Result := '.';
    Zelle_SchussWasser :
      Result := 'o';
    Zelle_SchussNebenSchiff :
      Result := 'o';
    Zelle_SchussSchiff :
      Result := 'X';
  end;
end;

procedure ZeigeSpielfeld( Spielfeld : TSpielfeld );
var
  LY : Integer;
  LX : Integer;
begin
  for LY := yMin to yMax do
  begin
    Write( chr( Ord( 'A' ) + LY ), ' ' );
    for LX := xMin to xMax do
      Write( ZeichenFuerZelle( Spielfeld[LX, LY] ) );
    WriteLn;
  end;
end;

function KoordinatenVonEingabe( const Eingabe : string; var x, y : Integer ) : Boolean;
begin
  Result := Length( Eingabe ) >= 2;

  if Result then
    Result := Ord( Eingabe[1] ) >= Ord( 'A' );

  if Result then
    y := Ord( Eingabe[1] ) - Ord( 'A' );

  if Result then
    Result := TryStrToInt( Copy( Eingabe, 2 ), x );

  if Result then
    x := x - 1;
end;

procedure Spiel;
var
  LSpielfeld : TSpielfeld;
  LSchussErgebnis : Integer;
  LSchussKoordinate : string;
  LX, LY : Integer;
begin
  Vorbereiten( LSpielfeld );
  repeat
    ZeigeSpielfeld( LSpielfeld );
    repeat
      repeat
        Write( 'Schuss auf: ' );
        Readln( LSchussKoordinate );
      until KoordinatenVonEingabe( LSchussKoordinate, LX, LY );
      LSchussErgebnis := SchussAuf( LSpielfeld, LX, LY );
      case LSchussErgebnis of
        Schuss_Wasser :
          WriteLn( 'Wasser' );
        Schuss_Treffer :
          WriteLn( 'Treffer' );
        Schuss_SchiffVersenkt :
          WriteLn( 'Treffer und Versenkt' );
        Schuss_FlotteVersenkt :
          WriteLn( 'Treffer, Versenkt und Gewonnen' );
        Schuss_Doppelt :
          WriteLn( 'Auf die Koordinaten ', LSchussKoordinate, ' wurde schon geschossen!' );
        Schuss_Ausserhalb :
          WriteLn( 'Koordinaten ', LSchussKoordinate, ' ungültig!' );
      end;
    until ( LSchussErgebnis <> Schuss_Doppelt ) or ( LSchussErgebnis <> Schuss_Ausserhalb );
  until LSchussErgebnis = Schuss_FlotteVersenkt;
end;

begin
  Randomize;
  try
    Spiel;
  except
    on E : Exception do
      WriteLn( E.ClassName, ': ', E.Message );
  end;
  Readln;

end.
und die Spiellogik
Delphi-Quellcode:
unit SchiffeVersenken;

interface

const
  xMin = 0;
  xMax = 11;
  yMin = 0;
  yMax = 11;

type
  TSpielfeld = array [xMin .. xMax, yMin .. yMax] of Integer;

const
  Zelle_Wasser = 0;
  Zelle_NebenSchiff = 1;
  Zelle_Schiff = 2;
  Schuss = 10;
  Zelle_SchussWasser = Zelle_Wasser + Schuss;
  Zelle_SchussNebenSchiff = Zelle_NebenSchiff + Schuss;
  Zelle_SchussSchiff = Zelle_Schiff + Schuss;

procedure Vorbereiten( var Spielfeld : TSpielfeld );

const
  Schuss_Wasser = 0;
  Schuss_Treffer = 1;
  Schuss_SchiffVersenkt = 2;
  Schuss_FlotteVersenkt = 3;
  Schuss_Doppelt = 4;
  Schuss_Ausserhalb = 5;

function SchussAuf( var Spielfeld : TSpielfeld; x, y : Integer ) : Integer;

implementation

uses
  Math;

const
  Einer = 1;
  Zweier = 2;
  Dreier = 3;
  Vierer = 4;

procedure FuelleBereich( var Spielfeld : TSpielfeld; VonX, BisX, VonY, BisY : Integer; Wert : Integer );
var
  LX : Integer;
  LY : Integer;
begin
  for LY := VonY to BisY do
    for LX := VonX to BisX do
      Spielfeld[LX, LY] := Wert;
end;

const
  Ausrichtung_Horizontal = 0;
  Ausrichtung_Vertikal = 1;

function KannSchiffDorthin( Spielfeld : TSpielfeld; x, y, Ausrichtung, Laenge : Integer ) : Boolean;
var
  LIdx : Integer;
begin
  Result := False;
  case Ausrichtung of
    Ausrichtung_Horizontal :
      begin
        if x + Laenge - 1 <= xMax then
        begin
          Result := True;
          for LIdx := x to x + Laenge - 1 do
          begin
            Result := Result and ( Spielfeld[LIdx, y] = Zelle_Wasser );
          end;
        end;
      end;
    Ausrichtung_Vertikal :
      begin
        if y + Laenge - 1 <= yMax then
        begin
          Result := True;
          for LIdx := y to y + Laenge - 1 do
          begin
            Result := Result and ( Spielfeld[x, LIdx] = Zelle_Wasser );
          end;
        end;
      end;
  end;
end;

procedure PositioniereSchiff( var Spielfeld : TSpielfeld; Laenge : Integer );
var
  LX, LY : Integer;
  LAusrichtung : Integer;
begin
  repeat
    LAusrichtung := Random( 2 );
    LX := Random( xMin + xMax + 1 ) + xMin;
    LY := Random( yMin + yMax + 1 ) + yMin;
  until KannSchiffDorthin( Spielfeld, LX, LY, LAusrichtung, Laenge );

  case LAusrichtung of
    Ausrichtung_Horizontal :
      begin
        FuelleBereich( Spielfeld, Max( xMin, LX - 1 ), Min( xMax, LX + Laenge ), Max( yMin, LY - 1 ), Min( yMax, LY + 1 ), Zelle_NebenSchiff );
        FuelleBereich( Spielfeld, LX, LX + Laenge - 1, LY, LY, Zelle_Schiff );
      end;
    Ausrichtung_Vertikal :
      begin
        FuelleBereich( Spielfeld, Max( xMin, LX - 1 ), Min( xMax, LX + 1 ), Max( xMin, LY - 1 ), Min( yMax, LY + Laenge ), Zelle_NebenSchiff );
        FuelleBereich( Spielfeld, LX, LX, LY, LY + Laenge - 1, Zelle_Schiff );
      end;
  end;

end;

procedure Vorbereiten( var Spielfeld : TSpielfeld );
begin
  FuelleBereich( Spielfeld, xMin, xMax, yMin, yMax, Zelle_Wasser );
  PositioniereSchiff( Spielfeld, Vierer );
  PositioniereSchiff( Spielfeld, Dreier );
  PositioniereSchiff( Spielfeld, Dreier );
  PositioniereSchiff( Spielfeld, Zweier );
  PositioniereSchiff( Spielfeld, Zweier );
  PositioniereSchiff( Spielfeld, Einer );
  PositioniereSchiff( Spielfeld, Einer );
end;

function IstSchiffVersenkt( Spielfeld : TSpielfeld; x, y : Integer ) : Boolean;
var
  LIdx : Integer;
begin
  Result := True;
  LIdx := x;
  while Result and ( LIdx >= xMin ) and ( ( Spielfeld[LIdx, y] = Zelle_Schiff ) or ( Spielfeld[LIdx, y] = Zelle_SchussSchiff ) ) do
  begin
    if Spielfeld[LIdx, y] = Zelle_Schiff then
      Result := False;
    Inc( LIdx, - 1 );
  end;
  LIdx := x;
  while Result and ( LIdx <= xMax ) and ( ( Spielfeld[LIdx, y] = Zelle_Schiff ) or ( Spielfeld[LIdx, y] = Zelle_SchussSchiff ) ) do
  begin
    if Spielfeld[LIdx, y] = Zelle_Schiff then
      Result := False;
    Inc( LIdx, 1 );
  end;
  LIdx := y;
  while Result and ( LIdx >= yMin ) and ( ( Spielfeld[x, LIdx] = Zelle_Schiff ) or ( Spielfeld[x, LIdx] = Zelle_SchussSchiff ) ) do
  begin
    if Spielfeld[x, LIdx] = Zelle_Schiff then
      Result := False;
    Inc( LIdx, - 1 );
  end;
  LIdx := y;
  while Result and ( LIdx <= yMax ) and ( ( Spielfeld[x, LIdx] = Zelle_Schiff ) or ( Spielfeld[x, LIdx] = Zelle_SchussSchiff ) ) do
  begin
    if Spielfeld[x, LIdx] = Zelle_Schiff then
      Result := False;
    Inc( LIdx, 1 );
  end;
end;

function IstFlotteVersenkt( Spielfeld : TSpielfeld ) : Boolean;
var
  LY : Integer;
  LX : Integer;
begin
  Result := True;
  for LY := yMin to yMax do
    for LX := xMin to xMax do
    begin
      if Spielfeld[LX, LY] = Zelle_Schiff then
        Result := False;
    end;
end;

function SchussAuf( var Spielfeld : TSpielfeld; x, y : Integer ) : Integer;
begin
  if InRange( x, xMin, xMax ) and InRange( y, yMin, yMax ) then
  begin
    if Spielfeld[x, y] < Schuss then
    begin
      case Spielfeld[x, y] of
        Zelle_Wasser :
          Result := Schuss_Wasser;
        Zelle_NebenSchiff :
          Result := Schuss_Wasser;
        Zelle_Schiff :
          Result := Schuss_Treffer;
      end;

      Spielfeld[x, y] := Spielfeld[x, y] + Schuss;

      if Result = Schuss_Treffer then
        if IstSchiffVersenkt( Spielfeld, x, y ) then
          if IstFlotteVersenkt( Spielfeld ) then
            Result := Schuss_FlotteVersenkt
          else
            Result := Schuss_SchiffVersenkt;
    end
    else
      Result := Schuss_Doppelt;
  end
  else
    Result := Schuss_Ausserhalb;
end;

end.

mkinzler 2. Mär 2014 17:28

AW: Schiffe versenken programmieren
 
Wenn du mit gültig: auf dem Brett meint, ja.
Mal dir das doch mal auf Papier auf und beschrifte die Matrix.

Popov 2. Mär 2014 17:31

AW: Schiffe versenken programmieren
 
@mkinzler

Du hast Recht. Auf der anderen Seite habe ich bereits die Probleme gleich am Anfang zukommen sehen. Ich hab gesehen, dass die Kenntnisse des TE, wenn überhaupt, nur rudimentär sind. Da geht man anders an die Lösung ran, nicht wie ein Profi, auch wenn es eigentlich den "einzig richtigen Weg" gibt. Was dem TE am Anfang für Lösungen für sein Projektplan geliefert wurde, da hätte sogar ich Probleme das umzusetzten. Ich wollte es von anfang an simpel machen. Und wenn es dem Programmierer am abstraktem Denkvermögen fehlt, dann soll er es Try and Error machen. Dann wird eben am Anfang eine Anzeige programmiert und er soll es testen.

Sir Rufo 2. Mär 2014 17:36

AW: Schiffe versenken programmieren
 
Zitat:

Zitat von mkinzler (Beitrag 1250279)
Wenn du mit gültig: auf dem Brett meint, ja.
Mal dir das doch mal auf Papier auf und beschrifte die Matrix.

Das funktioniert nicht, das habe ich gefühlt in jeder zweiten Antwort von mir gesagt und Reaktion war gleich 0

Zitat:

Zitat von Popov (Beitrag 1250281)
@mkinzler

Du hast Recht. Auf der anderen Seite habe ich bereits die Probleme gleich am Anfang zukommen sehen. Ich hab gesehen, dass die Kenntnisse des TE, wenn überhaupt, nur rudimentär sind. Da geht man anders an die Lösung ran, nicht wie ein Profi, auch wenn es eigentlich den "einzig richtigen Weg" gibt. Was dem TE am Anfang für Lösungen für sein Projektplan geliefert wurde, da hätte sogar ich Probleme das umzusetzten. Ich wollte es von anfang an simpel machen. Und wenn es dem Programmierer am abstraktem Denkvermögen fehlt, dann soll er es Try and Error machen. Dann wird eben am Anfang eine Anzeige programmiert und er soll es testen.

Absoluter Unsinn ... gerade wenn Projektteilnehmer nicht programmieren können, bleibt man so lange wie möglich weg von der Implementierung sondern schreibt das in verständlichen Worten auf.

Ein jeder, der dir einen Zusammenhang nicht erklären kann ohne sich hinter Fachtermini oder Implementationsgeschwafel zu verstecken, hat im Grunde keine Ahnung wie es funktioniert. Er weiß lediglich wo er mit dem Hammer hinschlagen muss, aber er weiß nicht warum und wieso.

Einfach mal in den nächsten Gesprächen darauf achten ... es geht immer mit einfachen Worten zu erklären ... es dauert länger, evtl. muss man weiter ausholen ... aber es geht.

DeddyH 2. Mär 2014 17:40

AW: Schiffe versenken programmieren
 
@Sir Rufo: :thumb: made my day

Popov 2. Mär 2014 17:41

AW: Schiffe versenken programmieren
 
@Sir Rufo

Den TE wird es freuen. Er wird vermutlich nichts davon verstehen, aber du hast dich durchgesetzt, den Code geliefert, dem TE einen einfachen Weg aufgezeigt. Vielleicht wird er das auch nehmen. Hast du das nötig gehabt? Der Lehrer wird erkennen, dass es nicht sein Code ist, somit ist alles was du hier geliefert hast absolut wertlos. Ich wollte dem TE langsam, aber selbst das Programm programmieren lassen. Jetzt ist es mit zu dumm es weiter zu machen. Der TE gehört dir.

Popov 2. Mär 2014 17:53

AW: Schiffe versenken programmieren
 
Zitat:

Zitat von Sir Rufo (Beitrag 1250283)
Absoluter Unsinn ...

Sir Rufo, ich bin seit 15 Jahren u. a. als Dozent tätig, bzw. führe Schulungen durch, als Ausbilder bin ich seit 30 Jahren tätig. Ich hab sehr oft mit blutigen Anfängern zu tun. Kannst du das auch vorweisen? Du hast sehr gute Kenntnisse als Programmierer, aber ich sage dir was - bei eurer Hilfe am Anfang musste ich nur Kopf schütteln. Didaktisch eine Katastrophe. Wenn ich von etwas eine Ahnung habe, dann wie man einen Anfänger an das Ziel bringe, denn das mache ich seit Jahren. Merke dir, programmieren können bedeutet nicht zu wissen wie man einem anderen das beibringen kann.

Und zu deinem Code, der ist eine Katastrophe. Programmtechnisch sehr gut, aber für einen Anfänger nicht zu gebrauchen. Den Code soll der TE verstehen? Bravo.

leodinho 2. Mär 2014 17:54

AW: Schiffe versenken programmieren
 
Zitat:

Zitat von Sir Rufo (Beitrag 1250278)
So, ich kann mir das Elend nicht mehr mit anschauen und hier ein fertiges Schiffe Versenken in einer Konsolen-Version und ohne Highscore.

Wie man sieht bleibt vom eigentlichen Spiel nicht viel mehr als Vorbereiten und SchussAuf.
Logisch, denn die Erfassung der Schusskoordinaten und Ausgabe des Spielfeldes gehört zum User-Interface und nicht zum Spiel, denn das Spiel funktioniert auch ohne User-Interface.

Es ist bewusst rudimentär gehalten ohne viel BlinkBlink um den Blick nicht vom Wesentlichen abzulenken.
Ich habe mir erlaubt keine Kommentare zu setzen, da der Code sich im Wesentlichen selber erklärt, bzw. der TE auch noch etwas zu tun haben soll.

Hautprogramm (User-Interface)
Delphi-Quellcode:
program sv;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  SysUtils,
  SchiffeVersenken in 'SchiffeVersenken.pas';

function ZeichenFuerZelle( Wert : Integer ) : Char;
begin
  case Wert of
    Zelle_Wasser :
      Result := '.';
    Zelle_NebenSchiff :
      Result := '.';
    Zelle_Schiff :
      Result := '.';
    Zelle_SchussWasser :
      Result := 'o';
    Zelle_SchussNebenSchiff :
      Result := 'o';
    Zelle_SchussSchiff :
      Result := 'X';
  end;
end;

procedure ZeigeSpielfeld( Spielfeld : TSpielfeld );
var
  LY : Integer;
  LX : Integer;
begin
  for LY := yMin to yMax do
  begin
    Write( chr( Ord( 'A' ) + LY ), ' ' );
    for LX := xMin to xMax do
      Write( ZeichenFuerZelle( Spielfeld[LX, LY] ) );
    WriteLn;
  end;
end;

function KoordinatenVonEingabe( const Eingabe : string; var x, y : Integer ) : Boolean;
begin
  Result := Length( Eingabe ) >= 2;

  if Result then
    Result := Ord( Eingabe[1] ) >= Ord( 'A' );

  if Result then
    y := Ord( Eingabe[1] ) - Ord( 'A' );

  if Result then
    Result := TryStrToInt( Copy( Eingabe, 2 ), x );

  if Result then
    x := x - 1;
end;

procedure Spiel;
var
  LSpielfeld : TSpielfeld;
  LSchussErgebnis : Integer;
  LSchussKoordinate : string;
  LX, LY : Integer;
begin
  Vorbereiten( LSpielfeld );
  repeat
    ZeigeSpielfeld( LSpielfeld );
    repeat
      repeat
        Write( 'Schuss auf: ' );
        Readln( LSchussKoordinate );
      until KoordinatenVonEingabe( LSchussKoordinate, LX, LY );
      LSchussErgebnis := SchussAuf( LSpielfeld, LX, LY );
      case LSchussErgebnis of
        Schuss_Wasser :
          WriteLn( 'Wasser' );
        Schuss_Treffer :
          WriteLn( 'Treffer' );
        Schuss_SchiffVersenkt :
          WriteLn( 'Treffer und Versenkt' );
        Schuss_FlotteVersenkt :
          WriteLn( 'Treffer, Versenkt und Gewonnen' );
        Schuss_Doppelt :
          WriteLn( 'Auf die Koordinaten ', LSchussKoordinate, ' wurde schon geschossen!' );
        Schuss_Ausserhalb :
          WriteLn( 'Koordinaten ', LSchussKoordinate, ' ungültig!' );
      end;
    until ( LSchussErgebnis <> Schuss_Doppelt ) or ( LSchussErgebnis <> Schuss_Ausserhalb );
  until LSchussErgebnis = Schuss_FlotteVersenkt;
end;

begin
  Randomize;
  try
    Spiel;
  except
    on E : Exception do
      WriteLn( E.ClassName, ': ', E.Message );
  end;
  Readln;

end.
und die Spiellogik
Delphi-Quellcode:
unit SchiffeVersenken;

interface

const
  xMin = 0;
  xMax = 11;
  yMin = 0;
  yMax = 11;

type
  TSpielfeld = array [xMin .. xMax, yMin .. yMax] of Integer;

const
  Zelle_Wasser = 0;
  Zelle_NebenSchiff = 1;
  Zelle_Schiff = 2;
  Schuss = 10;
  Zelle_SchussWasser = Zelle_Wasser + Schuss;
  Zelle_SchussNebenSchiff = Zelle_NebenSchiff + Schuss;
  Zelle_SchussSchiff = Zelle_Schiff + Schuss;

procedure Vorbereiten( var Spielfeld : TSpielfeld );

const
  Schuss_Wasser = 0;
  Schuss_Treffer = 1;
  Schuss_SchiffVersenkt = 2;
  Schuss_FlotteVersenkt = 3;
  Schuss_Doppelt = 4;
  Schuss_Ausserhalb = 5;

function SchussAuf( var Spielfeld : TSpielfeld; x, y : Integer ) : Integer;

implementation

uses
  Math;

const
  Einer = 1;
  Zweier = 2;
  Dreier = 3;
  Vierer = 4;

procedure FuelleBereich( var Spielfeld : TSpielfeld; VonX, BisX, VonY, BisY : Integer; Wert : Integer );
var
  LX : Integer;
  LY : Integer;
begin
  for LY := VonY to BisY do
    for LX := VonX to BisX do
      Spielfeld[LX, LY] := Wert;
end;

const
  Ausrichtung_Horizontal = 0;
  Ausrichtung_Vertikal = 1;

function KannSchiffDorthin( Spielfeld : TSpielfeld; x, y, Ausrichtung, Laenge : Integer ) : Boolean;
var
  LIdx : Integer;
begin
  Result := False;
  case Ausrichtung of
    Ausrichtung_Horizontal :
      begin
        if x + Laenge - 1 <= xMax then
        begin
          Result := True;
          for LIdx := x to x + Laenge - 1 do
          begin
            Result := Result and ( Spielfeld[LIdx, y] = Zelle_Wasser );
          end;
        end;
      end;
    Ausrichtung_Vertikal :
      begin
        if y + Laenge - 1 <= yMax then
        begin
          Result := True;
          for LIdx := y to y + Laenge - 1 do
          begin
            Result := Result and ( Spielfeld[x, LIdx] = Zelle_Wasser );
          end;
        end;
      end;
  end;
end;

procedure PositioniereSchiff( var Spielfeld : TSpielfeld; Laenge : Integer );
var
  LX, LY : Integer;
  LAusrichtung : Integer;
begin
  repeat
    LAusrichtung := Random( 2 );
    LX := Random( xMin + xMax + 1 ) + xMin;
    LY := Random( yMin + yMax + 1 ) + yMin;
  until KannSchiffDorthin( Spielfeld, LX, LY, LAusrichtung, Laenge );

  case LAusrichtung of
    Ausrichtung_Horizontal :
      begin
        FuelleBereich( Spielfeld, Max( xMin, LX - 1 ), Min( xMax, LX + Laenge ), Max( yMin, LY - 1 ), Min( yMax, LY + 1 ), Zelle_NebenSchiff );
        FuelleBereich( Spielfeld, LX, LX + Laenge - 1, LY, LY, Zelle_Schiff );
      end;
    Ausrichtung_Vertikal :
      begin
        FuelleBereich( Spielfeld, Max( xMin, LX - 1 ), Min( xMax, LX + 1 ), Max( xMin, LY - 1 ), Min( yMax, LY + Laenge ), Zelle_NebenSchiff );
        FuelleBereich( Spielfeld, LX, LX, LY, LY + Laenge - 1, Zelle_Schiff );
      end;
  end;

end;

procedure Vorbereiten( var Spielfeld : TSpielfeld );
begin
  FuelleBereich( Spielfeld, xMin, xMax, yMin, yMax, Zelle_Wasser );
  PositioniereSchiff( Spielfeld, Vierer );
  PositioniereSchiff( Spielfeld, Dreier );
  PositioniereSchiff( Spielfeld, Dreier );
  PositioniereSchiff( Spielfeld, Zweier );
  PositioniereSchiff( Spielfeld, Zweier );
  PositioniereSchiff( Spielfeld, Einer );
  PositioniereSchiff( Spielfeld, Einer );
end;

function IstSchiffVersenkt( Spielfeld : TSpielfeld; x, y : Integer ) : Boolean;
var
  LIdx : Integer;
begin
  Result := True;
  LIdx := x;
  while Result and ( LIdx >= xMin ) and ( ( Spielfeld[LIdx, y] = Zelle_Schiff ) or ( Spielfeld[LIdx, y] = Zelle_SchussSchiff ) ) do
  begin
    if Spielfeld[LIdx, y] = Zelle_Schiff then
      Result := False;
    Inc( LIdx, - 1 );
  end;
  LIdx := x;
  while Result and ( LIdx <= xMax ) and ( ( Spielfeld[LIdx, y] = Zelle_Schiff ) or ( Spielfeld[LIdx, y] = Zelle_SchussSchiff ) ) do
  begin
    if Spielfeld[LIdx, y] = Zelle_Schiff then
      Result := False;
    Inc( LIdx, 1 );
  end;
  LIdx := y;
  while Result and ( LIdx >= yMin ) and ( ( Spielfeld[x, LIdx] = Zelle_Schiff ) or ( Spielfeld[x, LIdx] = Zelle_SchussSchiff ) ) do
  begin
    if Spielfeld[x, LIdx] = Zelle_Schiff then
      Result := False;
    Inc( LIdx, - 1 );
  end;
  LIdx := y;
  while Result and ( LIdx <= yMax ) and ( ( Spielfeld[x, LIdx] = Zelle_Schiff ) or ( Spielfeld[x, LIdx] = Zelle_SchussSchiff ) ) do
  begin
    if Spielfeld[x, LIdx] = Zelle_Schiff then
      Result := False;
    Inc( LIdx, 1 );
  end;
end;

function IstFlotteVersenkt( Spielfeld : TSpielfeld ) : Boolean;
var
  LY : Integer;
  LX : Integer;
begin
  Result := True;
  for LY := yMin to yMax do
    for LX := xMin to xMax do
    begin
      if Spielfeld[LX, LY] = Zelle_Schiff then
        Result := False;
    end;
end;

function SchussAuf( var Spielfeld : TSpielfeld; x, y : Integer ) : Integer;
begin
  if InRange( x, xMin, xMax ) and InRange( y, yMin, yMax ) then
  begin
    if Spielfeld[x, y] < Schuss then
    begin
      case Spielfeld[x, y] of
        Zelle_Wasser :
          Result := Schuss_Wasser;
        Zelle_NebenSchiff :
          Result := Schuss_Wasser;
        Zelle_Schiff :
          Result := Schuss_Treffer;
      end;

      Spielfeld[x, y] := Spielfeld[x, y] + Schuss;

      if Result = Schuss_Treffer then
        if IstSchiffVersenkt( Spielfeld, x, y ) then
          if IstFlotteVersenkt( Spielfeld ) then
            Result := Schuss_FlotteVersenkt
          else
            Result := Schuss_SchiffVersenkt;
    end
    else
      Result := Schuss_Doppelt;
  end
  else
    Result := Schuss_Ausserhalb;
end;

end.

Du hättest dir nicht die mühe machen sollen /:
Ich werde meins so wie es jetzt ist abgeben, da es das ist was ich zustande gebracht habe.. egal was dabei rauskommt..

Trotzdem nochmal danke für eure hilfe aber programmieren ist nicht mein ding /:

Sir Rufo 2. Mär 2014 18:02

AW: Schiffe versenken programmieren
 
Zitat:

Zitat von Popov (Beitrag 1250290)
Zitat:

Zitat von Sir Rufo (Beitrag 1250283)
Absoluter Unsinn ...

Sir Rufo, ich bin seit 15 Jahren u. a. als Dozent tätig, bzw. führe Schulungen durch, als Ausbilder bin ich seit 30 Jahren tätig. Ich hab sehr oft mit blutigen Anfängern zu tun. Kannst du das auch vorweisen? Du hast sehr gute Kenntnisse als Programmierer, aber ich sage dir was - bei eurer Hilfe am Anfang musste ich nur Kopf schütteln. Didaktisch eine Katastrophe. Wenn ich von etwas eine Ahnung habe, dann wie man einen Anfänger an das Ziel bringe, denn das mache ich seit Jahren. Merke dir, programmieren können bedeutet nicht zu wissen wie man einem anderen das beibringen kann.

Und zu deinem Code, der ist eine Katastrophe. Programmtechnisch sehr gut, aber für einen Anfänger nicht zu gebrauchen. Den Code soll der TE verstehen? Bravo.

Na denn ...

leodinho 2. Mär 2014 18:46

AW: Schiffe versenken programmieren
 
@Popov

Soll ich nochmal neu anfangen und mir jetzt schritt für schritt alles erklären lassen von dir?
wäre der Beste weg, auch wenn ich es bis dienstag nicht fertig bekomme , will ich weiterkommen als bisher.. Ich hab grad n Motivationsschub :thumb:

Sherlock 3. Mär 2014 15:24

AW: Schiffe versenken programmieren
 
Nix für ungut, aber ich denke ab jetzt könnt ihr das per PN klären...

Sherlock

Mavarik 4. Mär 2014 02:07

AW: Schiffe versenken programmieren
 
Liste der Anhänge anzeigen (Anzahl: 2)
hmm... Konnte es nicht lassen...:stupid:

Ist zwar "nur" 2D...

Bekannte Fehler:
- In der Computer KI ist noch irgendwo ein kleiner Fehler für die Berechnung des nächsten Schusses..
- Es gibt noch eine kleine Lücke, wenn man zu früh klickt bei einem Gegner-Treffen, läuft die Animation falsch...

Und die KI ist noch nicht optimiert, nur in den Lücken zu suchen wo auch noch die fehlenden Schiffe reinpassen...

Egal... ist schon "Spielbar"...

Kleine Schwierigkeit... Es wird nicht angezeigt auf welches Feld schon geschossen wurde...
Das gleicht ein bisschen den "Doofen-Random" aus, da die KI es sich natürlich merkt...

Grüsse Mavarik


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:38 Uhr.
Seite 5 von 5   « Erste     345   

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