boolean check behaving unexpectedly when returning value - c++

#include <iostream>
#include <string>
bool is_favorite(std::string word)
{
int isTrueCounter = 0;
std::cout << "\nisTrueCounter: " << isTrueCounter;
if (isTrueCounter == word.length())
{
return true;
}
else {
for (int i = 0; i < word.length(); i++)
{
if (word[i] == 'a' || word[i] == 'A')
{
isTrueCounter++;
std::cout << "\nisTrue +1 ";
}
else
{
if (word[i] == 'b' || word[i] == 'B')
{
isTrueCounter++;
std::cout << "\nisTrue +1 ";
}
else
{
if (word[i] == 'c' || word[i] == 'C')
{
isTrueCounter++;
std::cout << "\nisTrue +1 ";
}
else {
if (word[i] == 'd' || word[i] == 'D')
{
isTrueCounter++;
std::cout << "\nisTrue +1 ";
}
else
{
if (word[i] == 'e' || word[i] == 'E')
{
isTrueCounter++;
std::cout << "\nisTrue +1 ";
}
else
{
if (word[i] == 'f' || word[i] == 'F')
{
isTrueCounter++;
std::cout << "\nisTrue +1 ";
}
}
}
}
}
}
} //for
}
std::cout << "\nisTrueCounter: " << isTrueCounter;
}
int main()
{
std::string favWord;
std::cout << "Please input your word: ";
std::cin >> favWord;
std::cout << "\nFavWord Length: " << favWord.length();
if (is_favorite(favWord) == true)
{
std::cout << "\nThis is a favorite word!";
}
else
{
std::cout << "\nThis is NOT a favorite word!";
}
}
Here is my code, I am attempting to pass a string into a boolean function that will return true if all criteria is met by the string passed. The qualifications for a "passing" word is that it contains ONLY the letters a-f (of either case) so words like AaAa or Cafe or Bad should pass, but after trial and error, even words that I know should pass are failing and I feel like I am keeping track of the letters' qualifications properly, by incrementing on a variable (isTrueCounter) to count if all the characters in the string are qualifying characters, but even when the function should be returning true, the false case displays. What am I doing wrong? What am I not seeing? When I run this code it will display the variables to help keep track of when stuff is being added to the holder variables but even when all the numbers are right the false case displays.

You didn't return anything, you can do this in many way. For example from your code, return false immediatly after condition is not true (not in a-f).
bool is_favorite(std::string word)
{
int isTrueCounter = 0;
std::cout << "\nisTrueCounter: " << isTrueCounter;
if (isTrueCounter == word.length())
{
return true;
}
else {
for (int i = 0; i < word.length(); i++)
{
if (word[i] == 'a' || word[i] == 'A')
{
isTrueCounter++;
std::cout << "\nisTrue +1 ";
}
else
{
if (word[i] == 'b' || word[i] == 'B')
{
isTrueCounter++;
std::cout << "\nisTrue +1 ";
}
else
{
if (word[i] == 'c' || word[i] == 'C')
{
isTrueCounter++;
std::cout << "\nisTrue +1 ";
}
else {
if (word[i] == 'd' || word[i] == 'D')
{
isTrueCounter++;
std::cout << "\nisTrue +1 ";
}
else
{
if (word[i] == 'e' || word[i] == 'E')
{
isTrueCounter++;
std::cout << "\nisTrue +1 ";
}
else
{
if (word[i] == 'f' || word[i] == 'F')
{
isTrueCounter++;
std::cout << "\nisTrue +1 ";
} else { //add this else clause
return false;
}
}
}
}
}
}
} //for
}
std::cout << "\nisTrueCounter: " << isTrueCounter;
}
But some of your code can improve.
1.I don't know why you add these lines. This will never true unless word.length() is 0.
if (isTrueCounter == word.length())
{
return true;
}
2.Don't split condition that can write in one if into many if, it's a bad behavior.
if (word[i] == 'a' || word[i] == 'A')
{
isTrueCounter++;
std::cout << "\nisTrue +1 ";
}
else
{
if (word[i] == 'b' || word[i] == 'B')
{
isTrueCounter++;
std::cout << "\nisTrue +1 ";
}
This is better.
if (word[i] == 'a' || word[i] == 'A' || word[i] == 'b' || word[i] == 'B')
{
isTrueCounter++;
std::cout << "\nisTrue +1 ";
}
3.You can compare char, instead of check if word[i] == 'a'... Use > < >= <=.
if (word[i] >= 'a' && word[i] <= 'f' || word[i] >= 'A' && word[i] <= 'F')
{
isTrueCounter++;
std::cout << "\nisTrue +1 ";
}
4.string is already in iostream you don't have to import it again.
In conclusion your code can turn into this
bool is_favorite(std::string word)
{
int isTrueCounter = 0;
for (int i = 0; i < word.length(); i++)
{
if (word[i] >= 'a' && word[i] <= 'f' || word[i] >= 'A' && word[i] <= 'F') {
isTrueCounter++;
std::cout << "\nisTrue +1 ";
} else {
return false;
}
}
std::cout << "\nisTrueCounter: " << isTrueCounter;
return true;
}

Related

What's wrong with this Minimax implementation for Tic-Tac-Toe?

I wanted to expand on an older Tic Tac Toe game I made where two players can play versus each other. I want to give the user the option of playing against a difficult AI. The issue is that the AI won't pick the best move all the time. For instance, it will always pick spot 1 if going first. If the user picks spot 2, it will pick spot 4. After this, no matter what the user picks (besides spot 7) the AI won't pick spot 7. Victory for the AI is far from inevitable (the user can still win the game at this point), so that's not the problem.
Any help is appreciated. Thanks!
I'm positive the problem is with my minimax or bestmove functions. It may just be that I haven't properly implemented by minimax function, but I can't spot the issue.
#include <iostream>
#include <iomanip>
#include <string>
#include <array>
// This is a program to play a single game of tic-tac-toe
// between either two human (non-AI) players or an AI.
using namespace std;
void PrintBoard(array <char, 9>);
int programprogress();
int checkwin(array <char, 9>);
int minimax(array <char, 9>, int, int, bool);
int bestMove(array <char, 9>, int);
int Opposite(int);
char PlayerSymbol(int);
const int SIZE = 9;
array <char, SIZE> Pos = { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
int player_number = 1;
int k = -11, result;
bool AI = false, first;
// Global variables used by 2 or more functions.
// Array had to be initialized with numbers instead of blank spaces
// because the check win function wouldn't work properly.
int main()
{
string userinp;
cout << "This is tic tac toe! Here's your board!" << endl;
PrintBoard(Pos);
cout << "Would you like to play versus an AI? (Y/N)" << endl;
cin >> userinp;
if (userinp[0] == 'Y')
{
cout << "Excellent! Would you like to start first, or second? (F/S)" << endl;
cin >> userinp;
if (userinp[0] == 'F')
{
cout << "You will start first!" << endl;
first = false;
player_number = 2;
}
else
{
cout << "The AI will start first!" << endl;
first = true;
}
AI = true;
}
else
{
cout << "Excellent! Your game will start soon." << endl;
}
result = programprogress();
player_number--;
PrintBoard(Pos);
if (result == 1)
cout << endl << "Player " << player_number << " has won!!!\n";
else if (result == 10)
cout << endl << "The AI has won! Better luck next time!\n";
else if (result = -10)
cout << endl << "You beat the world's best AI! Congratulations!\n";
else
cout << endl << "The game has been drawn!" << endl;
return 0;
}
void PrintBoard(array <char, 9> Pos)
{
system("cls");
cout << setw(6) << "|" << setw(6) << "|" << endl << setw(3) << Pos[0] << setw(3) << "|" << setw(3) << Pos[1] << setw(3) << "|" << setw(3) << Pos[2] << " TIC TOE" << endl;
cout << "_____|_____|_____" << endl;
cout << setw(6) << "|" << setw(6) << "|" << endl << setw(3) << Pos[3] << setw(3) << "|" << setw(3) << Pos[4] << setw(3) << "|" << setw(3) << Pos[5] << " TAC " << endl;
cout << "_____|_____|_____" << endl;
cout << setw(6) << "|" << setw(6) << "|" << endl << setw(3) << Pos[6] << setw(3) << "|" << setw(3) << Pos[7] << setw(3) << "|" << setw(3) << Pos[8] << " TIC TOE " << endl;
cout << " | |" << endl;
}
int programprogress()
{
while (k == -11 && AI)
{
bool InvalidChoice = false;
char letter;
//player_number = (player_number % 2) ? 1 : 2;
int PlayerChoice;
if (player_number == 2)
{
cout << endl << "What is your move?" << endl;
cin >> PlayerChoice;
while ((PlayerChoice < 1) || (PlayerChoice > 9))
{
cout << "That's an invalid choice! Please choose a number that is 1-9!" << endl;
cin >> PlayerChoice;
}
PlayerChoice--;
letter = (!first) ? 'X' : 'O';
if (Pos[PlayerChoice] == '1' || Pos[PlayerChoice] == '2' || Pos[PlayerChoice] == '3' || Pos[PlayerChoice] == '4' || Pos[PlayerChoice] == '5' || Pos[PlayerChoice] == '6' || Pos[PlayerChoice] == '7' || Pos[PlayerChoice] == '8' || Pos[PlayerChoice] == '9')
{
Pos[PlayerChoice] = letter;
PrintBoard(Pos);
}
/*else
{
cout << "That space is already taken!" << endl;
player_number--;
}*/
k = checkwin(Pos);
if (k != -11)
k = k * -10;
player_number = 1;
}
else
{
cout << endl << "The computer has made its move!" << endl;
letter = (first) ? 'X' : 'O';
if (first)
PlayerChoice = bestMove(Pos, 1);
else
PlayerChoice = bestMove(Pos, 2);
Pos[PlayerChoice] = letter;
PrintBoard(Pos);
k = checkwin(Pos);
if (k != -11)
k = k * 10;
player_number = 2;
}
}
while (k == -11 && !AI)
{
bool InvalidChoice = false;
char letter;
player_number = (player_number % 2) ? 1 : 2;
int PlayerChoice;
cout << endl << "What's player " << player_number << "'s move?" << endl;
cin >> PlayerChoice;
while ((PlayerChoice < 1) || (PlayerChoice > 9))
{
cout << "That's an invalid choice! Please choose a number that is 1-9!" << endl;
cin >> PlayerChoice;
}
PlayerChoice--;
letter = (player_number == 1) ? 'X' : 'O';
if (Pos[PlayerChoice] == '1' || Pos[PlayerChoice] == '2' || Pos[PlayerChoice] == '3' || Pos[PlayerChoice] == '4' || Pos[PlayerChoice] == '5' || Pos[PlayerChoice] == '6' || Pos[PlayerChoice] == '7' || Pos[PlayerChoice] == '8' || Pos[PlayerChoice] == '9')
{
Pos[PlayerChoice] = letter;
PrintBoard(Pos);
}
else
{
cout << "That space is already taken!" << endl;
player_number--;
}
k = checkwin(Pos);
player_number++;
}
return k;
}
int checkwin(array <char, SIZE> Pos)
{
if (Pos[0] == Pos[1] && Pos[1] == Pos[2])
return 1;
else if (Pos[3] == Pos[4] && Pos[4] == Pos[5])
return 1;
else if (Pos[6] == Pos[7] && Pos[7] == Pos[8])
return 1;
else if (Pos[0] == Pos[3] && Pos[3] == Pos[6])
return 1;
else if (Pos[1] == Pos[4] && Pos[4] == Pos[7])
return 1;
else if (Pos[2] == Pos[5] && Pos[5] == Pos[8])
return 1;
else if (Pos[0] == Pos[4] && Pos[4] == Pos[8])
return 1;
else if (Pos[2] == Pos[4] && Pos[4] == Pos[6])
return 1;
else if (Pos[0] != '1' && Pos[1] != '2' && Pos[2] != '3'
&& Pos[3] != '4' && Pos[4] != '5' && Pos[5] != '6'
&& Pos[6] != '7' && Pos[7] != '8' && Pos[8] != '9')
return 0;
else
return -11;
}
int minimax(array <char, SIZE> newpos, int depth, int player, bool opp)
{
int scale = 0;
if ((player == 1 && first) || (player == 2 && !first))
scale = 10;
else
scale = -10;
//cout << scale;
int score = scale*checkwin(newpos);
if (score < 0)
score += depth;
else if (score > 0)
score -= depth;
if (score == -10 || score == 10 || score == 0)
return score;
if (opp)
{
int best = -1000;
for (int i = 0; i < SIZE; i++)
{
if (newpos[i] != 'X' && newpos[i] != 'O')
{
char temp = newpos[i];
newpos[i] = PlayerSymbol(player);
best = max(best, minimax(newpos, depth + 1, Opposite(player), !opp));
newpos[i] = temp;
}
}
return best;
}
else
{
int best = 1000;
for (int i = 0; i < SIZE; i++)
{
if (newpos[i] != 'X' && newpos[i] != 'O')
{
char temp = newpos[i];
newpos[i] = PlayerSymbol(player);
best = min(best, minimax(newpos, depth + 1, Opposite(player), !opp));
newpos[i] = temp;
}
}
return best;
}
}
int bestMove(array <char, SIZE> newpos, int player)
{
int best = -1000;
int bestpos = -1;
for (int i = 0; i < SIZE; i++)
{
if (newpos[i] != 'X' && newpos[i] != 'O')
{
char temp = newpos[i];
newpos[i] = PlayerSymbol(player);
int move = minimax(newpos, 0, player, !first);
newpos[i] = temp;
if (move > best)
{
//cout << "I like pineapple on pizza" << endl;
bestpos = i;
best = move;
}
/*if (move == best)
{
cout << "I like pineapple on pizza" << endl;
}*/
}
}
cout << bestpos;
return bestpos;
}
int Opposite(int x)
{
if (x == 1)
return 2;
else
return 1;
}
char PlayerSymbol(int x)
{
if (x == 1)
return 'X';
else
return 'O';
}
An out of bounds error due to the -1 value of bestpos. I'm not sure how to change this, though.
There are 4 issues that I could find. Solving them seems to lead to the intended behavior.
Firstly, when you call minimax(newpos, 0, player, !first); from inside the bestMove function, you pass player rather than Opposite(player), indicating that the first minimax step will be performed by the same player as the bestMove step. In other words: The AI makes two successive moves for itself. Therefore player needs to be changed to Opposite(player).
Secondly, minimax has a bool variable named opp that seems to indicate whether it is the AI or its opponent making the move. For the first minimax step, opp is set to !first, indicating that only if the AI goes first, the opponent will make a move after the AI. That is incorrect. It is always the opponent making a move after the AI. So bestMove should call minimax with true rather than !first. As an aside, opp is redundant, because you can use (player == 1 && first) || (player == 2 && !first) to check whether it's the AI or its opponent making the move.
Thirdly, the scale is set the wrong way around. With (player == 1 && first) || (player == 2 && !first) you check whether its the AI making a move. But you do that in the next minimax step, after the potentially winning move. So if the AI is making a move and the game is already won, then the opponent made the winning move, not the AI. Ergo, the scale should be
if ((player == 1 && first) || (player == 2 && !first))
scale = -10;
else
scale = 10;
instead.
Lastly, you check whether the score is 10 or -10 after adding the depth. If depth is not 0, then this check will always fail. So beyond depth 0, the AI can only see a draw, never a win. You could instead write
if (score == -10 || score == 10 || score == 0)
{
if (score < 0)
score += depth;
else if (score > 0)
score -= depth;
return score;
}
Hope this answers your question fully.

C++ Erasing Vector element

vector<char>teikums(count);
Having problems when trying to erase a element from vector.
For Example i input:
a b c d e f
and when trying to erase a element
teikums.erase(teikums.begin() + 3);
it will output
a b d e e f
Been trying to figure out why it doesn't output
a b c d f
Code:
int main() {
system("cls"); // Notira Ekranu
patsk = 0; // Pieskir vertibu
cout << "Ievadi Massiva lielumu: ";
cin >> count;
vector<char>teikums(count);
cout << "Vai aizpildit burtus automatiski (Y/Cits): ";
cin >> aizp;
srand(time(NULL));
cout << "\n";
if (aizp == 'y' || aizp == 'Y') {
for (int i = 1; i <= count; i++) {
teikums[i] = (rand() % 26) + 'a';
cout << teikums[i] << " ";
}
}
else {
do {
cout << "Ievadi " << count << " burtus vienu pa vienam\n";
for (i = 1; i <= count; i++) {
cin >> teikums[i];
if (!((teikums[i] >= 'a' && teikums[i] <= 'z') || (teikums[i] >=
'A' && teikums[i] <= 'Z'))) {
cout << "Kluda! Ievadiet tikai burtus\n";
i = i - 1;
}
}
}
while (i <= count);
}
teikums.erase(teikums.begin() + 3);
do {
cout << "\n";
cout << "\n1.Izpildit individualo uzdevumu";
cout << "\n2.Pievienot jaunu elementu vektoram";
cout << "\n3.Dzest elementu no vektroa";
cout << "\n4.Sakt programmu no jauna";
cout << "\n5.Beigt Darbu";
cout << "\nIevadi izveli : ";
cin >> opcijas;
switch (opcijas) {
case 1:
izpildit_uzdevumu(teikums);
break;
case 2:
pievienot_elementu(teikums, count);
break;
case 3:
dzest_elementu(teikums);
break;
case 4:
no_jauna();
break;
case 5:
return 0;
}
}
while (opcijas != 4);
getch();
}
void izpildit_uzdevumu(vector<char>& teikums) {
patskani = 0;
for (i = 0; i <= count; i++) {
cout << " " << teikums[i];
}
cout << "\nIzmantotie Patskani:";
for (i = 1; i < count; i = i + 2) {
if (teikums[i] == 'a' || teikums[i] == 'e' || teikums[i] == 'i' ||
teikums[i] == 'o' || teikums[i] == 'u' || teikums[i] == 'A' ||
teikums[i] == 'E' || teikums[i] == 'I' || teikums[i] == 'O' ||
teikums[i] == 'U') {
patskani = patskani + 1;
cout << teikums[i];
}
}
cout << "\nPatskanu Skaits: " << patskani;
}
When you erase the element, you should also decrease count, or use teikums.size() to monitor the size of your vector.
You had 6 elements, you did:
teikums.erase(teikums.begin() + 3);
which erases the 4th element, thus now the vector has 5 elements in number.
Check the example in the ref too.

TicTacToe in C++ won't work? Help please

So I'm trying to get this simple Multiplayer TicTacToe game to work in eclipse (C++ version), but it seems that whenever I run my program, only for the top row of a TicTacToe can people win.
Here's my code:
#include <iostream>
using namespace std;
string board[3][3]; // creates the game board
void draw(int player, int num)
{
num--;
int row = num/3;
int col = num%3;
if ( player == 1 ) board[row][col] = "X";
else board[row][col] = "O";
}// end draw method
bool checkWin(int num)
{
bool win = false;
if (num == 1 || num == 2 || num == 3)
{
if ( board[0][0] == board[0][1] && board[0][0] == board[0][2])
return true;
}
if (num == 4 || num == 5 || num == 6)
{
if ( board[1][0] == board[1][1] && board[1][0] == board[1][2])
return true;
}
if (num == 7 || num == 8 || num == 9)
{
if ( board[2][0] == board[2][1] && board[2][0] == board[2][2])
return true;
}
if (num == 1 || num == 4 || num == 7)
{
if ( board[0][0] == board[1][0] && board[0][0] == board[2][0])
return true;
}
if (num == 2 || num == 5 || num == 8)
{
if ( board[0][1] == board[1][1] && board[0][1] == board[2][1])
return true;
}
if (num == 3 || num == 6 || num == 9)
{
if ( board[0][2] == board[1][2] && board[0][2] == board[2][2])
return true;
}
if (num == 1 || num == 5 || num == 9)
{
if ( board[0][0] == board[1][1] && board[0][0] == board[2][2])
return true;
}
if (num == 3 || num == 5 || num == 7)
{
if ( board[0][2] == board[1][1] && board[0][2] == board[2][0])
return true;
}
return win;
} // end checkWin method
int main()
{
cout << "C++ TIC TAC TOE GAME" << endl;
cout << "The board is labeled from 1-9 in row-major order." << endl;
bool winner = false;
int turns = 0;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
board[i][j] = "-";
cout << board[i][j] << " ";
}
cout << endl; // "enters" to next line
} // prints the game board 2d array
while (winner == false && turns < 9)
{
int player = 0;
int placedAt = 0;
if ( turns % 2 == 0 )
{
int num1;
cout << "Player 1 enter what space to place X: ";
cin >> num1;
player = 1;
draw(player,num1);
placedAt = num1;
}
else
{
int num2;
cout << "Player 2 enter what space to place O: ";
cin >> num2;
player = 2;
draw(player,num2);
placedAt = num2;
}
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
cout << board[i][j] << " ";
}
cout << endl; // "enters" to next line
} // prints the game board 2d array
winner = checkWin(placedAt);
if (winner == true)
{
cout << endl << "Player " << player << " WINS!";
}
turns++;
cout << endl;
} // end while loop
if (winner == false) cout << endl << "NO ONE WON!";
return 0;
} // end main method
Change string board[3][3]; to char board[3][3]; , and "X" to 'X'.
The corrected code below should compile just fine.
#include <iostream>
using namespace std;
char board[3][3]; // creates the game board
void draw(int player, int num)
{
num--;
int row = num/3;
int col = num%3;
if ( player == 1 ) board[row][col] = 'X';
else board[row][col] = 'O';
}// end draw method
bool checkWin(int num)
{
bool win = false;
if (num == 1 || num == 2 || num == 3)
{
if ( board[0][0] == board[0][1] && board[0][0] == board[0][2])
return true;
}
if (num == 4 || num == 5 || num == 6)
{
if ( board[1][0] == board[1][1] && board[1][0] == board[1][2])
return true;
}
if (num == 7 || num == 8 || num == 9)
{
if ( board[2][0] == board[2][1] && board[2][0] == board[2][2])
return true;
}
if (num == 1 || num == 4 || num == 7)
{
if ( board[0][0] == board[1][0] && board[0][0] == board[2][0])
return true;
}
if (num == 2 || num == 5 || num == 8)
{
if ( board[0][1] == board[1][1] && board[0][1] == board[2][1])
return true;
}
if (num == 3 || num == 6 || num == 9)
{
if ( board[0][2] == board[1][2] && board[0][2] == board[2][2])
return true;
}
if (num == 1 || num == 5 || num == 9)
{
if ( board[0][0] == board[1][1] && board[0][0] == board[2][2])
return true;
}
if (num == 3 || num == 5 || num == 7)
{
if ( board[0][2] == board[1][1] && board[0][2] == board[2][0])
return true;
}
return win;
} // end checkWin method
int main()
{
cout << "C++ TIC TAC TOE GAME" << endl;
cout << "The board is labeled from 1-9 in row-major order." << endl;
bool winner = false;
int turns = 0;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
board[i][j] = '-';
cout << board[i][j] << ' ';
}
cout << endl; // "enters" to next line
} // prints the game board 2d array
while (winner == false && turns < 9)
{
int player = 0;
int placedAt = 0;
if ( turns % 2 == 0 )
{
int num1;
cout << "Player 1 enter what space to place X: ";
cin >> num1;
player = 1;
draw(player,num1);
placedAt = num1;
}
else
{
int num2;
cout << "Player 2 enter what space to place O: ";
cin >> num2;
player = 2;
draw(player,num2);
placedAt = num2;
}
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
cout << board[i][j] << " ";
}
cout << endl; // "enters" to next line
} // prints the game board 2d array
winner = checkWin(placedAt);
if (winner == true)
{
cout << endl << "Player " << player << " WINS!";
}
turns++;
cout << endl;
} // end while loop
if (winner == false) cout << endl << "NO ONE WON!";
return 0;
} // end main method

C++ TicTacToe errorClass problems [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I am trying to learn C++ and I have made litte tictactoe game but somethings wrong. I've tried to make a error bool. But somethings wrong with it. I've tried for 2 hours now and I can't find out how to solve the problem. Whats wrong? When I type in 2 2, which is should work, The error message pops up and it says invalid move. But the X or O will still pop up on the board
Here's the code:
#include <iostream>
const int rows = 3;
const int elements = 3;
char SetPlayer;
char SetEnemyPlayer;
char chooseTurn = 0;
char board[rows][elements];
void Clear()
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < elements; j++)
{
board[i][j] = ' ';
}
}
}
void Show()
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < elements; j++)
{
std::cout << " " << board[i][j] << " |";
}
std::cout << std::endl;
std::cout << "------------" << std::endl;
}
}
void StartTurn()
{
std::cout << "Which character would you like to be? (X or O) "; std::cin >> chooseTurn;
switch (chooseTurn){
case 'O':
std::cout << "You have choosen O" << std::endl << std::endl;
chooseTurn = 'O';
break;
case 'X':
std::cout << "You have choosen X" << std::endl << std::endl;
chooseTurn = 'X';
break;
default:
std::cout << "Enter a valid character" << std::endl;
StartTurn();
}
}
bool PlayerAttack(int x, int y, char PlayerAttackChar)
{
if (board[x][y] == ' ')
{
board[x][y] = PlayerAttackChar;
return true;
}
return false;
}
bool EnemyAttack(int x, int y, char PlayerAttackChar)
{
if (board[x][y] == ' ')
{
board[x][y] = PlayerAttackChar;
return true;
}
return false;
}
bool OWinner()
{
if (board[0][0] == 'O' && board[0][1] == 'O' && board[0][2] == 'O' ||
board[0][0] == 'O' && board[1][0] == 'O' && board[2][0] == 'O' ||
board[0][0] == 'O' && board[1][1] == 'O' && board[2][2] == 'O' ||
board[0][1] == 'O' && board[1][1] == 'O' && board[2][1] == 'O' ||
board[0][2] == 'O' && board[1][2] == 'O' && board[2][0] == 'O' ||
board[0][2] == 'O' && board[1][2] == 'O' && board[2][2] == 'O' ||
board[1][0] == 'O' && board[1][1] == 'O' && board[1][2] == 'O' ||
board[2][0] == 'O' && board[2][1] == 'O' && board[2][2] == 'O')
{
std::cout << "You won!" << std::endl;
return true;
}
return false;
}
bool XWinner()
{
if (board[0][0] == 'X' && board[0][1] == 'X' && board[0][2] == 'X' ||
board[0][0] == 'X' && board[1][0] == 'X' && board[2][0] == 'X' ||
board[0][0] == 'X' && board[1][1] == 'X' && board[2][2] == 'X' ||
board[0][1] == 'X' && board[1][1] == 'X' && board[2][1] == 'X' ||
board[0][2] == 'X' && board[1][2] == 'X' && board[2][0] == 'X' ||
board[0][2] == 'X' && board[1][2] == 'X' && board[2][2] == 'X' ||
board[1][0] == 'X' && board[1][1] == 'X' && board[1][2] == 'X' ||
board[2][0] == 'X' && board[2][1] == 'X' && board[2][2] == 'X')
{
std::cout << "You won!" << std::endl;
return true;
}
return false;
}
bool error(int x, int y)
{
if (board[x][y] != ' ')
{
return true;
}
}
int main()
{
Clear();
StartTurn();
Show();
if (chooseTurn == 'X')
{
SetPlayer = 'X';
SetEnemyPlayer = 'O';
}
else
{
SetPlayer = 'O';
SetEnemyPlayer = 'X';
}
int pos1 = 0;
int pos2 = 0;
bool Xwinner = false;
bool Owinner = false;
int PlayerTurn = 0;
while (!Xwinner && !Owinner)
{
while (PlayerTurn == 0)
{
bool yourAttack = false;
PlayerTurn++;
std::cout << SetPlayer << " turn. Please input a coordinate: "; std::cin >> pos1 >> pos2; std::cout << std::endl;
pos1 -= 1;
pos2 -= 1;
if (error(pos1, pos2))
{
std::cout << "Please enter a valid position (1 to 3)" << std::endl;
PlayerTurn = 0;
}
PlayerAttack(pos1, pos2, SetPlayer);
Show();
}
while (PlayerTurn != 0)
{
PlayerTurn = 0;
std::cout<< SetEnemyPlayer << " turn. Please input a coordinate: "; std::cin >> pos1 >> pos2; std::cout << std::endl;
pos1 -= 1;
pos2 -= 1;
if (error(pos1, pos2))
{
std::cout << "Please enter a valid position (1 to 3)" << std::endl;
PlayerTurn = 1;
}
EnemyAttack(pos1, pos2, SetEnemyPlayer);
Show();
// AI
}
Xwinner = XWinner();
Owinner = OWinner();
}
}
Your error function will not return anything if the move is valid, and cause undefined behavior. You want to add a return false; after the if statement. Also you want to make sure x and y are in the bounds of the array.
bool error(int x, int y)
{
if(x > 2 || y > 2 || board[x][y] != ' ')
{
return true;
}
return false;
}
Also, you probably want you if(error) checks to be in a loop. So the game won't continue until the player enters a valid move.
while (error(pos1, pos2))
{
std::cout << "Please enter a valid position (1 to 3)" << std::endl;
PlayerTurn = 0;
}

program skip over getline

I am suppose to create a program such that when 'y' is entered it will execute the code in the first do-while loop. however, when 'y' is entered it just skips over the chunk of codes!
Enter a phone symbols:
a
2
Continue (Y/y): y
Enter a phone symbols:
Continue (Y/y):
Is there anyway I can solve this without using cin.ignore as it changes the layout. Thanks in advance!
#include <iostream>
#include <cstdlib>
#include <cctype>
#include <iomanip>
#include <cstring>
const int MAX = 100;
using namespace std;
int getInt(char);
bool isValidChar(char);
int main()
{
int num;
int j = 0;
char name, conti;
char alpha[MAX];
do {
cout << "Enter a phone symbols: " << endl;
cin.getline(alpha, MAX);
// cin.ignore(100, '\n');
while (alpha[j] != '\0')
{
name = alpha[j];
if (isValidChar(name) == true)
{
num = getInt(name);
if (num == -1)
{
cout << "-";
}
else
{
cout << num;
}
}
else
{
cout << " - Invalid Char " << name << " found - rejected";
}
j++;
} // end while
cout << endl;
do {
cout << "\nContinue (Y/y): ";
cin >> conti;
cout << "\n" << endl;
conti = tolower(conti);
if (conti == 'n')
{
exit(0);
}
} while (conti != 'n' && conti != 'y');
} while (conti == 'y');
}
int getInt(char input)
{
int result;
char value;
value = tolower(input);
if ((value >= 'a' && value <= 'c'))
{
result = 2;
}
else if ((value >= 'd' && value <= 'f'))
{
result = 3;
}
else if ((value >= 'g' && value <= 'i'))
{
result = 4;
}
else if ((value >= 'j' && value <= 'l'))
{
result = 5;
}
else if ((value >= 'm' && value <= 'o'))
{
result = 6;
}
else if ((value >= 'p' && value <= 's'))
{
result = 7;
}
else if ((value >= 't' && value <= 'v'))
{
result = 8;
}
else if ((value >= 'w' && value <= 'z'))
{
result = 9;
}
else if (value == ' ')
{
result = -1;
}
return result;
}
bool isValidChar(char value)
{
if (isalpha(value) || value == ' ')
{
return true;
}
else
{
return false;
}
}
What do you mean as: Is there anyway I can solve this without using cin.ignore as it changes the layout.?
Your layout is contolled, basicly by this line:
cout << "\nContinue (Y/y): ";
cin >> conti;
cout << "\n" << endl; // <-- this one
conti = tolower(conti);
If you supress it, there will be no empty line. Otherwise, if you change it to
cout << endl;
Just one empty line.