Tic Tac Toe Tie Condition C++ - c++

I can't seem to get this function to work correctly. You would assume since I check for vertical, horizontal and diagonal if those don't get a win it would be a tie, but my program says its a tie after I fill in the Top left box and the middle box. Any suggestions? Do I have to change the way I search for vertical horizontal and diagonal?
Here is my code for this function:
char winningLetter;
for (int i = 0; i < 3; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2])
{
winningLetter = board[i][0];
}
}
for (int i = 0; i < 3; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i])
{
winningLetter = board[0][i];
}
}
if ((board[0][0] == board[1][1] && board[1][1] == board[2][2]) ||
(board[0][2] == board[1][1] && board[1][1] == board[2][0]))
{
winningLetter == board[1][1];
}
if (winningLetter == 'X')
{
cout << "Player One is the winner!" << endl;
}
else if (winningLetter == 'O')
{
cout << "Player Two is the winner!" << endl;
}
else
{
cout << "The game is a tie!" << endl;
tie = true;
}
return;

The problem is having the wrong conditions for a tie.
The condition is not
There is no winner
but
The game is over and there is no winner
You never checked if the game is over.

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.

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++ Tic Tac Toe AI

I am almost done with my tic tac toe game. Currently it is set up as two-player person vs. person but I know I'll have to implement a simple AI to be approved. Now I need your help with this. I know I'll have to think about it in small steps such as three "make a move" methods like
If AI has a move in the 1st column && the two box to the right is open make a move in either box and return true
If AI has a move in the middle && the box to the left and right is open make a move in either box and return true
If AI has a move in the 3rd column && the two box to the left is open make a move in either box and return true
I can't understand exactly how I can implement it in my code below:
#include <iostream>
using namespace std;
char matrix[3][3] = { '7', '8', '9', '4', '5', '6', '1', '2', '3' };
char player = 'X';
int n;
void Draw()
{
system("cls");
cout << "Tic Tac Toe !\n" << endl;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
cout << matrix[i][j] << " ";
}
cout << endl;
}
}
void Input()
{
int a;
cout << "\nIt's " << player << " turn. " << "Press the number of the field: ";
cin >> a;
if (a == 7)
{
if (matrix[0][0] == '7')
matrix[0][0] = player;
else
{
cout << "Field is already in use try again!" << endl;
Input();
}
}
else if (a == 8)
{
if (matrix[0][1] == '8')
matrix[0][1] = player;
else
{
cout << "Field is already in use try again!" << endl;
Input();
}
}
else if (a == 9)
{
if (matrix[0][2] == '9')
matrix[0][2] = player;
else
{
cout << "Field is already in use try again!" << endl;
Input();
}
}
else if (a == 4)
{
if (matrix[1][0] == '4')
matrix[1][0] = player;
else
{
cout << "Field is already in use try again!" << endl;
Input();
}
}
else if (a == 5)
{
if (matrix[1][1] == '5')
matrix[1][1] = player;
else
{
cout << "Field is already in use try again!" << endl;
Input();
}
}
else if (a == 6)
{
if (matrix[1][2] == '6')
matrix[1][2] = player;
else
{
cout << "Field is already in use try again!" << endl;
Input();
}
}
else if (a == 1)
{
if (matrix[2][0] == '1')
matrix[2][0] = player;
else
{
cout << "Field is already in use try again!" << endl;
Input();
}
}
else if (a == 2)
{
if (matrix[2][1] == '2')
matrix[2][1] = player;
else
{
cout << "Field is already in use try again!" << endl;
Input();
}
}
else if (a == 3)
{
if (matrix[2][2] == '3')
matrix[2][2] = player;
else
{
cout << "Field is already in use try again!" << endl;
Input();
}
}
}
void TogglePlayer()
{
if (player == 'X')
player = 'O';
else
player = 'X';
}
char Win()
{
//first player
if (matrix[0][0] == 'X' && matrix[0][1] == 'X' && matrix[0][2] == 'X')
return 'X';
if (matrix[1][0] == 'X' && matrix[1][1] == 'X' && matrix[1][2] == 'X')
return 'X';
if (matrix[2][0] == 'X' && matrix[2][1] == 'X' && matrix[2][2] == 'X')
return 'X';
if (matrix[0][0] == 'X' && matrix[1][0] == 'X' && matrix[2][0] == 'X')
return 'X';
if (matrix[0][1] == 'X' && matrix[1][1] == 'X' && matrix[2][1] == 'X')
return 'X';
if (matrix[0][2] == 'X' && matrix[1][2] == 'X' && matrix[2][2] == 'X')
return 'X';
if (matrix[0][0] == 'X' && matrix[1][1] == 'X' && matrix[2][2] == 'X')
return 'X';
if (matrix[2][0] == 'X' && matrix[1][1] == 'X' && matrix[0][2] == 'X')
return 'X';
//second player
if (matrix[0][0] == 'O' && matrix[0][1] == 'O' && matrix[0][2] == 'O')
return 'O';
if (matrix[1][0] == 'O' && matrix[1][1] == 'O' && matrix[1][2] == 'O')
return 'O';
if (matrix[2][0] == 'O' && matrix[2][1] == 'O' && matrix[2][2] == 'O')
return 'O';
if (matrix[0][0] == 'O' && matrix[1][0] == 'O' && matrix[2][0] == 'O')
return 'O';
if (matrix[0][1] == 'O' && matrix[1][1] == 'O' && matrix[2][1] == 'O')
return 'O';
if (matrix[0][2] == 'O' && matrix[1][2] == 'O' && matrix[2][2] == 'O')
return 'O';
if (matrix[0][0] == 'O' && matrix[1][1] == 'O' && matrix[2][2] == 'O')
return 'O';
if (matrix[2][0] == 'O' && matrix[1][1] == 'O' && matrix[0][2] == 'O')
return 'O';
return '/';
}
int main()
{
n = 0;
Draw();
while (1)
{
n++;
Input();
Draw();
if (Win() == 'X')
{
cout << "X wins!" << endl;
break;
}
else if (Win() == 'O')
{
cout << "O wins!" << endl;
break;
}
else if (Win() == '/' && n == 9)
{
cout << "It's a draw!" << endl;
break;
}
TogglePlayer();
}
system("pause");
return 0;
}
A computer player for a simple board game like Tic-Tac-Toe can be implemented using the Minimax algorithm, which can be improved using α-β-pruning. Although the resulting implementation will be quite small, it might require some time to understand.
#include <iostream>
#include <string>
using namespace std;
int main()
{
/*
the chart is :
X 2 X
4 5 6
X 8 X
*/
char Matrix[3][3] = { 'X','2','X','4','5','6','X','8','X' };
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
cout << Matrix[i][j] << " ";
}
cout << endl;
}
/*
after this for :
X O X
4 5 6
X O X
*/
int l = 0, m = 0, p[3] = { 0,0,0 };
for (l; l <= 2; l++)
{
for (m; m <= 2; m++)
{
if ((Matrix[l][m]) == 'X')
{
p[l]++;
if ((p[l]) == 2)
{
for (m; m >= 0; m--)
{
if ((Matrix[l][m]) != 'X')
{
Matrix[l][m] = 'O';
}
}
}
}
}
}
return 0;
}
why this code dosent work?

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;
}

Can I chain comparisons together in an IF statement?

I am currently making a naught's and crosses program for college. I have finished the bare bones of this assignment however I am having some trouble creating a win condition to end the game. Below is all of the code I have used so far:
#include <iostream>
#include <string>
using namespace std;
class Player
{
private:
char NorX;
public:
char Choose(char InitialValue)
{
NorX = InitialValue;
return InitialValue;
}
char GetNorX()
{
return NorX;
}
};
int main()
{
Player Player1;
Player Player2;
Player1.Choose('O');
Player2.Choose('X');
cout << "The board is being drawn please wait..." << endl;
const int Rows = 4;
const int Columns = 4;
char Board[Rows][Columns] = { {' ', ' ', ' ', ' ' },
{' ', '_', '_', '_' },
{' ', '_', '_', '_' },
{' ', '_', '_', '_' } };
for (int i = 0; i < Rows; ++i)
{
for (int j = 0; j < Columns; ++j)
cout << Board [i][j];
cout << endl;
}
cout << endl << endl;
int row;
int column;
do
{
do
{
cout << "Please enter the value of the row you would like to take ";
cin >> row;
}while (row != 0 && row != 1 && row != 2 && row != 3);
do
{
cout << "Please enter the value of the column you would like to take ";
cin >> column;
}while (column != 0 && column != 1 && column != 2 && column != 3);
Board [row][column] = Player1.GetNorX();
for (int i = 0; i < Rows; ++i)
{
for (int j = 0; j < Columns; ++j)
cout << Board [i][j];
cout << endl;
}
/*int row;*/
do
{
cout << "Please enter the value of the row you would like to take ";
cin >> row;
}while (row != 0 && row != 1 && row != 2 && row != 3);
/*int column;*/
do
{
cout << "Please enter the value of the column you would like to take ";
cin >> column;
}while (column != 0 && column != 1 && column != 2 && column != 3);
Board [row][column] = Player2.GetNorX();
for (int i = 0; i < Rows; ++i)
{
for (int j = 0; j < Columns; ++j)
cout << Board [i][j];
cout << endl;
}
if (Board[1][1] == Board[1][2] == Board[1][3] == 'O')
{
cout << endl << "Well done you win";
}
}while (column != 4 && row != 4);
system("pause");
}
The problem occurs in the if statement as it doesn't seem to have any affect on the running of the program.
The result of chaining comparison operators in C++ is not what one expects. The correct way to do this is to connect them with a "logical and" &&
if (Board[1][1] == 'O' && Board[1][2] == 'O' && Board[1][3] == 'O')
For the given example
if (Board[1][1] == Board[1][2] == Board[1][3] == 'O')
you must consider operator precedence, which is left to right for equality operator ==. This means, the example is the same as (note the additional parenthesis)
if ((Board[1][1] == Board[1][2]) == Board[1][3]) == 'O')
and works as follows:
Board[1][1] == Board[1][2]
gives either true or false. This will be compared to the next part
true == Board[1][3]
which gives false, because true or false is never equal to a character. This will be compared to the character zero
false == '0'
which again will result in false.
You cannot do this stringing together of comparisons:
Board[1][1] == Board[1][2] == Board[1][3] == 'O'
All that will happen is Board[1] == Board[1][2] is first evaluated to either true or false and then that boolean value is compared toBoard[1][3]` and so on.
What you want is:
Board[1][1] == 'O' && Board[1][2] == 'O' && Board[1][3] == 'O'
Your if condition is wrong.
You should replace it with the code below:
if ((Board[1][1] == Board[1][2]) &&
(Board[1][2] == Board[1][3]) &&
(Board[1][3] == 'O'))
When you are checking for horizontal winning condition, all three blocks in the horizontal line must have a value of 0.
You should use
if (Board[1][1] == Board[1][2] &&
Board[1][1] == Board[1][3] &&
Board[1][1] == 'O')
or
if (Board[1][1] == 'O' &&
Board[1][2] == 'O' &&
Board[1][3] == 'O')
In its current form your statement, for example, compares Board[1][2] to the result of Board[1][3]=='O' comparsion, not to Board[1][3].
You should run this in a debugger such as gdb. Google "gdb cheatsheet" to get started. You will see exactly what lines of code are executing and in particular can verify the "if" is being evaluated.