I am trying to make a simple tic-tac-toe game. Right now I am trying to make it so the computer can't place inside of certain places in a 2d array. The computer is set to place randomly, and I am using loops and goto to make it random until it gets a suitable spot.
#include <iostream>
#include <string>
#include <ctime>
#include <Windows.h>
using namespace std;
string team;
string a = " ";
const int rows = 5;
const int elements = 5;
string Board[rows][elements] = { a, "| ", a, "| ", a,
"- ", "+ ", "- ", "+ ", "- ",
a, "| ", a, "| ", a,
"- ", "+ ", "- ", "+ ", "- ",
a, "| ", a, "| ", a };
void showBoard()
{
for (int i = 0; i < rows; i++) {
for (int j = 0; j < elements; j++) {
cout << Board[i][j];
}
cout << endl;
}
}
int main()
{
int nonFilled = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < elements; j++) {
if (Board[i][j] == a && a == " ")
nonFilled++;
}
}
int circleFilled = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < elements; j++) {
if (Board[i][j] == a && a == "0 ")
circleFilled++;
}
}
int crossFilled = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < elements; j++) {
if (Board[i][j] == a && a == "X ")
crossFilled++;
}
}
cout << "Welcome to tic-tac-toe game." << endl;
cout << endl;
showBoard();
cout << "Please select team if circle or cross: (0/X)" << endl;
cin >> team;
if (team == "0") {
int ifCircle = 1;
cout << "You have selected circle." << endl;
while (nonFilled > circleFilled + crossFilled) {
srand(time(NULL));
int x, y = 0;
int xx, xy = 0;
cout << "Select square: " << endl;
cout << "Y cord (0-4): ";
cin >> x;
cout << endl;
cout << "X cord (0-4): ";
cin >> y;
if (x == 0 || y == 0)
return 0;
/*if (Board[x - 1][y - 1] = "| ", "+ ", "- ")
{
cout << "You cannot place one there. " << endl;
nonFilled = 100;
}*/
int b = 1;
if (Board[x - 1][y - 1] == a)
b = 1;
else
b = 2;
switch (b) {
case 1:
Board[x - 1][y - 1] = "0 ";
break;
case 2:
cout << "You cannot place one there. " << endl;
continue;
}
/* if (Board[x - 1][y - 1] == a)
{
Board[x - 1][y - 1] = "0 ";
}
else
{
cout << "You cannot place one there." << endl;
}*/
cout << endl;
showBoard();
cout << "The opponent will now pick a square:" << endl;
system("pause");
xx = rand() % rows;
xy = rand() % elements;
int c = 1;
if (Board[xx][xy] == a)
c = 1;
else if (Board[xx][xy] == "| ", "+ ", "- ")
c = 2;
switch (c) {
case 1:
Board[xx][xy] = "X ";
break;
case 2: {
LOOP: // here is my label for the goto statement
while (true) // this loop
{
xx = rand() % rows;
xy = rand() % elements;
if (Board[xx][xy] == "| ", "+ ", "- ") {
goto LOOP; // goto statement
}
else {
Board[xx][xy] = "X ";
}
}
}
}
cout << endl;
cout << "The opponent has picked:" << endl;
showBoard();
}
}
else if (team == "X") {
int ifCircle = 0;
}
system("pause");
return 0;
}
The loop in question is at the very bottom, I am not sure if it is a problem with how I placed the label or how I am using the statement or if it is a problem with a different part of the code.
I have looked at loads of questions on goto statements inside of while loops and I couldn't find anything.
The immediate problem lies neither with the placement of your LOOP:
label nor with the use of the goto
statement (and I am not here going to get involved in the argument over whether or not that keyword should ever be used in a C++ program).
The problem is in the following line:
if (Board[xx][xy] == "| ", "+ ", "- ") {
(and the similar if else...
statement a few lines earlier).
This does not do what you may want it to! In fact, it will always return a true
value, as the nett result of the expression is simply, if ("- ")
- which will always be a non-null (i.e. non-zero) address of the string literal.
What you need (if you are looking to match the indexed Board[][]
string to any one of the three literals) is the following:
if (Board[xx][xy] == "| " || Board[xx][xy] == "+ " || Board[xx][xy] == "- ") {
//...
The code you have, using the comma operator, evaluates each of the comma-separated expressions (in left-to-right order), discarding each but the last (right-most) value; the overall result is just that of the right-most expression.
EDIT: Having applied the fixes I suggested above, I then noticed another problem: Your while
loop, as it stands, will never exit (either it will goto
to the LOOP:
or just keep running). Here is one (quick) way to fix the loop, which also removes the need for the goto
statement:
case 2:
{
bool done = false;
while (!done)
{
xx = rand() % rows;
xy = rand() % elements;
if (Board[xx][xy] == "| " || Board[xx][xy] == "+ " || Board[xx][xy] == "- ") {
continue;
}
else {
Board[xx][xy] = "X ";
done = true;
}
}
}
There are more 'elegant' ways to achieve the same result but, hopefully, you will at least be able to follow (and understand) the fairly minor changes I have made to your code. Please feel free to ask for any further clarification and/or explanation.