So I went to the next step in learning c++ and that's a matrix. I tried to do an easy tic tac toe game but my game fails to correctly check if the game is over. If you put height = 2 and width = 2 in the first round it says you won... I don't see where could I have messed it up, all seemed pretty good in my mind...
int map[3][3];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
map[i][j] = 0;
}
}
bool finished = false;
int player = 1;
while (!finished) {
//attack
cout << "player " << player << " it is your turn"<< endl;
cout << "The map looks like this:" << endl;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
cout << map[i][j] << " ";
}
cout << endl;
}
bool correctMove;
int height, width;
do
{
correctMove = true;
cout << "Where do you want to attack?" << endl;
cout << "height = "; cin >> height;
cout << "width = "; cin >> width;
if (map[height][width] != 0 || width > 2 || height > 2) {
correctMove = false;
}
} while (!correctMove);
map[height][width] = player;
//check finish game
bool foundSequenceLine = true;
for (int i = 0; i < 3; i++) {
if (map[height][i] != player) {
foundSequenceLine = false;
}
}
bool foundSequenceColumn = true;
for (int i = 0; i < 3; i++) {
if (map[i][width] != player) {
foundSequenceColumn = false;
}
}
bool foundSequenceDiag1 = true;
if (height == width) {
for (int i = 0; i < 3; i++) {
if (map[i][i] != player) {
foundSequenceDiag1 = false;
}
}
}
bool foundSequenceDiag2 = true;
if (height + width == 2) {
for (int i = 0; i < 3; i++) {
if (map[2-i][i] != player) {
foundSequenceDiag2 = false;
}
}
}
if (foundSequenceColumn || foundSequenceLine || foundSequenceDiag1 || foundSequenceDiag2) {
finished = true;
cout << "Congrats player " << player << " you won!!!";
}
//change turn
if (player == 1) {
player++;
}
else {
player--;
}
}
}
Your code assumes the player has won unless you can exhaustively prove they haven't.
The problem is that you then short-circuit two of the tests that prove a move is not a winning move.
Look at what this code is doing:
bool foundSequenceDiag1 = true;
if (height == width) {
for (int i = 0; i < 3; i++) {
if (map[i][i] != player) {
foundSequenceDiag1 = false;
}
}
}
First, you say "the player has won" foundSequenceDiag1=true;
. Then you say, "was the move on a diagonal?", and only then do you run code that can set foundSequenceDiag1
to false.
If the player makes a move that isn't on the diagonal, the check won't run.
to fix:
bool foundSequenceDiag1 = (height==width); // true if the player played on diagonal
if (foundSequenceDiag1) { // loop code now only executes if player played on diagonal
for (int i = 0; i < 3; i++) {
if (map[i][i] != player) {
foundSequenceDiag1 = false;
}
}
}
If I were writing your checks, I'd make use of the break
keyword to stop looking once I found an answer.
for (int i = 0; i < 3; i++) {
if (map[i][i] != player) {
foundSequenceDiag1 = false;
break; // can't be true now, so stop checking.
}
}