Hilfe bei 4 gewinnt
-
Und statt der if-else Kaskaden solltest du eine einfache for-Schleife benutzen (und diese dann in eine eigene Funktion auslagern).
Funktionen helfen dir dabei Codeduplizierungen und Fehler zu vermeiden.
Am besten schreib ersteinmal deine Hauptfunktion main so, daß sie nur aus Funktionsaufrufen besteht, im Sinne von:int main() { menu(); while (!is_gameover()) { do_move_for_playerX(); print_board(); } print_winner(); }
Dann kannst du nach und nach die Funktionen implementieren und die richtigen Funktionsparameter einsetzen.
-
die kaskaden habe ich dann genommen, als ich mit for schleifen nicht auf das richtige gekommen bin. mir tut es selbst schon weh, wenn ich es sehe, da ich weiß, dass es einfacher und besser geht, ich aber momentan keine bessere lösung hinklotzen kann.
was für mich persönlich wichtiger ist, wäre die unentschieden auswertung. ich komme auf kein gutes ergebnis. ich hatte ja meinen ansatz mit den spielfeldern auszählen, die gefüllt sind, welcher entweder gar nicht oder sofort beim ersten zug zum unentschieden geführt hat.
zudem die variante vom dirk.
das führt, bei mir zumindest, dazu, dass das spiel immer dann endet, wenn das oberste feld der ersten spalte gefüllt ist. also spielfeld [0][0].ich wollte es jetzt noch umformulieren, in der hoffnung, dass es vllt anders funktioniert und ich es danach schöner formulieren könnte:
if(spielfeld[0][0] != ' ' && spielfeld[0][1] != ' ' &&spielfeld[0][2] != ' ' &&spielfeld[0][3] != ' ' &&spielfeld[0][4] != ' ' &&spielfeld[0][5] != ' ' &&spielfeld[0][6] != ' ') { ende = 2; } }
also wenn jedes feld der obersten zeile ungleich dem ursprünglich eingefügtem leerzeichen ist. führt aber auch nur dazu, dass es ein unentschieden genau dann ausgibt, wenn die erste spalte voll ist.
woran könnte das liegen?
-
Hast du denn den Fehler bei
[code"=c"]
if (ende = 2)
[/code]
korrigiert (s. Antwort von volkard)? Am besten die Warnstufe deines Compilers auf Maximum stellen - und die Warnungen auch beachten und korrigierenUnd weil ich gerne helfe guten Code zu erzeugen:
for (i = 0; i < 6; i++) if(spielfeld[zeile - i][spalte-1] != '+' && spielfeld[zeile - i][spalte-1] != '-' ) { spielfeld[zeile - i][spalte-1] = '+'; break; // Schleife beenden }
(kann man noch weiter verschönern, aber so solltest du es wohl verstehen!)
-
ja, = wurde durch == im if ersetzt.
11|warning: missing braces around initializer [-Wmissing-braces]|
11|warning: (near initialization for 'spielfeld[0]') [-Wmissing-braces]|
201|warning: control reaches end of non-void function [-Wreturn-type]|
||=== Build finished: 0 error(s), 3 warning(s) (0 minute(s), 0 second(s)) ===|das ist zeile 11
char spielfeld [6][7]={' '};
die for-schleife verstehe ich, ja. abermals danke dafür. ich werde sie aber nicht einbauen. solange ich in irgendeiner form eine eigene lösung erarbeitet habe, will ich die auch nehmen, solange sie funktioniert. ich fühl mich nicht wohl dabei fremde sachen einfach einzubauen und abzugeben. ich werde mir das aber auch alles speichern und für mich selbst ansehen und durchdenken, wie man es besser hätte machen können.
nur dieses unentschieden macht mich fertig
bevor ich dann zum letzten teil des programms komme, wenn es darum einen sieg festzustellen.
-
hmm...den fehler beim unentschieden finde ich immer noch nicht.
dafür funktionert scheinbar die restliche gewinnauswertung mit horizontalen, vertikalen und diagonalen (zwar umständlich, weil er bei jedem durchlauf jedes feld kontrolliert, aber immerhin selbst gebastelt).dafür gibt es zum abschluss noch ein kleines problem
char auswahl; if (ende != 0) { while (auswahl != 'q' && auswahl != 'n') { printf("Neues Spiel (n) - Spiel verlassen (q)\n"); scanf("%c", &auswahl); if (auswahl == 'n') { goto anfang; } if (auswahl == 'q') { } } }
n und q nimmt er auch an und es passiert, was passieren soll, aber der text vom printf wird zweimal ausgegeben. woran liegt das? soll ja nur ein kleiner abschlusstext sein, wenn ein ende erreich wurde so dass das programm nicht gleich schließt.
kann abschließend noch jemand dazu was sagen? dann will ich euch nicht länger belästigen^^ ich habe viele gute und hilfreiche antworten und ansätze bekommen. das mit dem unentschieden werde ich dann schon noch selbst rausbekommen^^
-
Schreib mal ein Leerzeichen vor den Formatbefehl bei scanf:
scanf(" %c", &auswahl);
Dadurch werden sog. Whitespaces (Linefeed, Carriage Return, Tabs und Leerzeichen) überlesen (da wahrscheinlich noch bei Druck auf Return/Enter dieses Zeichen im Tastaturpuffer drin ist - welches du sonst zuerst einliest und dann erst im zweiten Durchgang deiner Schleife auf deine weitere Eingabe gewartet wird).
Es freut mich, daß du selber die Probleme angehst. Falls du doch nicht weiter mit dem Unentschieden kommst (und bevor es zum Elfmeterschießen kommt ;-), kannst du ja deinen aktuellen Code dazu posten.
-
stimmt. das hatten wir auch mal in einer übung gelernt. glaube ich. es kommt mir zumindest bekannt vor. außerhalb einer schleifen hatten wir mal, in einer der ersten übungen, auch ein zweites scanf darunter geschrieben, da das erste von einem "return" gefressen wurde, welches noch in der eingabe stand. ich habe nur so viele sachen, die wir gelernt haben auch schon wieder vergessen^^ (der kurs ist für studienbegleitende IT-ausbildung. ich lerne das also mehr aus eigenintesse und nicht, weil ich das dauerhaft brauchen werde.)
freitag ist abgabe *hust
also werde ich heut abend und morgen nochmal schauen, ob ich was rausfinde bzgl. unentschieden und im zweifelsfall frage ich nachmittags/abends nochmal. wenn jemand da ist, ist es gut...wenn nicht dann halt nicht^^
-
programmiernoob schrieb:
stimmt. das hatten wir auch mal in einer übung gelernt.
Das wäre schon sensationell.
programmiernoob schrieb:
außerhalb einer schleifen hatten wir mal, in einer der ersten übungen, auch ein zweites scanf darunter geschrieben, da das erste von einem "return" gefressen wurde, welches noch in der eingabe stand
Das relativiert die Sache schon wieder.
Denn die wenigsten wissen, was ein Leerzeichen im Formatstring vonscanf
bedeutet.Aber nochmal zu deinem Problem mit der auswahl.
Das wäre etwas für eine do-while-Schleife (über fast alles).int main() { do // (nochmal) { menu(); while (!is_gameover()) { do_move_for_playerX(); print_board(); } print_winner(); nochmal abfragen } while (nochmal); }
und schon brauchst du auch kein
goto
mehr.
Und du brauchst auch nur auf 'n' prüfen.
-
also das mit dem leerzeichen im scanf hat er auch gezeigt, war aber nicht direkt im skript. also ich hätte es kennen können. mein dozent kennt das sehr sicher^^ das zweite scanf war nur die anfangsvariante, um uns nicht gleich zu überfordern^^
ja, die gotos sind nicht schön. morgen mache ich mich daran das ganze in funktionen zu packen. da das programm jetzt in der form funktioniert, werde ich mich darum kümmern dinge zusammen zufassen, wo möglich. beim nächsten mal habe ich dann vllt genug ahnung es von vornherein so zu machen
ich schau mir das morgen nochmal genau an. ein freund von mir hatte einen sehr guten einfall wegen dem unentschiedeneinfach ende = 3 setzen, wenn der spielzugzähler bei 42 ist. das ganze mit if. das spart alle rätselerei und ist relativ narrensicher.
an do while dachte ich auch mal. ich hab in erinnerung, dass bei do while und while die art der abfrage der bedingung anders ist. also beim einen wird am anfang geprüft, beim anderen am ende. vllt meine ich gerade spontan aber auch was anderes. ich muss mir das morgen nochmal anschauen.
danke für deine mühe.
-
oje..mir fällt gerade auf, dass das e schon ein vorschlag vom dirk war. das habe ich damals fehlinterpretiert. das tut mir leid
(ich kann jetzt nur nicht editieren - darum der spam)