Suche Hilfe bei dem Spiel Hangman in C++

OP #7781822
Lesenswert?

Hallo,

if (user != troll) {

ich versuche mein erstes Spiel in C++ zu programmieren - Hangman. Hier der Link für Nicht-Kenner: https://en.wikipedia.org/wiki/Hangman_(game)

Im Groben ist mein Spiel spielbar... Natürlich ist es noch nicht alles, nach meinen Wünschen entsprechend umgesetzt, aber das werde ich noch peu à peu integrieren, soweit es meine Fähigkeiten zulassen.

Nun zu meinem Problem, wobei ich nicht weiterkomme:

Beim Spiel Hangman wird ein Buchstabe in einem Wort gesucht und wenn es was findet, in irgend einer Form dargestellt, dass man weiß auf welcher Position es ist, wie bei Glücksrad (für die ältere Generation unter euch).

Mein Wunsch wäre z.B. so: Eingabe "e" -> e_e_ (lol die Formatierung spielt nicht mit)

Da ich mir nicht anders zu helfen wusste, habe ich das sehr rudimentär umgesetzt, da ich nicht weiß, wie ich den Wert von string.find so ausgeben kann, dass die Buchstaben so dargestellt werden und beim nächsten Erraten noch die neuen Buchstaben hinzugefügt werden.

Hat jemand für mich ein Tip oder ein Beispiel, das mir das aufschlüsseln kann?

Wäre sehr dankbar, Ihr würdet mir viele schlaflose Nächte ersparen... :D

1
/*
2
 * Hangman - The Game
3
 */ 
4

5

6
#include <iostream>
7
#include <string>
8

9

10
bool loop        = true;
11
int attempt        = 5;
12
std::string secretWord  = "concealed";
13
std::string guess;
14

15

16
// Won game
17
int won () {
18
  if (secretWord == guess) {
19
    loop = false;
20
    std::cout << "\nCongratulations, you have won!\n";
21
  }
22
  return 0;
23
}
24

25

26
// Lost Game
27
int lost () {
28
  if (attempt == 0) {
29
    loop = false;
30
    std::cout << "\nGame over!\n";
31
  }
32
  return 0;
33
}
34

35

36
// Exit Game
37
int exit () {
38
  if (guess == "exit") {
39
    loop = false;
40
    std::cout << "\nByebye!\n";
41
  }
42
  return 0;
43
}
44

45

46
// Notification
47
int notification () {
48
  std::cout << "Note your result on a paper!\n\n";
49
  return 0;
50
}
51

52

53
int main () {
54

55
  // Welcome Screen
56
  std::cout << "Hangman - The Game\n\n";
57

58
  while (loop) {
59

60
    // Input guess
61
    std::cout << "Attempt: " << attempt << "\n";
62
    std::cout << "Hint   : Secret\n";
63
    std::cout << "Rules  : Only write lower case letters or the secret word.\n";
64
    std::cout << "Guess  : ";
65
    std::cin >> guess;
66

67
    size_t found = secretWord.find (guess);
68
    if (found != std::string::npos) {
69
      // Do stuff if guess is valid
70
      if (guess == "c") {
71
        std::cout << "\nc**c*****\n";
72
        notification();
73
      }
74
      if (guess == "o") {
75
        std::cout << "\n*o*******\n";
76
        notification();
77
      }
78
      if (guess == "n") {
79
        std::cout << "\n**n******\n";
80
        notification();
81
      }
82
      if (guess == "e") {
83
        std::cout << "\n****e**e*\n";
84
        notification();
85
      }
86
      if (guess == "a") {
87
        std::cout << "\n*****a***\n";
88
        notification();
89
      }
90
      if (guess == "l") {
91
        std::cout << "\n******l**\n";
92
        notification();
93
      }
94
      if (guess == "d") {
95
        std::cout << "\n********d\n";
96
        notification();
97
      }
98
    }
99
    else {
100
      // Do stuff when guess is invalid
101
      std::cout << "\n";
102
      attempt--;
103
    }
104

105
    won();
106
    lost ();
107
    exit ();
108
    }
109
}

}

else { exit () }

#7781830
Lesenswert?

Hi,

zuerst mal was anderes. Wenn du aus einer Funktion nichts zurückgeben willst, dann mach statt dem in ein void als Rückgabetyp. Alles andere ist verwirrend.

Code mag ich gar nicht liefern, du willst ja lernen.

du könntest einen weiteren String anlegen, der so viele '*' enthält, wie dein Suchwort.

string::find liefert dir die position des gesuchten chars zurück. Du kannst dann also hergehen und an der Position in deinem zusätzlichen String das '*' durch den passenden Buchstaben ersetzten.

Danach gibts du einfach immer nur deinen zweiten String aus. Der enthält dann automatisch mehr und mehr Buchstaben des Lösungswortes.

Grüße

OP #7782053
Lesenswert?

Hallo,

und danke für die zwei unterschiedlichen Ansätze an Antworten. Den Code habe ich mal überflogen, aber ohne Erklärung.... Mein Programm wurde auch geändert... was ich so eigentlich erstmal nicht wollte.

Deswegen tendiere ich zu ersterem...

Micha schrieb:

Hi,

zuerst mal was anderes. Wenn du aus einer Funktion nichts zurückgeben willst, dann mach statt dem in ein void als Rückgabetyp. Alles andere ist verwirrend.

Dadurch, dass ich etwas ändern musste, habe ich die Funktionen einfach rausgenommen, somit sollten die Verwirrungen entworren sein, hoffentlich.

Micha schrieb:

du könntest einen weiteren String anlegen, der so viele '*' enthält, wie dein Suchwort.

string::find liefert dir die position des gesuchten chars zurück. Du kannst dann also hergehen und an der Position in deinem zusätzlichen String das '*' durch den passenden Buchstaben ersetzten.

Danach gibts du einfach immer nur deinen zweiten String aus. Der enthält dann automatisch mehr und mehr Buchstaben des Lösungswortes.

Ich habe den String hiddenWord angelegt und musste dann erstmal recherchieren wie der Befehl aussehen muss. Hab dann gemerkt, dass ich nur mit einem Char arbeiten konnte und musste somit meinen "Exit" rausschmeißen und hier und da etwas anpassen. Nach einem kurzen Test bin ich auch zufrieden, aber jetzt habe ich das Problem, dass z.B. zwei gleiche Werte nicht erkannt werden, sondern nur der erste. Wie kann ich den ganzen String Buchstabe für Buchstabe überprüfen?

1
/*
2
 * Hangman - The Game
3
 */ 
4

5

6
#include <iostream>
7
#include <string>
8

9

10
char guess;
11
bool loop        = true;
12
int attempt        = 5;
13
std::string secretWord  = "concealed";
14
std::string hiddenWord  = "*********";
15

16

17
int main () {
18

19
  // Welcome Screen
20
  std::cout << "Hangman - The Game\n\n";
21

22
  while (loop) {
23

24
    // Input guess
25
    std::cout << "Attempts: " << attempt << "\n";
26
    std::cout << "Hint    : Secret\n";
27
    std::cout << "Rules   : Only write lower case letters.\n";
28
    std::cout << "Guess   : ";
29
    std::cin >> guess;
30

31
    size_t found = secretWord.find (guess);
32
    if (found != std::string::npos) {
33
      //Do stuff if guess is valid
34
      hiddenWord[found] = guess;
35
      std::cout << "\n" << hiddenWord << "\n\n";
36
    }
37
    else {
38
      //Do stuff when guess is invalid
39
      std::cout << "\n";
40
      attempt--;
41
    }
42

43
    if (secretWord == hiddenWord) {
44
      std::cout << "\nCongratulations, you have won!\n";
45

46
    }
47

48
    if (attempt == 0) {
49
      loop = false;
50
      std::cout << "\nGame over!\n";
51
    }
52
    }
53
}
#7782071
Lesenswert?

Mirko schrieb:

Nach einem kurzen Test bin ich auch zufrieden, aber jetzt habe ich das Problem, dass z.B. zwei gleiche Werte nicht erkannt werden, sondern nur der erste.

Das ist ja auch nicht verwunderlich. Dein Aufruf von std::string:::find() gibt dir das erste Vorkommen des gesuchten Buchstaben. Die Funktion weiß ja nicht, dass der schon mal gefunden wurde und du diesmal das zweite Vorkommen suchst.

Wie kann ich den ganzen String Buchstabe für Buchstabe überprüfen?

Eine Möglichkeit wäre, mit dem secretWord das umgekehrte zu machen wie mit dem hiddenWord, also alle gefundenen Buchstaben durch Sternchen ersetzen. Besteht das hiddenWord nur noch aus Sternchen, hat man gewonnen.

#7782190
Lesenswert?

Mirko schrieb:

Nach einem kurzen Test bin ich auch zufrieden, aber jetzt habe ich das Problem, dass z.B. zwei gleiche Werte nicht erkannt werden, sondern nur der erste. Wie kann ich den ganzen String Buchstabe für Buchstabe überprüfen?

Mit einem simplen for-loop anstatt dem std::string::find()

1
for (size_t i = 0; i < secretWord.size(); i++) {
2
  if (secretWord[i] == guess) {
3
    // your sophisticated handling goes here (instead of printing)
4
    std::cout << "found at position: " << i << "\n";
5
  }
6
}
OP #7782231
Lesenswert?

Roger S. schrieb:

Mirko schrieb:

Nach einem kurzen Test bin ich auch zufrieden, aber jetzt habe ich das Problem, dass z.B. zwei gleiche Werte nicht erkannt werden, sondern nur der erste. Wie kann ich den ganzen String Buchstabe für Buchstabe überprüfen?

Mit einem simplen for-loop anstatt dem std::string::find()

Ha, genau das hab ich gesucht! Ich hab schon mit einer for Schleife experimentiert, aber es hat nicht so geklappt. Jetzt muss ich nur noch das Konstrukt darum ändern, aber ich denke das bekomme ich schon hin. Danke vielmals.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren