I'm still really new to the C language and I'm trying to make a hangman game but I keep failing to end the game when I win.
Here is the code:
const int true = 1;
const int false = 0;
char words[][20] = {
"hangman",
"computer",
"programming",
"microsoft",
"visual",
"studio",
"express",
"learning"
};
int isletterinword(char word[], char letter)
{
int i;
for (i = 0; i < strlen(word); i++) {
if (word[i] == letter) {
return true;
}
}
return false;
}
int iswordcomplete(char secretword[], char rights[])
{
int i;
for (i = 0; i < strlen(secretword); i++) {
if (rights[i] == secretword[i] ) {
return true;
}
}
return false;
}
void printhangman(int numofwrongs)
{
// Line 1
printf("\t ______\n");
// Line 2
printf("\t | |\n");
// Line 3
printf("\t | +\n");
// Line 4 - left arm, head and right arm
printf("\t |");
if (numofwrongs > 0) printf(" \\");
if (numofwrongs > 1) printf("O");
if (numofwrongs > 2) printf("/");
printf("\n");
// Line 5 - body
printf("\t |");
if (numofwrongs > 3) printf(" |");
printf("\n");
// Line 6 - left leg and right leg
printf("\t |");
if (numofwrongs > 4) printf(" /");
if (numofwrongs > 5) printf(" \\");
printf("\n");
// Line 7
printf("\t |\n");
// Line 8
printf("\t__|__\n");
}
void printletters(char letters[])
{
int i;
for (i = 0; i < strlen(letters); i++) {
printf("%c ", letters[i]);
}
}
void printscreen(char rights[], char wrongs[], char secretword[])
{
int i;
for (i = 0; i < 25; i++)
printf("\n");
printhangman(strlen(wrongs));
printf("\n");
printf("Correct guesses: ");
printletters(rights);
printf("\n");
printf("Wrong guesses: ");
printletters(wrongs);
printf("\n\n\n");
printf("\t");
for (i = 0; i < strlen(secretword); i++) {
if (isletterinword(rights, secretword[i])) {
printf("%c ", secretword[i]);
}
else {
printf("_ ");
}
}
printf("\n\n");
}
int main()
{
int i;
int secretwordindex;
char rights[20];
char wrongs[7];
char guess;
secretwordindex = 0;
srand(time(0));
secretwordindex = rand() % 8;
for (i = 0; i < 20; i++) {
rights[i] = '\0';
}
for (i = 0; i < 6; i++) {
wrongs[i] = '\0';
}
while (strlen(wrongs) < 6) {
printscreen(rights, wrongs, words[secretwordindex]);
printf("\nPlease enter your guess: ");
scanf(" %c", &guess);
if (isletterinword(words[secretwordindex],guess)) {
rights[strlen(rights)] = guess;
}
else {
wrongs[strlen(wrongs)] = guess;
}
}
printscreen(rights, wrongs, words[secretwordindex]);
if ( iswordcomplete(words[secretwordindex],rights[20])==true && strlen(wrongs) <= 6 ) { // The if condition here might be problematic.
printf("You have won!\n");
}
else {
printf("You have lost!\n");
}
}
Here is the error message:
main.c:197:48: warning: passing argument 2 of ‘iswordcomplete’ makes pointer from integer without a cast [-Wint-conver sion]
main.c:55:5: note: expected ‘char *’ but argument is of type ‘char’
First things first: The compiler error is caused by the fact that you are passing a single character to your call to iswordcomplete()
, rather than an array of characters. So, in the check near the end of your main
function, you need to pass rights
(unadorned) as the argument, in place of rights[20]
(which, incidentally, is an out-of-bounds element of the array). Also, you don't – at that stage – need the second check (counting the number of wrongs – see later). Here's the fix for that part of the code:
// if (iswordcomplete(words[secretwordindex], rights[20]) == true && strlen(wrongs) <= 6) { // The if condition here might be problematic.
if (iswordcomplete(words[secretwordindex], rights)){// && strlen(wrongs) <= 6) { // Needs the whole string as an argument
printf("You have won!\n");
}
Now to address a couple of other issues that will stop your code from working properly ...
(1) Your main while
loop won't stop running until you have entered 6 'wrong' letters – even if you do guess the word correctly. So, you need to add an iswordcomplete()
check to the while
condition (negating it with the !
operator†), to keep running the loop only if the word isn't complete. Like this:
while (strlen(wrongs) < 6 && !iswordcomplete(words[secretwordindex], rights)) { // Need to break loop if we win!!
printscreen(rights, wrongs, words[secretwordindex]);
//...
(2) The logic of your iswordcomplete
function is flawed, as it will return "true" as soon as it finds any match. Instead, you need two loops, returning false if any of the word's letters is not found in the list of 'rights'. Here's one possible version:
int iswordcomplete(char secretword[], char rights[])
{
int i, j;
for (i = 0; i < strlen(secretword); i++) {
for (j = 0; j < strlen(rights); j++) {
if (secretword[i] == rights[j]) break;
}
if (j >= strlen(rights)) return false; // Didn't find this letter
}
return true;
}
Please feel free for any further clarification and/or explanation.
† If you're not (yet) familiar with this use of the !
operator, then you can explicitly compare the function's return value to the false
constant, if you are more comfortable with that, like so:
while (strlen(wrongs) < 6 && iswordcomplete(words[secretwordindex], rights) == false) { // Break loop if we win!