Kleines "Labyrinth-Spiel", freu mich über jede Kritik!
-
Hallo,
ich habe heute mal aus Spaß an der Freue versucht ein einfaches Spiel zu programmieren, würde mich jetzt aber sehr freuen wenn ihr euch das ganze mal anseht, auch wenn es knapp 300 Zeilen sind... Ich habe diverse Kommentare eingefügt um das ganze möglichst verständlich zu machen. Womit ich besonders unglücklich bin ist zum einen das
system("cls");
(gibts hierfür eine portablere äquivalente Lösung?!) und zum anderen, dass es nicht immer einen "Weg nach draußen" gibt. Ich freu mich über jeden noch so kleinen Hinweis
Vielen Dank im Voraus!
#include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <time.h> #include <limits.h> #define MAX 25 typedef struct figure fig; struct figure { int x_coord; int y_coord; }; int spielfeld(char **feld,int x,int y, fig *spieler_pos,int *schritte); void input(fig *spieler_pos,char **feld); void eingabe_universal(char wahl,void *adresse); /*******************************************************************/ /*******************************************************************/ /*******************************************************************/ int main() { puts("*****************************************************************"); puts("** Kleines Labyrinth Version 1.0 **"); puts("*****************************************************************"); puts("** Steuerung: A W S D - Steuerung **"); puts("** Jeden Schritt mit ENTER bestaetigen **"); puts("*****************************************************************\n"); fig spieler_pos; int i=0,j=0,temp=0,schritte=0; char **feld; int groesse_x=0,groesse_y=0; srand(time(NULL)); /* Angeben der Spielfeldgroesse */ printf("Maximale Spielfeldgroesse: %i x %i",MAX,MAX); printf("\nSpielfeldgroesse x: "); eingabe_universal('i',&groesse_x); if(groesse_x <= 0) { printf("\nZahl muss groesser 0 sein!"); return 0; } printf("\nSpielfeldgroesse y: "); eingabe_universal('i',&groesse_y); if(groesse_y <= 0) { printf("\nZahl muss groesser 0 sein!"); return 0; } /* reservieren des Speichers fürs Spielfeld */ if( (feld = malloc(sizeof(char *) * groesse_x)) == NULL) free(feld); for(i=0; i<groesse_x;i++) { feld[i] = malloc(groesse_y * sizeof(char)); if(feld[i] == NULL) { free(feld[i]); printf("\nERROR\n"); break; } } /* Spielfeldrand erstellen */ //linker Rand for(i=0;i<groesse_x;i++) { feld[i][0] = '*'; } //oberer Rand for(j=0;j<groesse_y;j++) { feld[0][j] = '*'; } //rechter Rand for(i=0;i<groesse_x;i++) { feld[i][groesse_y-1] = '*'; } //unterer Rand for(j=0;j<groesse_y;j++) { feld[groesse_x-1][j] = '*'; } feld[0][groesse_y-2] = 'Z'; feld[1][groesse_y-2] = ' '; /* zufälliges initialisieren des inneren Spielfelds mit einem * oder einem Leerzeichen. * zu 1/3%, leerzeichen ca 2/3 */ for(i=1;i<=groesse_x-2;i++) { for(j=1;j<=groesse_y-2;j++) { temp = rand(); if(temp > (RAND_MAX/3)) { feld[i][j] = ' '; } else feld[i][j] = '*'; } } //StartPosition setzen spieler_pos.y_coord = 0; spieler_pos.x_coord = groesse_x -2; feld[spieler_pos.x_coord][spieler_pos.y_coord] = 'x'; feld[spieler_pos.x_coord][spieler_pos.y_coord+1] = ' '; //Zur Sicherheit, dass man raus kann // for(i=0;i<groesse_x;i++) { printf("\n"); for(j=0;j<groesse_y;j++) { printf("%c",feld[i][j]); } } //Schleife ist solange wahr, bis der Spieler beim Ziel angekommen ist while(spielfeld(feld,groesse_x,groesse_y,&spieler_pos,&schritte)); printf("\n\ngewonnen!!!\n\n"); return 0; } /*******************************************************************/ /*******************************************************************/ /*******************************************************************/ /*Diese Funktion liest char oder int ein, und prüft auf die Richtigkeit der Eingabe*/ void eingabe_universal(char wahl,void *adresse) { int i=0; /*einlesen und pruefen ob Zahl eingetippt wurde*/ if(wahl == 'i') { char temp[4]; fgets(temp,sizeof(temp),stdin); for(i=0;i<4;i++) { if( (temp[i] < 48 || temp[i] > 57) && !(temp[i] == '\0' || temp[i] == '\n')) { printf("\nError, falsche Eingabe, bitte eine Zahl eingeben!"); return; } } if( (i = atoi(temp)) > MAX) { printf("\nERROR, Zahl größer %i",MAX); return; } else *(int *) adresse = i; } /* Falls Buchstaben eingelesen und geprueft werden: */ else if(wahl == 'c') { char temp[3]; fgets(temp,sizeof(temp),stdin); for(i=0;i<3;i++) { if( !(temp[i] == 'a' || temp[i] == 'w' || temp[i] == 's' || temp[i] == 'd' || temp[i] == '\n' || temp[i] == '\0') ) { printf("\nError, falsche Eingabe!"); } else *(char *)adresse = temp[0]; } return; } } /*******************************************************************/ /*******************************************************************/ /*******************************************************************/ int spielfeld(char **feld,int x,int y, fig *spieler_pos,int *schritte) { int i=0,j=0; //Eingeben der Laufrichtung und überprüfen ob dort eine Wand ist oder nicht input(spieler_pos,feld); //Neues setzen der Spielerposition feld[spieler_pos->x_coord][spieler_pos->y_coord] = 'x'; //Clearen der Console, gibts hierfür eine portable Lösung?! system("cls"); //Generieren des Neuen Spielfelds for(i=0;i<x;i++) { for(j=0;j<y;j++) { printf("%c",feld[i][j]); } printf("\n"); } *schritte += 1; //Zählen der Schritte die man bis zum Ziel gebraucht hat if(feld[0][y-2] == 'x') { printf("\nAnzahl benoetigter Schritte: %i",*schritte); return 0; } else return 1; } /*******************************************************************/ /*******************************************************************/ /*******************************************************************/ void input(fig *spieler_pos,char **feld) { /*Der Spieler bewegt sich mit der bekannten A-W-S-D Steuerung muss aber nach jeder Eingabe mit ENTER bestätigen*/ //MEMO: Falscheingaben werden noch nicht abgefangen... char weg; printf("\n:"); eingabe_universal('c',&weg); //Prüfen in welche Richtung gegangen werden soll if(weg == 'a') { if(feld[spieler_pos->x_coord][spieler_pos->y_coord-1] != '*') { feld[spieler_pos->x_coord][spieler_pos->y_coord] = ' '; spieler_pos->y_coord -= 1; } else printf("\n geht nicht!\n"); } else if(weg == 'd') { if(feld[spieler_pos->x_coord][spieler_pos->y_coord+1] != '*') { feld[spieler_pos->x_coord][spieler_pos->y_coord] = ' '; spieler_pos->y_coord += 1; } else printf("\n geht nicht!\n"); } else if(weg == 'w') { if(feld[spieler_pos->x_coord-1][spieler_pos->y_coord] != '*') { feld[spieler_pos->x_coord][spieler_pos->y_coord] = ' '; spieler_pos->x_coord -= 1; } else printf("\n geht nicht!\n"); } else if(weg == 's') { if(feld[spieler_pos->x_coord+1][spieler_pos->y_coord] != '*') { feld[spieler_pos->x_coord][spieler_pos->y_coord] = ' '; spieler_pos->x_coord += 1; } else printf("\n geht nicht!\n"); } return; }
EDIT: Falls mir jemand sagen könnte wie ich das mit dem "aktualisieren des Spielfelds" (bei einer Größe von ca 20x20 kriegt man Kopfschmerzen von dem "gewackel"...) besser machen könnte, wär das Top!:)
-
Hey,
ich finde dein Spiel sehr gelungen. Insbesondere, da es nur eine Konsole benötigt. Sehr schön
Man kann übrigens das Spielfeld verlassen. Wenn das Spiel beginnt, dann kann man einfach "verschwinden".
Damit es immer einen Weg nach draußen gibt, das ist eigentlich nicht so schwierig. Nehmen wir an, du hast ein Labyrinth, dass 5x5 groß ist:
_ _ _ _ _
_ _ _ _ _
_ _ _ _ _
_ _ _ _ _
_ _ _ _ _Nun suchst du zufällig eine Stelle am Rand aus:
_ _ _ _ _
_ _ _ _ _
_ _ _ _ E
_ _ _ _ _
_ _ _ _ _Von dieser Stelle bildest du nun zufällig einen Weg (zufällig eine Aktion auswählen: hoch, runter, links, rechts) und das solange bis du wieder an irgendeinem Rand bist:
_ _ _ _ _
_ _ _ _ _
* * _ * E
_ * * * _
_ _ _ _ _Diese Koordinaten speicherst du in ein Array, anschließend generierst du zufällig weitere Blöcke. Dabei überprüfst du, ob diese Stelle schon für den Weg belegt ist. Wenn das so ist, dann setzt du dort keinen Block.
So hast du immer einen Weg, und evtl. sogar mehrere. Aber immer mindestens einen.
Für system("cls") gibt es keine portable Lösung. Da stößt du so langsam an die Grenze einer Konsolenanwendung.
-
..... schrieb:
Hey,
ich finde dein Spiel sehr gelungen. Insbesondere, da es nur eine Konsole benötigt. Sehr schön
Man kann übrigens das Spielfeld verlassen. Wenn das Spiel beginnt, dann kann man einfach "verschwinden".
Damit es immer einen Weg nach draußen gibt, das ist eigentlich nicht so schwierig. Nehmen wir an, du hast ein Labyrinth, dass 5x5 groß ist:
_ _ _ _ _
_ _ _ _ _
_ _ _ _ _
_ _ _ _ _
_ _ _ _ _Nun suchst du zufällig eine Stelle am Rand aus:
_ _ _ _ _
_ _ _ _ _
_ _ _ _ E
_ _ _ _ _
_ _ _ _ _Von dieser Stelle bildest du nun zufällig einen Weg (zufällig eine Aktion auswählen: hoch, runter, links, rechts) und das solange bis du wieder an irgendeinem Rand bist:
_ _ _ _ _
_ _ _ _ _
* * _ * E
_ * * * _
_ _ _ _ _Diese Koordinaten speicherst du in ein Array, anschließend generierst du zufällig weitere Blöcke. Dabei überprüfst du, ob diese Stelle schon für den Weg belegt ist. Wenn das so ist, dann setzt du dort keinen Block.
So hast du immer einen Weg, und evtl. sogar mehrere. Aber immer mindestens einen.
Für system("cls") gibt es keine portable Lösung. Da stößt du so langsam an die Grenze einer Konsolenanwendung.
Tschuldigung. Falscher Daumen. Es war natürlich der gemeint:
-
Herzlichen Dank, das freut mich sehr, dass es dir gefällt!
Danke für den Hinweis mit dem Lösungsweg, werde ich gleich mit einbauen
und verschwinden darf natürlich auch keiner
-
..... schrieb:
Tschuldigung. Falscher Daumen. Es war natürlich der gemeint:
musst du deshalb das forum zumüllen und den ganzen ramsch nochmal wiederholen?
-
du könntest anstatt
system("cls")
Ev auch mit ANSI escape codes wieder an den anfang der Ausgabe springen und neu ausgeben...
Hab es jedoch noch nie gebraucht^^
-
So, ich habe das ganze jetzt nochmal ein bisschen überarbeitet, es ist jetzt nicht mehr möglich aus dem Bild zu "verschwinden", auch gibt es jetzt immer min. einen Lösungsweg. Die Spielfeldgroesse ist ein wenig flexibler geworden. Da ich an vielen Stellen einiges geändert habe, poste ich lieber nochmal den ganzen Code, anstatt nur die Änderungen. Ich hoffe ihr seht mir das etwas längere Listing nach
Schonmal vielen Dank an alle die sich das ganze trotzdem anschauen
Wie gesagt, ich freue mich über jeden Hinweis, sei es eine Möglichkeit etwas besser zu schreiben, ein Fehler oder eine andere Kleinigkeit.
Viele Grüße
#include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <time.h> #include <limits.h> #define MAX_X 25 #define MAX_Y 50 typedef struct figure fig; struct figure { int x_coord; int y_coord; }; int spielfeld(char **feld,int x,int y, fig *spieler_pos,int *schritte); void input(fig *spieler_pos,char **feld); void eingabe_universal(char wahl,void *adresse,char typ); /*******************************************************************/ /*******************************************************************/ /*******************************************************************/ int main() { puts("*****************************************************************"); puts("** Kleines Labyrinth Version 1.1 **"); puts("*****************************************************************"); puts("** Steuerung: A W S D - Steuerung **"); puts("** Jeden Schritt mit ENTER bestaetigen **"); puts("*****************************************************************\n"); fig spieler_pos; int i=0,j=0,temp=0,temp_x=0,temp_y=0,schritte=0; char **feld; int groesse_x=0,groesse_y=0; srand(time(NULL)); /* Angeben der Spielfeldgroesse */ printf("Maximale Spielfeldgroesse: %i x %i",MAX_X,MAX_Y); printf("\nSpielfeldgroesse x: "); eingabe_universal('i',&groesse_x,'x'); if(groesse_x <= 0) { printf("\neingegen: groesse_x: %i",groesse_x); printf("\nZahl muss groesser 0 sein!"); return 0; } printf("\nSpielfeldgroesse y: "); eingabe_universal('i',&groesse_y,'y'); if(groesse_y <= 0) { printf("\neingegen: groesse_y: %i",groesse_y); printf("\nZahl muss groesser 0 sein!"); return 0; } /* reservieren des Speichers fürs Spielfeld */ if( (feld = malloc(sizeof(char *) * groesse_x)) == NULL) free(feld); for(i=0; i<groesse_x;i++) { feld[i] = malloc(groesse_y * sizeof(char)); if(feld[i] == NULL) { free(feld[i]); printf("\nERROR\n"); break; } } /* Spielfeldrand erstellen */ //linker Rand for(i=0;i<groesse_x;i++) { feld[i][0] = '*'; } //oberer Rand for(j=0;j<groesse_y;j++) { feld[0][j] = '*'; } //rechter Rand for(i=0;i<groesse_x;i++) { feld[i][groesse_y-1] = '*'; } //unterer Rand for(j=0;j<groesse_y;j++) { feld[groesse_x-1][j] = '*'; } /******************************************************/ /*Sicherstellen, dass min. 1 Lösungsweg vorhanden ist!*/ /******************************************************/ /*temp_x und temp_y sind die Koordinaten UNTER dem Ziel*/ temp_x = 1; temp_y = groesse_y-2; /*suchen eines Weges VOM Ziel ZUM Start*/ do { /*Am rechten Rand, nur nach unten oder links*/ if(temp_y == (groesse_y-2)) { if( (temp=rand()) < RAND_MAX/2) { if(temp_y > 1) {temp_y--;} } else { if(temp_x < (groesse_x-2)) {temp_x++;} } } /*jetzt links oben oder unten*/ else { if( (temp=rand()) < (RAND_MAX/3) ) { if( temp_y > 1) //prüfen ob man an den Feldrand kommen würde {temp_y--;} else {temp_x++;} } else if( (temp=rand()) < (RAND_MAX/2) ) { if(temp_x < (groesse_x-2)) //prüfen ob man an den Feldrand kommen würde {temp_x++;} else {temp_y--;} } else { if( temp_x > 2) //prüfen ob man an den Feldrand kommen würde {temp_x--;} else { if(temp_x < (groesse_x-2)) //prüfen ob man an den Feldrand kommen würde {temp_x++;} } } } feld[temp_x][temp_y] = ' '; } while((temp_x != (groesse_x-2) ) || (temp_y !=1)); /* zufälliges initialisieren des inneren Spielfelds mit einem * oder einem Leerzeichen. * zu 1/3, leerzeichen ca 2/3 */ for(i=1;i<=groesse_x-2;i++) { for(j=1;j<=groesse_y-2;j++) { if( (temp = rand()) < (RAND_MAX/3)) { feld[i][j] = ' '; } else { if( (feld[i][j] != ' ') ) { feld[i][j] = '*'; } } } } //Ziel setzen und Feld davor freimachen feld[0][groesse_y-2] = 'Z'; feld[1][groesse_y-2] = ' '; //StartPosition setzen spieler_pos.y_coord = 0; spieler_pos.x_coord = groesse_x -2; feld[spieler_pos.x_coord][spieler_pos.y_coord] = 'X'; feld[spieler_pos.x_coord][spieler_pos.y_coord+1] = ' '; //Zur Sicherheit, dass man raus kann // for(i=0;i<groesse_x;i++) { printf("\n"); for(j=0;j<groesse_y;j++) { printf("%c",feld[i][j]); } } //Schleife ist solange wahr, bis der Spieler beim Ziel angekommen ist while(spielfeld(feld,groesse_x,groesse_y,&spieler_pos,&schritte)); printf("\n\ngewonnen!!!\n\n"); return 0; } /*******************************************************************/ /*******************************************************************/ /*******************************************************************/ /*Diese Funktion liest char oder int ein, und prüft auf die Richtigkeit der Eingabe*/ void eingabe_universal(char wahl,void *adresse,char typ) { int i=0; /*einlesen und pruefen ob Zahl eingetippt wurde*/ if(wahl == 'i') { char temp[4]; fgets(temp,sizeof(temp),stdin); for(i=0;i<4;i++) { if( (temp[i] < 48 || temp[i] > 57) && !(temp[i] == '\0' || temp[i] == '\n')) { printf("\nError, falsche Eingabe, bitte eine Zahl eingeben!"); return; } } if( typ == 'x') { if((i = atoi(temp)) > MAX_X) { printf("\nERROR, Zahl größer %i",MAX_X); return; } } else if( typ == 'y') { if((i = atoi(temp)) > MAX_Y) { printf("\nERROR, Zahl größer %i",MAX_Y); return; } } *(int *) adresse = i; } /* Falls Buchstaben eingelesen und geprueft werden: */ else if(wahl == 'c') { char temp[3]; fgets(temp,sizeof(temp),stdin); for(i=0;i<3;i++) { if( !(temp[i] == 'a' || temp[i] == 'w' || temp[i] == 's' || temp[i] == 'd' || temp[i] == '\n' || temp[i] == '\0') ) { printf("\nError, falsche Eingabe!"); } else *(char *)adresse = temp[0]; } return; } } /*******************************************************************/ /*******************************************************************/ /*******************************************************************/ int spielfeld(char **feld,int x,int y, fig *spieler_pos,int *schritte) { int i=0,j=0; //Eingeben der Laufrichtung und überprüfen ob dort eine Wand ist oder nicht input(spieler_pos,feld); //Neues setzen der Spielerposition feld[spieler_pos->x_coord][spieler_pos->y_coord] = 'X'; //Clearen der Console, gibts hierfür eine portable Lösung?! system("cls"); //Generieren des Neuen Spielfelds for(i=0;i<x;i++) { for(j=0;j<y;j++) { printf("%c",feld[i][j]); } printf("\n"); } *schritte += 1; //Zählen der Schritte die man bis zum Ziel gebraucht hat if(feld[0][y-2] == 'X') { printf("\nAnzahl benoetigter Schritte: %i",*schritte); return 0; } else return 1; } /*******************************************************************/ /*******************************************************************/ /*******************************************************************/ void input(fig *spieler_pos,char **feld) { /*Der Spieler bewegt sich mit der bekannten A-W-S-D Steuerung muss aber nach jeder Eingabe mit ENTER bestätigen*/ char weg; printf("\n:"); eingabe_universal('c',&weg,'z'); // 'z' muss aufgrund der Funktionsdefiniton angegeben werden, // ist hier aber ohne jeglichen Effekt! //Prüfen in welche Richtung gegangen werden soll if(weg == 'a') { if(feld[spieler_pos->x_coord][spieler_pos->y_coord-1] != '*' && spieler_pos->y_coord >0) { feld[spieler_pos->x_coord][spieler_pos->y_coord] = ' '; spieler_pos->y_coord -= 1; } else printf("\n geht nicht!\n"); } else if(weg == 'd') { if(feld[spieler_pos->x_coord][spieler_pos->y_coord+1] != '*') { feld[spieler_pos->x_coord][spieler_pos->y_coord] = ' '; spieler_pos->y_coord += 1; } else printf("\n geht nicht!\n"); } else if(weg == 'w') { if(feld[spieler_pos->x_coord-1][spieler_pos->y_coord] != '*') { feld[spieler_pos->x_coord][spieler_pos->y_coord] = ' '; spieler_pos->x_coord -= 1; } else printf("\n geht nicht!\n"); } else if(weg == 's') { if(feld[spieler_pos->x_coord+1][spieler_pos->y_coord] != '*') { feld[spieler_pos->x_coord][spieler_pos->y_coord] = ' '; spieler_pos->x_coord += 1; } else printf("\n geht nicht!\n"); } return; }
-
Sehr nettes Spiel.
Wenn man etwas falsches eingegeben hat, sollte die Meldung aber besser nach dem Spielfeld angezeigt werden, da sonst die obere Labyrinthreihe "weggeschoben" wird.Eine portabler***e*** Möglichkeit zum Bildschirmlöschen gibt's schon und zwar:
#ifdef __WIN32__ system("cls"); #else system("clear"); #endif
Sollte man am besten in eine eigene Funktion auslagern.
-
Ihr immer mit Eurem scheiß
system("cls")
. Für Windows gibt es da entsprechende WinAPI-Funktionen:const HANDLE OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE); void gotoxy(short x, short y) { const COORD position = { x, y }; SetConsoleCursorPosition(OutputHandle, position); } void clrscr() { gotoxy(0, 0); const CONSOLE_SCREEN_BUFFER_INFO info = GetScreenBufferInfo(); const COORD position = { info.dwCursorPosition.X, info.dwCursorPosition.Y }; const DWORD lenght = info.dwSize.X * info.dwSize.Y; DWORD number; FillConsoleOutputAttribute(OutputHandle, info.wAttributes, length, position, &number); FillConsoleOutputCharacter(OutputHandle, TEXT(' '), length, position, &number); }
Und bei Linux schreibt man schlicht und ergreifend
cout << "\033[2J";
Und nicht
system("clear")
.Ansonsten:
Die Fehlermeldung, wenn man eine falsche Eingabe getätigt hat, erscheint immer nur ganz kurz und danach wird sofort der Bildschirm gelöscht.
Außerdem könntest Du vielleichtgetch()
für die Eingabe nehmen. Obwohl das nicht mehr plattformunabhängig ist, aber Du könntest ja auch hier ein #ifdef benutzen, so daß Windows-Benutzer mitgetch()
spielen können, während Linux-Benutzer weiterhin mit Eingabe + Enter spielen.
Und ich weiß nicht, ob es nötig ist, immer wieder den gesamten Bildschirm zu löschen und neuzuzeichnen. Geh doch einfach an die Position der Spielfigur, übermale sie mit einem Leerzeichen und zeichne sie dann an der neuen Position. Das gotoxy hab ich ja oben schon hingeschrieben. Für Linux geht es so:cout << "\033[" << y + 1 << ";" << x + 1 << "m";
(Bitte beachten: Mit den Windows-Funktionen ist die Position oben links (0,0), während sie bei der Linuxfunktion (1,1) ist. Deshalb das x + 1 und das y + 1, damit Du mit denselben Positionsangaben beide Varianten benutzen kannst.)
-
NES-Spieler schrieb:
Ihr immer mit Eurem scheiß
system("cls")
.daran ist nix scheiße und für so ein spiel durchaus angemesen
-
Wow, was für eine geniale Begründung! Ja, damit hast Du mich jetzt echt überzeugt.
-
deine einsicht freut mich, so brauche ich wenigstens keine überflüssigen erklärungen für so etwas offensichtliches abzugeben.
-
Vielleicht solltest Du es doch erklären, damit ich auch ganz sicher gehen kann, daß ich es wirklich verstanden habe: Warum ist es nicht scheiße, den Befehl, der eigentlich dazu gedacht ist, explizit externe Programme bzw. Kommandozeilenbefehle aufzurufen, zweckzuentfremden, um ein Verhalten zu simulieren, das eigentlich zum eigenen Programm gehört und gar nichts mit dem bewußten Aufrufen externer Kommandos zu tun hat?
-
NES-Spieler schrieb:
Warum ist es nicht scheiße, den Befehl, der eigentlich dazu gedacht ist, explizit externe Programme bzw. Kommandozeilenbefehle aufzurufen, zweckzuentfremden, um ein Verhalten zu simulieren, das eigentlich zum eigenen Programm gehört und gar nichts mit dem bewußten Aufrufen externer Kommandos zu tun hat?
Also geht es dir nur ums Prinzip? Oder gibt es auch ein echtes Problem?
Wobei, es bringt einem Anfänger sicher gewaltig viel mehr, wenn er statt
system("cls")
20 Zeilen WinAPI-Code aus einem Internetforum kopiert, ohne eine einzige davon zu verstehen.
-
Stimmt. Soll er sich lieber schlechten Stil angewöhnen und lernen, daß es besser ist, mal schnell irgendwas hinzuhacken, statt zu gucken, ob es irgendwo Funktionen gibt, die genau dafür gedacht sind. Wieso sollte man sich auch mit WinAPI-Funktionen auseinandersetzen, wenn man einfach
system("cls")
schreiben kann? Ist zwar ein Systemaufruf, der normalerweise nur dazu gedacht ist, externe Anwendungen zu starten, aber er erfüllt doch seinen Zweck, nicht wahr? Und wenn man die Konsole offen lassen will, bis der Benutzer Enter bzw. eine Taste drückt, nimmt mansystem("pause")
stattcin.get()
bzw.fgets
oder was es da in C auch immer gibt, stimmt's? Immerhin muß man sich bei solchen Funktionen um das mögliche Leeren des Puffers kümmern, falls da noch irgendeine Eingabe drin hängt, und das würde den Anfänger ja vollkommen überfordern. Und wenn er das Labyrinth in blau mit weißem Hintergrund darstellen will, dann empfehlen wir ihmsystem("color f9")
statt ihn darauf hinzuweisen, daß es auch dafür richtige Funktionen gibt. Immerhin ist er ja ein Anfänger, also sollte man ihm keinen Code zeigen, durch den er sich erstmal durchfuchsen müßte, um ihn zu verstehen. Könnte ja sein, daß er dadurch noch was lernt oder vielleicht sogar angeregt wird, selbst in die Richtung nachzforschen, falls ihm in den Sinn kommt, daß er dieclrscr
-Funktion so umschreiben will, daß man angeben kann, von wo bis wo der Bildschirm gelöscht werden soll. Viel besser sind da billige Hacks, die allgemeine Shellbefehle einfach im lokalen Programm aufrufen. Wieso benutzen wir eigentlich nochcout
undprintf
? Nehmen wir doch gleichsystem("echo ...")
. Und wenn wir mal rausfinden wollen, was es so für Ordner und Dateien im aktuellen Pfad gibt, dann machen wirsystem("dir /b > Dateien.txt")
, lesen dann die Datei aus und löschen sie dann wieder mitsystem("del Dateien.txt")
.
-
NES-Spieler schrieb:
Wieso sollte man sich auch mit WinAPI-Funktionen auseinandersetzen, wenn man einfach
system("cls")
schreiben kann?Genau das frage ich mich auch.
statt ihn darauf hinzuweisen, daß es auch dafür richtige Funktionen gibt.
Es gibt aber keine "richtigen" Funktionen dafür. Nicht, wenn man plattformunabhängiges C programmiert. Man muss Win-API benutzen, und überaus schöner Code ist das auch nicht.
Leider sagst du nach wie vor nicht, was wirklich das Problem ist. "Hack", "schnelle Shellbefehle", "schlechter Stil"... Werd lieber mal konkret. Einen Anfänger kümmern deine momentanen Argumente nämlich kein bisschen, solange er mit einer Zeile dasselbe erreicht wie du mit 20.
Wieso benutzen wir eigentlich noch
cout
undprintf
?Schlechter Vergleich. Die beiden sind einfach zu benutzen, portabel und erfordern kein wochenlanges Einstudieren in ein Framework.
-
Systemanalytiker schrieb:
Nicht, wenn man plattformunabhängiges C programmiert.
system("cls");
ist auch nicht gerade plattformunabhängig. funktioniert lediglich für ein paar plattformen mehr als nur eine.letztlich läuft die ganze diskussion doch nur darauf hinaus, dass beide seiten recht haben. ja, das ist nicht sonderlich doller stil (erst recht, wenn man das als allgemeingültigen prototyp für situationen ansieht, in denen man anders nicht spontan weiter weiß), aber nein, das ist noch lange kein grund, als anfänger darauf unbedingt zu verzichten.
ru,
cirion
-
Und wenn ihr schon mal dabei seid... Warum nicht gleich SDL verwenden?
-
Systemanalytiker schrieb:
Leider sagst du nach wie vor nicht, was wirklich das Problem ist. "Hack", "schnelle Shellbefehle", "schlechter Stil"... Werd lieber mal konkret. Einen Anfänger kümmern deine momentanen Argumente nämlich kein bisschen, solange er mit einer Zeile dasselbe erreicht wie du mit 20.
Bitteschön: www.c-plusplus.net/forum/viewtopic-var-t-is-39453.html. Sogar ein FAQ-Eintrag, was zumindest zeigt, daß ich mit meiner Abneigung nicht allein dastehe.
dasdasa schrieb:
Und wenn ihr schon mal dabei seid... Warum nicht gleich SDL verwenden?
Weil die Frage nach SDL nicht nur eine codetechnische ist, sondern eine, die auch das Aussehen des Programms komplett ändern würde.
cirion schrieb:
aber nein, das ist noch lange kein grund, als anfänger darauf unbedingt zu verzichten.
Außer natürlich, wenn man die richtige Variante bereits fertig vorgelegt bekommen hat. Und da ich mir vorstellen kann, daß als nächstes die Frage kommt, wie man das Spiel auch farbig gestaltet, wäre in dem Fall die WinAPI sowieso unausweichlich, denn dann hat's sich mit den Systembefehlen geschissen, wenn man nicht nur eine Farbe für alles haben will.
-
NES-Spieler schrieb:
Bitteschön: www.c-plusplus.net/forum/viewtopic-var-t-is-39453.html. Sogar ein FAQ-Eintrag, was zumindest zeigt, daß ich mit meiner Abneigung nicht allein dastehe.
Keines der Argumente greift hier.
Plattformabhängigkeit? Recht egal, die angestrebte Alternative wäre WinAPI, wenn ich mich recht erinnere.
Geschwindigkeit? Für eine Wartefunktion.
Hänger bei Fehlern? Naja, da schreibt man pause halt mal richtig.
Sicherheit? Soll ich meinen Rechner knacken?