if((!((phrase[i]>=65&& phrase[i]<=90)|| phrase[i]==32))||(phrase[i]==32&& phrase[i+1]==32)){//Check if character is not a letter or space, or if there are multiple spaces in a row
validPhrase =0;
}
}
if(validPhrase==0||strlen(phrase)==0|| phrase[0]==32|| phrase[strlen(phrase)-1]==32){//Check if input is invalid by validPhrase, empty, or starts/ends with a space
printf("Invalid/Empty input. Please enter a word/phrase with only letters and only 1 space between words.\n");
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <time.h>
struct Settings { // Struct for settings
int maxAttempts;
int Hint;
int attemptsLevel;
};
int mainMenu() { // Main menu function
int setting_num;
char option_confirmation;
Start: // Label for goto statement
printf("\e[1;1H\e[2J"); // Clear screen
printf(" HANGMAN \n");
printf("**********************************************\n");
printf("* *\n");
printf("* Menu *\n");
printf("* *\n");
printf("* 1. Player VS. Player *\n");
printf("* 2. Player VS. Computer *\n");
printf("* 3. Settings *\n");
printf("* 4. Exit *\n");
printf("* *\n");
printf("* *\n");
printf("**********************************************\n");
printf("\n");
printf("Choose your option: ");
scanf("%d", &setting_num);
if (setting_num < 1 || setting_num > 4) {
printf("ERROR: option not available\n");
printf("Choose another option: ");
scanf("%d", &setting_num);
}
printf("Are you choosing option %d? y/n: ", setting_num);
scanf(" %c", &option_confirmation);
if (option_confirmation != 'y') {
goto Start;
}
printf("\e[1;1H\e[2J"); //Clear screen
return setting_num; // Setting number is returned to main
}
void pvpStringGrab(char phrase[100]) { // Function to grab a word/phrase from another player
char trash[100];
fgets(trash, 100, stdin); //Clear stdin
char confirmPhrase='n';
while (confirmPhrase!='y') {
int validPhrase = 1;
printf("Player 2, please enter a word/phrase: ");
fgets(phrase, 100, stdin);
phrase[strlen(phrase)-1] = '\0'; //Remove newline character from fgets
for (int i = 0; i < strlen(phrase); i++) {
phrase[i] = toupper(phrase[i]);
}
for (int i = 0; i < strlen(phrase); i++) {
if ((!((phrase[i]>=65 && phrase[i]<=90) || phrase[i]==32)) || (phrase[i]==32 && phrase[i+1]==32)) { //Check if character is not a letter or space, or if there are multiple spaces in a row
validPhrase = 0;
}
}
if (validPhrase==0 || strlen(phrase)==0 || phrase[0]==32 || phrase[strlen(phrase)-1]==32) { //Check if input is invalid by validPhrase, empty, or starts/ends with a space
printf("Invalid/Empty input. Please enter a word/phrase with only letters and only 1 space between words.\n");
} else {
printf("\e[1;1H\e[2J"); //Clear screen
printf("You entered: %s. Is that correct? (y/n): ", phrase);
scanf("%c", &confirmPhrase);
while(getchar()!='\n'); //Prevent newline from being read as next input
}
}
}
void fileStringGrab(char phrase[100]) { // Function to grab a word/phrase from a file
srand(time(NULL)); //The seed for the random number generator because rand() is not random
FILE *categoryFilePointer; //for not having chances of messing up the code categoryFilePointer is used for the words.txt file
categoryFilePointer = fopen("words.txt", "r");
if (categoryFilePointer == NULL) {
printf("File does not exist, make sure all files are placed in the root directory.\n");
exit(1);
}
int categoryCount = 0;
char counterChar[100];
while (fgets(counterChar, 100, categoryFilePointer) != NULL) {
categoryCount++;
}
fclose(categoryFilePointer);
categoryFilePointer = fopen("words.txt", "r");
int randomLine = (rand() % (categoryCount+1));
for (int i = 0; i < randomLine; i++) {
fgets(counterChar, 100, categoryFilePointer);
}
if (counterChar[strlen(counterChar)-1] == '\n') { //Ensure no newline characters
counterChar[strlen(counterChar)-1] = '\0';
}
strcpy(phrase, counterChar); //Copy the word/phrase from the file to the phrase variable
for (int i = 0; i < strlen(phrase); i++) {
phrase[i] = toupper(phrase[i]);
}
fclose(categoryFilePointer);
char trash[100];
fgets(trash, 100, stdin); //Clear stdin
}
void printHangman(int attempts, int maxAttempts) { // Function to print
int result=0;
if (maxAttempts == 8) {
result=(attempts);
} else if (maxAttempts == 6) {
if (attempts == 0) {
result=1;
} else if (attempts == 1) {
result=2;
} else {
result=(attempts+2);
}
} else if (maxAttempts == 4) {
result=(attempts*2);
}
switch (result) {
case 0:
printf("* --- *\n");
printf("* | *\n");
printf("* | *\n");
printf("* | *\n");
printf("* ------ *\n");
break;
case 1:
printf("* ---| | *\n");
printf("* | *\n");
printf("* | *\n");
printf("* | *\n");
printf("* ------ *\n");
break;
case 2:
printf("* ---|-| *\n");
printf("* | *\n");
printf("* | *\n");
printf("* | *\n");
printf("* ------ *\n");
break;
case 3:
printf("* ---|-| *\n");
printf("* | O *\n");
printf("* | *\n");
printf("* | *\n");
printf("* ------ *\n");
break;
case 4:
printf("* ---|-| *\n");
printf("* | O *\n");
printf("* | / *\n");
printf("* | *\n");
printf("* ------ *\n");
break;
case 5:
printf("* ---|-| *\n");
printf("* | O *\n");
printf("* | /| *\n");
printf("* | *\n");
printf("* ------ *\n");
break;
case 6:
printf("* ---|-| *\n");
printf("* | O *\n");
printf("* | /|\\ *\n");
printf("* | *\n");
printf("* ------ *\n");
break;
case 7:
printf("* ---|-| *\n");
printf("* | O *\n");
printf("* | /|\\ *\n");
printf("* | / *\n");
printf("* ------ *\n");
break;
case 8:
printf("* ---|-| *\n");
printf("* | O *\n");
printf("* | /|\\ *\n");
printf("* | / \\ *\n");
printf("* ------ *\n");
break;
}
}
int mainGame(char word[100], int maxAttempts, int hint) {
char guessedLetters[50]; //created an array to store already guessed letters
char letterBank[27] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; //Letter bank displayed to user
char input[100]; //variable to store user input
int attempts = 0; //variable to keep track of number of attempts
int errorMsg = 0; //variable to store error message
for (int i = 0; i < strlen(word); i++) {
if (word[i] == ' ') {
guessedLetters[i] = ' ';
} else {
guessedLetters[i] = '_';
}
}
guessedLetters[strlen(word)] = '\0';
int alreadyGuessed = 0;
int usedHint = 0;
while (strcmp(word, guessedLetters) != 0 && attempts < maxAttempts) {
printf("\e[1;1H\e[2J"); //Clear screen
printf(" HANGMAN \n");
printf("**********************************************\n");
if (hint){
if (attempts == 3 && usedHint == 0){
char hintLetter = word[rand()%strlen(word)];
while (strchr(guessedLetters, hintLetter) != NULL){ //ensure no already guessed letters are given as hint
hintLetter = word[rand()%strlen(word)];
}
printf("* Free letter: %c *\n", hintLetter);
usedHint = 1;
} else {
printf("* *\n");
}
} else {
printf("* *\n");
}
if (alreadyGuessed == 1) {
printf("* You already guessed that letter. Try again *\n");
alreadyGuessed = 0;
} else {
printf("* *\n");
}
printHangman(attempts, maxAttempts);
printf("* %s *\n", letterBank);
printf("* Word: %-36s *\n", guessedLetters);
printf("* *\n");
printf("**********************************************\n");
printf("Please enter a letter/phrase: ");
fgets(input, 100, stdin);
input[strlen(input)-1] = '\0'; //Remove newline character from fgets
for (int i = 0; i < strlen(input); i++) {
input[i] = toupper(input[i]);
}
printf("%s", input); //Clear screen
if (strlen(input) > 1) {
if (strcmp(word, input) == 0) {
strcpy(guessedLetters, word);
return 1;
} else {
attempts++;
}
} else {
char letter = input[0];
if (strchr(letterBank, letter) == NULL) { //ran loop to ensure that the input letter user put is not repeated
alreadyGuessed = 1;
} else {
int correctGuess = 0; //variable to store number of correct guesses
for (int i = 0; i < strlen(word); i++) {
if (word[i] == letter) {
guessedLetters[i] = letter;
correctGuess = 1; //if guess is correct, the variable correctGuess is incremented by 1
}
}
letterBank[letter-65] = ' '; //removes the letter from the letter bank
if (!correctGuess) {
attempts++; //else the variable attempts is incremented by 1
}
}
}
}
printf("\n");
if (attempts < maxAttempts) {
return 1;
} else {
return 0;
}
}
void printResult(int result, char word[100]) {
printf("\e[1;1H\e[2J"); //Clear screen
printf(" HANGMAN \n");
printf("**********************************************\n");
printf("* *\n");
if (result) {
printf("* You Win! You guessed the word/phrase! *\n");
printHangman(0,8);
} else {
printf("* You lose! You ran out of attempts. *\n");
printHangman(8, 8);
}
printf("* The word/phrase was *\n");
printf("* Word: %-36s *\n", word);
printf("* *\n");
printf("**********************************************\n");
int choice;
printf("Enter 1 to exit (any other number to continue): ");
scanf("%d", &choice);
if (choice == 1) {
exit(0);
}
}
void settingsMenu(struct Settings *settings) {
int setting_num;
char option_confirmation;
Start: // Label for goto statement
printf("\e[1;1H\e[2J"); // Clear screen
printf(" HANGMAN \n");
printf("**********************************************\n");
printf("* *\n");
printf("* Settings *\n");
printf("* *\n");
printf("* 1. Attempt Difficulty: %d *\n", settings->attemptsLevel);
printf("* 2. Hint Enabled: %d *\n", settings->Hint);
printf("* 3. Back *\n");
printf("* *\n");
printf("* *\n");
printf("* *\n");
printf("**********************************************\n");
printf("\n");
printf("Choose your option: ");
scanf("%d", &setting_num);
if (setting_num < 1 || setting_num > 4) {
printf("ERROR: option not available\n");
printf("Choose another option: ");
scanf("%d", &setting_num);
}
printf("Are you choosing option %d? y/n: ", setting_num);
scanf(" %c", &option_confirmation);
if (option_confirmation != 'y') {
goto Start;
}
switch (setting_num)
{
case 1:
int attemptsLevel;
printf("Enter the difficulty level (1-3, Low/Medium/High): ");
scanf("%d", &attemptsLevel);
while (attemptsLevel < 1 || attemptsLevel > 3) {
printf("ERROR: option not available\n");
printf("Choose another option: ");
scanf("%d", &attemptsLevel);
}
if (attemptsLevel == 1) {
settings->maxAttempts = 8;
} else if (attemptsLevel == 2) {
settings->maxAttempts = 6;
} else if (attemptsLevel == 3) {
settings->maxAttempts = 4;
}
settings->attemptsLevel = attemptsLevel;
break;
case 2:
int hint;
printf("Enable hint? (1 for yes, 0 for no): ");
scanf("%d", &hint);
while (hint < 0 || hint > 1) {
printf("ERROR: option not available\n");
printf("Choose another option: ");
scanf("%d", &hint);
}
settings->Hint = hint;
break;
default:
break;
}
printf("%d %d %d", settings->maxAttempts, settings->Hint, settings->attemptsLevel);
}
int main() {
srand(time(NULL)); //The seed for the random number generator because rand() is not random
struct Settings settings = {6, 1, 2}; // Default settings
while (1) {
int setting_num = mainMenu();
char stringToGuess[100];
char trash[100];
int result;
switch (setting_num) {
case 1:
pvpStringGrab(stringToGuess);
result = mainGame(stringToGuess, settings.maxAttempts, settings.Hint);
printResult(result, stringToGuess);
break;
case 2:
fileStringGrab(stringToGuess);
result = mainGame(stringToGuess, settings.maxAttempts, settings.Hint);
printResult(result, stringToGuess);
break;
case 3:
settingsMenu(&settings);
break;
case 4:
exit(0);
return 0;
default:
exit(0);
break;
}
}
return 0;
}