Schere, Stein, Papier



  • Hallo liebe Leute,
    ich habe heute probier, das bekannte Schere, Stein, Papier in der Konsole umzusetzen. Das sollte als Übung für das Programmieren dienen.

    Nun habe ich den Quellcode fertig und der Compiler meldet: "[Warning] assignment makes integer from pointer without a cast" und "invalid lvalue in assignment". Hier nun der Code. Ich würde mich freuen, wenn mir jemand helfen könnte, das Prolem zu beseitigen...

    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
    #include <time.h>
    #include <string.h>
    
    #define AE (unsigned char)142
    #define ae (unsigned char)132
    #define OE (unsigned char)153
    #define oe (unsigned char)148
    #define UE (unsigned char)154
    #define ue (unsigned char)129
    #define ss (unsigned char)225 
    
    int main()
    {
      SetConsoleTitle("Schere, Stein, Papier!");
      system("color 0A");
    
      int wahl1, wahl2, wahl_zufall, punkte_pc=0, punkte_spieler=0;
      char wahl_pc, wahl_spieler, gewinner, ende;
    
      printf("Willkommen zu Schere, Stein, Papier!\n");
      printf("\n");
      printf("     1. Neues Spiel starten!\n");
      printf("     2. Das Programm beenden\n");
      printf("Was wollen Sie tun: ");
      scanf("%i", &wahl1); 
    
      if(wahl1==1) {
                   do {
                   system("cls");
                   printf("Sie haben nun 3 Möglichkeiten: ");
                   printf("    1. Schere\n");
                   printf("    2. Stein\n");
                   printf("    3. Papier\n");
                   printf("Was wollen Sie tun?: ");
                   scanf("%i\n", &wahl2);
    
                   switch(wahl2) {
                                  case 1: wahl_spieler="Schere"; break;
                                  case 2: wahl_spieler="Stein"; break;
                                  case 3: wahl_spieler="Papier"; break;
                                  }
    
                  srand(time(0));
                  wahl_zufall = 1+(rand() % (4-1));
    
                  switch(wahl_zufall) {
                                       case 1: wahl_pc="Schere"; break;
                                       case 2: wahl_pc="Stein"; break;
                                       case 3: wahl_pc="Papier"; break;
                                       }
    
                  printf("Sie haben %s ausgew%chlt!\n", wahl_spieler, ae);
                  printf("Der PC hat %s ausgew%chlt!\n", wahl_pc, ae);
    
                  //Eigentliches Vergleichen der Wahl - Schere
                  if(wahl_spieler="Schere" && wahl_pc="Schere") {
                                                                 printf("Unentschieden...Niemand bekommt einen Punkt!");
                                                                 }
                  if(wahl_spieler="Schere" && wahl_pc="Stein") {
                                                               printf("Der Computer gewinnt...er bekommt einen Punkt!");
                                                               gewinner="PC";
                                                               }
                  if(wahl_spieler="Schere" && wahl_pc="Papier") {
                                                                 printf("Sie gewinnen...Sie bekommen einen Punkt!");
                                                                 gewinner="Spieler";
                                                                 }
    
                  //Eigentliches Vergleichen der Wahl - Stein
                  if(wahl_spieler="Stein" && wahl_pc="Stein") {
                                                               printf("Unentschieden...Niemand bekommt einen Punkt!");
                                                               }
                  if(wahl_spieler="Stein" && wahl_pc="Schere") {
                                                                printf("Sie gewinnen...Sie bekommen einen Punkt!");
                                                                gewinner="Spieler";
                                                                }
                  if(wahl_spieler="Stein" && wahl_pc="Papier") {
                                                                printf("Der Computer gewinnt...er bekommt einen Punkt!");
                                                                gewinner="PC";
                                                                }
    
                  //Eigentliches Vergleichen der Wahl - Papier
                  if(wahl_spieler="Papier" && wahl_pc="Papier") {
                                                                 printf("Unentschieden...Niemand bekommt einen Punkt!");
                                                                 }
                  if(wahl_spieler="Papier" && wahl_pc="Schere") {
                                                                 printf("Der Computer gewinnt...er bekommt einen Punkt!");
                                                                 gewinner="PC";
                                                                 }
                  if(wahl_spieler="Papier" && wahl_pc="Stein") {
                                                                printf("Sie gewinnen...Sie bekommen einen Punkt!");
                                                                gewinner="Spieler";
                                                                }
    
                  //Wer ist der Gewinner?
                  if(gewinner="PC") {punkte_pc++;}
                  if(gewinner="Spieler") {punkte_spieler++;}
    
                  printf("               Spieler       PC\n");
                  printf("                 %i          %i\n", punkte_spieler, punkte_pc);
                  printf("M%cchten Sie eine neue Runde starten? (ja/nein)? ", oe);
                  scanf("%s", &ende);
                  } while(ende!="ja");
                    return 0;
                  }
    
      if(wahl1==2) {return 0;}
    
      system("PAUSE");	
      return 0;
    }
    


  • Du hast in den ganzen if()-Anweisungen die Zuweisung (=) anstelle des Vergleichs (==) verwendet. Außerdem ist der Typ char zu klein für längere Zeichenketten - dafür benötigst du Zeichen-Arrays (und strcmp() für die Vergleiche) oder std::string (wenn du C++ verwenden darfst).

    PS: Und im Zweifelsfall würde ich lieber direkt mit den int-Werten wahl2 bzw. wahl_zufall arbeiten.

    PPS: Über die Programmstruktur sage ich jetzt nichts.



  • Danke schonmal. Ich habe jetzt alle nötigen = in == "verwandelt" und das Programm läuft auch. Nur das ich bei der Auswahl Schere, Stein, Papier hängenbleibe. Ich kann die 1 eingeben und auch mit Enter bestätigen aber es passiert nichts. Wenn ich die 2 eingebe kommen kurz ein paar weitere grüne Zeichen(sieht ein bisschen aus wie das weitere Programm) und die verschwinden aber gleich wieder. Kannst du die bitte die Mühe machen, den Fehler zu finden und doch etwas zur(ich nehme an schrecklichen) Prgrammstruktur sagen. Man bedenke das ich erst ein Anfänger bin.

    Danke im Vorraus!



  • Hast du denn auch den Rest des Beitrags beachtet (besonders im Bezug auf die Zeichenketten-Verarbeitung)?

    Ansonsten: Die Struktur des Programms ist so unübersichtlich, daß vermutlich jeder Außenstehende den Überblick verliert. Darum bin ich mir nicht so sicher, wo der Fehler liegen könnte. Auf Anhieb fallen mir nur einige Details auf:
    * srand() benötigst du nur einmal bei Programmstart
    * den Umgang mit Zeichenketten habe ich schon erwähnt (char hat nur Platz für ein einzelnes Zeichen
    * die ganzen Abfragen zum Vergleich sind (abgesehen von den Werten) auch identisch - das lässt sich mit etwas Übung in kürzere Formeln zusammenfassen
    * system() ist hier auch nicht besoners beliebt
    * deine Einrückungen sind auch nicht gerade förderlich für die Übersicht

    PS: voraus schreibt man übrigens mit einem r 😃



  • Also. Hier die überarbeitete Variante. Ich hoffe jetzt wirst du schlau draus 😉

    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
    #include <time.h>
    #include <string.h>
    
    #define AE (unsigned char)142
    #define ae (unsigned char)132
    #define OE (unsigned char)153
    #define oe (unsigned char)148
    #define UE (unsigned char)154
    #define ue (unsigned char)129
    #define ss (unsigned char)225 
    
    int main()
    {
      SetConsoleTitle("Schere, Stein, Papier!");
      srand(time(0));
    
      int wahl1;                      //VAR für "Neues Spiel" oder "Programm beenden"
      int punkte_pc=0;                //Punkte des Computers
      int punkte_spieler=0;           //Punkte des Spielers
      int wahl_spieler;               //Wahl des Spielers
      int wahl_pc;                    //Wahl des PCs
      int neue_runde;                 //"Neue Runde"...1 oder 2
      char gewinner[80];              //"Spieler" oder "PC"
    
      printf("Willkommen zu Schere, Stein, Papier!\n\n");
      printf("1. Neues Spiel starten!\n");
      printf("2. Das Programm beenden\n");
      printf("Was wollen Sie tun: ");
      scanf("%i", &wahl1); 
    
      if(wahl1==1) {
                   do {
                   system("cls"); //Ich finde keine bessere Möglichkeit
                   printf("Sie haben nun 3 Moglichkeiten: \n", oe);
                   printf("    1. Schere\n");
                   printf("    2. Stein\n");
                   printf("    3. Papier\n");
                   printf("Was wollen Sie tun?: ");
                   scanf("%i\n", &wahl_spieler);   //Wahl des Spielers wird zugewiesen
                                                   //ACHTUNG! Hier bekomme ich das beschriebene Problem:
                                                   //Ich kann zwar eine Zahl eingeben, aber das hat 
                                                   //keinerlei Auswirkungen. Das Programm zeigt wieder
                                                   //genau den selben Bildschirm! HILFE!!!
    
                  wahl_pc=1+(rand()%(4-1));        //Wahl des PCs wird generiert
    
                  printf("Sie haben %i ausgew%chlt!\n", wahl_spieler, ae);
                  printf("Der PC hat %i ausgew%chlt!\n", wahl_pc, ae);
    
                  //Eigentliches Vergleichen der Wahl - Schere
                  if(wahl_spieler==1 && wahl_pc==1) {
                                                    printf("Unentschieden...Niemand bekommt einen Punkt!");
                                                    }
                  if(wahl_spieler==1 && wahl_pc==2) {
                                                    printf("Der Computer gewinnt...er bekommt einen Punkt!");
    												punkte_pc++;
                                                    }
                  if(wahl_spieler==1 && wahl_pc==3) {
                                                    printf("Sie gewinnen...Sie bekommen einen Punkt!");
    												punkte_spieler++;
                                                    }
    
                  //Eigentliches Vergleichen der Wahl - Stein
                  if(wahl_spieler==2 && wahl_pc==2) {
                                                    printf("Unentschieden...Niemand bekommt einen Punkt!");
                                                    }
                  if(wahl_spieler==2 && wahl_pc==1) {
                                                    printf("Sie gewinnen...Sie bekommen einen Punkt!");
    												punkte_spieler++;
                                                    }
                  if(wahl_spieler==2 && wahl_pc==3) {
                                                    printf("Der Computer gewinnt...er bekommt einen Punkt!");
    												punkte_pc++;
                                                    }
    
                  //Eigentliches Vergleichen der Wahl - Papier
                  if(wahl_spieler==3 && wahl_pc==3) {
                                                    printf("Unentschieden...Niemand bekommt einen Punkt!");
                                                    }
                  if(wahl_spieler==3 && wahl_pc==1) {
                                                    printf("Der Computer gewinnt...er bekommt einen Punkt!");
    												punkte_pc++;
                                                    }
                  if(wahl_spieler==3 && wahl_pc==2) {
                                                    printf("Sie gewinnen...Sie bekommen einen Punkt!");
    												punkte_spieler++;
                                                    }
    
                  printf("Spieler: %i\n", punkte_spieler);
                  printf("PC:      %i\n", punkte_pc);                
                  printf("M%cchten Sie eine neue Runde starten? (1: ja/2: nein)? ", oe);
                  scanf("%i", &neue_runde);
                  } while(neue_runde=1);
                    return 0;
                  }
    
      if(wahl1==2) {
                   return 0;
                   }
    
      system("PAUSE");	
      return 0;
    }
    

    Schonmal DANKE im Voraus 😉



  • HA! Ich habe es geschafft! ICch konnte den Bildschirmaufnehmen!

    http://img4.fotos-hochladen.net/uploads/scheresteinpapx7isthgz6.png

    das kommt bei mir!



  • 3P!CF41L schrieb:

    Ich hoffe jetzt wirst du schlau draus

    Jein.

    Was geht denn jetzt nicht?

    PS. Die Schließende Klammer kommt unter das erste Zeichen der öffneden Zeile.
    Und man rückt i.A 2 - 8 Zeichen ein.
    Man findet sehr Schlecht die } vom if(wahl1==1) und die vom do erkennt man nur am while

    if(wahl_spieler==1 && wahl_pc==1) {
                    printf("Unentschieden...Niemand bekommt einen Punkt!");
                  }
    

    Geht auch als

    if (wahl_spieler == wahl_pc) {
                    printf("Unentschieden...Niemand bekommt einen Punkt!");
                  }
    

    Und so hast du schon mal drei Fälle auf einmal abgearbeitet.



  • Ich sehe noch eine fehlerhafte Zuweisung in Zeile 96, Ideone beschwert sich darüber, daß die Rückgabe von scanf() nicht ausgewertet wird und "cls" nicht bekannt ist, aber technisch fällt mir nichts auf.

    Obwohl, wenn ich genauer hinschaue: Die Eingabe wird vermutlich verarbeitet, allerdings schägt dein Aufruf sstem("cls"); danach sofort zu und löscht alle weiteren Ausgaben aus der Schleife.



  • CStoll du bist ein Held! Da hätte ich echt auch selbst drauf kommen können. Das Programm löscht am Anfang der Schleife alles, und dadurch ist nichts zu sehen.
    Das Programm läuft jetzt bis auf eine Sache: Die Abfrage am Ende:

    printf("M%cchten Sie eine neue Runde starten? (1: ja/2: nein)? ", oe);
    scanf("%i", &neue_runde);
    sleep(5000); //Das Sleep ist nur eingebaut um wenigstens zu sehen wer gewonnen hat
    system("cls");
    } while(neue_runde=1);
    

    Wenn das noch klappen würde wäre das Programm ja beinahe perfekt für meine Verhältnisse. Ein bisschen Struktur ist auch reingekommen.

    Danke an euch alle 🙂



  • Da ist noch ein '\n' (die Enter-Taste) im Tastatur-Puffer.

    Versuch mal

    scanf(" %i", &neue_runde);
    

    Da ist ein Leerzeichen vor dem %.



  • Vielen Dank an alle, die beim fehlerbeheben geholfen haben. Das Programm läuft jetzt so, wie ich mir das vorgestellt hatte!

    Ich wäre dankbar, wenn ihr noch strukturelle Besserungsvorschläge hättet.
    nochmal der aktuelle, fertige Code:

    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
    #include <time.h>
    #include <string.h>
    
    #define AE (unsigned char)142
    #define ae (unsigned char)132
    #define OE (unsigned char)153
    #define oe (unsigned char)148
    #define UE (unsigned char)154
    #define ue (unsigned char)129
    #define ss (unsigned char)225 
    
    int main()
    {
      SetConsoleTitle("Schere, Stein, Papier!");
      srand(time(0));
    
      int wahl1;                      //VAR für "Neues Spiel" oder "Programm beenden"
      int punkte_pc=0;                //Punkte des Computers
      int punkte_spieler=0;           //Punkte des Spielers
      int wahl_spieler;               //Wahl des Spielers
      int wahl_pc;                    //Wahl des PCs
      int neue_runde=1;               //"Neue Runde"...1 oder 2
    
      printf("Willkommen zu Schere, Stein, Papier!\n");
      printf("1. Neues Spiel starten!\n");
      printf("2. Das Programm beenden\n");
      printf("Was wollen Sie tun: ");
      scanf("%i", &wahl1);
      system("cls"); 
    
      if(wahl1==1) {
                   do {
                   printf("Sie haben nun 3 Moglichkeiten: \n", oe);
                   printf("    1. Schere\n");
                   printf("    2. Stein\n");
                   printf("    3. Papier\n");
                   printf("Was wollen Sie tun?: ");
                   scanf("%i", &wahl_spieler); 
    
                  wahl_pc=1+(rand()%(4-1));        //Wahl des PCs wird generiert
    
                  printf("Sie haben %i ausgew%chlt!\n", wahl_spieler, ae);
                  printf("Der PC hat %i ausgew%chlt!\n", wahl_pc, ae);
    
                  //Eigentliches Vergleichen der Wahl - Schere
                  if(wahl_spieler==wahl_pc) {
                                            printf("Unentschieden...Niemand bekommt einen Punkt!\n");
                                            }
                  if(wahl_spieler==1 && wahl_pc==2) {
                                                    printf("Der Computer gewinnt...er bekommt einen Punkt!\n");
    												punkte_pc++;
                                                    }
                  if(wahl_spieler==1 && wahl_pc==3) {
                                                    printf("Sie gewinnen...Sie bekommen einen Punkt!\n");
    												punkte_spieler++;
                                                    }
    
                  //Eigentliches Vergleichen der Wahl - Stein
                  if(wahl_spieler==2 && wahl_pc==1) {
                                                    printf("Sie gewinnen...Sie bekommen einen Punkt!\n");
    												punkte_spieler++;
                                                    }
                  if(wahl_spieler==2 && wahl_pc==3) {
                                                    printf("Der Computer gewinnt...er bekommt einen Punkt!\n");
    												punkte_pc++;
                                                    }
    
                  //Eigentliches Vergleichen der Wahl - Papier
                  if(wahl_spieler==3 && wahl_pc==1) {
                                                    printf("Der Computer gewinnt...er bekommt einen Punkt!\n");
    												punkte_pc++;
                                                    }
                  if(wahl_spieler==3 && wahl_pc==2) {
                                                    printf("Sie gewinnen...Sie bekommen einen Punkt!\n");
    												punkte_spieler++;
                                                    }
    
                  printf("Spieler: %i\n", punkte_spieler);
                  printf("PC:      %i\n", punkte_pc); 
    
                  printf("M%cchten Sie eine neue Runde starten? (1=ja, 2=nein)", oe);
                  scanf("%i", &neue_runde);
                  system("cls");
                  } while(neue_runde==1);
                    return 0;
                  }
    
      if(wahl1==2) {
                   return 0;
                   }
    
      system("PAUSE");	
      return 0;
    }
    


  • Ich würde auf die Frage am Anfang verzichten.
    Gib den aktuellen Punktestand aus und lass dem User die Wahl 1, 2, 3 und 0 (für Programm verlassen).

    Das system() kann auch weg. Mach einfach ein paar Leerzeilen (3 reichen)
    Und wenn du Probleme mit Umlauten hast, dann nutze sie nicht.



  • Wenn du das Windowszeugs entfernst, funktioniert es sogar unter Unix:

    http://ideone.com/NNdzB



  • DirkB schrieb:

    Da ist noch ein '\n' (die Enter-Taste) im Tastatur-Puffer.

    Versuch mal

    scanf(" %i", &neue_runde);
    

    Da ist ein Leerzeichen vor dem %.

    Nein das bringt nichts. Whitespaces direkt vor Formatspezifizierern sind redundant.

    scanf("%i"
    

    ist äquivalent zu

    scanf(" %i"
    

    ist äquivalent zu

    scanf("  %i"
    

    ist äquivalent zu

    scanf("\n%i"
    

    ist äquivalent zu

    scanf("\t%i"
    

    ist äquivalent zu

    scanf("\n \t %i"
    

    ist äquivalent zu

    ...
    


  • Ersetz mal deine vielen if-abfragen durch sowas wie

    /* ----->8------->8------->8------->8------->8------ */
    
    /* +1: erste Dimension gewinnt */
    /* -1: erste Dimension verliert */
    /*  0: Unentschieden */
    
    int gewinn_matrix[][] = {
    /*	SCHERE, STEIN, PAPIER */
    	{0,     +1,     -1},      /* SCHERE */
    	{-1,     0,     +1},      /* STEIN */
    	{+1,    -1,      0}       /* PAPIER */
    }
    
    /* ----->8------->8------->8------->8------->8------ */
    
    switch (gewinn_matrix[wahl_spieler][wahl_pc]) {
    	case +1:
    		printf("du hast gewonnen\n");
    		break;
    	case -1:
    		printf("du hast verloren\n");
    		break;
    	default:
    		printf("unentschieden\n");
    }
    
    /* ----->8------->8------->8------->8------->8------ */
    

    Das macht deinen Code um einiges lesbarer.



  • mazal schrieb:

    Das macht deinen Code um einiges lesbarer.

    Das bezweifle ich.
    Aber symbolische Konstanten statt magic numbers wären nett.

    if(wahl_spieler==SCHERE && wahl_pc==STEIN) {
                                                    printf("Der Computer gewinnt...er bekommt einen Punkt!\n");
                                                    punkte_pc++;
                                                    }
    

    Das Folgende ist auch nicht gut zu lesen.

    int wergewinnt=(wahl_spieler+2-wahl_pc)%3;//0:Sie, 1:Computer, 2:Unentschieden
    


  • volkard schrieb:

    Das Folgende ist auch nicht gut zu lesen.

    int wergewinnt=(wahl_spieler+2-wahl_pc)%3;//0:Sie, 1:Computer, 2:Unentschieden
    

    Halte meine Variante zwar für verständlicher, aber was er wirklich machen sollte, ist irgendwie ausrechnen wer gewonnen hat und erst dann Ausgeben, damit, wenn er mal die Ausgabe ändert, dies nicht gleich an drei Stellen machen muss. Aber das brauch ich dir wohl nicht zu erklären 😉

    Im Übrigen mach ich das eigentlich gerne, wenn die "Daten" schon bekannt sind, die nicht zur Laufzeit auszurechnen, sondern hardzucoden.



  • mazal schrieb:

    aber was er wirklich machen sollte, ist irgendwie ausrechnen wer gewonnen hat und erst dann Ausgeben, damit, wenn er mal die Ausgabe ändert, dies nicht gleich an drei Stellen machen muss. Aber das brauch ich dir wohl nicht zu erklären 😉

    Trotzdem gut, daß Du es erwähnst.

    Deine Tabelle hat den Vorteil, daß man sie leicht für die richtigen Spielregeln http://www.youtube.com/watch?v=5cujdrWbc9k ausbauen kann.



  • mazal schrieb:

    Ersetz mal deine vielen if-abfragen durch sowas wie

    int gewinn_matrix[][] = {
    ...
    

    Ersetze den Code lieber nicht mit o.g., der Vorschlag ist nämlich falsch wegen fehlender 2. Dimensionsgröße.



  • ups, schon erledigt


Anmelden zum Antworten