![]() |
Schiffe versenken (zum XX-ten Mal :3 )
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Dpler, Ich habe mich auch mal an ein Schiffe versenken rangesetzt, in bin für meine Verhältnisse und Programmierkenntnisse ziemlich weit gekommen :D
Bei meinem Schiffe versenken, spielen 2 Leute gegeneinander, erst können sie ein Schiff setzen, und anschließend auf das andere Spielfeld feuern :)) -> Im Anhang befindet befindet sich alles und alles ;) (Bitte nicht über den Quellcode aufregen. So wie ich es aufgeschrieben habe, verstehe ich es einigermaßen!) Aber wie gesagt, man kann leider nur 1 (sprich EIN) Schiff setzen :(:( , da ich denke das man einfach später nach und nach weitere Schiffe anfügen kann <,< Aber irgendwie erweist sich das schwerer als gedacht. Ich habe mir das so gedacht: Es befindet sich eine Radiogroup auf der Form, die dir zeigt, welches Schiff du jetzt setzen musst, anschließend kannst du zwischen waagerecht und senkrecht auswählen. Wenn man jetzt auf das Stringgrid klickt, wird das komplette Schiff gesetzt. Anschließend wandert der Pinökel von der Radiogroup eins weiter, und nun kannst du das nächste Schiff setzen. Und so weiter, insgesamt von 5-2. _________________________ In der "Aufs-stringgrid-klicken"-prozedur befindet sich der Hauptquelltext. Wenn man jetzt auf eine Zelle klickt, wird zuerst geschaut, ob man sich gerade im Setzen-Modus oder im Schießen-modus befindet. Beim Setzenmodus: 1. Wo befindet sich der Pinökel? Waagerecht/senkrecht, Schiff für 5/4/3/2 Kästchen? Und nun wäre es doch am besten eine neue Prozedur zu schreiben, womit man testen kann, ob sich ein Schiff dort befindet, bzw, ob es direkt neben einem Schiff sein würde. Aber mein Gedankengang bei der Programmierung will, glaube ich, nicht so wirklich aufgehen ^^ hat jemand eine Idee, wie ich das Abfragen kann, bzw. ändern kann? Grüße Grayknife |
AW: Schiffe versenken (zum XX-ten Mal :3 )
Edit: Man könnte ja einfach schauen, ob um das schiff rum schon was liegt. Man würde dann in die Prozedur, die Spalte, die Zeile und die Anzahl übergeben. Es gibt eine Prozedur für waagerecht und eine prozedur für senkrecht. in der Prozedur wird bei waagerecht, dann die Zeile-1 gerechnet, um zuschauen ob darüber eine 1 ist, dann wird die Zeile+1 gerechnet, dann, die gleiche Zeile nur die Spalte-1 und dann nochmal Spalte+1. Bei meinem Programm ist das halt so, dass, wenn man einmal klickt, sich alle 5 Zellen in die jeweilige Richtung automatisch füllen
Delphi-Quellcode:
Wenn ich jetzt spezifisch auch beim ersten Schiff schon alles abfrage:
if (radiobutton1.checked=True) and ((Spalte<4)) then begin //waagerecht setzen. Spalte<4, damit es nicht über den Rand hinausragt..
PlaySound(PChar('AyeSir1'),HInstance,SND_Resource or SND_Async); //Sound abspielen. for I:=Spalte to Spalte+4 do SetzeSchiff1(I,Reihe); //Fünf mal die 1 wird im Array gespeichert. stringgrid1.Enabled:=False; //Deaktivieren des Grids1, //damit nichts weiter gesetzt werden kann.
Delphi-Quellcode:
Die
IF start=0 then begin //Prozeduren fürs Schiffe setzen.
Stringgrid1.MouseToCell(X,Y,Spalte,Reihe); //Abfrage, welche Zelle ausgewählt wurde. //----------------------------------------------------------------------------- Case Radiogroup1.ItemIndex of 0:begin if (radiobutton1.checked=True) and (Schifftesten1(Spalte,Reihe,4)=True) and ((Spalte<4)) then begin //waagerecht setzen. PlaySound(PChar('AyeSir1'),HInstance,SND_Resource or SND_Async); //Sound abspielen. for I:=Spalte to Spalte+4 do SetzeSchiff1(I,Reihe); //Fünf mal die 1 wird im Array gespeichert.
Delphi-Quellcode:
-Prozedur ist hierbei dann wichtig:
Schifftesten1
Delphi-Quellcode:
So habe ich mir das gedacht, aber Ich glaube ich setze meine Gedanken falsch um :S :( :S
function Tform1.SchiffTesten1(Spalte,Reihe, Anz:Integer):Boolean;
var i,Ges:Integer; begin Ges:=0; For i:=Spalte to Spalte+Anz do begin if (Spielfeld1[I,Reihe]=0) then inc(Ges); //Liegt auf dem Schiff was? if (Spielfeld1[I,Reihe-1]=0) then inc(ges); //Liegt überhalb des Schiffes was? if (Spielfeld1[I,Reihe+1]=0) then inc(ges); //Unterhalb? End; If (Spielfeld1[Spalte-1,Reihe]=0) then inc(ges); //vor dem Schiff? If (Spielfeld1[Spalte+Anz+1,Reihe]=0) then inc(ges); //Hinter dem schiff? If (Anz=4) and (Ges=17) then result:=True Else result:=False; // If Anz=3 and Ges=14... // If Anz=2 and Ges=11... End; Versteht ihr, wie ich das denke? :roll::roll: Und noch ein Update-Edit <,< vllt sollte ich erst denken und dann schreiben ^^
Delphi-Quellcode:
Und:function Tform1.SchiffTesten1(Spalte,Reihe, Anz:Integer):Boolean; var i,Ges:Integer; begin Ges:=0; For i:=Spalte to Spalte+Anz do begin if (Spielfeld1[I,Reihe]=0) then Ges:=Ges+1; //Liegt auf dem Schiff was? if (Spielfeld1[I,Reihe-1]=0) then Ges:=Ges+1; //Liegt überhalb des Schiffes was? if (Spielfeld1[I,Reihe+1]=0) then Ges:=Ges+1; //Unterhalb? End; If (Spielfeld1[Spalte-1,Reihe]=0) then Ges:=Ges+1; //vor dem Schiff? If (Spielfeld1[Spalte+Anz+1,Reihe]=0) then Ges:=Ges+1; //Hinter dem schiff? Case Anz of 4: If Ges=17 then result:=True else result:= false; 3: If Ges=14 then result:=True else result:= false; 2: If Ges=11 then result:=True else result:= false; 1: If Ges=8 then result:=True else result:= false; End; End;
Delphi-Quellcode:
Jetzt bin ich soweit, klappt auch einigermaßen, aber irgendwie möchte er bei manchen Feldern trotzdem nichts setzen...
procedure TForm1.StringGrid1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer); var Spalte,Reihe,I:Integer; begin IF start=0 then begin //Prozeduren fürs Schiffe setzen. Stringgrid1.MouseToCell(X,Y,Spalte,Reihe); //Abfrage, welche Zelle ausgewählt wurde. //----------------------------------------------------------------------------- Case Radiogroup1.ItemIndex of 0:begin if (radiobutton1.checked=True) and ((Spalte<4)) and (Schifftesten1(Spalte,Reihe,4)=True)then begin //waagerecht setzen. PlaySound(PChar('AyeSir1'),HInstance,SND_Resource or SND_Async); //Sound abspielen. for I:=Spalte to Spalte+4 do SetzeSchiff1(I,Reihe); //Fünf mal die 1 wird im Array gespeichert. radiogroup1.ItemIndex:=1; End; { if (radiobutton2.Checked=True) and ((Reihe<4)) then begin //senkrecht setzen. PlaySound(PChar('AyeSir1'),HInstance,SND_Resource or SND_Async); for I:=Reihe to Reihe+4 do SetzeSchiff1(Spalte,I); //s.o. End; } ZeigeSpielfeld1; End; 1:begin if (radiobutton1.checked=True) and ((Spalte<5)) and (Schifftesten1(Spalte,Reihe,3)=True) then begin PlaySound(PChar('AyeSir1'),HInstance,SND_Resource or SND_Async); for I:=Spalte to Spalte+3 do SetzeSchiff1(I,Reihe); radiogroup1.ItemIndex:=2; end; ZeigeSPielfeld1; end; 2:begin if (radiobutton1.checked=True) and ((Spalte<6)) and (Schifftesten1(Spalte,Reihe,2)=True) then begin PlaySound(PChar('AyeSir1'),HInstance,SND_Resource or SND_Async); //Sound abspielen. for I:=Spalte to Spalte+2 do SetzeSchiff1(I,Reihe); Radiogroup1.ItemIndex:=3; end; ZeigeSPielfeld1; end; 3:begin if (radiobutton1.checked=True) and ((Spalte<7)) and (Schifftesten1(Spalte,Reihe,1)=True) then begin PlaySound(PChar('AyeSir1'),HInstance,SND_Resource or SND_Async); //Sound abspielen. for I:=Spalte to Spalte+1 do SetzeSchiff1(I,Reihe); stringgrid1.Enabled:=False; // Deaktivieren des Grids, Button3.Enabled:=True; //damit nichts weiter gesetzt werden kann. Button3.Visible:=True; end; ZeigeSPielfeld1; End; End; Und wie verhält sich das eigentlich am "Rand" des Arrays? Wenn ich ganz links an der Kante bin, und dann nochmal Reihe-1 rechne, was macht mein Delphi dann da? |
AW: Schiffe versenken (zum XX-ten Mal :3 )
Zum Thema Schiffe Versenken ist doch schon hinreichend - auch von mir - geschrieben worden und dieser Thread ist dir auch bekannt. Da habe ich mich lang und breit dazu ausgelassen, auch dass man sich erst einen Plan machen soll (Bleistift und viel Papier), weil man sich ohne diese Zettel schnell verzettelt.
|
AW: Schiffe versenken (zum XX-ten Mal :3 )
Ja ich weiß, tut mir Leid.. -.-" :(
vielleicht hätte ich mir auch einen Plan machen sollen <,< Aber sonst wollt ihr auch immer, das wir das selber lösen, und das ist meine Lösung ;3 |
AW: Schiffe versenken (zum XX-ten Mal :3 )
Schießen sich Planung und Eigeninitiative neuerdings gegenseitig aus? Wieso informiert mich niemand darüber?
|
AW: Schiffe versenken (zum XX-ten Mal :3 )
Ich weiß jetzt nicht genau...
dann also einfach eine Frage: Was passiert, wenn ich diese Prozedur aufrufe:
Delphi-Quellcode:
und zwar mit dem Spaltenwert=0. Dann wird bei dem einen Aufruf 0-1 also -1 gerechnet. Das Array geht aber nur von 0-7. bricht er dann den Vorgang ab?
function Tform1.SchiffTesten1(Spalte,Reihe, Anz:Integer):Boolean;
var i,Ges:Integer; begin Ges:=0; //... If (Spielfeld1[Spalte-1,Reihe]=0) then inc(ges); //vor dem Schiff? If (Spielfeld1[Spalte+Anz+1,Reihe]=0) then inc(ges); //Hinter dem schiff? If (Anz=4) and (Ges=17) then result:=True Else result:=False; // If Anz=3 and Ges=14... // If Anz=2 and Ges=11... End; Denn wenn ich einfach ein kleines Testprogramm schreibe und auf einen Wert, der kleiner als 0 ist, zugreife, zeigt er mir eine Fehlermeldung an :( |
AW: Schiffe versenken (zum XX-ten Mal :3 )
Kommt darauf an: ohne Bereichsprüfung merkst Du nicht, dass Du auf irgendwelchen Schrott zugreifst. Bei aktivierter Bereichsprüfung bekommst Du eine Fehlermeldung.
|
AW: Schiffe versenken (zum XX-ten Mal :3 )
Achso, selbstgeschriebene Prozeduren, testen also nicht, ob es den Bereich überhaupt gibt?
Also müsste ich noch eine(oder mehrere) Prozedur schreiben, wenn die Spalte bzw. die Zeile 0 ist? damit dort gar nicht über oder links neben dem Schiff abgefragt wird? |
AW: Schiffe versenken (zum XX-ten Mal :3 )
Eine einfache If-Abfrage vor dem Zugriff sollte genügen.
Delphi-Quellcode:
Das Gleiche dann äquivalent auf der anderen Seite.
if Spalte > Low(Spielfeld1) then
If (Spielfeld1[Spalte-1,Reihe]=0) then inc(ges); |
AW: Schiffe versenken (zum XX-ten Mal :3 )
Okey, und dieses low(Spielfeld1), gibt genau welchen wert an? :roll:
|
AW: Schiffe versenken (zum XX-ten Mal :3 )
Guckst Du
![]() |
AW: Schiffe versenken (zum XX-ten Mal :3 )
ok, jetzt kann jeder spieler 6 schiffe setzen mit verschiedener Größe, nur an Positionen die erlaubt sind. Cool :D
Jetzt wollte ich theoretisch einfach die Zahlen durch Bilder ersetzen, aber ich habe keinen Plan wie ich das machen soll :( Wenn ich zum beispiel mit canvas eine Bitmap grafik in das stringgrid einfügen möchte, verschwindet das sofort wieder >.< . Kann ich das auch noch anders lösen? (wie sieht es mit drawgrid aus? ist das anders? habe auch gelesen einfach ein riesiges TImage machen?) |
AW: Schiffe versenken (zum XX-ten Mal :3 )
Im Prinzip ist es Wurst, wie du es machst. Wenn du auf den Canvas zeichnest, dann musst du dafür sorgen, dass es bei einem Refresh/Repaint wieder gezeichnet wird.
Dafür gibt es bei den (grafischen) Komponenten das Ereignis
Delphi-Quellcode:
und die Grids haben so ein Ereignis auch noch für jede Zelle.
OnPaint
|
AW: Schiffe versenken (zum XX-ten Mal :3 )
Kannst du mir das genauer erklären? Wo genau finde ich das Ereignis OnPaint? o: Wenn ich jetzt im OI in die Ereignisse vom Stringgrid gehe, finde ich da nichts was sich wie OnPaint und Zelle anhört :roll: :pale:
|
AW: Schiffe versenken (zum XX-ten Mal :3 )
![]() |
AW: Schiffe versenken (zum XX-ten Mal :3 )
Ahja klar. Man bin ich doof <,< Draw und Paint und so :D . Ok, Ich versuche mich damit mal durchzufuchsen :wink:
|
AW: Schiffe versenken (zum XX-ten Mal :3 )
So, an dieser Stelle möchte ich euch gerne das eigentlich fertige Programm einmal zeigen :)
Das Spiel ist für 2 Spieler ausgelegt. Gerne sind Verbesserungsvorschläge gesehen! Im Anhang die .Zip-Datei, die die .Exe und einen Ordner mit benötigten Elementen enthält. Edit: Da die maximale Größe der Zip-Datei 5MB sein darf, habe ich hier einen Dropbox-Link: ![]() |
AW: Schiffe versenken (zum XX-ten Mal :3 )
Zitat:
- Ich kann kein Schiff setzen und das Spiel nicht starten... - Spieler Namen mit Passwort? |
AW: Schiffe versenken (zum XX-ten Mal :3 )
Ohne Quellen werd ich die Exe nicht mal aus dem Zip rausholen...Sorry. Das ist mir zu riskant.
Sherlock |
AW: Schiffe versenken (zum XX-ten Mal :3 )
Zitat:
|
AW: Schiffe versenken (zum XX-ten Mal :3 )
@Grayknife
40 MB gepackt? Wie groß ist noch mal Office 2013? Viel größer kann es nicht sein. Entpackt macht die Exe 49 MB. Entfernt man die Wavs, macht das etwas über 3 MB große Datei. Ich denke alleine 40 MB macht die gewaltige Eröffnungsmelodie. Auch ist es nicht nötig Bitmaps als Hintergrund zu nehmen. Warum keine Jpegs? Die machen etwa 2% der Größe aus. Die Konvertierung ist ein Kinderspiel. Beispiel (aus dem Kopf):
Delphi-Quellcode:
Dann die Sache mit dem Passwort. Das scheint dir ganz wichtig zu sein. Ok, meinetwegen. Aber du wurdest mehrmals drauf hingewiesen ein Ausstieg aus der Passwortabfrage zu liefern. Jeder macht es. Dein Programm muss man mit dem Taskmanager abschießen wenn man das Passwort nicht mehr weiß.
uses
Jpeg; procedure LoadJpegToBitmap(const FileName: String; Bitmap: TBitmap); var Jpg: TJPEGImage; begin Jpg := TJPEGImage.Create; try Jpg.LoadFromFile(FileName); Bitmap.Assign(Jpg); finally Jpg.Free; end; end; procedure TForm1.Button1Click(Sender: TObject); var Bmp: TBitmap; begin Bmp := TBitmap.Create; try //Bmp.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Bild1.bmp'); LoadJpegToBitmap(ExtractFilePath(ParamStr(0)) + 'Bild1.jpg', Bmp); Canvas.Draw(0, 0, Bmp); finally Bmp.Free; end; end; Und noch was ist mir in der einen Minute aufgefallen: man weiß nie wer gerade dran ist. Wie wäre es mit einem Hinweis? |
AW: Schiffe versenken (zum XX-ten Mal :3 )
Okey, also Jpeg Bilder verwenden (y).
Hinweis einblenden, wer dran ist, gute Idee (y). Zur Not kann man doch einfach Alt+F4 drücken, um aus der Passwortabfrage zu kommen. Oder ist das nicht legitim? :? Kann ich auch die WAVE-Dateien verkleinern? @Sherlock, wie kann ich das erreichen? Quellen: Grayknife? ^^ |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:31 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz