Input validation not functioning - c++

I am trying to parse input from a file to represent a standard deck of cards (i.e. 2C represents the two of clubs). However, my solution is not working as expected, and is declaring all inputs to be invalid. I can't see any logical errors in my code, so I wanted to get a second opinion. The code is below:
/*
* Determines if the input string is valid.
*
* A string is considered valid if it begins with either a number (2-10)
* or a letter (J/j, Q/q, K/k) to deetermine rank, followed by a letter to
* determine suit (C/c, D/d, H/h, S/s).
*/
bool inputValidator(string cardData)
{
if (cardData.length() == 2) //Input string is two characters long
{
if (cardData[0] < '2' || cardData[0] > '9'
|| cardData[0] != 'J' || cardData[0] != 'j'
|| cardData[0] != 'Q' || cardData[0] != 'q'
|| cardData[0] != 'K' || cardData[0] != 'k'
|| cardData[0] != 'A' || cardData[0] != 'a')
{
cout << "Card with data " << cardData << " has an invalid rank." << endl;
return false;
}
if (cardData[1] != 'C' || cardData[1] != 'c' //Parse suit
|| cardData[1] != 'D' || cardData[1] != 'd'
|| cardData[1] != 'H' || cardData[1] != 'h'
|| cardData[1] != 'S' || cardData[1] != 's')
{
cout << "Card with data " << cardData << " has an invalid suit." << endl;
return false;
}
return true;
}
else if (cardData.length() == 3) //Input string is three characters long
//This occurs only if the number is 10.
{
if (cardData[0] != '1' || cardData[1] != '0') //Parse rank
{
cout << "Card with data " << cardData << " has an invalid rank." << endl;
return false;
}
if (cardData[2] != 'C' || cardData[2] != 'c' //Parse suit
|| cardData[2] != 'D' || cardData[2] != 'd'
|| cardData[2] != 'H' || cardData[2] != 'h'
|| cardData[2] != 'S' || cardData[2] != 's')
{
cout << "Card with data " << cardData << " has an invalid suit." << endl;
return false;
}
return true;
}
return false;
}
If there are any logical flaws (or an inherently better way to do this), I would appreciate being told. Thanks.

You're writing clauses like this:
cardData[2] != 'D' || cardData[2] != 'd'
Which will always be true, as the variable being tested can't be both values at the same time. You probably meant to use && rather than ||.
You could certainly simplify the logic, for example by converting the input to lower or upper case before comparing it.

The problem seems to be in the way you combine your conditions. If I understand your expectation correctly, what you want for the first conditions is this:
if (!(cardData[0] > '2' && cardData[0] < '9')
&& cardData[0] != 'J' && cardData[0] != 'j'
&& cardData[0] != 'Q' && cardData[0] != 'q'
&& cardData[0] != 'K' && cardData[0] != 'k'
&& cardData[0] != 'A' && cardData[0] != 'a')
And what you want for the second condition is this:
if (cardData[1] != 'C' && cardData[1] != 'c' //Parse suit
&& cardData[1] != 'D' && cardData[1] != 'd'
&& cardData[1] != 'H' && cardData[1] != 'h'
&& cardData[1] != 'S' && cardData[1] != 's')

You can simplify the conditions a bit:
And your conditions must be changed to do what you want.
bool inputValidator(string cardData)
{
if (cardData.length() == 2) //Input string is two characters long
{
if (!((cardData[0] >= '2' && cardData[0] <= '9')
|| (cardData[0]|32) == 'j'
|| (cardData[0]|32) == 'q'
|| (cardData[0]|32) == 'k'
|| (cardData[0]|32) == 'a'))
{
cout << "Card with data " << cardData << " has an invalid rank." << endl;
return false;
}
if (!((cardData[1]|32) == 'c' //Parse suit
|| (cardData[1]|32) == 'd'
|| (cardData[1]|32) == 'h'
|| (cardData[1]|32) == 's'))
{
cout << "Card with data " << cardData << " has an invalid suit." << endl;
return false;
}
return true;
}
else if (cardData.length() == 3) //Input string is three characters long
//This occurs only if the number is 10.
{
if (!(cardData[0] == '1' || cardData[1] == '0')) //Parse rank
{
cout << "Card with data " << cardData << " has an invalid rank." << endl;
return false;
}
if (!((cardData[2]|32) == 'C' //Parse suit
|| (cardData[2]|32) == 'd'
|| (cardData[2]|32) == 'h'
|| (cardData[2]|32) == 's'))
{
cout << "Card with data " << cardData << " has an invalid suit." << endl;
return false;
}
return true;
}
return false;
}
The code duplication for the second / third character should also be refactored.

Your logic expression isn't correct, also you are duplicating code, try to simply them to functions.
bool inputValidator(string cardData)
{
if (cardData.length() == 2 && IsValidCard(cardData[0])) //Input string is two characters long
{
return IsValidSuite(cardData[1]);
}
else if(cardData.length() == 3)
{
if (isValidRank(cardData[0]))
{
return IsValidSuite(cardData[2]);
}
}
return false;
}
bool isValidRank(char c)
{
if (c =='0' || c=='1')[
{
return true;
}
return false;
}
bool IsValidCard(char c)
{
if (c > '2' && c < '9')
{
return true;
}
switch(c)
{
case 'J':
case 'j':
case 'Q':
case 'q':
case 'K':
case 'k':
case 'A':
case 'a':
return true;
}
return false;
}
bool IsValidSuite(char c)
{
switch(c)
{
case 'C':
case 'c':
case 'D':
case 'd':
case 'H':
case 'h':
case 'S':
case 's':
return true;
}
return false;
}

Related

Check if both characters are vowels or consonant and say yes, if they are different say no. Display vowels and consonants

I need to write a program where I enter 2 letters and it should display "Yes" if both letters are vowels or consonants. If they are different types it should display "NO".
At the end it should display the 2 entered vowels and consonants separately.
I've tried this code but it doesn't work for NO. Can you help me fix it?
#include <iostream>
using namespace std;
int main()
{
char a = 'a';
char b = 'b';
cout << "enter first charcter: " << endl;
cin >> a;
cout << "enter second character: " << endl;
cin >> b;
if ((a == 'a' || a == 'e' || a == 'i' || a == 'o' || a == 'u') && (b == 'a' || b == 'e' || b == 'i' || b == 'o' || b == 'u'))
{
cout << "YES" << endl;
}
else if ((a != 'a' || a != 'e' || a != 'i' || a != 'o' || a != 'u') && (b != 'a' || b != 'e' || b != 'i' || b != 'o' || b != 'u'))
{
cout << "YES" << endl;
}
else if ((a == 'a' || a == 'e' || a == 'i' || a == 'o' || a == 'u') && (b != 'a' || b != 'e' || b != 'i' || b != 'o' || b != 'u'))
{
cout << "NO" << endl;
}
else if ((a != 'a' || a != 'e' || a != 'i' || a != 'o' || a != 'u') && (b == 'a' || b == 'e' || b == 'i' || b == 'o' || b == 'u'))
{
cout << "NO" << endl;
}
return 0;
}
There is one issue in your second YES case and likely every consonant check. You are using logical OR, when it should be logical AND. Your character a can't be 'a' AND it cannot be 'e' AND etc. If a = 'e', it's still not the other vowels, and your big logical OR case returns true when it shouldn't.
You also repeat yourself too much. It's annoying to write, and if there is an error, like you have, it needs to be fixed in many places. Use DRY (Don't Repeat Yourself) and create a function that tells you if you have a vowel or not.
Then, you only need to explicitly check for just the YES cases or just the NO cases. Here's an example:
#include <iostream>
#include <string>
bool is_vowel(char c) {
std::string vowels = "aeiou";
return vowels.find(c) != std::string::npos;
}
int main() {
char first;
char second;
std::cout << "Letter: ";
std::cin >> first;
std::cout << "Letter: ";
std::cin >> second;
bool firstIsVowel = is_vowel(first);
bool secondIsVowel = is_vowel(second);
if ((firstIsVowel && secondIsVowel) || (!firstIsVowel && !secondIsVowel)) {
std::cout << "YES\n";
} else {
std::cout << "NO\n";
}
}
Output:
~/tmp
❯ ./a.out
Letter: a
Letter: i
YES
~/tmp
❯ ./a.out
Letter: b
Letter: c
YES
~/tmp
❯ ./a.out
Letter: a
Letter: h
NO
~/tmp took 4s
❯ ./a.out
Letter: h
Letter: a
NO
I have managed to make it work. Thank you guys!
#include <iostream>
using namespace std;
int main()
{
char a = 'a';
char b = 'b';
bool vowel1, vowel2;
cout << "enter first letter: " << endl;
cin >> a;
cout << "enter second letter: " << endl;
cin >> b;
vowel1 = (a == 'a' || a == 'e' || a == 'i' || a == 'o' || a == 'u');
vowel2 = (b == 'a' || b == 'e' || b == 'i' || b == 'o' || b == 'u');
if ((vowel1 && vowel2) || (!vowel1 && !vowel2))
{
cout << "YES" << endl;
}
else
{
cout << "NO" << endl;
}
if (vowel1)
{
cout << "vowel: " << a << endl;
}
else
{
cout << "consonant: " << a << endl;
}
if (vowel2)
{
cout << "vowel: " << b << endl;
}
else
{
cout << "consonant: " << b << endl;
}
return 0;
}

C++ Why does my recursion function return random characters or fail completely?

I am working on creating a recursion function that tells me when there are no more numbers in a string that I pass into it. For some reason, the recursion works fine and stops when there are no more numbers. However, when I try to return the numbers and use them in my code, I either get random characters or it will fail the program if I set the function to a variable string. Here is my code:
if (checkX(equalsLocation, math)) {
cout << "Start on the left side, x is on the right" << endl;
xSide = 1;
cout << partOneFinder(0, equalsLocation, math, "") << endl;
}
And then my function is here:
string partOneFinder(int current, int max, string math, string total) {
cout << "This is the current iteration: " << current << "and the string: " << total <<endl;
if (((math[current] == '0') || (math[current] == '1') || (math[current] == '2') || (math[current] == '3') || (math[current] == '4') || (math[current] == '5') ||
(math[current] == '6') || (math[current] == '7') || (math[current] == '8') || (math[current] == '9')) && current <= max)
{
total += math[current];
partOneFinder(current + 1, max, math, total);
} else if (math[current] == 'x'){
cout << "FOUND X!" << endl;
}
else {
string testTotal = total;
return testTotal;
}
}
What am I doing wrong?
You have to execute return statement in all execution paths of non-void function, or undefined behavior is invoked.
string partOneFinder(int current, int max, string math, string total) {
cout << "This is the current iteration: " << current << "and the string: " << total <<endl;
if (((math[current] == '0') || (math[current] == '1') || (math[current] == '2') || (math[current] == '3') || (math[current] == '4') || (math[current] == '5') ||
(math[current] == '6') || (math[current] == '7') || (math[current] == '8') || (math[current] == '9')) && current <= max)
{
total += math[current];
// return something (I guessed to return the result of recursive call)
return partOneFinder(current + 1, max, math, total);
} else if (math[current] == 'x'){
cout << "FOUND X!" << endl;
// return something (I couldn't guess)
return "";
}
else {
string testTotal = total;
return testTotal;
}
}

Tic Tac Toe with Random coin flip

Homework problem from class: I have to generate a tic tac toe game which uses a coin toss to determine who goes first. I've generated most of my code, but there are still several things/bugs I can't figure out.
I know how to do the coin flip. But, how do I get the program to choose who goes first.
Winning square or Game-ending square doesn't get X or O on it.
There is no message for a Tie game.
There is no message when you just press enter without entering any value.
#include "pch.h"
#include <iostream>
#include <string>
#include <cstdlib>
#include <time.h>
using namespace std;
void Flip_Coin();
void Do_Exercise();
void Display_Board();
void Ask_Turn();
char Check_Winner();
void Computer_Player_Turn();
char Board[3][3] = { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
int n = 0;
int main()
{
srand(time(0));
Do_Exercise();
cin.get();
return 0;
}
void Do_Exercise()
{
Flip_Coin();
while (true)
{
n++;
Display_Board();
Ask_Turn();
if (Check_Winner() == 'X')
{
cout << "Human Wins!" << endl;
break;
}
else if (Check_Winner() == 'O')
{
cout << "Computer Wins!" << endl;
break;
}
else if (Check_Winner() == 'T' && n == 9)
{
cout << "It's a draw." << endl;
break;
}
Computer_Player_Turn();
if (Check_Winner() == 'X')
{
cout << "Human Wins!" << endl;
break;
}
else if (Check_Winner() == 'O')
{
cout << "Computer Wins!" << endl;
break;
}
else if (Check_Winner() == 'T' && n == 9)
{
cout << "It's a draw." << endl;
break;
}
}
}
void Flip_Coin()
{
int Flip;
cout << "Welcome to Tic - Tac - toe.\n\n"
<< "Wait I am flipping a coin to see who goes first . . .\n\n";
Flip = rand() % 2;
if (Flip == 0)
{
cout << "Computer wins coin toss.\n\n";
}
else
{
cout << "Human wins coin toss.\n\n";
}
cout << "The board is laid out like this:\n\n";
}
void Display_Board()
{
for (int Row = 0; Row < 3; Row++)
{
for (int Column = 0; Column < 3; Column++)
{
cout << Board[Row][Column] << "\t";
}
cout << "\n\n";
}
}
void Ask_Turn()
{
string input;
while (true)
{
cout << "Enter the position to place your X: ";
cin >> input;
cout << endl;
if (input != "")
{
char entered = input.c_str()[0]; // sets char character to act in place of string
if (entered >= '1' && entered <= '9')
{
cout << "The human places a X-token at position: " << entered << "\n\n";
cout << "Current board:\n\n";
int entered_number = entered - '0'; // changes char to int form
int index = entered_number - 1;
int row = index / 3;
int col = index % 3;
char grid_position = Board[row][col];
if (grid_position == 'X' || grid_position == 'O')
{
cout << "That position is already taken. ";
}
else {
Board[row][col] = 'X';
break;
}
}
else {
cout << "You must entered in the the range of 1-9.\n";
}
}
else {
cout << "You must enter something!"; // doesnt work
}
}
}
char Check_Winner()
{
//first player
if (Board[0][0] == 'X' && Board[0][1] == 'X' && Board[0][2] == 'X')
return 'X';
if (Board[1][0] == 'X' && Board[1][1] == 'X' && Board[1][2] == 'X')
return 'X';
if (Board[2][0] == 'X' && Board[2][1] == 'X' && Board[2][2] == 'X')
return 'X';
if (Board[0][0] == 'X' && Board[1][0] == 'X' && Board[2][0] == 'X')
return 'X';
if (Board[0][1] == 'X' && Board[1][1] == 'X' && Board[2][1] == 'X')
return 'X';
if (Board[0][2] == 'X' && Board[1][2] == 'X' && Board[2][2] == 'X')
return 'X';
if (Board[0][0] == 'X' && Board[1][1] == 'X' && Board[2][2] == 'X')
return 'X';
if (Board[2][0] == 'X' && Board[1][1] == 'X' && Board[0][2] == 'X')
return 'X';
//second player
if (Board[0][0] == 'O' && Board[0][1] == 'O' && Board[0][2] == 'O')
return 'O';
if (Board[1][0] == 'O' && Board[1][1] == 'O' && Board[1][2] == 'O')
return 'O';
if (Board[2][0] == 'O' && Board[2][1] == 'O' && Board[2][2] == 'O')
return 'O';
if (Board[0][0] == 'O' && Board[1][0] == 'O' && Board[2][0] == 'O')
return 'O';
if (Board[0][1] == 'O' && Board[1][1] == 'O' && Board[2][1] == 'O')
return 'O';
if (Board[0][2] == 'O' && Board[1][2] == 'O' && Board[2][2] == 'O')
return 'O';
if (Board[0][0] == 'O' && Board[1][1] == 'O' && Board[2][2] == 'O')
return 'O';
if (Board[2][0] == 'O' && Board[1][1] == 'O' && Board[0][2] == 'O')
return 'O';
return 'T';
}
void Computer_Player_Turn()
{
while (true)
{
int computer_choice = (rand() % 9) + 1;
int row = (computer_choice - 1) / 3;
int col = (computer_choice - 1) % 3;
char grid_position = Board[row][col];
if (grid_position == 'X' || grid_position == 'O')
{
continue;
}
else {
cout << "The Computer places a O-token at position: " << computer_choice << "\n\n";
Board[row][col] = 'O';
break;
}
}
}
Here is the solution.
1) Right now you have hard-coded to call Ask_Turn first and then call Computer_Player_Turn. Instead of calling them in this way, call them first from coin flip and then let the two functions call each other when they finish.
2) Call Display_Board() before checking for winner.
3) Fixed here. You were only adding n by 1 for every 2 turns.
4) Ask for the input in a while loop, and as long as the input is empty be in the loop
So making all those changes, the code should look something similar to below.
I have tested the code here, https://onlinegdb.com/S1Qdcr63X
#include <iostream>
#include <string>
#include <cstdlib>
#include <time.h>
using namespace std;
void Flip_Coin();
void Do_Exercise();
void Display_Board();
void Ask_Turn();
char Check_Winner();
void Computer_Player_Turn();
char Board[3][3] = { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
int n = 0;
void Computer_Player_Turn();
void Ask_Turn();
int main()
{
srand(time(0));
Do_Exercise();
cin.get();
return 0;
}
void Do_Exercise()
{
Flip_Coin();
}
void Flip_Coin()
{
int Flip;
cout << "Welcome to Tic - Tac - toe.\n\n"
<< "Wait I am flipping a coin to see who goes first . . .\n\n";
Flip = rand() % 2;
if (Flip == 0)
{
cout << "Computer wins coin toss.\n\n";
Computer_Player_Turn();
}
else
{
cout << "Human wins coin toss.\n\n";
Ask_Turn();
}
}
void Display_Board()
{
for (int Row = 0; Row < 3; Row++)
{
for (int Column = 0; Column < 3; Column++)
{
cout << Board[Row][Column] << "\t";
}
cout << "\n\n";
}
}
char Check_Winner()
{
//first player
if (Board[0][0] == 'X' && Board[0][1] == 'X' && Board[0][2] == 'X')
return 'X';
if (Board[1][0] == 'X' && Board[1][1] == 'X' && Board[1][2] == 'X')
return 'X';
if (Board[2][0] == 'X' && Board[2][1] == 'X' && Board[2][2] == 'X')
return 'X';
if (Board[0][0] == 'X' && Board[1][0] == 'X' && Board[2][0] == 'X')
return 'X';
if (Board[0][1] == 'X' && Board[1][1] == 'X' && Board[2][1] == 'X')
return 'X';
if (Board[0][2] == 'X' && Board[1][2] == 'X' && Board[2][2] == 'X')
return 'X';
if (Board[0][0] == 'X' && Board[1][1] == 'X' && Board[2][2] == 'X')
return 'X';
if (Board[2][0] == 'X' && Board[1][1] == 'X' && Board[0][2] == 'X')
return 'X';
//second player
if (Board[0][0] == 'O' && Board[0][1] == 'O' && Board[0][2] == 'O')
return 'O';
if (Board[1][0] == 'O' && Board[1][1] == 'O' && Board[1][2] == 'O')
return 'O';
if (Board[2][0] == 'O' && Board[2][1] == 'O' && Board[2][2] == 'O')
return 'O';
if (Board[0][0] == 'O' && Board[1][0] == 'O' && Board[2][0] == 'O')
return 'O';
if (Board[0][1] == 'O' && Board[1][1] == 'O' && Board[2][1] == 'O')
return 'O';
if (Board[0][2] == 'O' && Board[1][2] == 'O' && Board[2][2] == 'O')
return 'O';
if (Board[0][0] == 'O' && Board[1][1] == 'O' && Board[2][2] == 'O')
return 'O';
if (Board[2][0] == 'O' && Board[1][1] == 'O' && Board[0][2] == 'O')
return 'O';
return 'T';
}
bool winner()
{
if (Check_Winner() == 'X')
{
cout << "Human Wins!" << endl;
return true;
}
else if (Check_Winner() == 'O')
{
cout << "Computer Wins!" << endl;
return true;
}
else if (Check_Winner() == 'T' && n == 9)
{
cout << "It's a draw." << endl;
return true;
}
return false;
}
void Ask_Turn()
{
n++;
string input = "";
while (true)
{
do
{
cout << "Enter the position to place your X: ";
cin >> input;
cout << endl;
}
while(input == "" || (input.c_str()[0] < '1' || input.c_str()[0] > '9'));
char entered = input.c_str()[0]; // sets char character to act in place of string
cout << "The human places a X-token at position: " << entered << "\n\n";
cout << "Current board:\n\n";
int entered_number = entered - '0'; // changes char to int form
int index = entered_number - 1;
int row = index / 3;
int col = index % 3;
char grid_position = Board[row][col];
if (grid_position == 'X' || grid_position == 'O')
{
cout << "That position is already taken. ";
n--;
Ask_Turn();
}
else {
Board[row][col] = 'X';
break;
}
}
Display_Board();
if(winner())
return;
else
Computer_Player_Turn();
}
void Computer_Player_Turn()
{
n++;
while (true)
{
int computer_choice = (rand() % 9) + 1;
int row = (computer_choice - 1) / 3;
int col = (computer_choice - 1) % 3;
char grid_position = Board[row][col];
if (grid_position == 'X' || grid_position == 'O')
{
continue;
}
else {
cout << "The Computer places a O-token at position: " << computer_choice << "\n\n";
Board[row][col] = 'O';
break;
}
}
Display_Board();
if(winner())
return;
else
Ask_Turn();
}

C++ Printing strange characters

So I have this program below and currently after I run it outputs this:
abcdefghijklmnopqrstuvwxyz
eklpyqrbgjdwtcaxzsnifvhmou
TEst
iyniЉhb�{���{���`�5b�v4b�q4b�{����8b�`�5b��`{���{����o���7�vb��{�����or��o���#`�lhb���5b��`x#
any reason why?
also the lines which are meant to be randomised currently aren't random
#include <algorithm>
#include <array>
#include <iostream>
#include <numeric>
#include <fstream>
#include <string>
using namespace std;
int main()
{
char Text[256];
array<char, 26> letters;
iota(letters.begin(), letters.end(), 'a');
for(char c: letters) //Array before shuffling
{
cout << c;
}
cout << '\n';
random_shuffle(letters.begin(), letters.end());
for(char c: letters) //After shuffling
{
cout << c;
}
cout << '\n';
cin.getline (Text,256);
for (char & c : Text)
{
if (c == 'a' || c == 'A')
{
cout << letters[0];
}
else if (c == 'b' || c == 'B')
{
cout << letters[1];
}
else if (c == 'c' || c == 'C')
{
cout << letters[2];
}
else if (c == 'd' || c == 'D')
{
cout << letters[3];
}
else if (c == 'e' || c == 'E')
{
cout << letters[4];
}
else if (c == 'f' || c == 'F')
{
cout << letters[5];
}
else if (c == 'g' || c == 'G')
{
cout << letters[6];
}
else if (c == 'h' || c == 'H')
{
cout << letters[7];
}
else if (c == 'i' || c == 'I')
{
cout << letters[8];
}
else if (c == 'j' || c == 'J')
{
cout << letters[9];
}
else if (c == 'k' || c == 'K')
{
cout << letters[10];
}
else if (c == 'l' || c == 'L')
{
cout << letters[11];
}
else if (c == 'm' || c == 'M')
{
cout << letters[12];
}
else if (c == 'n' || c == 'N')
{
cout << letters[13];
}
else if (c == 'o' || c == 'O')
{
cout << letters[14];
}
else if (c == 'p' || c == 'P')
{
cout << letters[15];
}
else if (c == 'q' || c == 'Q')
{
cout << letters[16];
}
else if (c == 'r' || c == 'R')
{
cout << letters[17];
}
else if (c == 's' || c == 'S')
{
cout << letters[18];
}
else if (c == 't' || c == 'T')
{
cout << letters[19];
}
else if (c == 'u' || c == 'U')
{
cout << letters[20];
}
else if (c == 'v' || c == 'V')
{
cout << letters[21];
}
else if (c == 'w' || c == 'W')
{
cout << letters[22];
}
else if (c == 'x' || c == 'X')
{
cout << letters[23];
}
else if (c == 'y' || c == 'Y')
{
cout << letters[24];
}
else if (c == 'z' || c == 'Z')
{
cout << letters[25];
}
else if (c == ' ')
{
cout << ' ';
}
else if (c == '/n')
{
return 0;
}
else
{
cout << c;
}
}
}
else if (c == '/n')
{
return 0;
}
Should be
else if (c == '\n')
{
return 0;
}
However, if you're looking for the end of your input, you actually want
else if (c == '\0')
{
return 0;
}
Which is a null terminator which indicates the end of a string. Basically you're getting all the junk that is stored in the entire 256 character array.
However, that doesn't help with your 29 if else statements. Try this:
if(c == ' '){ // Space
cout << ' ';
}
else if(c >= 'A' && c <= 'Z'){ // Uppercase
cout << letters[c - 'A'];
}
else if(c >= 'a' && c <= 'z'){ // Lowercase
cout << letters[c - 'a'];
}
else if(c == '\0'){ // End of string
return 0;
}
else{ // Anything else
cout << c;
}
How it works:
There are not "letters" in a computer, only binary. 'A' doesn't exist, but 01000001 which is 65 which is A does. So if you enter an 'A', your program will see a 65. However, I just happen to know that in your letters array, you have an A in position 0, so letters[0] == letters['A' - 'A']. The same logic can be used for B, C, D, ect. The same thing for the lowercase letters, they just at a different range (97-122).
Problem is here
else if (c == '/n') // '/n' is not correct
change it to
else if (c == '\0') // Check EOF

How to check for a tie game beginner C++ [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
I am creating a tic-tac-toe program and cannot get the game to accurately check if there is a tie. The tie should be declared when all numbers on the board are filled with 'X' or 'O' & there is no winner.
With the code I have now, every time I run the program it declares there is a tie. Am I placing the function wrong? I think something is wrong INSIDE of the tieGame() boolean.
using namespace std;
char board[9] { //array of characters with number placeholders for chars X and O
'1', '2', '3', '4', '5', '6', '7', '8', '9'
};
bool checkWinner(void) {
bool winner = false;
if // Check for possible winning solutions for X
((board[0] == 'X' && board[1] == 'X' && board[2] == 'X')
||
(board[3] == 'X' && board[4] == 'X' && board[5] == 'X')
||
(board[6] == 'X' && board[7] == 'X' && board[8] == 'X')
||
(board[0] == 'X' && board[4] == 'X' && board[8] == 'X')
||
(board[2] == 'X' && board[4] == 'X' && board[6] == 'X')
||
(board[0] == 'X' && board[3] == 'X' && board[6] == 'X')
||
(board[1] == 'X' && board[4] == 'X' && board[7] == 'X')
||
(board[2] == 'X' && board[5] == 'X' && board[8] == 'X'))
{
winner = 1; // Winner is true if conditions are met
cout << "Player 1 Wins!" << endl;
}
else if // Check for possible winning solutions for O
((board[0] == 'O' && board[1] == 'O' && board[2] == 'O')
||
(board[3] == 'O' && board[4] == 'O' && board[5] == 'O')
||
(board[6] == 'O' && board[7] == 'O' && board[8] == 'O')
||
(board[0] == 'O' && board[4] == 'O' && board[8] == 'O')
||
(board[2] == 'O' && board[4] == 'O' && board[6] == 'O')
||
(board[0] == 'O' && board[3] == 'O' && board[6] == 'O')
||
(board[1] == 'O' && board[4] == 'O' && board[7] == 'O')
||
(board[2] == 'O' && board[5] == 'O' && board[8] == 'O'))
{
winner = 1; // winner is True if conditions are met
cout << "Player 2 Wins!" << endl;
}
return winner; // Is there a winner?
}
bool tieGame() {
bool tiegame = false;
if // check for tie
((board[0] == 'X' || 'O') && (board[1] == 'X' || 'O') && (board[2] == 'X' || 'O')
&&
(board[3] == 'X' || 'O') && (board[4] == 'X' || 'O') && (board[5] == 'X' || 'O')
&&
(board[6] == 'X' || 'O') && (board[7] == 'X' || 'O') && (board[8] == 'X' || 'O'))
{
tiegame = 1;
cout << "The game is a tie! Play again!" << endl;
}
else {
tiegame = 0;
}
return tiegame; // Is the game a tie?
}
void displayBoard(void) { //Displays the game board
int index; // used to access the array
index = 0;
cout << endl;
cout << board[index] << "|" << board[index+1] << "|" << board[index+2] << endl;
cout << "-----" << endl;
cout << board[index+3] << "|" << board[index+4] << "|" << board[index+5] << endl;
cout << "-----" << endl;
cout << board[index+6] << "|" << board[index+7] << "|" << board[index+8] << endl;
}
void tictactoe(void) { //Main function; displays board and inputs player moves
int movePosition; // used to track user input and replace array indexes with the user input
cout << "Player 1 is X, player 2 is O" << endl;
for (int i=0; i < 5; i++) {
if (tieGame() ) {
cout << "Tie game!" << endl;
return;
}
displayBoard(); // Display game board with updated characters
if (checkWinner() ) //if winner is TRUE, return "Winner" and exit game.
{
cout << "Good Game!" << endl;
return;
}
cout << "Player 1, Enter the space number where you would like to place X" << endl;
cin >> movePosition; // Retrieve user input & call it 'movePosition'
while ((board[movePosition - 1] == 'X' || board[movePosition - 1] == 'O')) { //Check to make sure a user has not
cout << "This space is already taken. Please choose an open space." << endl; // attempted to enter a
cin >> movePosition; // value that has already been entered
}
board[movePosition - 1] = 'X';
displayBoard(); // Display game board with updated characters
if (checkWinner() ) //if winner is TRUE, return "Winner" and exit game.
{
cout << "Good Game!" << endl;
return;
}
cout << "Player 2, Enter the space number where you would like to place O" << endl;
cin >> movePosition;
while ((board[movePosition - 1] == 'X' || board[movePosition - 1] == 'O')) {
cout << "This space is already taken. Please choose an open space." << endl;
cin >> movePosition;
}
board[movePosition - 1] = 'O';
}
}
int main (int argc, char *argv[]) {
tictactoe();
}
The conditions like the following are wrong:
(board[0] == 'X' || 'O')
Because of C++ operator precedence and evaluation rules, the compiler understands it as:
(board[0] == 'X') || ('O' != 0)
The second part is, of course, always true, so it always succeeds for every field and therefore for the whole board.
You would need to write it explicitly in two comparisons like this:
(board[0] == 'X' || board[0] == 'O')
For the future, a better solution than a bunch of conditions would be a loop, for example:
bool tieGame()
{
for (int i = 0; i < 9; i++) {
if (board[i] != 'X' && board[i] != 'O') {
// Some field is empty, not a tie
return false;
}
}
// All fields are either 'X' or 'O'
cout << "The game is a tie! Play again!" << endl;
return true;
}
And even more better, as Nenad wrote in his answer, just count the number of free spaces left (or the used fields) -- that's just one variable comparison instead of going through the whole board each time.
You can check if it's a tie by having a counter
int freeSpaces = 9;
Which you will decrement each time players fills an empty slot on board.
Then check
if (freeSpaces == 0 && !winner) tieGame = true;
else tieGame = false;
The expressions of the form (board[0] == 'X' || 'O') always evaluate to true since 'O' is a non-zero value (79 to be exact). As a result, all your checks for tieGame are true. What you want is (board[0] == 'X' || board[0] == 'O').