Du bist nicht angemeldet.

Werbeanzeige

1

09.05.2020, 16:59

Aufgabenstellung 5.11

Ich hab mich jetzt über einen Tag mit der Aufgabe aussernandergesetzt und es einfach nicht geschafft sie zu lösen. :(
Nichts ausser das Menü funktioniert.

Hier der Lösungscode vom Buch:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
// C++ für Spieleprogrammierer
// Listing 5.8
// Lösungsvorschlag zur Aufgabe in Kapitel 5
//
#include <iostream>

using namespace std;

// Strukturen
//
struct S_FeldInfo
{
    bool Besetzt;
    char Name[30];
};

// Variablen und Konstanten
//
const int Breite = 5;
const int Hoehe = 5;
S_FeldInfo Spielfeld[Breite][Hoehe];

// Prototypen
//
void LoescheSpielfeld ();
void ZeigeSpielfeld ();
void ZeigeFelddaten ();
void BesetzeFeld ();

// Hauptprogramm
//
int main ()
{
    int Auswahl = 0;

    LoescheSpielfeld (); // Spielfeld initialisieren

    // Menü anzeigen und Eingabe bearbeiten
    do
    {
        cout << endl;
        cout << "1 - Spielfeld anzeigen" << endl;
        cout << "2 - Feld besetzen" << endl;
        cout << "3 - Felddaten anzeigen" << endl;
        cout << "4 - Spielfeld loeschen" << endl;
        cout << "5 - Programm beenden" << endl;
        cout << "Auswahl: ";
        cin >> Auswahl;

        switch (Auswahl)
        {
            // Spielfeld anzeigen?
            case (1):
            {
                ZeigeSpielfeld ();
            } break;

            // Feld besetzen?
            case (2):
            {
                BesetzeFeld ();
            } break;

            // Felddaten anzeigen?
            case (3):
            {
                ZeigeFelddaten ();
            } break;

            // Spielfeld löschen?
            case (4):
            {
                LoescheSpielfeld ();
                cout << "Spielfeld wurde geloescht!" << endl;
            } break;

            // Programm beenden?
            case (5):
            {
                cout << "Programm beendet." << endl;
            } break;

            // Falsche Eingabe?
            default:
            {
                cout << "Ungueltiger Menuepunkt!" << endl;
            }
        }

    } while (Auswahl != 5);

    return 0;
}

// LoescheSpielfeld
//
// Aufgabe: Spielfeld löschen
//
void LoescheSpielfeld ()
{
    for (int y=0; y<Hoehe; y++)
    {
        for (int x=0; x<Breite; x++)
        {
            Spielfeld[x][y].Besetzt = false;
        }
    }

} // LoescheSpielfeld

// ZeigeSpielfeld ()
//
// Aufgabe: Spielfeld anzeigen
//
void ZeigeSpielfeld ()
{
    cout << endl;

    for (int y=0; y<Hoehe; y++)
    {
        for (int x=0; x<Breite; x++)
        {
            // Wenn das Feld besetzt ist, ein X zeichnen,
            // ansonsten einen Punkt
            if (Spielfeld[x][y].Besetzt == true)
                cout << "X";
            else
                cout << ".";
        }

        cout << endl;
    }
} // ZeigeSpielfeld

// BesetzeFeld
//
// Ein Feld an bestimmten Koordinaten besetzen
//
void BesetzeFeld ()
{
    int x = 0;
    int y = 0;

    // Koordinaten abfragen
    do
    {
        cout << "x-Position (1-" << Breite << "): ";
        cin >> x;
    } while (x<1 || x>Breite);

    do
    {
        cout << "y-Position (1-" << Hoehe << "): ";
        cin >> y;
    } while (y<1 || y>Breite);

    // Name abfragen und Felddaten füllen
    cout << "Name: ";
    cin.ignore ();
    cin.get (Spielfeld[x-1][y-1].Name, 29);
    Spielfeld[x-1][y-1].Besetzt = true;

} // BesetzeFeld

// ZeigeFelddaten
//
// Aufgabe: Felddaten an bestimmten Koordinaten anzeigen
//
void ZeigeFelddaten ()
{
    int x = 0;
    int y = 0;

    // Koordinaten abfragen
    do
    {
        cout << "x-Position (1-" << Breite << "): ";
        cin >> x;
    } while (x<1 || x>Breite);

    do
    {
        cout << "y-Position (1-" << Hoehe << "): ";
        cin >> y;
    } while (y<1 || y>Breite);

    // Felddaten ausgeben
    if (Spielfeld[x-1][y-1].Besetzt == false)
    {
        cout << "Dieses Feld ist noch nicht besetzt." << endl;
    }
    else
    {
        cout << "Feld ist besetzt von: ";
        cout << Spielfeld[x-1][y-1].Name << endl;
    }

} // ZeigeFelddaten


So jetzt versteh ich die Schleife nicht

for (int y=0; y<Hoehe; y++)
{
for (int x=0; x<Breite; x++)

was hat das fürn Sinn? Warum muss man hier x und y um 1 pro schleife erhöhen, dass will ich doch gar nicht, die x und y werte sollen doch per Hand zugeweisen werden!

Die stelle Hier versteh ich auch nicht:


while (y<1 || y>Breite)

wieso soll die schleife so lange laufen bis y grösser als die Breite ist, die Breite ist doch der maximale wert?!?

Danke für eventuelle Hilfe :crazy:

2

09.05.2020, 18:15

Mir hat es oft geholfen Code, Zeile für Zeile, mit dem Debugger durchzusteppen. Vielleicht hilft es dir ja auch?
In Visual Studio geht das mit den Tasten:
F5 - Führt das Programm bis zum nächsten Breakpoint aus;
F9 - Setzt in die Zeile einen Breakpoint
F10 - Führt eine Codezeile aus
F11 - Führt eine Zeile Code aus und springt in die Funktion

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Hannes« (09.05.2020, 18:58)


Jonathan

Community-Fossil

  • Private Nachricht senden

3

10.05.2020, 10:17

was hat das fürn Sinn? Warum muss man hier x und y um 1 pro schleife erhöhen, dass will ich doch gar nicht, die x und y werte sollen doch per Hand zugeweisen werden!

Soweit ich das sehe ist die Schleife doch gar nicht an der Stelle, wo es darum geht die Werte zuzuweisen, sondern da, wo das gesamte Spielfeld gezeichnet oder gelöscht werden soll. Und da ist es schon praktisch, wenn man nicht jedes Feld von Hand anzeigen muss.

wieso soll die schleife so lange laufen bis y grösser als die Breite ist, die Breite ist doch der maximale wert?!?

Solange y größer als die Breite ist, ist der Wert ungültig und die Abfrage wird wiederholt. Wenn die Breite kleiner als die maximale Breite ist, ist der Wert gültig und die Schleife wird beendet.

Hannes Tipp ist schon sehr wertvoll. Alles was das Programm macht ist extrem einfache Operationen auszuführen, deren Kombination erst das gewünschte Verhalten erzeugen. Dieser Abstraktionsschritt ist am Anfang etwas schwierig, muss aber unbedingt verstanden werden, wenn man selber Code schreiben will. Geh das Programm also im Debugger durch, überlege dir, was du erwarten würdest das passieren soll und falls etwas anderes geschieht, nutze die Gelegenheit um etwas Neues zu lernen :)
Lieber dumm fragen, als dumm bleiben!

4

10.05.2020, 13:38

Danke für die antworten, ja möchte eigentlich bevor ich mit dem Buch weitermache das erst mal verstehen, der Code ist ja jetzt mal komplizierter als alles zuvor :)
Ich probiers mal mit dem Debbuger

Das grösste Problem ist die for Schleife, ich versteh einfach nicht wie man darauf kommt und das auch noch funktioniert.
Alternativ, könnte jemand mir vielleicht zeichen um zeichen bei diesem Code erklären warum man es genau so schreibt, das was ich daran genau nicht verstehe, wenn x= 0 ist und man denn wert imkrementiert, warum ist dann das Spielfeld gelöscht, man erzeugt dadurch dorch werte über x= 0, man schreibt zwar mit dem Befehl - Spielfeld[x][y].Besetzt = false -, das dass Feld nicht besetzt ist, aber eigentlich hat man doch werte über 0 erzeugt, also hat man es selbst besetzt oder? ich hab wohl nen Denkfehler, irgendwie kommt mir das ganze nicht Logisch vor :/

C-/C++-Quelltext

1
2
3
4
5
6
7
8
void LoescheSpielfeld ()
{
    for (int y=0; y<Hoehe; y++)
    {
        for (int x=0; x<Breite; x++)
        {
            Spielfeld[x][y].Besetzt = false;
        }


So, habs mit dem debugger probiert aber der Hilft mir nicht weiter da er ja nur zeigt ob es funktioniert aber nicht warum es das tut :/

Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von »DasViereck« (10.05.2020, 17:22)


5

10.05.2020, 19:08

So, ich denke ich habe die for Schleife und einen grossen teil des Beispiels verstanden, hab auch selbst versucht das Beispiel selbst zu programmieren und hat auch funktioniert.
Eine Frage hab ich aber noch:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void ZeigeSpielfeld ()
{
    cout << endl;

    for (int y=0; y<Hoehe; y++)
    {
        for (int x=0; x<Breite; x++)
        {
            // Wenn das Feld besetzt ist, ein X zeichnen,
            // ansonsten einen Punkt
            if (Spielfeld[x][y].Besetzt == true)
                cout << "X";
            else
                cout << ".";
        }

        cout << endl;
    }
} // ZeigeSpielfeld


Warum muss am Anfang und am Ende der FUnktion cout << endl; stehen? mein Beispiel hab ich ohne dem programmiert und festgestellt das dass Programm dann nur Punkte in Horizontaler linie ausgibt aber ohne Vertikale Punkte.

Wenn cout << endl; am anfang und am Ende stehen werden die Punkte sowohl horizontal wie auch vertikal ausgegeben, warum ist das so?

6

10.05.2020, 20:52

In der inneren x for-Schleife gibst du die Zeile, bestehend aus Xen und Punkten, Zeichen für Zeichen aus.
Wenn das Ende der x for-Schleife erreicht ist springst du, in der y for-Schleife, in die nächste Zeile der Ausgabe.
Du gibst also in der y for-Schleife Zeile für Zeile aus, bis du das ganze Spielfeld ausgegeben hast.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Hannes« (10.05.2020, 20:57)


Werbeanzeige