Quellcode Bewertung Vier Gewinnt
-
Ich bin ein blutiger Anfänger was Sachen in C angeht.
Deswegen würde ich mich über eine Bewertung meines neuen C Codes freuen.
Wo könnte man etwas verkürzen wo kann etwas besser gemacht werden.
Das Spiel ist Vier gewinnt von vier Seiten. Das heißt die Steine rutschen auf einem 6x6 Feld sozusagen in die Mitte, weil von allen Seiten der Stein reingeworfen werden kann
Danke#include <stdio.h> #include <conio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> char feld[6][6],spielstein; int spieler,gewinner=0,wahl,setzencom=0,versuch=1; void spielfeldAnzeigen(){ system("cls"); printf("\n\t A B C D E F\n"); printf("\t +--+--+--+--+--+--+\n"); printf("\tX | %c: %c: %c| %c: %c: %c| G\n", feld[0][0], feld[0][1], feld[0][2], feld[0][3], feld[0][4], feld[0][5]); printf("\t +--+--+--+--+--+--+\n"); printf("\tW | %c: %c: %c| %c: %c: %c| H\n", feld[1][0], feld[1][1], feld[1][2], feld[1][3], feld[1][4], feld[1][5]); printf("\t +--+--+--+--+--+--+\n"); printf("\tV | %c: %c: %c| %c: %c: %c| I\n", feld[2][0], feld[2][1], feld[2][2], feld[2][3], feld[2][4], feld[2][5]); printf("\t +--+--+--+--+--+--+\n"); printf("\tU | %c: %c: %c| %c: %c: %c| J\n", feld[3][0], feld[3][1], feld[3][2], feld[3][3], feld[3][4], feld[3][5]); printf("\t +--+--+--+--+--+--+\n"); printf("\tT | %c: %c: %c| %c: %c: %c| K\n", feld[4][0], feld[4][1], feld[4][2], feld[4][3], feld[4][4], feld[4][5]); printf("\t +--+--+--+--+--+--+\n"); printf("\tS | %c: %c: %c| %c: %c: %c| L\n", feld[5][0], feld[5][1], feld[5][2], feld[5][3], feld[5][4], feld[5][5]); printf("\t +--+--+--+--+--+--+\n"); printf("\t R Q P O N M\n"); } void auswertung(){ for (int i=0;i<=5;i++) { for (int u=0;u<=2;u++) { if (feld[i][u] == 88 && feld[i][u+1] == 88 && feld[i][u+2] == 88 && feld[i][u+3] == 88) { gewinner=1; /*if (gewinner=1) { break; } */}/* else { printf("falsch"); } */ if (feld[i][u] == 79 && feld[i][u+1] ==79 && feld[i][u+2] ==79 && feld[i][u+3] == 79) { gewinner=2; /*if (gewinner=1) { break; }*/ } } } for (int u=0;u<=5;u++) { for (int i=0;i<=2;i++) { if (feld[i][u] == 88 && feld[i+1][u] == 88 && feld[i+2][u] == 88 && feld[i+3][u] == 88) { gewinner=1; /*if (gewinner=1) { break; } */}/* else { printf("falsch"); } */ if (feld[i][u] == 79 && feld[i+1][u] ==79 && feld[i+2][u] ==79 && feld[i+3][u] == 79) { gewinner=2; /*if (gewinner=1) { break; }*/ } } } for (int u=0;u<=2;u++) { for (int i=0;i<=2;i++) { if (feld[u][i] == 88 && feld[u+1][i+1] == 88 && feld[u+2][i+2] == 88 && feld[u+3][i+3] == 88) { gewinner=1; /*if (gewinner=1) { break; } */}/* else { printf("falsch"); } */ if (feld[u][i] == 79 && feld[u+1][i+1] == 79 && feld[u+2][i+2] == 79 && feld[u+3][i+3] == 79) { gewinner=2; /*if (gewinner=1) { break; }*/ } } } for (int u=0;u<=2;u++) { for (int i=5;i>=3;i--) { if (feld[u][i] == 88 && feld[u+1][i-1] == 88 && feld[u+2][i-2] == 88 && feld[u+3][i-3] == 88) { gewinner=1; /*if (gewinner=1) { break; } */}/* else { printf("falsch"); } */ if (feld[u][i] == 79 && feld[u+1][i-1] == 79 && feld[u+2][i-2] == 79 && feld[u+3][i-3] == 79) { gewinner=2; /*if (gewinner=1) { break; }*/ } } } } void stein_setzen (char *chrEingabe) { for(int i=0;i<=5;i++){ if(*chrEingabe==(97+i)){ if(feld[0][i]==32){ if(feld[1][i]==32){ if(feld[2][i]==32){ feld[2][i]=spielstein; } else{ feld[1][i]=spielstein; } } else { feld[0][i]=spielstein; } }else{ printf("bittewählen"); } } } for(int i=0;i<=5;i++){ if(*chrEingabe==(103+i)){ if(feld[i][5]==32){ if(feld[i][4]==32){ if(feld[i][3]==32){ feld[i][3]=spielstein; } else{ feld[i][4]=spielstein; } } else { feld[i][5]=spielstein; } }else{ printf("Kordinate setzten"); } } } for(int i=0;i<=5;i++){ if(*chrEingabe==(-i+114)){ if(feld[5][i]==32){ if(feld[4][i]==32){ if(feld[3][i]==32){ feld[3][i]=spielstein; } else{ feld[4][i]=spielstein; } } else { feld[5][i]=spielstein; } }else{ printf("Kordinate setzen"); } } } for(int i=0;i<=5;i++){ if(*chrEingabe==(-i+120)){ if(feld[i][0]==32){ if(feld[i][1]==32){ if(feld[i][2]==32){ feld[i][2]=spielstein; } else{ feld[i][1]=spielstein; } } else { feld[i][0]=spielstein; } }else{ printf("Kordinate setzen"); } } } } void computer_gehirn (char *comEingabe) { for (int i=0;i<=5;i++) { for (int u=0;u<=4;u++) { if (feld[i][u] == 79 && feld[i][u+1] == 79) { if (versuch==1){ if (feld[i][u+2] == 32){ feld[i][u+2] = spielstein; versuch=0; } } else { setzencom=0; break; } setzencom = 1; } } } for (int i=0;i<=5;i++) { for (int u=0;u<=3;u++) { if (feld[i][u] == 79 && feld[i][u+1] == 79 && feld[i][u+2] == 79) { if (versuch==1){ if (feld[i][u-1] == 32){ feld[i][u-1] = spielstein; versuch=0; } } else { setzencom=0; break; } setzencom = 1; } } } for (int u=0;u<=5;u++) { for (int i=0;i<=4;i++) { if (feld[i][u] == 79 && feld[i+1][u] == 79) { if (versuch==1){ if (feld[i+2][u] == 32){ feld[i+2][u] = spielstein; versuch=0; } } else { setzencom=0; break; } setzencom = 1; } } } for (int i=0;i<=5;i++) { for (int u=0;u<=3;u++) { if (feld[i][u] == 79 && feld[i+1][u] == 79 && feld[i-1][u] == 79) { if (versuch==1){ if (feld[i-2][u] == 32){ feld[i-2][u] = spielstein; versuch=0; } } else { setzencom=0; break; } setzencom = 1; } } } for (int i=0;i<=4;i++) { for (int u=0;u<=4;u++) { if (feld[u][i] == 79 && feld[u+1][i+1] == 79) { if (versuch==1){ if (feld[i-1][u-1] == 32){ feld[i-1][u-1] = spielstein; versuch=0; } } else { setzencom=0; break; } setzencom = 1; } } } for (int i=0;i<=3;i++) { for (int u=0;u<=3;u++) { if (feld[u][i] == 79 && feld[u+1][i+1] == 79&& feld[u+2][i+2] == 79) { if (versuch==1){ if (feld[i+3][u+3] == 32){ feld[i+3][u+3] = spielstein; versuch=0; } } else { setzencom=0; break; } setzencom = 1; } } } if (setzencom ==0 &&versuch ==1) { for(int i=0;i<=5;i++){ if(*comEingabe==(97+i)){ if(feld[0][i]==32){ if(feld[1][i]==32){ if(feld[2][i]==32){ feld[2][i]=spielstein; } else{ feld[1][i]=spielstein; } } else { feld[0][i]=spielstein; } }else{ if(feld[0][i+1]==32){ if(feld[1][i+1]==32){ if(feld[2][i+1]==32){ feld[2][i+1]=spielstein; } else{ feld[1][i+1]=spielstein; } } else { feld[0][i+1]=spielstein; } }else{ printf("hallo´"); } } } } for(int i=0;i<=5;i++){ if(*comEingabe==(103+i)){ if(feld[i][5]==32){ if(feld[i][4]==32){ if(feld[i][3]==32){ feld[i][3]=spielstein; } else{ feld[i][4]=spielstein; } } else { feld[i][5]=spielstein; } }else{ if(feld[i+1][5]==32){ if(feld[i+1][4]==32){ if(feld[i+1][3]==32){ feld[i+1][3]=spielstein; } else{ feld[i][4]=spielstein; } } else { feld[i][5]=spielstein; } }else{ printf("Kordinate setzten"); } } } } for(int i=0;i<=5;i++){ if(*comEingabe==(-i+114)){ if(feld[5][i]==32){ if(feld[4][i]==32){ if(feld[3][i]==32){ feld[3][i]=spielstein; } else{ feld[4][i]=spielstein; } } else { feld[5][i]=spielstein; } }else{ if(feld[5][i+1]==32){ if(feld[4][i+1]==32){ if(feld[3][i+1]==32){ feld[3][i+1]=spielstein; } else{ feld[4][i+1]=spielstein; } } else { feld[5][i+1]=spielstein; } }else{ printf("Kordinate setzen"); } } } } for(int i=0;i<=5;i++){ if(*comEingabe==(-i+120)){ if(feld[i][0]==32){ if(feld[i][1]==32){ if(feld[i][2]==32){ feld[i][2]=spielstein; } else{ feld[i][1]=spielstein; } } else { feld[i][0]=spielstein; } }else{ if(feld[i+1][0]==32){ if(feld[i+1][1]==32){ if(feld[i+1][2]==32){ feld[i+1][2]=spielstein; } else{ feld[i+1][1]=spielstein; } } else { feld[i+1][0]=spielstein; } }else{ printf("Kordinate setzen"); } } } } } versuch=1; } int main(void) { int y=0; char chrEingabe,comEingabe,alphabet[30] = "abcdefhijklmnopqrstuvwx"; //Array komplett auf Leerzeichen setzen for (int x=0;x<7;x++) { for (int y=0;y<7;y++){ feld[x][y] = 32; } } scanf_s("%i",&wahl); switch (wahl) { case 1: spielfeldAnzeigen(); printf("\n\nWelcher Spieler soll beginen?\n1 oder 2?\n\n"); scanf_s("%i",&spieler); for(int y=1;y<=30;y++) { if (spieler&1) { spielstein='O'; } else { spielstein ='X'; } fflush(stdin); chrEingabe=tolower(getchar()); stein_setzen(&chrEingabe); spielfeldAnzeigen(); spieler++; auswertung(); if (gewinner==1) { printf("Spieler 1 ist der Sieger\n\n"); } else if (gewinner==2) { printf("Spieler 2 ist der Sieger\n\n"); } if (gewinner == 1 || gewinner == 2) { printf("Herzlichen Glueckwunsch!"); } else{ if (spieler&1) { printf("\n\nSpieler 2 ist an der Reihe, der Spielstein ist: O\n\n"); } else { printf("\n\nSpieler 1 ist an der Reihe, der Spielstein ist: X\n\n"); } } } _getch(); break; case 2: spielfeldAnzeigen(); printf("\n\nWelcher Spieler soll beginen?\nSpieler [1] oder Computer [2]?\n\n"); scanf_s("%i",&spieler); while (gewinner != 1 || gewinner !=2) { if (spieler&1) { spielstein='O'; fflush(stdin); chrEingabe=tolower(getchar()); stein_setzen(&chrEingabe); } else { spielstein ='X'; fflush(stdin); comEingabe=alphabet[rand() % sizeof alphabet]; computer_gehirn(&comEingabe); _sleep(900); } spielfeldAnzeigen(); spieler++; auswertung(); if (gewinner==1) { printf("Computer ist der Sieger\n\n"); } else if (gewinner==2) { printf("Spieler ist der Sieger\n\n"); } if (gewinner == 1 || gewinner == 2) { printf("Herzlichen Glueckwunsch!"); } else{ if (spieler&1) { printf("\n\nSpieler ist an der Reihe, der Spielstein ist: O\n\n"); } else { printf("\n\nComputer ist an der Reihe, der Spielstein ist: X\n\n"); } } } _getch(); break; } }
-
für bessere leslichkeit verwende funktionen, hilft auch der übersichts halber =b
hab mir jetzt nicht alles angeguckt... aber es scheint sich wie gesagt vieles
mit funktionen/rekursiven funktionen einfacher lösen. Aber sonst durchs überfliegen
hab ich keine schwerwiegende fehler gefunden, aber ich guck mir das später mal genauer
an =b
-
Kannst du mir das genauer erläutern mit den Funktionen?
Ich würde mich freuen wenn du dir das nochmal in Ruhe anschauen würdest, das wäre sehr lieb:)
Mich interressiert jede Kritik, jeder Verbesserungsvorschlag, jeder kleinster Fehler:) Will lernen;)
Danke
-
Du solltest deinen Code vernünftig einrücken!
Beispiel aus deinem Code (man sieht nicht, was zu welchem Block gehört, etc.):
for (int u=0;u<=4;u++) { if (feld[i][u] == 79 && feld[i][u+1] == 79) { if (versuch==1){ if (feld[i][u+2] == 32){ feld[i][u+2] = spielstein; versuch=0; } } else { setzencom=0; break; } setzencom = 1; } }
Besser:
for (int u=0;u<=4;u++) { if (feld[i][u] == 79 && feld[i][u+1] == 79) { if (versuch==1) { if (feld[i][u+2] == 32) { feld[i][u+2] = spielstein; versuch=0; } } else { setzencom=0; break; } setzencom = 1; } }
Außerdem ist das hier nicht so toll:
feld[x][y] = 32;
Warum nicht?
feld[x][y] = ' ';
Dann versteht man auch später noch, was da passiert...
-
1. Compiliert bei mir nicht, weil conio.h nicht portabel ist
2. Dass system("cls") nicht portabel ist, fällt da weniger in's Gewicht. Aber gibt es dafür denn nichts besseres in der conio.h?
3. Wenige Compilerwarnungen, bloß ein unbenutztes y in Zeile 494
4. Die Deklaration von Variablen in for-Schleifenköpfen ist C99, was man natürlich verwenden darf. Aber jetzt bin ich verwirrt: conio.h ist ganz klar Windows, aber der wohl gängigste Windowscompiler (MSVC) kann kein C99. Womit compilierst du das?
5. Globale Zustandsvariablen. Das Spielfeld global kann man ja noch verteidigen, aber die meisten anderen sind unverzeihlich
6. Funktion auswertung(): Hast du schon mal was von Funktionen oder Schleifen gehört? Offensichtlich ja. wieso nutzt du sie dann nicht? Wenn in deinem Quelltext gleiche oder ähnliche Blöcke mehr als 2x auftauchen, dann machst du etwas falsch.
7. Funktion stein_setzen(): Das geht ja immer so weiter...
8. Funktion computer_gehirn(): Und weiter...
9.alphabet[30] = "abcdefhijklmnopqrstuvwx";
Das ist ja fast unfreiwillig komisch.
10. 32 ist kein portables Leerzeichen. ' ' ist ein Leerzeichen, portabel und besser verständlich
11.fflush(stdin);
Auch böse unportabel.
12. Es ist kein Zeichen einer starken KI, wenn sie scheinbar lange überlegt wegen eines sleep.Das ist jetzt nur quer gelesen, weil viel zu lang. Und die Funktion habe ich natürlich auch nicht geprüft, siehe Punkt 1.
P.S.: ich wusste gar nicht, dass es eine Obergrenze für Smileys gibt. Eigentlich sollten da bei einigen Punkten mehr Daumen runter hin, aber das Forum hindert mich.
-
Ich habe nicht die große Ahnung von dem was du gesagt hast, aber ich versuche es!
SeppJ schrieb:
1. Compiliert bei mir nicht, weil conio.h nicht portabel ist
2. Dass system("cls") nicht portabel ist, fällt da weniger in's Gewicht. Aber gibt es dafür denn nichts besseres in der conio.h?
3. Wenige Compilerwarnungen, bloß ein unbenutztes y in Zeile 494
4. Die Deklaration von Variablen in for-Schleifenköpfen ist C99, was man natürlich verwenden darf. Aber jetzt bin ich verwirrt: conio.h ist ganz klar Windows, aber der wohl gängigste Windowscompiler (MSVC) kann kein C99. Womit compilierst du das?
5. Globale Zustandsvariablen. Das Spielfeld global kann man ja noch verteidigen, aber die meisten anderen sind unverzeihlich
6. Funktion auswertung(): Hast du schon mal was von Funktionen oder Schleifen gehört? Offensichtlich ja. wieso nutzt du sie dann nicht? Wenn in deinem Quelltext gleiche oder ähnliche Blöcke mehr als 2x auftauchen, dann machst du etwas falsch.
7. Funktion stein_setzen(): Das geht ja immer so weiter...
8. Funktion computer_gehirn(): Und weiter...
9.alphabet[30] = "abcdefhijklmnopqrstuvwx";
Das ist ja fast unfreiwillig komisch.
10. 32 ist kein portables Leerzeichen. ' ' ist ein Leerzeichen, portabel und besser verständlich
11.fflush(stdin);
Auch böse unportabel.
12. Es ist kein Zeichen einer starken KI, wenn sie scheinbar lange überlegt wegen eines sleep.Das ist jetzt nur quer gelesen, weil viel zu lang. Und die Funktion habe ich natürlich auch nicht geprüft, siehe Punkt 1.
P.S.: ich wusste gar nicht, dass es eine Obergrenze für Smileys gibt. Eigentlich sollten da bei einigen Punkten mehr Daumen runter hin, aber das Forum hindert mich.
1. Ich nutze Visual Studio C++ Express
2. Wie genau nicht portabel?
3. Y wird entfernt!
4. Visual Studo c++, Was für ein Problemt gibt es mit conio?
5. so lokal wie möglich, so global wie nötig? Wird geändert!
6. Welche Blöcke kommen öfters vor? ich wüüste nicht welche funktionen ich noch erstellen könnte oder schleifen
9. Wieso komisch? Wie hätte ich es anders machen können?
10. Leerzeichen wird geändert
11 flush stdin ist böse?
12. einer starken KI?vielen Dank
-
tkuest schrieb:
1. Ich nutze Visual Studio C++ Express
2. Wie genau nicht portabel?
3. Y wird entfernt!
4. Visual Studo c++, Was für ein Problemt gibt es mit conio?
5. so lokal wie möglich, so global wie nötig? Wird geändert!
6. Welche Blöcke kommen öfters vor? ich wüüste nicht welche funktionen ich noch erstellen könnte oder schleifen
9. Wieso komisch? Wie hätte ich es anders machen können?
10. Leerzeichen wird geändert
11 flush stdin ist böse?
12. einer starken KI?
vielen DankIch habe keine Zeile Code gelesen, aber antworte trotzdem mal
1. Gut
2. Bedeutet, dass es nur für Windows funktioniert. C könnte man sonst für alle Systeme benutzen, für die ein geeigneter Compiler existiert.
3.
4. conio.h ist nicht portabel, und du hast .cpp statt .c Dateien angelegt, somit wird dein Code als C++ und nicht als C Code kompiliert.
5.
6. Na ja, das ist schwer ohne den Code zu lesen.
9. Lies dir das Alphabet noch mal durch
11. Ja, fflush() ist nur für Output Streams definiert, dass es auf Windows auch mit stdin funktioniert ist Zufall.
12. Mach einfach alle Sleeps() weg, die sind eh nicht portabel.
-
Zu 1. 2. 10. 11. 12.
Dies istdas Unterforum für C99 und C89 (auch ANSI-C).
D.h. es ist genormt und es gibt eine offizielle Standardbeschreibung dazu.
Die genannten Punkte gehören nicht zu diesem Standard sondern sind Erweiterungen von Microsoft. (Und dann gehört das in das DOS oder WindowsAPI Forum).
Es sind aber Sachen, die du nicht wirklich brauchst.Zu 10. Gilt genauso für 88 und 'X' (für 79 und 'O' natürlich auch)
Zu 9. Du machst irgendwo ein
% sizeof(alphabet)
Durch deine Definition ist das aber 30. Du brauchst aber nur 24 Zeichen.
-
Ich meinte 4. und nicht 12.
Warum hat
void stein_setzen (char *chrEingabe)
ein char* als Eingabe? Warum ist das ein Zeiger und kein int?
Beivoid computer_gehirn (char *comEingabe)
genauso.Wozu ist dieses
switch (wahl) {
in main?
Und worin bestehen die Unterschide in den Fällen?
-
ah, in diesem code-wirrwar verstecken sich ja funktionen xD beim überfliegen
glatt nicht aufgefallen xDaber ohne dass ich den schlaf nachgeholt habe der mir seit 3 tagen fehlt, ist es
logisch dass ich dies nicht erkannt hatte xD
-
ist
scanf_s("%i",&wahl);
nicht auch ein Microsoft-C Spezialweg?
MfG f.-th.