Ianamus
Anmeldungsdatum: 26. Januar 2010
Beiträge: Zähle...
Wohnort: Villmergen
|
Hallo Welt! Ich habe ein ganz unerwartetes Problem. Und zwar habe ich ein Programm geschrieben bei dem es um Pokerkarten geht: 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
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483 | #include<iostream>
#include<stdlib.h>
#include<time.h>
#include<string>
#include<cstdio>
using namespace std;
/*Urspruenglich wollte ich ein Pokerprogramm schreiben, das den Computer dazu befaehigt je nach Situation
zu entscheiden wieviel Geld er setzen soll. Nach reifer Ueberlegung bin ich leider zu Schluss gekommen,
dass der Versuch, eine sinnvolle Formel fuer den Einsatz zu finden, zu zeitraubend ist. So habe ich mich
dafuer entschieden bloss vom Spieler einen Tipp zu erfragen, ob er denkt zu gewinnen oder nicht.*/
int main ()
{
for (int i = 0; i < 60; ++i)
cout << endl;
cout << "*******************************************************************************\n"
"Quelltextname: Aufgabe3_kp2.cpp\n"
"Programmname: quest3_kp2\n"
"Programmierer: Zensur\n"
"Erstellungsdatum: 29. Mai 2010\n\n";
"Es werden jeweils fuenf Karten an Sie und den Computer verteilt.\n";
srand(time(0));
for (int zaehler = 0; zaehler < 10; ++zaehler)
{
//Erstellung zweier zufaelliger Haende
short const Handgroesse = 5;
short const Farben = 4;
short const Punkte = 13;
struct Kartentyp
{
short punkte;
short farbe;
};
string Punkt [13] = {"Zwei ", "Drei ", "Vier ", "Fuenf ", "Sechs ", "Sieben", "Acht ", "Neun ",
"Zehn ", "Bube ", "Dame ", "Koenig", "Ass "};
string Farbe [4] = {"HERZ - ", "KARO - ", "KREUZ - ", "PIK - "};
string Blaetter [10] = {"Royal Flush ", "Straight Flush", "Vierlinge ", "Full House ",
"Flush ", "Straight ", "Drillinge ", "Zwei Paare ",
"Ein Paar ", "Hoechste "};
struct
{
Kartentyp Karte [Handgroesse];
short Blatt;
bool gewonnen;
}AHand, BHand;
bool Kartenspiel [Farben][Punkte] = {};
for (short farbe = 0; farbe < Farben; ++farbe)
for (short punkte = 0; punkte < Punkte; ++punkte)
Kartenspiel [farbe][punkte] = true;
for (int i = 0, j = 0; j < 2; ++i)
{
short farbe = rand() % Farben;
short punkte = rand() % Punkte;
if (Kartenspiel[farbe][punkte])
{
if (j)
{
Kartenspiel[farbe][punkte] = false;
BHand.Karte[i].farbe = farbe;
BHand.Karte[i].punkte = punkte;
}
else
{
Kartenspiel[farbe][punkte] = false;
AHand.Karte[i].farbe = farbe;
AHand.Karte[i].punkte = punkte;
}
}
else
--i;
if (i == Handgroesse - 1)
{
i = 0;
++j;
}
}
//Kartensortierung(Bubblesort)
//Hand A
for (int j = 0; j < Handgroesse - 1; ++j)
for (int i = 0; i < Handgroesse - 1; ++i)
{
if (AHand.Karte[i].punkte > AHand.Karte[i + 1].punkte)
{
short punkte;
short farbe;
punkte = AHand.Karte[i + 1].punkte;
farbe = AHand.Karte[i + 1].farbe;
AHand.Karte[i + 1].punkte = AHand.Karte[i].punkte;
AHand.Karte[i + 1].farbe = AHand.Karte[i].farbe;
AHand.Karte[i].punkte = punkte;
AHand.Karte[i].farbe = farbe;
}
}
//Hand B
for (int j = 0; j < Handgroesse - 1; ++j)
for (int i = 0; i < Handgroesse - 1; ++i)
{
if (BHand.Karte[i].punkte > BHand.Karte[i + 1].punkte)
{
short punkte;
short farbe;
punkte = BHand.Karte[i + 1].punkte;
farbe = BHand.Karte[i + 1].farbe;
BHand.Karte[i + 1].punkte = BHand.Karte[i].punkte;
BHand.Karte[i + 1].farbe = BHand.Karte[i].farbe;
BHand.Karte[i].punkte = punkte;
BHand.Karte[i].farbe = farbe;
}
}
//Bestimmung des Blatts
//Hand A
bool blaetter [10] = {false};
string Blatt [10] = {"Royal Flush", "Straight Flush", "Vierlinge", "Full House", "Flush",
"Straight", "Drillinge", "Zwei Paare", "Ein Paar", "Hoechste"};
//Flush
for (int i = 0; i < Handgroesse - 1; ++i)
{
if (AHand.Karte[i].farbe != AHand.Karte[i + 1].farbe)
break;
if (i == Handgroesse - 2)
blaetter [4] = true;
}
//Straight
for (int i = 0; i < Handgroesse - 1; ++i)
{
if (AHand.Karte[i + 1].punkte - AHand.Karte[i].punkte != 1)
break;
if (i == Handgroesse - 2)
blaetter [5] = true;
}
//Straight Flush
if(blaetter [4] && blaetter [5])
{
blaetter [1] = true;
blaetter [4] = false;
blaetter [5] = false;
}
//Royal Flush
if (blaetter [1] && (AHand.Karte[Handgroesse - 1].punkte == 12))
{
blaetter [0] = true;
blaetter [1] = false;
}
if (!(blaetter [4] || blaetter [5] || blaetter [1] || blaetter [0]))
for (int q = 1; q == 1; ++q)
{
//Vierlinge
for (int i = 0; i < Handgroesse - 3; ++i)
{
if (AHand.Karte[i].punkte == AHand.Karte[i + 3].punkte)
blaetter [2] = true;
}
if (blaetter [2])
break;
//Drillinge
for (int i = 0; i < Handgroesse - 2; ++i)
{
if (AHand.Karte[i].punkte == AHand.Karte[i + 2].punkte)
blaetter [6] = true;
}
//Full House
if (blaetter [6])
{
if (AHand.Karte[0].punkte == AHand.Karte[1].punkte &&
AHand.Karte[Handgroesse - 1].punkte == AHand.Karte[Handgroesse - 2].punkte)
blaetter [3] = true;
}
if (blaetter [3])
{
blaetter [6] = false;
break;
}
if (blaetter[6])
break;
//Zwei Paar
for (int i = 0, j = 0; i < Handgroesse - 1; ++i)
{
if (AHand.Karte[i].punkte == AHand.Karte[i + 1].punkte)
++j;
if (j == 2)
blaetter [7] = true;
}
if (blaetter [7])
break;
//Ein Paar
for (int i = 0; i < Handgroesse - 1; ++i)
{
if (AHand.Karte[i].punkte == AHand.Karte[i + 1].punkte)
blaetter [8] = true;
}
if (blaetter [8])
break;
//Hoechste Karte
blaetter [9] = true;
}
//Abspeicherung des Blatts in der Hand A
for (int i = 0; i < 10; ++i)
if (blaetter [i])
{
AHand.Blatt = i;
blaetter [i] = 0;
}
//Hand B
//Flush
for (int i = 0; i < Handgroesse - 1; ++i)
{
if (BHand.Karte[i].farbe != BHand.Karte[i + 1].farbe)
break;
if (i == Handgroesse - 2)
blaetter [4] = true;
}
//Straight
for (int i = 0; i < Handgroesse - 1; ++i)
{
if (BHand.Karte[i + 1].punkte - BHand.Karte[i].punkte != 1)
break;
if (i == Handgroesse - 2)
blaetter [5] = true;
}
//Straight Flush
if(blaetter [4] && blaetter [5])
{
blaetter [1] = true;
blaetter [4] = false;
blaetter [5] = false;
}
//Royal Flush
if (blaetter [1] && (AHand.Karte[Handgroesse - 1].punkte == 12))
{
blaetter [0] = true;
blaetter [1] = false;
}
if (!(blaetter [4] || blaetter [5] || blaetter [1] || blaetter [0]))
for (int q = 1; q == 1; ++q)
{
//Vierlinge
for (int i = 0; i < Handgroesse - 3; ++i)
{
if (BHand.Karte[i].punkte == BHand.Karte[i + 3].punkte)
blaetter [2] = true;
}
if (blaetter [2])
break;
//Drillinge
for (int i = 0; i < Handgroesse - 2; ++i)
{
if (BHand.Karte[i].punkte == BHand.Karte[i + 2].punkte)
blaetter [6] = true;
}
//Full House
if (blaetter [6])
{
if (BHand.Karte[0].punkte == BHand.Karte[1].punkte &&
BHand.Karte[Handgroesse - 1].punkte == BHand.Karte[Handgroesse - 2].punkte)
blaetter [3] = true;
}
if (blaetter [3])
{
blaetter [6] = false;
break;
}
if (blaetter[6])
break;
//Zwei Paar
for (int i = 0, j = 0; i < Handgroesse - 1; ++i)
{
if (BHand.Karte[i].punkte == BHand.Karte[i + 1].punkte)
++j;
if (j == 2)
blaetter [7] = true;
}
if (blaetter [7])
break;
//Ein Paar
for (int i = 0; i < Handgroesse - 1; ++i)
{
if (BHand.Karte[i].punkte == BHand.Karte[i + 1].punkte)
blaetter [8] = true;
}
if (blaetter [8])
break;
//Hoechste Karte
blaetter [9] = true;
}
//Abspeicherung des Blatts in der Hand B
for (int i = 0; i < 10; ++i)
if (blaetter [i])
{
BHand.Blatt = i;
blaetter [i] = 0;
}
//Wer hat gewonnen?
AHand.gewonnen = BHand.gewonnen = false;
if (AHand.Blatt != BHand.Blatt)
if (AHand.Blatt < BHand.Blatt)
AHand.gewonnen = true;
else
BHand.gewonnen = true;
else//Vergleich wenn gleiche Blaetter bestehen
{
//Straight Flush, Flush, Straight, Hoechste Karte
if (AHand.Blatt == 9 || AHand.Blatt == 5 || AHand.Blatt == 4 || AHand.Blatt == 1)
for (int i = Handgroesse - 1; i > -1; --i)
{
if (AHand.Karte[i].punkte > BHand.Karte[i].punkte)
{
AHand.gewonnen = true;
i = -1;
}
if (AHand.Karte[i].punkte < BHand.Karte[i].punkte)
{
BHand.gewonnen = true;
i = -1;
}
}
//Vierlinge, Drillinge und Full House
if (AHand.Blatt == 6 || AHand.Blatt == 2 || AHand.Blatt == 3)
if (AHand.Karte[Handgroesse / 2].punkte > BHand.Karte[Handgroesse / 2].punkte)// ;)
AHand.gewonnen = true;
else
BHand.gewonnen = true;
//Zwei Paare
if (AHand.Blatt == 7)
{
int i = 3;
if (AHand.Karte[i].punkte > BHand.Karte[i].punkte)
AHand.gewonnen = true;
if (AHand.Karte[i].punkte < BHand.Karte[i].punkte)
BHand.gewonnen = true;
if (AHand.Karte[i].punkte == BHand.Karte[i].punkte)
{
i = 1;
if (AHand.Karte[i].punkte > BHand.Karte[i].punkte)
AHand.gewonnen = true;
if (AHand.Karte[i].punkte < BHand.Karte[i].punkte)
BHand.gewonnen = true;
}
if (AHand.Karte[i].punkte == BHand.Karte[i].punkte)
{
int j;
if (AHand.Karte[i].punkte == AHand.Karte[i + 1].punkte)
j = 0;
else
j = 2;
if (BHand.Karte[i].punkte == BHand.Karte[i + 1].punkte)
i = 0;
else
i = 2;
if (AHand.Karte[j].punkte > BHand.Karte[i].punkte)
AHand.gewonnen = true;
if (AHand.Karte[j].punkte < BHand.Karte[i].punkte)
BHand.gewonnen = true;
}
}
//Ein Paar
if (AHand.Blatt == 8)
{
int i = 0, j = 0;
while (i < Handgroesse - 1)
if (AHand.Karte[i].punkte == AHand.Karte[i + 1].punkte)
break;
else
++i;
while (j < Handgroesse - 1)
if (BHand.Karte[j].punkte == BHand.Karte[j + 1].punkte)
break;
else
++j;
if (AHand.Karte[i].punkte == BHand.Karte[j].punkte)
for (int k = Handgroesse - 1; k > -1; --k)
{
if (AHand.Karte[k].punkte > BHand.Karte[k].punkte)
{
AHand.gewonnen = true;
break;
}
if (AHand.Karte[k].punkte < BHand.Karte[k].punkte)
{
BHand.gewonnen = true;
break;
}
}
else
if (AHand.Karte[i].punkte > BHand.Karte[j].punkte)
AHand.gewonnen = true;
else
BHand.gewonnen = true;
}
}
//Die Entscheidung
string Abstand = " ";
cout << endl << "Ihre Karten:\n\n";
cout << Blaetter [AHand.Blatt] << endl << endl;
for (int i = Handgroesse - 1; i >= 0 ; --i)
{
cout << Farbe [AHand.Karte[i].farbe] << Punkt [AHand.Karte[i].punkte] << endl;
}
//Tipp
char tipp = 'l';
while (tipp != 'j' && tipp != 'n')
{
cout << "\nDenken Sie mit diesen Karten zu gewinnen?(j/n)\n";
cin >> tipp;
}
for (int i = 0; i < 60; ++i)
cout << endl;
//Aufdecken der Karten
cout << endl << "Ihre Karten: " << Abstand << "Karten des PC's:\n\n";
cout << Blaetter [AHand.Blatt] << Abstand << Blaetter [BHand.Blatt] << endl << endl;
for (int i = Handgroesse - 1; i >= 0 ; --i)
{
cout << Farbe [AHand.Karte[i].farbe] << Punkt [AHand.Karte[i].punkte] << Abstand <<
Farbe [BHand.Karte[i].farbe] << Punkt [BHand.Karte[i].punkte] << endl;
}
if (tipp == 'j')
if (AHand.gewonnen)
cout << "\nJa, Sie haben gewonnen!\n\n";
else
cout << "\nNein, Sie haben leider nicht gewonnen.\n\n";
else
if (AHand.gewonnen)
cout << "\nNein, Sie haben gewonnen.\n\n";
else
cout << "\nJa, Sie haben verloren.\n\n";
cout << "Weiter mit Enter...";
getchar();
getchar();
}
}
|
Zunächst hat es ohne die zweite for-Schleife wie erwartet funktioniert. Doch jetzt, wenn ich bei der zweiten for-Schleife anstatt "for (short zaehler = 0; zaehler < 10; ++zaehler)" - "for (int zaehler = 0; zaehler < 10; ++zaehler)" schreibe, erhalte ich am Schluss, bei der "//Aufdeckung der Karten", einen Programmabbruch mit der Meldung eines "Segmentation fault". Auf die Karten kann nicht zugegriffen werden, weil an den Stellen "AHand.Karte[i].punkte" normaler Weise harmlose Zahlen stehen wie 2 oder 6. Aber wenn nun in der for-Schleife der Typ des Laufindexes von short auf int umgestellt wird, stehen an den besagten Stellen Zahlen wie -1239818 oder so. Und jetzt die Frage: Inwiefern kann dieser Laufindex mit der Abspeicherung von short-Zahlen an diesen Stellen im Zusammenhang stehen? Für An- und Bemerkungen, Belehrungen bzw. Zurechtweisungen danke ich im voraus. Es gruesst euch Ianamus.
|
Vain
Anmeldungsdatum: 12. April 2008
Beiträge: 2503
|
Zurechtweisung Nummer eins: Spare doch nicht so sehr an Einrückungen und geschwiffenen Klammern. ☺ Stichwort Lesbarkeit und so. Ich weiß, es erscheint dir vielleicht gerade bei diesem Problem als schwer machbar, aber versuche doch mal, den Fehler auf ein Minimalbeispiel einzugrenzen. Erster Schritt könnte da zum Beispiel sein, dass du dir die Werte von "AHand.Karte[i].farbe " und ".punkte " mal im Klartext anschaust – genauso bei "BHand ". Mir ist dabei aufgefallen, dass unabhängig von deinem Datentyp, um den es dir hier geht, da negative Zahlen drinstehen. Dann stürzt er natürlich ab. Und er stürzt bei mir übrigens auch unabhängig von "int " oder "short " ab. Die Variable "zaehler " benutzt du später ja auch gar nicht mehr, also hat das nur indirekt einen Effekt auf dein Programm. Sowas deutet meistens auf dusselige Fehler wo ganz anders hin. 😉 Sehe ich das denn richtig, dass deine Arrays nicht initialisiert sind? Vielleicht liege ich völlig daneben, aber fehlt dir nicht am Anfang so etwas wie das hier?
| for (int a = 0; a < Handgroesse; a++)
{
AHand.Karte[a].punkte = 0;
AHand.Karte[a].farbe = 0;
BHand.Karte[a].punkte = 0;
BHand.Karte[a].farbe = 0;
}
|
-edit: Das heißt, in deiner Schleife ab Zeile 70 erwischst du nicht alle nötigen Indizes. Das wäre so das einzige, was mir in dieser Hinsicht einfällt. Aber auch sonst kann es sein, dass dir noch ein paar Fehlerchen unterlaufen sind. Lasse ich den Text von Vim einrücken, dann sieht man zum Beispiel, dass deine "Willkommensnachricht" etwas zu früh durch ein Semikolon beendet wird – diese letzte Zeile hat überhaupt keinen Effekt, was übrigens auch der Compiler bemängelt:
| cout << "*******************************************************************************\n"
"Quelltextname: Aufgabe3_kp2.cpp\n"
"Programmname: quest3_kp2\n"
"Programmierer: Zensur\n"
"Erstellungsdatum: 29. Mai 2010\n\n";
"Es werden jeweils fuenf Karten an Sie und den Computer verteilt.\n";
|
Vielleicht mal "-Wall " und "-Wextra " als Compileroptionen aktivieren.
|
Dalai
Anmeldungsdatum: 16. Juni 2008
Beiträge: 2316
Wohnort: Meiningen
|
Ich bin jetzt kein Typ, der was von C/C++ versteht, aber warum änderst du die Laufvariablen i und j in einer for-Schleife (Zeilen 60 bis 85)? Das ist zwar IIRC in C/C++ erlaubt, aber ich denke, das kann ins Auge gehen. Und wahrscheinlich ist deine Datentypänderung nur der Ausdruck eines Fehlers an einer ganz anderen Stelle - wie das meist beim Programmieren so ist 😉. MfG Dalai
|
Lunar
Anmeldungsdatum: 17. März 2006
Beiträge: 5792
|
@Ianamus: An dieser Stelle vielleicht auch mal den Quelltext in einzelne, unabhängige Funktionen teilen, um die Übersichtlichkeit zu erhöhen. Ich denke, Du verstehst, dass niemand große Lust hat, fast 500 Zeilen Quelltexts mit oftmals nur minimaler oder gar nicht vorhandener Einrückung, mehreren geschachtelten Schleifen und Abfragen und diversen magischen Zahlen zu lesen. Schreibe übersichtlichen, klar strukturieren Quelltext. Zum einen findest Du dann viele Fehler von selbst, da die Lesbarkeit erhöht und das Verständnis gefördert wird, zum anderen finden sich bei sauberem und lesbarem Quelltext auch mehr Helfer.
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
Ja, und C++ kennt Klassen - vielleicht kann man davon Gebrauch machen, und aus den 2 auscodierten Tests ob 4ling, Drilling, Paar usw. eine machen, die der Hand zugeordnet ist. Als mindestestes oder ersten Schritt würde ich einzelne Funktionen bauen, die für AHand wie BHand, evtl. auch hand[0] und hand[1] aufgerufen werden, schreiben. Die Arbeit mit dem Array erscheint mir auch fehleranfällig, weil die Datenstruktur nicht garantiert, daß sich die Blätter gegenseitig ausschließen. //Straight Flush
if(blaetter [4] && blaetter [5])
{
blaetter [1] = true;
blaetter [4] = false;
blaetter [5] = false;
}
Ein enum könnte hier immerhin bei der Lesbarkeit weiterhelfen aber ein großer Fortschritt ist das nicht.
//Straight Flush
if (blaetter [FLUSH] && blaetter [STRAIGHT])
{
blaetter [STRAIGHT_FLUSH] = true;
blaetter [STRAIGHT] = false;
//...
Wieso eigentlich 'blaetter' in Mehrzahl?
|
Ianamus
(Themenstarter)
Anmeldungsdatum: 26. Januar 2010
Beiträge: 36
Wohnort: Villmergen
|
@all - Danke! @Vain Zurechtweisung Nummer eins: Spare doch nicht so sehr an Einrückungen und geschwiffenen Klammern. ☺ Stichwort Lesbarkeit und so.
Wird sofort erledigt! Der Code sieht ev. ein bisschen merkwürdig aus, weil ich zuerst ein Programm geschrieben habe das fünf Karten ausgibt. Danach habe ich ein zweites Programm geschrieben, das fünf Karten sortiert ausgibt - indem ich das erste Programm nahm und ein wenig änderte. Das dritte Programm erkannte dann das Blatt in der sortierten Hand - ebenfalls mit verändertem Code vom zweiten Programm usw..Das letzte Programm erzeugte zwei Hände und konnte eindeutig entscheiden welches der beiden Hände hochwertiger war. Bis dahin hat alles wunderbar geklappt! Aber jetzt wollte ich das ganze noch in eine Schleife packen und nur wegen dieser Schleife läuft es jetzt nicht mehr - als ob es nicht mehr genug Arbeitspeicher für das Programm gäbe...
Sehe ich das denn richtig, dass deine Arrays nicht initialisiert sind? Vielleicht liege ich völlig daneben, aber fehlt dir nicht am Anfang so etwas wie das hier? 1
2
3
4
5
6
7 for (int a = 0; a < Handgroesse; a++)
{
AHand.Karte[a].punkte = 0;
AHand.Karte[a].farbe = 0;
BHand.Karte[a].punkte = 0;
BHand.Karte[a].farbe = 0;
} -edit: Das heißt, in deiner Schleife ab Zeile 70 erwischst du nicht alle nötigen Indizes.
Ich weiss es sieht auf den ersten Blick so aus als ob es möglich sei, dass hier nicht alles eine Zuweisung erhält, aber ich bin mir da 100 %, dass alles eine legitime Zuweisung erhält.
Das wäre so das einzige, was mir in dieser Hinsicht einfällt. Aber auch sonst kann es sein, dass dir noch ein paar Fehlerchen unterlaufen sind. Lasse ich den Text von Vim einrücken, dann sieht man zum Beispiel, dass deine "Willkommensnachricht" etwas zu früh durch ein Semikolon beendet wird – diese letzte Zeile hat überhaupt keinen Effekt, was übrigens auch der Compiler bemängelt:
Das ist mir nachher auch noch aufgefallen... @Dalai Das kommt daher, dass ich das in einem älteren Programm zuerst für eine Hand schrieb, und nicht mehr eine ganz neue Schleife schreiben wollte. @Lunar Ich hätte gerne Funktionen geschrieben, es war mir aber quasi nicht erlaubt. @user unknown Klassen beherrsche ich noch nicht, hab' aber gehört es sei eine tolle Sache. Die Enumerationen kenne ich eigentlich, bin nur nicht auf die Idee gekommen das hier ausnützen zu können. Danke für den Anstoss.
Wieso eigentlich 'blaetter' in Mehrzahl?
Um deiner Neugier entgegen zu kommen:
Weil es ein Array ist mit allen Blättern; im Gegensatz zum Blatt, das dann tatsächlich in der Hand ist(vielleicht nur scheinbar logisch). Könnte es denn sein, dass einfach zuwenig Speicher für das Programm zur Verfügung steht, denn bevor ich alles in eine Schleife packte, lief es einwandfrei?
|
Vain
Anmeldungsdatum: 12. April 2008
Beiträge: 2503
|
Ianamus schrieb: Ich weiss es sieht auf den ersten Blick so aus als ob es möglich sei, dass hier nicht alles eine Zuweisung erhält, aber ich bin mir da 100 %, dass alles eine legitime Zuweisung erhält.
Also, ich wäre mir da nicht so sicher. Bau doch mal eine einfache Schleife nach den Zuweisungen oder nach der Sortierung ein, die alle Werte von (A|B)Hand.Karte[] ausgibt. Ich erhalte da in manchen Durchläufen negative Werte (= nicht initialisiert, führt zum Segfault). Manchmal klappt es aber. Ein andermal nicht. Ich vermute, du hast einen fiesen Sonderfall des etwas kryptisch anmutenden Würfelns nicht bedacht, dessen Analyse mir jetzt aber doch zu müßig ist. ☺
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
Ianamus schrieb: @all - Danke!
@Lunar Ich hätte gerne Funktionen geschrieben, es war mir aber quasi nicht erlaubt.
Wieso das nicht?
@user unknown Klassen beherrsche ich noch nicht, hab' aber gehört es sei eine tolle Sache. Die Enumerationen kenne ich eigentlich, bin nur nicht auf die Idee gekommen das hier ausnützen zu können. Danke für den Anstoss.
Wieso eigentlich 'blaetter' in Mehrzahl?
Um deiner Neugier entgegen zu kommen:
Weil es ein Array ist mit allen Blättern; im Gegensatz zum Blatt, das dann tatsächlich in der Hand ist(vielleicht nur scheinbar logisch).
Das ist kein Grund. In der Verwendung ist ja die Frage, ob ein konkretes Blatt ein Drilling usw. ist -
if (blaetter [FLUSH] && blaetter [STRAIGHT])
Die Bezeichner helfen nicht sehr zu begreifen, was hier los ist, eher schon bei if (blaett [FLUSH] && blaett [STRAIGHT])
Könnte es denn sein, dass einfach zuwenig Speicher für das Programm zur Verfügung steht, denn bevor ich alles in eine Schleife packte, lief es einwandfrei?
Kaum. a) belegt das Programm quasi keinen Speicher - auf einem Taschenrechner der 80er Jahre vielleicht. b) Wäre das ja ein OutOfMemory-Fehler, kein Segfault.
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
Beim Kartenverteilen verstehe ich folgende Steuerung nicht:
for (int i = 0, j = 0; j < 2; ++i)
{
int farbe = r.nextInt (Farben);
int punkte = r.nextInt (Punkte);
if (Kartenspiel[farbe][punkte])
{
if (j != 0)
{
// ...
}
else
--i;
if (i == Handgroesse - 1)
{
i = 0;
++j;
}
}
Wie soll das funktionieren? Sonst wird ja alles mit for-Schleifen gemacht. Wieso hier nicht HandA, HandB? In Zeile 350 fehlt m.E. ein 'else'
|
Marc_BlackJack_Rintsch
Ehemalige
Anmeldungsdatum: 16. Juni 2006
Beiträge: 4577
Wohnort: Berlin
|
@Ianamus: Ist ja echt toll, dass Du so verdammt sicher bist, dass das "mischen" bzw. "austeilen" der Karten gaaanz bestimmt fehlerfrei ist. Guess what – es ist nicht fehlerfrei. Wenn eine Karte zufällig ein zweites mal "gezogen" wird, dann bleibt die entsprechende Karte uninitialisiert. Dafür sorgt die if -Bedingung in Zeile 65. 🙄
|
Ianamus
(Themenstarter)
Anmeldungsdatum: 26. Januar 2010
Beiträge: 36
Wohnort: Villmergen
|
Danke @all! Heureka!
Nach einmaligem darüber schlafen habe ich den Fehler jetzt gefunden; Zeile 84: dort muss es heissen: Ich denke und hoffe, dass das der einzige Fehler ist, der zum Segmetation fault führt... 😛 @user unknown:
Hie und da lerne ich aus dem Buch "Einstieg in C++" von Arnold Willemer. Da ich nach grösseren Pausen die Übersicht über das bereits Gelernte verloren habe, habe ich eine Zusammenfassung über den gelernten Stoff geschrieben, so dass ein anderer selber die Zusammenfassung nutzen könnte. Im Falle, dass das tatsächlich passiert, habe ich noch Aufgaben gestellt und gelöst, damit der andere auch etwas von der Anwendung mitbekommt. - Ja, ich hab' jetzt kapiert, dass die Art und Weise wie ich Code schreibe nicht vorbildlich ist und werde mir das auch in Zukunft zu Herzen nehmen. Funktionen kommen erst in meinem dritten Kapitel, daher das Programm ohne Funktionen.
@user unknown Klassen beherrsche ich noch nicht, hab' aber gehört es sei eine tolle Sache. Die Enumerationen kenne ich eigentlich, bin nur nicht auf die Idee gekommen das hier ausnützen zu können. Danke für den Anstoss. Wieso eigentlich 'blaetter' in Mehrzahl? Um deiner Neugier entgegen zu kommen: Weil es ein Array ist mit allen Blättern; im Gegensatz zum Blatt, das dann tatsächlich in der Hand ist(vielleicht nur scheinbar logisch). Das ist kein Grund. In der Verwendung ist ja die Frage, ob ein konkretes Blatt ein Drilling usw. ist - if (blaetter [FLUSH] && blaetter [STRAIGHT]) Die Bezeichner helfen nicht sehr zu begreifen, was hier los ist, eher schon bei if (blaett [FLUSH] && blaett [STRAIGHT])
"Meine" Logik dabei ist, dass es mehrer Möglichkeiten an Blättern gibt, aber es kann nur ein einziges Blatt in der Hand sein. Ich sehe ein, dass das nicht aus einer herausgepickten Zeile hervorgeht. In Zukunft werde ich mir Namesgebungen ausdenken, die direkter darauf hinweisen was an der aktuellen Stelle vor sich geht.
In Zeile 350 fehlt m.E. ein 'else'
Die Karten sind nach Werten geordnet. Hier geht es darum, wenn zweimal ein Flush oder ein Staight Flush usw. vorliegt, herauszufinden welches der beiden Blätter das höhere ist. else würde auch beinhalten, wenn die Karten den gleichen Wert haben, jedoch ist das an dieser Stelle nicht gefragt, denn wenn keiner gewonnen hat, ist einfach unentschieden. Darum wird auch nicht überprüft, wenn beide ein Royal Flush haben, denn dann haben beide die Sequenz: "Ass, König ... Zehn". Beim Flush z.B. - Hand A: "Ass, Dame, Acht...", Hand B: "Ass, Bube, Sieben..." - an der ersten Stelle haben beide ein Ass, d.h. noch nichts entschieden. Aber an der zweiten Stelle hat Hand A eine Dame, im Gegensatz zum Buben in der Hand B, und so den Sieg für sich entschieden. - Okay? @Marc 'BlackJack' Rintsch @Ianamus: Ist ja echt toll, dass Du so verdammt sicher bist, dass das "mischen" bzw. "austeilen" der Karten gaaanz bestimmt fehlerfrei ist.
Mag sein, dass ich nicht wie du einen IQ habe der dem Erdumfang in Nanometer gemessen gleich, oder schon drei Doktorarbeiten in Theoretischer Informatik verfasst habe, aber ich glaube nicht, dass es anmassend ist von einem Supporter zu erwarten, dass er nicht stets seinen bemäntelten Spott über Fremde ergiesst; denn es könnte sein, dass auch Leute anwesend sind, die sich nicht um nicht-adulte Kommunikation kümmern. Nichts für ungut, dein Engagement hier auf dieser Page ist echt rühmenswert und ich bin wahrscheinlich wirklich nur ein kleiner dummer Newcomer - doch für einen intelligenten Menschen wie dich ist es ein kleiner Schritt ein klein wenig emotionale Hygiene an den Tag zu legen, oder? Und ja - du hattest recht, aber das ist eben nicht alles in einem Forum.
|
Marc_BlackJack_Rintsch
Ehemalige
Anmeldungsdatum: 16. Juni 2006
Beiträge: 4577
Wohnort: Berlin
|
@Ianamus: Entschuldige bitte den etwas bissigen Ton. Vain hat zweimal geschrieben er bekommt da definitiv uninitialisierte Werte bei den Karten ausgegeben und Du warst Dir trotzdem sicher, dass da 100% jeder Karte gültige Werte zugewiesen werden. Das hat Vain sich ja nicht ausgedacht. Und der Fehler ist immer noch da. Ich habe Dir ja gesagt woran es liegt und das war nicht diese Zuweisung an i . Schnapp Dir mal ein Blatt und einen Stift und notiere die Datenstrukturen und ihren Inhalt während Du die Schleife zwei- bzw. dreimal durcharbeitest, wobei beide Male die selben Zufallszahlen gezogen werden. Dann sieht man ganz deutlich, dass eine Karte uninitialisiert bleibt, da also irgendwelche Zufallswerte drin stehen, die am Ende zum segfault führen können wenn die Werte zum Zugriff auf die Arrays mit den Texten verwendet werden. Ansonsten finde ich die Aufgabe zu komplex um sie ohne Funktionen zu lösen. Insbesondere wenn dann auch noch zwei identische Datenstrukturen mit einer Masse an "copy'n'paste"-Code bearbeitet werden.
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
In Zeile 350 fehlt m.E. ein 'else'
Die Karten sind nach Werten geordnet. Hier geht es darum, wenn zweimal ein Flush oder ein Staight Flush usw. vorliegt, herauszufinden welches der beiden Blätter das höhere ist.
Das bestreite ich nicht. Nur könnte hier AHand.Karte'[i].punkte größer sein, als BHand-bla, und dann wird gewonnen = true gesetzt, und i = -1, und dann wird das nächste if-statement angesteuert, und AHand.Karte[-1].punkte referenziert - kawumm! if (AHand.Karte[i].punkte > BHand.Karte[i].punkte)
{
AHand.gewonnen = true;
i = -1;
}
if (AHand.Karte[i].punkte < BHand.Karte[i].punkte)
{
|
Ianamus
(Themenstarter)
Anmeldungsdatum: 26. Januar 2010
Beiträge: 36
Wohnort: Villmergen
|
@user unknown & Marc 'BlackJack' Rintsch - Danke, dass ihr wieder geschrieben habt! @Marc 'BlackJack' Rintsch: @Ianamus: Entschuldige bitte
Schon okay... Aber um den springenden Punkt meines persönlichen Anliegens an dich zu verdeutlichen: Das hat Vain sich ja nicht ausgedacht.
Ich habe Dir ja gesagt...
Nenn' mich einen Pedanten, schon okay, aber diese "Ja's" bedeuten, dass du den Irrtum anderer ihnen noch zum Vorwurf machst und das ist eigentlich überflüssig. Entscheidend ist der Irrtum alleine. Für gewisse Wortfetischisten ist das der Dolchstoss ins Herz und für die kleinen Leute von heute erst recht. Wie schon oben angedeutet, weiss ich das Privileg, mich von einer fachlichen Kapazität wie dir belehren zu lassen, zu schätzen und das überwiegt bei Weitem "Deine Ja's" - doch vielleicht, so habe ich mich gedacht, ist der eben geschilderte Sachverhalt auch in deinem Interesse. Zurück zum Wesentlichen: 1. Der Fehler mit der falschen Zuweisung an i, am Schluss der Schleife, ist ein wirklicher Fehler, oder? Nicht dass ich jetzt noch einen zusätzlichen eingebaut habe! 2. Ich verstehe nicht warum die Wahl einer schon zuvor gewählten Karte nicht mit - Zeile 80 - ausgeglichen wird. Denn für die Position i wird danach nochmals gesucht. Ich hab' echt das Gefühl dass ich einfach zu dumm dafür bin.
Ist die Karte im Stapel vorhanden, wird sie einer Hand zugeteilt und danach quasi aus dem Stapel gelöscht. Wird eine Karte gewählt die gelöscht wurde, wird i um eins zurückgesetz um nochmals dafür suchen zu können. Bitte habt Verständnis - ich habe auch das Gefühl das ich es einfach nicht begreife, aber ich seh' meinen Irrtum einfach nicht. @user unknown: - kawumm!
- Kawumm. An dieser Stelle presse ich am Ende des Anweisungsblocks der ersten if-Verzweigung noch ein "break;" hinein. So ist diese Schwäche auch behoben - oder? Ja, dank euch komme ich zum Schluss, dass es eigentlich nicht zu erwarten war, dass das Programm überhaupt läuft. Somit denke ich jetzt alle Fehler ausgemerzt zu haben. Oder sieht da jemand noch was 😲 .
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
Ianamus schrieb: - Kawumm. An dieser Stelle presse ich am Ende des Anweisungsblocks der ersten if-Verzweigung noch ein "break;" hinein. So ist diese Schwäche auch behoben - oder?
Und wieso soll die Zuweisung zu i dann drinbleiben?
|