I am making a hangman game on my own and I have ran into a problem where I need to know if the guess is in the secret word. if it is I will change the bool innum to true, if it is not it will stay false. i have looked it up and cannot find anything that works. also the name printe is just the name of the string its just what I've named it.
here is the code I am working with:
using namespace std;
#include <iostream>
#include <conio.h>
void title();
void rightanswer();
void try1();
void try2();
void try3();
void try4();
void try5();
void try6();
void spacer();
int main()
{
bool innum = false;
int printe = 0, attempts_wrong = 0, trynum = 6;
char guess;
string secretword, hint1, hint2;
title();
// the welcoming senteces
cout << "Welcome to HANG MAN\n\n" << endl;
cout << "Please enter the secret word (no spaces): ";
cin >> secretword;
// the hints
cout << "\nenter the first hint: ";
cin >> hint1;
cout << "\nenter the second hint: ";
cin >> hint2;
//explanation for hints
cout << "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"; //so guesser cant see word
cout << "\nthe hints will be used as the guesser runs out of attemptts" << endl;
cout << "the first hint will be used immediately\n\n" << endl;
cout << "press any button to start...";
_getch();
cout << "\n\n" << endl;
for (int i = 0; secretword[i] != '\0'; ++i)
{
printe++;
}
rightanswer();
cout << "\nyour word is " << printe << " letters long" << endl;
if (attempts_wrong == 0)
{
cout << "your first hint is: ";
cout << hint1 << endl;
}
if (attempts_wrong == 3)
{
cout << "your second hint is: ";
cout << hint2 << endl;
}
cout << "enter a letter: ";
cin >> guess;
// im gonna have the code go here
// <-----------------------------
if (innum == true)
{
spacer();
cout << guess << " is in the secret word" << endl;
rightanswer();
}
else if (innum == false)
{
spacer();
cout << guess << " is not in the secret word" << endl;
rightanswer();
attempts_wrong++;
}
return 0;
}
void title() {
cout << "*****************************************" << endl;
cout << "* _____ *" << endl;
cout << "* | | /\\ |\\ | | *" << endl;
cout << "* |_____| /__\\ | \\ | | ___ *" << endl;
cout << "* | | / \\ | \\ | | | *" << endl;
cout << "* | | / \\| \\| |_____| *" << endl;
cout << "* *" << endl;
cout << "* |\\ /| /\\ |\\ | *" << endl;
cout << "* | \\ / | /__\\ | \\ | *" << endl;
cout << "* | \\ / | / \\ | \\ | *" << endl;
cout << "* | V | / \\| \\| *" << endl;
cout << "* *" << endl;
cout << "*****************************************" << endl;
}
//head, body, 2 arms, 2 legs - 6 in total
void rightanswer() {
//if the guess is right and the start
cout << " ___ " << endl;
cout << " | | " << endl;
cout << " | " << endl;
cout << " __|__ " << endl;
}
void try1() {
cout << " ___ " << endl;
cout << " | | " << endl;
cout << " O | " << endl;
cout << " | " << endl;
cout << " __|__ " << endl;
}
void try2() {
cout << " ___ " << endl;
cout << " | | " << endl;
cout << " O | " << endl;
cout << " | | " << endl;
cout << " __|__ " << endl;
}
void try3() {
cout << " ___ " << endl;
cout << " | | " << endl;
cout << " O | " << endl;
cout << " /| | " << endl;
cout << " __|__ " << endl;
}
void try4() {
cout << " ___ " << endl;
cout << " | | " << endl;
cout << " O | " << endl;
cout << " /|\ | " << endl;
cout << " __|__ " << endl;
}
void try5() {
cout << " ___ " << endl;
cout << " | | " << endl;
cout << " O | " << endl;
cout << " /|\ | " << endl;
cout << " / __|__ " << endl;
}
void try6() {
cout << " ___ " << endl;
cout << " | | " << endl;
cout << " O | " << endl;
cout << " /|\ | " << endl;
cout << " / \__|__ " << endl;
cout << " YOU LOSE" << endl;
cout << "you have run out of guesses";
exit(0);
}
// it creates a line to differ one try from the other
void spacer() {
cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
}
I don't know how much to show so that is all of it, its probably not the best but it works. I know that I don't some of the voids functions at the bottom but it works for now. if you have any suggestions tell me them. also don't be to harsh, I'm a beginner.
There are a few ways of approaching this. If you actually want to simply find if a string contains a character, the following works:
char needle;
haystack.find(needle) != string::npos;
As others have correctly answered. However, in this case, I think you are looking for something slightly different. Its a game of hangman so what you actually may want to do is show the portions of the word that the individual has actually guessed correctly.
Efficient
If we assume that: display is a string initialised with _ (or some character that is not a valid letter in a guessable word) as each character to the length of the string, you can work with this to partially display it.
If we have a map<char, vector<size_t>> that tells us exactly the indices that each character occurs at, which is easy to compute, we can take the guess and iterate through the corresponding vector of indices and replace characters in display with the actual character and then remove the character from the map. Once the map is empty, then the entire string has been guessed. You may also want to maintain a set of characters that have already been guessed to ensure that the same character can only be guessed once.
I will leave it as an exercise for you to implement this as it shouldn't be too difficult. If you'd like some pointers, let me know.
Less Efficient
This second way is less efficient, but since its a real-time game it won't make a difference unless these strings are really long.
Simply hold a copy of the string and iterate through it. Every time check which character you are checking against then replace the character at the index you are at in the _ word with the correct character. You can also keep a flag which checks whether or not any replacements happen and if not, you know that the character does not exist in the word.
You may use std::string::find method to find the given character (returns the position of the character or std::string::npos if it is not found): http://www.cplusplus.com/reference/string/string/find/
Example:
std::string str = "Hello.World";
auto found = str.find('.');
if (found != std::string::npos)
std::cout << "Period found at: " << found << std::endl;
In your case, it could look as such:
innum = (secretword.find(guess) != std::string::npos);
Try string.find.
auto i =secretword.find(guess); gives you the index. If it equals std::string::npos it isn't there.
Also, std::string has a size() method you can rrplace your letter counting with.
Related
I am creating a simple command line, tic-tac-toe game in C++. Whenever I reun the code I get no compiler errors but then VSCode tells me once I have given input that there is a Segmentation Fault. I will paste my code below:
#include <iostream>
#include <cmath>
using namespace std;
void print_board(string board[3][3])
{
cout << " | | " << endl;
cout << " " << board[0][0] << " | " << board[0][1] << " | " << board[0][2] << " " << endl;
cout << "_____|_____|_____" << endl;
cout << " | | " << endl;
cout << " " << board[1][0] << " | " << board[1][1] << " | " << board[1][2] << " " << endl;
cout << "_____|_____|_____" << endl;
cout << " | | " << endl;
cout << " " << board[2][0] << " | " << board[2][1] << " | " << board[2][2] << " " << endl;
cout << " | | " << endl;
}
string turn(string board[3][3], bool xturn)
{
int position;
cout << "Where would you like to go (1 - 9): ";
cin >> position;
if (xturn)
{
string player_turn = "X";
}
else
{
string player_turn = "O";
}
board[(int)floor(position / 3)][(position % 3) - 1] = "X";
return board[3][3];
}
int main(void)
{
string board[3][3] = {{" ", " ", " "}, {" ", " ", " "}, {" ", " ", " "}};
bool xturn = true;
while (true)
{
print_board(board);
board[3][3] = turn(board, xturn);
xturn = !xturn;
}
return 0;
}
Any help is much is much appreciated. Thanks! If it helps I am using the GCC compiler.
void print_board(string board[3][3])
why are you using a string[3][3] ? you basically just need a 3x3 character array
board[(int)floor(position / 3)][(position % 3) - 1] = "X";
make sure you keep yourself in range 0..2, -1 is outside and will
cause undefined behavior
return board[3][3];
No that is wrong in more ways than one, and in any case there is no need to return a copy
board[3][3] = turn(board, xturn);
this will not go well, you return a board of 3x3 strings but assign
it to at best, an undefined place.
since you already pass the address of the board to your turn function, that is that is all needed. change it in place.
turn(board, xturn);
arrays are addresses in memory, it is the starting address where in memory some data is stored
if you pass an array/matrix to a function you are letting the function know where in memory it is stored, so any changes to the array/matrix will be done in place, therefore you do not need to return a copy.
I am a beginner, so I have pretty messy code. I have not commented this game completely, so if you need clarification on some variables, I can give that to you.
(By the way, this is a c++ project which asks to make a game of tic Tac Toe)
My main question is, how would I repeat my board (which is updated every time someone makes a move in tic tac toe)? I cannot think of a way to do so, so it would be appreciated if someone gave me ideas, not the direct answer.
My Code below is only put to give you an idea of what I am doing, and also if you have any suggestions on how to fix my code (that being organization or mistakes, which has a 100% chance of occurring).
#include <iostream>
using namespace std;
char a[3][3];//sets 3x3 matrix
a[0][0]='1';//upper row left corner is 1
a[0][1]='2';//upper row middle is 2
a[0][2]='3';//upper row right corner is 3
a[1][0]='4';//middle row left is 4
a[1][1]='5';//middle row middle is 5
a[1][2]='6';//middle row right is 6
a[2][0]='7';//bottom row left is 7
a[2][1]='8';//bottom row middle is 8
a[2][2]='9';//bottom row right is 9
cout << " | | " << endl;//all these "shapes" make the board.
cout << " " << a[0][0] << " | " << a[0][1] << " | " << a[0][2] << endl;
cout << "_____|_____|_____" << endl;
cout << " | | " << endl;
cout << " " << a[1][0] << " | " << a[1][1] << " | " << a[1][2] << endl;
cout << "_____|_____|_____" << endl;
cout << " | | " << endl;
cout << " " << a[2][0] << " | " << a[2][1] << " | " << a[2][2] << endl;
cout << " | | " << endl;
bool match = true;//this tells the consul the match has not ended
bool checker;//checks if you actually chose X or O
checker=true;
cout << "play!play!play! you'll need two people" << endl;
cout << "decide who takes X, then press 1 to take X" << endl;
cout << "or press 2 to take O" << endl;
cin >> player;//so, organize will be the thing (1 or 2) that the player will put in
char XO;//helps make X and O
if (player == 1)
{
cout << "you chose X" << endl;
XO = 'X';
}
else if (player == 2)
{
cout << "you chose O" << endl;
XO = 'O';
}
else
{
cout << "press 1 or 2 only please" << endl;
checker=false;
}
bool invalid;//if you "accidentally" put your move in an illegal square, this will help you redo a move.
bool gameover = true;//helps differentiate between draws and wins
int nowwestart;//starts game
cout << "player play your move" << endl;//tells you to move it
cin >> nowwestart;
invalid = true;//you always make a valid move first turn.
if (nowwestart == 1 && a[0][0] == '1')//when you place your marker on square 1, i need to tell consul that your move equals a certain square
{
a[0][0]=XO;
cout << " | | " << endl;//all these "shapes" make the board.
cout << " " << a[0][0] << " | " << a[0][1] << " | " << a[0][2] << endl;
cout << "_____|_____|_____" << endl;
cout << " | | " << endl;
cout << " " << a[1][0] << " | " << a[1][1] << " | " << a[1][2] << endl;
cout << "_____|_____|_____" << endl;
cout << " | | " << endl;
cout << " " << a[2][0] << " | " << a[2][1] << " | " << a[2][2] << endl;
cout << " | | " << endl;
}
else if (nowwestart == 2 && a[0][1] == '2')
{
a[0][1]=XO;
cout << " | | " << endl;//all these "shapes" make the board.
cout << " " << a[0][0] << " | " << a[0][1] << " | " << a[0][2] << endl;
cout << "_____|_____|_____" << endl;
cout << " | | " << endl;
cout << " " << a[1][0] << " | " << a[1][1] << " | " << a[1][2] << endl;
cout << "_____|_____|_____" << endl;
cout << " | | " << endl;
cout << " " << a[2][0] << " | " << a[2][1] << " | " << a[2][2] << endl;
cout << " | | " << endl;
}
else if (nowwestart == 3 && a[0][2] == '3')
{
a[0][2]=XO;
cout << " | | " << endl;//all these "shapes" make the board.
cout << " " << a[0][0] << " | " << a[0][1] << " | " << a[0][2] << endl;
cout << "_____|_____|_____" << endl;
cout << " | | " << endl;
cout << " " << a[1][0] << " | " << a[1][1] << " | " << a[1][2] << endl;
cout << "_____|_____|_____" << endl;
cout << " | | " << endl;
cout << " " << a[2][0] << " | " << a[2][1] << " | " << a[2][2] << endl;
cout << " | | " << endl;
}
else if (nowwestart == 4 && a[1][0] == '4')
{
a[1][0]=XO;
cout << " | | " << endl;//all these "shapes" make the board.
cout << " " << a[0][0] << " | " << a[0][1] << " | " << a[0][2] << endl;
cout << "_____|_____|_____" << endl;
cout << " | | " << endl;
cout << " " << a[1][0] << " | " << a[1][1] << " | " << a[1][2] << endl;
cout << "_____|_____|_____" << endl;
cout << " | | " << endl;
cout << " " << a[2][0] << " | " << a[2][1] << " | " << a[2][2] << endl;
cout << " | | " << endl;
}
else if (nowwestart == 5 && a[1][1] == '5')
{
a[1][1]=XO;
cout << " | | " << endl;//all these "shapes" make the board.
cout << " " << a[0][0] << " | " << a[0][1] << " | " << a[0][2] << endl;
cout << "_____|_____|_____" << endl;
cout << " | | " << endl;
cout << " " << a[1][0] << " | " << a[1][1] << " | " << a[1][2] << endl;
cout << "_____|_____|_____" << endl;
cout << " | | " << endl;
cout << " " << a[2][0] << " | " << a[2][1] << " | " << a[2][2] << endl;
cout << " | | " << endl;
}
else if (nowwestart == 6 && a[1][2] == '6')
{
a[1][2]=XO; cout << " | | " << endl;//all these "shapes" make the board.
cout << " " << a[0][0] << " | " << a[0][1] << " | " << a[0][2] << endl;
cout << "_____|_____|_____" << endl;
cout << " | | " << endl;
cout << " " << a[1][0] << " | " << a[1][1] << " | " << a[1][2] << endl;
cout << "_____|_____|_____" << endl;
cout << " | | " << endl;
cout << " " << a[2][0] << " | " << a[2][1] << " | " << a[2][2] << endl;
cout << " | | " << endl;
}
else if (nowwestart == 7 && a[2][0] == '7')
{
a[2][0]=XO;
cout << " | | " << endl;//all these "shapes" make the board.
cout << " " << a[0][0] << " | " << a[0][1] << " | " << a[0][2] << endl;
cout << "_____|_____|_____" << endl;
cout << " | | " << endl;
cout << " " << a[1][0] << " | " << a[1][1] << " | " << a[1][2] << endl;
cout << "_____|_____|_____" << endl;
cout << " | | " << endl;
cout << " " << a[2][0] << " | " << a[2][1] << " | " << a[2][2] << endl;
cout << " | | " << endl;
}
else if (nowwestart == 8 && a[2][1] == '8')
{
a[2][1]=XO;
cout << " | | " << endl;//all these "shapes" make the board.
cout << " " << a[0][0] << " | " << a[0][1] << " | " << a[0][2] << endl;
cout << "_____|_____|_____" << endl;
cout << " | | " << endl;
cout << " " << a[1][0] << " | " << a[1][1] << " | " << a[1][2] << endl;
cout << "_____|_____|_____" << endl;
cout << " | | " << endl;
cout << " " << a[2][0] << " | " << a[2][1] << " | " << a[2][2] << endl;
cout << " | | " << endl;
}
else if (nowwestart == 9 && a[2][2] == '9')
{
a[2][2]=XO;
cout << " | | " << endl;//all these "shapes" make the board.
cout << " " << a[0][0] << " | " << a[0][1] << " | " << a[0][2] << endl;
cout << "_____|_____|_____" << endl;
cout << " | | " << endl;
cout << " " << a[1][0] << " | " << a[1][1] << " | " << a[1][2] << endl;
cout << "_____|_____|_____" << endl;
cout << " | | " << endl;
cout << " " << a[2][0] << " | " << a[2][1] << " | " << a[2][2] << endl;
cout << " | | " << endl;
}
else
{
cout << "you made an invalid move, please do it again" << endl;
invalid=false;//you made an illegal move :(
}
while(!invalid);
match = false;//when match has ended...
if (a[0][0] != '1')//all possible wins through square 1
{
if (a[0][0] == a[1][0] && a[1][0] == a[2][0])
{
match = true;
}
else if (a[0][0] == a[0][1] && a[0][1] == a[0][2])
{
match = true;
}
else if (a[0][0] == a[1][1] && a[1][1] == a[2][2])
{
match= true;
}
}
if (a[0][1] != '2')//all possible wins through square 2
{
if (a[0][1] == a[1][1] && a[1][1] == a[2][1])
{
match = true;
}
}
if (a[0][2] != '3')//all possible wins through square 3
{
if (a[0][2] == a[1][2] && a[1][2] == a[2][2])
{
match = true;
}
else if (a[0][2] == a[1][1] && a[1][1] == a[2][0])
{
match = true;
}
}
if (a[1][0] != '4')//all possible wins through square 4
{
if (a[1][0] == a[1][1] && a[1][1] == a[1][2])
{
match = true;
}
}
if (a[2][0] != '7')//all possible wins through square 7
{
if (a[2][0] == a[2][1] && a[2][1] == a[2][2])
{
match = true;
}
}
else//anything beside win is draw
{
gameover=false;//no one won...
match=true;//but the match is done anyway
}
if (match==true)//if the match is done
{
if (gameover==true)//if someone won
{
cout << "player" << player << "won" << player << endl;
}
cout << "the game has ended. play again? 1-yes, 2-false (press 2 please)" << endl;
if (1)
{
match = false;//dang it, you are still playing. the borad is below.
char a[3][3];//sets 3x3 matrix
a[0][0]='1';//upper row left corner is 1
a[0][1]='2';//upper row middle is 2
a[0][2]='3';//upper row right corner is 3
a[1][0]='4';//middle row left is 4
a[1][1]='5';//middle row middle is 5
a[1][2]='6';//middle row right is 6
a[2][0]='7';//bottom row left is 7
a[2][1]='8';//bottom row middle is 8
a[2][2]='9';//bottom row right is 9
}
player = 1;
}
else
{
if (player == 1)
{
player = 2;
}
else
{
player = 1;
}
}
while (!match);
cout << endl;
return 0;
}
int main()
{
dot();
}
You can loop the whole program with user input. while (getline(std::cin, input). And update the 2D array with the appropriate symbol. I would suggest you to use a constant to represent X and O. So that the code will be clear. And also I would suggest you move the repeated code to functions, which again would increase the clarity.
You could add a while loop and check for condition not won and not draw, like
while( !bWon && !bDraw )
In the loop you could add functions to
Select which player has to play (Hint: every odd in loop is a play for X and even for O.)
Once Player input. You could calculate if he won.
If he didn't win could calcule if its a draw. ( Hint: How many times will the loop run? )
Clear old board and display new one.
Program's Aim:
The program is a hangman game which get a list of planets from our solar system, saves it to an array then randomly selects one word from the array and subsequently prints two letters of the word on the board. The program runs perfectly in a windows environment, but fails in runtime on linux.
Problem:
The program replaces the first character in the output stream with the last character of that stream. That happens when printing the word on the board and also when the word is displayed when it is correctly or wrongly guessed.
e.g.:
word = Mars
For 6 wrong guess it's supposed to print, Too bad you didn't guess right. It was "mars".
Instead, it prints: "oo bad you didn't guess right. It was "mars
Here are the files:
wordlist.yx:
Mercury
Venus
Earth
Mars
Jupiter
Saturn
Uranus
Neptune
Pluto
Hangman.h:
#pragma once
#include <iostream>
using namespace std;
// Check for OS
#ifdef _WIN32
#define SYS "MS"
#else
#define SYS "LINUX"
#endif
class Hangman {
private:
int version = 3;
string release_date = "01/05/2016";
int &v = version;
string &r = release_date;
static const int WORDLIST_SIZE = 10;
string wordlist[WORDLIST_SIZE];
string word, hidden_word, wordfile = {"wordlist.yx"};
int word_length, tries_left;
bool is_match;
public:
Hangman();
~Hangman();
//attributes
string user_input, arch;
char choice;
// Game functionality methods
void printMenu(Hangman &);
void info(Hangman &) const;
void startGame(Hangman &);
void reset();
void getWordlist();
void getWordAndSetHidden();
int getTries();
void printHangman(int);
void printBoard();
void getInput(Hangman &);
int validateInput(char);
void decideFate(Hangman &);
void decision(Hangman &);
// Invalid input and screen clearing methods
void invalidInput1(Hangman &, char &);
void invalidInput2(Hangman &, string &);
void cls() const;
};
Hangman.cpp:
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <fstream>
#include <limits>
#include <algorithm>
#include <string>
#include "Hangman.h"
using namespace std;
//Constructor
Hangman::Hangman(){
//Get's OS
// Microsoft
if(SYS == "MS"){
arch = "cls";
} else{
//linux, unix, OSX
arch = "clear";
}
hidden_word = "";
tries_left = 6;
}
// De-constructor
Hangman::~Hangman(){
//Destroy objects
}
// Menu Options
void Hangman::printMenu(Hangman &s){
cls();
cout << " _____Hangman (v7)_____ " << endl;
cout << "| |" << endl;
cout << "| Play - P |" << endl;
cout << "| Info - I |" << endl;
cout << "| Quit - Q |" << endl;
cout << "------------------------" << endl;
cout << "Choice: ";
getline(cin, user_input);
// Pass first character of string to char
choice = user_input[0];
switch(choice){
case 'p':
case 'P':
startGame(s);
break;
case 'i':
case 'I':
info(s);
break;
case 'q':
case 'Q':
cls();
cout << "Thank you for playing..." << endl;
exit(EXIT_SUCCESS);
break;
default:
invalidInput1(s, choice);
}
}
void Hangman::info(Hangman &m) const{
string ic;
cls();
cout << "+--------------------------------------------------------------------+\n"
<< "| Hangman Instructions |\n"
<< "+--------------------------------------------------------------------+\n"
<< "| This Hangman game is played by entering a guessed letter at a time.|\n"
<< "| 6 wrong guesses are given by default and decrements by 1 (one) on |\n"
<< "| each wrong guess. |\n"
<< "+--------------------------------------------------------------------+\n"
<< "| In-game options |\n"
<< "+--------------------------------------------------------------------+\n"
<< "| restart - Start a new game |\n"
<< "| menu - Display main menu |\n"
<< "| quit - Exit game |\n"
<< "+--------------------------------------------------------------------+\n"
<< "| Game Information |\n"
<< "+--------------------------------------------------------------------+\n"
<< "| Version: " << v << " |\n"
<< "| Date: " <<r<< " |\n"
<< "+--------------------------------------------------------------------+\n"
<< "| Author |\n"
<< "+--------------------------------------------------------------------+\n"
<< "| Philan James (Zoutiyx) |\n"
<< "| zoutiyx#gmail.com |\n"
<< "+--------------------------------------------------------------------+\n\n";
cout << "Press enter to close... ";
getline(cin, ic);
m.printMenu(m);
}
void Hangman::startGame(Hangman &h){
cls();
h.reset();
h.getWordlist();
h.getWordAndSetHidden();
h.decideFate(h);
do {
h.printHangman(h.getTries());
h.printBoard();
h.getInput(h);
h.decideFate(h);
} while(h.getTries() != 0);
}
//Gets the wordlist from a file and stores it into an array
void Hangman::getWordlist(){
fstream in_words(wordfile, ios::in);
if(!in_words.is_open()){
cerr << "Error 0: " << wordfile << " isn't found in current directory!\n";
} else{
for(int i = 0; (i < WORDLIST_SIZE - 1) && !in_words.eof(); i++){
getline(in_words, *(wordlist + i), '\n');
}
}
in_words.close();
}
void Hangman::getWordAndSetHidden(){
srand(time(NULL));
int word_index, p1, p2;
word_index = rand() % (WORDLIST_SIZE - 1) + 0;
word = wordlist[word_index];
// Sets the hidden word letters to underscores
for(unsigned int i = 0; i < word.length(); i++){
if(word[i] == ' ') {
hidden_word.push_back(' ');
} else {
hidden_word.push_back('_');
}
}
//selecting the random two indexes of the word
p1 = rand() % word.length();
p2 = rand() % word.length();
while (p1 == p2 || p2 == p1){
p1 = rand() % word.length();
p2 = rand() % word.length();
}
// Assigning the letter to the corresponding index
for(int i = 0; i < (int)word.length(); i++){
if (i == p1){
hidden_word[i] = word[i];
} else if( i == p2){
hidden_word[i] = word[i];
}
// If a certain letter is the same as the on at the p1 or p2,
// It is also printed on the board, making it more than (2) default letters
if (tolower(word[p1]) == tolower(word[i])){
hidden_word[i] = word[i];
}
if (tolower(word[p2]) == tolower(word[i])){
hidden_word[i] = word[i];
}
}
}
// Get lives remaining
int Hangman::getTries(){
return tries_left;
}
// Print's hangman state based on lives left
void Hangman::printHangman(int ll){
cls();
cout << "Planets in our solor system...\n\n";
cout << "Tries left: " << tries_left << endl;
switch (ll){
case 6:
cout << " |----| " << endl;
cout << " | " << endl;
cout << " | " << endl;
cout << " | " << endl;
cout << " | " << endl;
cout << "____|____ " << endl;
cout << endl;
break;
case 5:
cout << " |----| " << endl;
cout << " | 0 " << endl;
cout << " | " << endl;
cout << " | " << endl;
cout << " | " << endl;
cout << "____|____ " << endl;
cout << endl;
break;
case 4:
cout << " |----| " << endl;
cout << " | 0 " << endl;
cout << " | | " << endl;
cout << " | | " << endl;
cout << " | " << endl;
cout << "____|____ " << endl;
cout << endl;
break;
case 3:
cout << " |----| " << endl;
cout << " | 0 " << endl;
cout << " | /| " << endl;
cout << " | | " << endl;
cout << " | " << endl;
cout << "____|____ " << endl;
cout << endl;
break;
case 2:
cout << " |----| " << endl;
cout << " | 0 " << endl;
cout << " | /|\\ " << endl;
cout << " | | " << endl;
cout << " | " << endl;
cout << "____|____ " << endl;
cout << endl;
break;
case 1:
cout << " |----| " << endl;
cout << " | 0 " << endl;
cout << " | /|\\ " << endl;
cout << " | | " << endl;
cout << " | / " << endl;
cout << "____|____ " << endl;
cout << endl;
break;
case 0:
cout << " |----| " << endl;
cout << " | 0 " << endl;
cout << " | /|\\ " << endl;
cout << " | | " << endl;
cout << " | / \\ " << endl;
cout << "____|____ " << endl;
cout << endl;
break;
}
}
// Display hidden word
void Hangman::printBoard(){
for(unsigned int i = 0; i < hidden_word.length(); i++){
if(word[i] == ' '){
cout << word[i];
} else if(i != hidden_word.length()){
cout << hidden_word[i] << " ";
} else{
cout << hidden_word[i];
}
}
cout << endl << endl;
}
// Get letter choice and assign position 0 to character
void Hangman::getInput(Hangman &c){
cout << "Letter choice: ";
getline(cin, user_input);
transform(user_input.begin(), user_input.end(),
user_input.begin(), ::tolower);
if(user_input == "restart"){
c.reset();
c.startGame(c);
} else if(user_input == "menu"){
printMenu(c);
} else if(user_input == "quit"){
cout << "\nThank you for playing...\n";
exit(EXIT_SUCCESS);
} else{
choice = user_input[0];
user_input = "";
validateInput(choice);
}
}
// test character for validity
int Hangman::validateInput(char choice){
for(unsigned int i = 0; i < hidden_word.length(); i++){
//Checks if entered character is already on the board
if(toupper(choice) == hidden_word[i] || tolower(choice) == hidden_word[i]){
--tries_left;
return 0;
}
// Checks if character is a valid input
if(toupper(choice) == word[i] || tolower(choice) == word[i]){
hidden_word[i] = word[i];
is_match = true;
}
// If end of loop and character is invalid, lives left -=1
if(i == hidden_word.length() -1 && is_match != true){
--tries_left;
return 0;
}
}
is_match = false;
return 0;
}
// Checks if the word was found or not
void Hangman::decideFate(Hangman &f){
if(hidden_word == word){
cls();
cout << "Congrats, \"" << word << "\" it is.\n\n";
f.decision(f);
}
if(tries_left == 0 && hidden_word != word){
cin.ignore();
f.printHangman(f.getTries());
cout << "Too bad you didn't guess right. It was \""
<< word << "\"" << endl << endl;
f.decision(f);
}
}
void Hangman::decision(Hangman &c) {
cout << "+----------------------+" << endl;
cout << "| Alternatives |" << endl;
cout << "+----------------------+" << endl;
cout << "\"restart\" or a new game\n"
<< "\"help\" for help information\n"
<< "\"quit\" to exit\n\nChoice: ";
getline(cin, user_input);
transform(user_input.begin(), user_input.end(),
user_input.begin(), ::tolower);
if(user_input == "restart"){
c.startGame(c);
} else if(user_input == "help"){
info(c);
} else if(user_input == "quit"){
cls();
cout << "Thank you for playing..." << endl;
exit(EXIT_SUCCESS);
} else{
invalidInput2(c,user_input);
}
}
void Hangman::invalidInput1(Hangman &i1, char &i){
//cin.clear();
cerr << "' " << i << " ' is not a valid input."
<< " Press <Enter> to try again.";
getline(cin, user_input);
Hangman::printMenu(i1);
}
void Hangman::invalidInput2(Hangman &i2, string &i){
//cin.clear();
cerr << "\" " << i << " \" is not a valid input."
<< " Press <Enter> to try again.";
getline(cin, user_input);
cls();
Hangman::decision(i2);
}
// Reset game
void Hangman::reset(){
tries_left = 6;
hidden_word = "";
}
// Calls clear screen command
void Hangman::cls() const{
// passes cls or clear string as character pointer
system(arch.c_str());
}
main.cpp:
#include "Hangman.h"
int main() {
Hangman hangman;
hangman.printMenu(hangman);
}
Tried:
Running the program in a lower standard (11) from 14.
Online compiler from tutorialspoint.
Manually setting the word.
Observation:
I observed that if I manually set the word, that situation is resolved. How do I narrow in on this issue further?
Edit:
Added wordlist and removed a stray backslash which prevented compiling..
Try running dos2unix on your wordlist.yx file. If it was created on Windows, the newlines are probably \r\n, not just \n. And if that \r is interpreted literally, that will return to the beginning of the line prior to continuing to output to cout, thus overwriting your first character.
Reference to dos2unix can be found here.
To avoid using dos2unix, you could strip the \r characters from your wordlist array. One approach would be to loop through each word in the array and processing them like so:
currWord.erase( std::remove(currWord.begin(), currWord.end(), '\r'), currWord.end() );
I'm new to C++. I have been following an online course that teaches you how to make a Hangman game in C++. For the most part the code was working, every time I debugged it ran fine. I completed the entire code and double checked it, but I'm getting an error on one of the 'else' the errors I'm getting is "error C2181: illegal else without matching if.
Here's my code.
// Hangman game
// CN
// Header file
#include "stdafx.h"
// Input/Output
#include <iostream>
// Text
#include <string>
// Information storage
#include <vector>
// Figuring out the information storage
#include <algorithm>
// Converts lower cased letters to higher case letters
#include <cctype>
// Reads computers time and distributes a word from a list accordingly
#include <ctime>
// Library for system
#include <cstdlib>
using namespace std;
int main()
{
// Constant data type which is a fixed value, MaxWrong in Pascal Text and the max number of guesses.
const int MaxWrong = 6;
vector<string> words;
words.push_back("SANTA CLAUSE");
words.push_back("REINDEER");
words.push_back("PRESENT");
words.push_back("TREE");
words.push_back("MILK");
words.push_back("COOKIE");
// Parenthesis must always match
srand(static_cast<unsigned int>(time(0)));
random_shuffle(words.begin(), words.end());
const string theWord = words[0];
int wrong = 0;
string soFar(theWord.size(), '_');
string used = "";
cout << "\n******** Welcome to Chaye's Hangman ********\n\n";
cout << " __ \n";
cout << " | | \n";
cout << " | \n";
cout << " | \n";
cout << " | \n";
cout << " | \n";
cout << " ___|____ \n\n";
cout << " Do Your Best Human \n\n";
// Loop
while ((wrong < MaxWrong) && (soFar != theWord))
{
cout << "\n You have " << (MaxWrong - wrong);
cout << " incorrect tries left.\n";
cout << "\n You've used these letters:\n" << used << endl;
char guess;
cout << "\n\n Enter your guess: ";
cin >> guess;
guess = toupper(guess);
while (used.find(guess) != string::npos)
{
cout << "\n You've already tried " << guess << endl;
cout << " Enter your guess: ";
cin >> guess;
guess = toupper(guess);
}
used += guess;
if (theWord.find(guess) != string::npos)
{
cout << " That's right " << guess << " is in the word,\n";
for (int i = 0; i < theWord.length(); ++i)
{
if (theWord[i] == guess)
{
soFar[i] = guess;
}
}
}
else
{
cout << " sorry. " << guess << " isn't in the word.\n";
++wrong;
}
// If one is wrong
if (wrong == 1)
{
cout << " __ \n";
cout << " | | \n";
cout << " | O \n";
cout << " | \n";
cout << " | \n";
cout << " | \n";
cout << " ___|____ \n\n";
cout << " Do Your Best Human \n\n";
}
else
{
cout << endl;
}
// If one is wrong
if (wrong == 2)
{
cout << " ___ \n";
cout << " | | \n";
cout << " | O \n";
cout << " | # \n";
cout << " | \n";
cout << " | \n";
cout << " ___|____ \n\n";
cout << " Do Your Best Human \n\n";
}
else
{
cout << endl;
}
// If one is wrong
if (wrong == 3)
{
cout << " ___ \n";
cout << " | | \n";
cout << " | O \n";
cout << " | /# \n";
cout << " | \n";
cout << " | \n";
cout << " ___|____ \n\n";
cout << " Do Your Best Human \n\n";
}
else
{
cout << endl;
}
// If one is wrong
if (wrong == 4)
{
cout << " ___ \n";
cout << " | | \n";
cout << " | O \n";
cout << " | /#\ \n";
cout << " | \n";
cout << " | \n";
cout << " ___|____ \n\n";
cout << " Do Your Best Human \n\n";
}
else
{
cout << endl;
}
// If one is wrong
if (wrong == 5)
{
cout << "\n You've been hung \n";
cout << " ___ \n";
cout << " | | \n";
cout << " | O \n";
cout << " | /#\ \n";
cout << " | / \n";
cout << " | \n";
cout << " ___|____ \n\n";
cout << " Do Your Best Human \n\n";
}
else
{
cout << "\n I'm suprised you've got this far\n";
}
cout << "\n The word was " << theWord << endl;
}
// If one is wrong
if (wrong == MaxWrong)
{
cout << "\n You've been hung \n";
cout << " ___ \n";
cout << " | | \n";
cout << " | O \n";
cout << " | /#\ \n";
cout << " | / \ \n";
cout << " | \n";
cout << " ___|____ \n\n";
cout << " Do Your Best Human \n\n";
}
else
{
cout << "\n I'm suprised you've got this far\n";
}
cout << "\n The word was " << theWord << endl;
// Pause Console
system("pause");
// Kills the application once done
return 0;
}
There should be no semicolon in this line:
if (theWord.find(guess) != string::npos);
this semicolon terminates the whole if statement and the following {...} block is executed unconditionally. Following else is therefore no longer matched with the if statement.
And you are also missing closing ) bracket in your while statement:
while (used.find(guess) != string::npos
{
...
}
Change
** else **
to
else
Your compiler is interpreting that as an operator. If it still fails, edit your post w/ the error. Also worth noting, if you compile w/ the -g flag you get some debug output which can be beneficial.
I'm trying to make a program to calculate the y component of a user-input number for 7 different aspect ratios. This is probably a simple problem somewhere in the declarations at the top, but I have very little experience with c++. I am writing in xcode. Thanks!
I'm getting the following error messages:
19:13: Invalid operands to binary expression ('std::__1::basic_istream' and '')
32:6: Expected unqualified-id
//
// aspect1.cpp
// aspectRatioCalculator
//
#include <iostream>
using namespace std;
int main()
{
int a;
cout << "Enter a number to calculate its complements at multiple aspect ratios." << endl;
cin>> a >> endl;
int b = (a*9)/17;
int c = (a*9)/16;
int d = (a*5)/8;
int e = (a*4)/5;
int f = (a*3)/5;
int g = (a*3)/4;
int h = (a*2)/3;
cout << "17:9 | " << a << ":" << b << endl;
cout << "16:9 | " << a << ":" << c << endl;
cout << " 8:5 | " << a << ":" << d << endl;
cout << " 5:4 | " << a << ":" << e << endl;
cout << " 5:3 | " << a << ":" << f << endl;
cout << " 4:3 | " << a << ":" << g << endl;
cout << " 3:2 | " << a << ":" << h << endl;
}
std::endl is an output manipulator. It isn't meant to be used with input streams (which are used for input). Change this: cin >> a >> endl; to cin >> a; cout << endl;.