Проблема проста. Я сделал тиктактое 3X3 игру с массивами 3X3. Но проблема в следующем:
array[0][3] = array[1][0]
Что странно, потому что, во-первых, массив, который я создал, не имел четвертого столбца. Так array[0][3]
даже не существует! И чтобы усложнить ситуацию, требуется значение [1][0]
У меня проблемы с вводом координат моего движения в виде: 0 2
void displayBoard(int tictac[3][3])
{
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
cout << tictac[i][j] << " ";
} cout << "\n" ;
} cout << "\n";
}int Horizontal(int x, int y, int tictac[3][3])
{
if(tictac[x][y+1]==0)
{
tictac[x][y+1]=2;
return 1;
}
if(tictac[x][y-1]==0)
{
tictac[x][y-1]=2;
return 1;
}
if(tictac[x][y-2]==0)
{
tictac[x][y-2]=2;
return 1;
}
if(tictac[x][y+2]==0)
{
tictac[x][y+2]=2;
return 1;
}
return 0;
}
int Vertical(int x, int y, int tictac[3][3])
{
if(tictac[x+1][y]==0)
{
tictac[x+1][y]=2;
return 1;
}
if(tictac[x-1][y]==0)
{
tictac[x-1][y]=2;
return 1;
}
if(tictac[x-2][y]==0)
{
tictac[x-2][y]=2;
return 1;
}
if(tictac[x+2][y]==0)
{
tictac[x+2][y]=2;
return 1;
}
return 0;
}
void AI(int X,int Y,int tictac[3][3])
{
int done = 0;
cout << "\n-------------------------\nComputer plays: \n";
done = Horizontal(X,Y,tictac);
if(done == 0)
{
done = Vertical(X,Y,tictac);
}
}int main()
{
int tictac[3][3] = {{0,0,0},{0,0,0}, {0,0,0} };
int X, Y;
for(int r=1; r<100; r++)
{
cout << "\n-------------------------\nPlayer play a move: \n";
cin >> X;
cin >> Y;
if(tictac[X][Y]==0)
{
tictac[X][Y] = 1;
displayBoard(tictac);
AI(X,Y,tictac);
displayBoard(tictac);
}
else
{
cout << "Space occupied. Try different cell." << endl;
}}
}
Вам нужно добавить проверку границ. Например, когда пользователь вводит координаты перемещения, вам необходимо убедиться, что они находятся в диапазоне от 0 до 2. В приведенном ниже примере проверяется ввод, чтобы убедиться, что вводятся только цифры, что координаты X и Y вводятся в одной строке и что координаты в пределах диапазона. Оно использует std::stringstream
анализировать координаты вместо того, чтобы иметь дело с проверкой и очисткой битов сбоя std::cin
#include <string> // at top of your .cpp file
#include <sstream>
// in main()
// Get en entire input line so we can skip extra characters
// after the cell coordinates
string inputLine;
std::getline(cin, inputLine);
stringstream inputStream(inputLine);
if(!(inputStream >> X) || !(inputStream >> Y))
{
cout << "Please enter the cell coordinates in the form of # #" << endl;
continue;
}
bool invalidCoordinates = false;
if(X < 0 || X > 2)
{
cout << "invalid X location" << endl;
invalidCoordinates = true;
}
if(Y < 0 || Y > 2)
{
cout << "invalid Y location" << endl;
invalidCoordinates = true;
}
// check for invalid input
if(invalidCoordinates) continue;
Вы также должны сделать то же самое в вашем Vertical
а также Horizontal
функции при проверке возможного допустимого перемещения. Например, если x
это 2 и y
2 следующие строки из Vertical
получит доступ к данным за пределами массива.
if(tictac[x+1][y]==0)
{
tictac[x+1][y]=2;
return 1;
}
Это потому, что вы на самом деле обращаетесь к четвертому элементу с x+1
, Этот элемент технически не существует, но с многомерным массивом вы получаете доступ tictac[0][y+1]
вместо.
Вы можете обойти границы проверки в Vertical
а также Horizontal
добавив некоторые отступы по краям и заполните их значением, которое указывает, что они непригодны. В вашем случае увеличьте размер на 3 в каждом направлении.
int tictac[9][9] = {
{3,3,3,3,3,3,3,3,3},
{3,3,3,3,3,3,3,3,3},
{3,3,3,3,3,3,3,3,3},
{3,3,3,0,0,0,3,3,3},
{3,3,3,0,0,0,3,3,3},
{3,3,3,0,0,0,3,3,3},
{3,3,3,3,3,3,3,3,3},
{3,3,3,3,3,3,3,3,3},
{3,3,3,3,3,3,3,3,3},
};
Вам нужно будет внести коррективы в X
а также Y
соответственно, чтобы они указывали на правильное местоположение.
X += 3; // Adjust for padding
Y += 3; // Adjust for padding
if(tictac[X][Y]==0)
{
tictac[X][Y] = 1;
displayBoard(tictac);
AI(X,Y,tictac);
displayBoard(tictac);
}
Возможно, вам придется внести изменения в другие части вашего кода, но приведенный выше пример должен помочь вам.
Существует также проблема в вашем displayBoard
функция. Когда он распечатывает элементы массива i
а также j
перевернуты, поэтому доска кажется повернутой на 90 градусов. Измените следующую строку
cout << tictac[i][j] << " ";
в
cout << tictac[j][i] << " ";
Другая проблема заключается в том, что вы используете \n
в конце каждой строки вы выводите без использования std::flush
чтобы убедиться, что линия отправляется на консоль. Вы можете поставить << flush;
после этих строк или же удалить \n
и положи << endl;
в конце строки.
cout << "\n-------------------------\nComputer plays: \n" << flush;
или же
cout << "\n-------------------------\nComputer plays: " << endl;
Приведенный ниже код является полным обновлением исходного кода, включенного в ваш вопрос. Он включает в себя вышеупомянутые предложения и вносит несколько других изменений. Я также добавил проверку эндшпиля, чтобы определить, остались ли какие-либо ходы.
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
static const int BoardSize = 3;
static const int BoardPadding = BoardSize;
static const int ArraySize = BoardSize + (BoardPadding * 2);
void displayBoard(int tictac[ArraySize][ArraySize])
{
for(int y = 0; y < BoardSize; y++)
{
for(int x = 0; x < BoardSize; x++)
{
cout << tictac[BoardPadding + x][BoardPadding + y] << " ";
}
cout << endl ;
}
cout << endl;
}int Horizontal(int x, int y, int tictac[ArraySize][ArraySize])
{
if(tictac[x][y+1]==0)
{
tictac[x][y+1]=2;
return 1;
}
if(tictac[x][y-1]==0)
{
tictac[x][y-1]=2;
return 1;
}
if(tictac[x][y-2]==0)
{
tictac[x][y-2]=2;
return 1;
}
if(tictac[x][y+2]==0)
{
tictac[x][y+2]=2;
return 1;
}
return 0;
}int Vertical(int x, int y, int tictac[ArraySize][ArraySize])
{
if(tictac[x+1][y]==0)
{
tictac[x+1][y]=2;
return 1;
}
if(tictac[x-1][y]==0)
{
tictac[x-1][y]=2;
return 1;
}
if(tictac[x-2][y]==0)
{
tictac[x-2][y]=2;
return 1;
}
if(tictac[x+2][y]==0)
{
tictac[x+2][y]=2;
return 1;
}
return 0;
}void AI(int X,int Y,int tictac[ArraySize][ArraySize])
{
int done = 0;
cout << "\n-------------------------\nComputer plays: " << endl;
done = Horizontal(X,Y,tictac);
if(done == 0)
{
done = Vertical(X,Y,tictac);
}
}// Check if all moves have been made
bool isEndGame(int tictac[ArraySize][ArraySize])
{
int count = 0;
for(int y = 0; y < BoardSize; y++)
{
for(int x = 0; x < BoardSize; x++)
{
count += tictac[BoardPadding + x][BoardPadding + y] ? 1 : 0;
}
}
return count == (BoardSize * BoardSize);
}int main()
{
int tictac[ArraySize][ArraySize] = {
{3,3,3,3,3,3,3,3,3},
{3,3,3,3,3,3,3,3,3},
{3,3,3,3,3,3,3,3,3},
{3,3,3,0,0,0,3,3,3},
{3,3,3,0,0,0,3,3,3},
{3,3,3,0,0,0,3,3,3},
{3,3,3,3,3,3,3,3,3},
{3,3,3,3,3,3,3,3,3},
{3,3,3,3,3,3,3,3,3},
};
int X, Y;
while(isEndGame(tictac) == false)
{
cout << "\n-------------------------\nPlayer play a move: " << flush;
// Get en entire input line so we can skip extra characters
// after the cell coordinates
string inputLine;
std::getline(cin, inputLine);
stringstream inputStream(inputLine);
if(!(inputStream >> X) || !(inputStream >> Y))
{
cout << "Please enter the cell coordinates in the form of # #" << endl;
continue;
}
bool invalidCoordinates = false;
if(X < 0 || X >= BoardSize)
{
cout << "invalid X location" << endl;
invalidCoordinates = true;
}
if(Y < 0 || Y >= BoardSize)
{
cout << "invalid Y location" << endl;
invalidCoordinates = true;
}
// check for invalid input
if(invalidCoordinates) continue;
// adjust the coordinates and do our thing
X += BoardPadding;
Y += BoardPadding;
if(tictac[X][Y]==0)
{
tictac[X][Y] = 1;
displayBoard(tictac);
AI(X,Y,tictac);
displayBoard(tictac);
}
else
{
cout << "Space occupied. Try different cell." << endl;
}
}
cout << "game finished...check for winner" << endl;
}
Примечание: это плохая идея using namespace std;
, Это тянет все от std
пространство имен в текущую область (в данном случае глобальное пространство имен) и может вызвать конфликты. Лучше использовать полностью квалифицированные имена, такие как std::cout
вместо этого, чтобы избежать этого.
В случае этого массива
int array[3][3];
следующее утверждение действительно
array[0][3] == array[1][0]
так как:
[j][i]
становится [j * width + i]
,array[0][3]
указывает на 0 * 3 + 3
(третья) ячейка в памяти, но array[1][0]
указывает на 1 * 3 + 0
(также третья!) ячейка памяти, начиная с начала вашего 2D-массива.