C++ Schiffe Versenken



  • @asdfsf:

    Okay...
    Ich hab echt nicht die geringste Ahnung was du da geschrieben hast, hab zwar schonmal von Klassen gehört, weiß aber nicht was das ist. Könntest du vllt mal mit Kommentaren versehen, was du geschrieben hast?
    Und was ist das Ziel von dem was du da geschrieben hast?


  • Mod

    Ich denke, das was asdfsf vorschlägt, ist hier wohl etwas zu hoch für den vorhandenen Kenntnisstand. Ich sehe auch nicht, wozu das hier überhaupt nötig sein sollte, denn es hat keinen Vorteil gegenüber dem verschachtelten Array (siehe mein vorheriger Beitrag), es ist bloß viel umständlicher. Daher würde ich das verschachtelte Array nehmen.



  • Ok, dann werde ich die nehmen. Danke 😉
    Würde ich das hier:

    #define SCHWARZ			0x0000
    #define DUNKELBLAU		0x0001
    #define DUNKELGRÜN		0x0002
    #define DUNKELTÜRKIS	0x0003
    #define DUNKELROT		0x0004
    #define LILA			0x0005
    #define GOLD			0x0006
    #define GRAU			0x0007
    #define DUNKELGRAU		0x0008
    #define BLAU			0x0009
    #define GRÜN			0x000a
    #define TÜRKIS			0x000b
    #define ROT				0x000c
    #define PINK			0x000d
    #define GELB			0x000e
    #define WEIß			0x000f
    

    dann so schreiben?:

    enum Farben {
    	SCHWARZ,
    	DUNKELBLAU,
    	DUNKELGRÜN,
    	DUNKELTÜRKIS,
    	DUNKELROT,
    	LILA,
    	GOLD,
    	GRAU,
    	DUNKELGRAU,
    	BLAU,
    	GRÜN,
    	TÜRKIS,
    	ROT,
    	PINK,
    	GELB,
    	WEIß
    }
    

  • Mod

    Bezüglich Farbenenum: Ist jedenfalls ein Fortschritt gegenüber Makros. Allgemein würde ich Umlaute weglassen, da es auch viele Compiler gibt, die streng auf ASCII für Bezeichner bestehen. Und wenn man schon dabei ist, würde ich auf Englisch programmieren, sofern es keine große Mühe ist. Ist sicherlich gut, sich frühzeitig da dran zu gewöhnen, früher oder später wird man ohnehin auf englisch programmieren.



  • Ja, ich wollte eigentlich auf Englisch programmieren, aber da ich die Ausgaben auch auf Deutsch habe, dachte ich mir mach ich doch alles auf Deutsch. Aber ok, werde es mir merken!

    EDIT: Und wie würde ich die Farben dann verwenden? Weil denen wurde doch jetzt kein Wert zugewiesen, oder?



  • jkhsjdhjs schrieb:

    EDIT: Und wie würde ich die Farben dann verwenden? Weil denen wurde doch jetzt kein Wert zugewiesen, oder?

    Doch.
    Der erste Wert eines Enums erhält die Nummer 0, alle anderen dann aufsteigend.
    Du kannst ihnen aber auch manuell Werte zuweisen.


  • Mod

    jkhsjdhjs schrieb:

    EDIT: Und wie würde ich die Farben dann verwenden?

    Wenn du es so wie hier definierst ( enum name { ... } ), dann gelten die Bezeichner im umgebenden Namensraum (also in der Regel überall, wenn du keine Namensräume benutzt). Das heißt, du kannst wirklich "SCHWARZ" im Programm schreiben und es ist wie eine Zahl mit Wert 0.

    Ab C++11 gibt es neu die "strongly-typed" enums, die mittels enum class name { ... }; definiert werden. Diese unterliegen einer strengen Typprüfung (es ist also nicht mehr möglich, ein Wert aus einem enum dort zu benutzen, wo ein anderes enum erwartet wird) und die Elemente sind nun ebenfalls im jeweiligen Scope des enums. Bei enum Farben {SCHWARZ, ...}; also zum Beispiel Farben::SCHWARZ .

    Was davon besser geeignet ist, kommt auf den Einzelfall an. Die alte Methode provoziert Namenskonflikte. Manchmal sollen die Bezeichner aber auch wirklich überall gelten. Farbwerte sind ein bisschen ein Grenzfall. Man kann leicht Beispiele konstruieren, wo die alte Methode unpassend ist, aber hier würde ich sagen, passt keiner dieser Fälle und ich würde es so machen, wie du es hier vorschlägst.

    Weil denen wurde doch jetzt kein Wert zugewiesen, oder?

    Wenn man nichts anderes angibt, dann gehen die Werte bei 0 los und sind dann jeweils um 1 aufsteigend. Hier passt also alles schon, sofern du keine Farben vergessen hast. Besserer Stil wäre es daher wohl (um solche Fehler zu vermeiden) allen Farben einen Wert zu zu weisen:

    enum foo
    {
      hundert = 100, 
      tausend = 1000, 
      million = 1000000
    };
    

    P.S.: In deinem Codebeispiel fehlen übrigens die Kommas zwischen den Werten, aber das hast du sicherlich schon bemerkt.



  • @Nathan:
    Aber ich brauche ja den Wert 0x0001 und nicht 1 oder ist das egal?

    @SeppJ:
    Danke, muss jetzt erstmal deinen Post komplett lesen, und nein, hatte es noch nicht gemerkt, hatte die komplett vergessen, ich editiers grad


  • Mod

    Wie viel ist denn 0x0001, wenn du es als Dezimalzahl schreibst?



  • Ok, ja das wird mir jetzt auch klar ^^

    Dann könnte ich doch auch schon vorher als ich noch #define verwendet habe, nur 1 schreiben. Habe das mit den Farben von irgendner Seite, die auf Google war. Da stand das mit dem 0x0001

    EDIT: Und seit wann gibt es C++ 11? Ich nutze Visual Studio 2008

    EDIT2: Und kommen bei enumeratoren dann nach 9 auch a,b,c usw?

    EDIT3: Und wie würde ein typedef für ein 2 Dimensionales Array aussehen?
    Habe das eben gegoogled, kam aber auf Schwachsinn, der nicht funktioniert hat 😃
    :

    typedef array<array<int, d_array;
    

    So leicht geht das dann doch nicht, oder? ^^
    Ich habe auch von typedef mit Parameter gelesen, ich muss warscheinlich solche nehmen, oder?

    Und wie teile ich Programmcode auf mehrere Dateien auf?
    Das wurde mir ja auch am Anfang geraten.

    Könnte mir bitte jemand all diese Fragen beantworten? Danke 😉



  • @asdfsdf:

    Bei deinem code für die Koordinatenverarbeitung bekomme ich die Meldung, dass tolower kein Element von std ist.

    und @ Mods: Sry für Doppelpost. Aber sonst hätte nie jemand den Post gesehn, wenn ich nur editiert hätte.



  • jkhsjdhjs schrieb:

    Bei deinem code für die Koordinatenverarbeitung bekomme ich die Meldung, dass tolower kein Element von std ist.

    #include <cctype>



  • Danke, funktioniert perfekt 😉



  • Für globale Funktionen (ohne Klassen) kannst du dich ersteinmal an http://www.mikrocontroller.net/articles/Funktionen_auslagern_(C) halten.
    Wichtig ist ein Verständnis von Headerdateien zu erhalten.



  • Ok, Danke. Ich verstehe jetzt wie man ein Programm in mehrere Dateien aufteilt. Was ich aber immer noch nicht weiß ist, was es mir bringt, wenn ich das Programm aufteile?



  • Stichwort: Modularität

    Wenn du beispielsweise die interne Spiellogik von der Ein- und Ausgabe getrennt hast, dann könntest du irgendwann einfach diese Spiellogik-Dateien nehmen und statt der Konsole ein Projekt mit einer Windows-GUI erstellen.
    Außerdem gibt es eine Richtlinie, daß einzelnen Dateien nicht größer als ca. 1000 Zeilen groß sein sollten (damit man noch einen Überblick darüber hat).

    P.S. Ich muss sagen, dein Code hat mich sehr an meine ersten BASIC Programme erinnert (auf dem C16 bzw. C64) - trotz C++. Und daher verstehe ich auch, warum es für Anfänger einfacher ist mit Imperative Programmierung zu beginnen (und so zu denken) als gleich mit objektorientierter Programmierung (und Denkweise).
    Als nächsten Schritt solltest du deinen Code in kleinere Funktionen unterteilen (am besten gleich so, daß du Eingabe, Verarbeitungsfunktionen (Spiellogik) und Ausgabe getrennt hältst).
    Und viele deiner bisherigen Codezeilen lassen sich stark vereinfache. Laß einfach den Computer für dich rechnen, anstatt selber, z.B. deine switch-case-Anweisungen:

    Pair Koordinatenverarbeitung(int x, int y) // oder besser char x, char y
    {
      int x1 = 0;
    
      if (x >= 'A' && x <'Z')
        x1 = 10 * (x - 'A' + 1);
      else if (x >= 'a' && x <'z')
        x1 = 10 * (x - 'a' + 1);
    
      // ähnliches für y
      // ...
    }
    

    (oder zusätzlich noch toupper() bzw. tolower() verwenden, damit man nur einmal die Formel hinschreiben braucht)

    Oder deine AppData-Zuweisung zu

    strcpy(&appdata[i], "\\C++ Schiffe versenken\\Optionen.cfg");
    

    usw...

    Viel Spaß und Erfolg weiterhin.



  • Ok, Danke für deine Tipps!

    Die switch case in der Koordinatenverarbeitung habe ich schon durch tolower ersetzt.

    Das mit Appdata werd ich auch noch änder, Danke. Nachdem ich damit fertig bin teil ich das Programm dann mal auf



  • Konnte jetzt ein paar Tage nicht weiter dran arbeiten, habe aber jetzt wieder Zeit.

    Wenn ich das mit dem strcpy verwende, bekomme ich folgenden Fehler:
    error C2664: 'strcpy': Konvertierung des Parameters 1 von 'TCHAR *' in 'char *' nicht möglich
    Die Typen, auf die verwiesen wird, sind nicht verknüpft; die Konvertierung erfordert einen reinterpret_cast-Operator oder eine Typumwandlung im C- oder Funktionsformat.

    Was könnte ich den sonst nehmen um einen String an ein TCHAR "dranzuhängen"?



  • Das liegt am MSVC. Du scheinst mit Unicode Support* zu kompilieren.

    *Weitet sich das TCHAR Gedöns echt bis auf strcpy aus???



  • Was meinst du mit deinem letzten Satz?

    EDIT: Und kann ich Unicode Support deaktivieren bzw. ist Unicode Support für irgendwas wichtig?


Anmelden zum Antworten