Не то что бы я опять обделался, но близко. Код более менее работает, но есть 1 нюанс. По которому и прошу помощи: не знаю как дать понять Ардуине, что если корабль вертикальный, то и стрелять нужно вертикально (и с горизонтальными те же проблемы). Сейчас ардуина просто обстреливает окружающие клетки (верх, низ, право, лево) с учетом ранее произведенных попаданий/промахов (т.е. по два раза в одно и то же место не стреляет и не отстает, пока не добьет корабль игрока). По сути проблема в строках 271-239. Но играть уже кажется можно... Хреново, но можно.
int battlefield_computer[10][10]; // Поле компьютера
int battlefield_player[10][10]; // Поле игрока
byte order_of_progress = 1; // Флаг очередности хода, 1 - игрок, 0 - компьютер
int total_tonnage; // Общее кол-во клеток-кораблей
void ship_arrangement(); // Функция расстановки кораблей, передаем размер и кол-во
void player_move(); // Функция хода игрока
void arduino_move(); // Функция хода компьютера
void setup() {
Serial.begin(115200); // Открываем последовательное соединение
randomSeed(analogRead(0)); // Запускаем функцию рандом случайным образом
for (int i = 0; i < 10; i++) { // заполним поле нулями
for (int j = 0; j < 10; j++) {
battlefield_computer[i][j] = 0;
battlefield_player[i][j] = 0;
}
}
//////////////////// Расставим корабли
ship_arrangement(4, 1); // Передаем размер корабля и кол-во
ship_arrangement(3, 2); // Передаем размер корабля и кол-во
ship_arrangement(2, 3); // Передаем размер корабля и кол-во
ship_arrangement(1, 4); // Передаем размер корабля и кол-во
for (int i = 0; i < 10; i++) { // Заменим 2 в полях вокруг корабля на 0
for (int j = 0; j < 10; j++) {
if (battlefield_computer[j][i] == 2) battlefield_computer[j][i] = 0;
}
}
//////////////////// Закончили расстановку
for (int i = 9; i >= 0; i--) { // Посмотрим, что получилось
for (int j = 0; j < 10; j++) {
//Serial.print(" ");
Serial.print(battlefield_computer[i][j]);
}
Serial.println();
}
Serial.println();
Serial.print("Общий тоннаж ");
Serial.println(total_tonnage);
} // Конец void setup()
void loop() {
if (order_of_progress == 1) {
Serial.println("Ход игрока");
player_move();
}
else arduino_move();
} // Конец void loop()
void ship_arrangement(int ship_size, int quantity) { // Функция расстановки кораблей
total_tonnage = total_tonnage + ship_size * quantity; // Кол-во клеток занятых кораблями
for (int t = 0; t < quantity; t++) { // Кол-во повторов равно кол-ву кораблей
label:
int x = random(0, 10); // Случайные координаты корабля
int y = random(0, 10);
uint8_t Direction = random(0, 2); // Случайное направление корабля
if (Direction == 1) { // Расположим корабль по оси Х (j)
for (int j = 0; j < ship_size ; j++) { // Проверяем свободны ли поля (т.е. равно ли оно 0)
if (battlefield_computer[y][x + j] == 0 && x + j < 10) { // Если условие не выполняется, то переносимся на начало
}
else {
goto label;
}
}
for (int i = 0; i < ship_size ; i++) battlefield_computer[y][x + i] = 1; // Если проверка прошла успешно, рисуем корабль
// А когда нарисовали корабль, заполним область вокруг
for (int i = 0; i < ship_size ; i++) {
if (y + 1 < 10) battlefield_computer[y + 1][x + i] = 2;
if (y - 1 >= 0) battlefield_computer[y - 1][x + i] = 2;
}
if (x - 1 >= 0) {
battlefield_computer[y][x - 1] = 2;
if (y - 1 >= 0) battlefield_computer[y - 1][x - 1] = 2;
if (y + 1 < 10) battlefield_computer[y + 1][x - 1] = 2;
}
if (x + ship_size < 10) {
battlefield_computer[y][x + ship_size] = 2;
if (y - 1 >= 0) battlefield_computer[y - 1][x + ship_size] = 2;
if (y + 1 < 10) battlefield_computer[y + 1][x + ship_size] = 2;
}
// Закончили заполнять область вокруг
} // Конец расположения корабля по оси Х (j)
else //Если корабль не расположен по оси Х
{ // Расположим корабль по оси Y (i)
for (int i = 0; i < ship_size ; i++) { // Проверяем свободны ли поля (т.е. равно ли оно 0)
if (battlefield_computer[y + i][x] == 0 && y + i < 10) { // Если условие не выполняется, то переносимся на начало
}
else {
goto label;
}
}
for (int i = 0; i < ship_size ; i++) battlefield_computer[y + i][x] = 1; // Если проверка прошла успешно, рисуем корабль
// А когда нарисовали корабль, заполним область вокруг
for (int i = 0; i < ship_size ; i++) {
if (x + 1 < 10) battlefield_computer[y + i][x + 1] = 2;
if (x - 1 >= 0) battlefield_computer[y + i][x - 1] = 2;
}
if (y - 1 >= 0) {
battlefield_computer[y - 1][x] = 2;
if (x - 1 >= 0) battlefield_computer[y - 1][x - 1] = 2;
if (x + 1 < 10) battlefield_computer[y - 1][x + 1] = 2;
}
if (y + ship_size < 10) {
battlefield_computer[y + ship_size][x] = 2;
if (x - 1 >= 0) battlefield_computer[y + ship_size][x - 1] = 2;
if (x + 1 < 10) battlefield_computer[y + ship_size][x + 1] = 2;
}
// Закончили заполнять область вокруг
}// Конец расположения корабля по оси Y (i)
}
}
void player_move() {
int Xp, Yp; // Координаты хода игрока
while (1) { // Ждем координату по Х
if (Serial.available() > 0) {
Xp = Serial.parseInt();
if (Xp < 0) Xp = 0;
if (Xp > 9) Xp = 9;
break;
}
}
while (1) { // Ждем координату по Y
if (Serial.available() > 0) {
Yp = Serial.parseInt();
if (Yp < 0) Yp = 0;
if (Yp > 9) Yp = 9;
Serial.print("Ход сделан ");
Serial.print(Xp);
Serial.print(" ");
Serial.print(Yp);
Serial.println();
break;
}
}
if (battlefield_computer[Yp][Xp] == 0) {
Serial.println("Промах, ход переходит компьютеру ");
order_of_progress = !order_of_progress;
}
int kill; // Вспомогательный счетчик
kill = 0;
if (battlefield_computer[Yp][Xp] == 1 || battlefield_computer[Yp][Xp] == 2) { // Если есть попадание или стреляем второй раз в раненый корабль
battlefield_computer[Yp][Xp] = 2; // Заменяем 1 на 2, что бы показать что корабль ранен
for (int i = 1; i < 10; i++) { // Пройдемся по полям в поисках 0 или 1 по оси Х++
if (Xp + i < 10) {
if (battlefield_computer[Yp][Xp + i] == 1) {
goto label;
// Serial.println("Ранен");
}
if (battlefield_computer[Yp][Xp + i] == 0) {
kill++;
break;
}
}
else { // Конец поля, корабль потоплен
kill++;
break;
}
} // Закончили хождения по оси Х++
for (int i = 1; i < 10; i++) { // Пройдемся по полям в поисках 0 или 1 по оси Х--
if (Xp - i >= 0) {
if (battlefield_computer[Yp][Xp - i] == 1) {
goto label;
// Serial.println("Ранен");
}
if (battlefield_computer[Yp][Xp - i] == 0) {
kill++;
break;
}
}
else { // Конец поля, корабль потоплен
kill++;
break;
}
} // Закончили хождения по оси Х--
for (int i = 1; i < 10; i++) { // Пройдемся по полям в поисках 0 или 1 по оси Y++
if (Yp + i < 10) {
if (battlefield_computer[Yp + i][Xp] == 1) {
goto label;
// Serial.println("Ранен");
}
if (battlefield_computer[Yp + i][Xp] == 0) {
kill++;
break;
}
}
else { // Конец поля, корабль потоплен
kill++;
break;
}
} // Закончили хождения по оси Y++
for (int i = 1; i < 10; i++) { // Пройдемся по полям в поисках 0 или 1 по оси Y--
if (Yp - i >= 0) {
if (battlefield_computer[Yp - i][Xp] == 1) {
goto label;
// Serial.println("Ранен");
}
if (battlefield_computer[Yp - i][Xp] == 0) {
kill++;
break;
}
}
else { // Конец поля, корабль потоплен
kill++;
break;
}
} // Закончили хождения по оси Y--
if (1 > 2) {
label:
Serial.println("Ранен");
}
// Serial.println(kill);
if (kill == 4) Serial.println("Убил"); // Если вокруг одни нули (через 2 перескакиваем и ищем 0 или 1)
} // Закончили проверку потоплен ли корабль
int w; // Проверим, а не победили ли мы за последний ход
w = 0;
for (int i = 0; i < 10; i++) { // скопируем поле компьютера во вспомогательное поле
for (int j = 0; j < 10; j++) {
if (battlefield_computer[i][j] == 1) w++;
}
}
if (w == 0) {
Serial.println("Победа");
while (1);
}
} // Конец функции стрельбы игрока
void arduino_move() { // Ход компьютера
//battlefield_player[10][10]; // Поле игрока
//order_of_progress
//total_tonnage; // Общее кол-во клеток-кораблей
int player_response = 0; // Переменная ответа игрока (3 - промах, 2 - убил, 1 - ранил)
int Xa = 99, Ya = 99; // Координаты хода компьютера
// int flag = 0; // Флаг, 1 - было попадание до начала хода, 0 - не было попаданий
// Проверяем есть ли прежние попадания (1)
replay2:
for (int k = 0; k < 10; k++) {
for (int m = 0; m < 10; m++) {
if (battlefield_player[k][m] == 1) { // нашли старое попадание
for (int i = 0; i < 10; i++) {
if (k + i < 10 && battlefield_player[k + i][m] == 3) {
goto z;
}
else {
if (k + i < 10 && battlefield_player[k + i][m] == 0) {
Xa = m;
Ya = k + i;
break;
}
}
z:
if (k - i >= 0 && battlefield_player[k - i][m] == 3) {
goto h;
}
else {
if (k - i >= 0 && battlefield_player[k - i][m] == 0) {
Xa = m;
Ya = k - i;
break;
}
h:
if (m + i < 10 && battlefield_player[k][m + i] == 3) {
goto p;
}
else {
if (m + i < 10 && battlefield_player[k][m + i] == 0) {
Xa = m + i;
Ya = k;
break;
}
}
p:
if (m - i >= 0 && battlefield_player[k][m - i] == 3) {
break;
}
else {
if (m - i >= 0 && battlefield_player[k][m - i] == 0) {
Xa = m - i;
Ya = k;
break;
}
}
}
}
}
}
} // Конец цикла, в котором мы стреляли по раненому кораблю
if (Xa != 99 && Ya != 99) {
Serial.print("Ход компьютера рядом со старым попаданием ");
Serial.print("Xa= ");
Serial.print(Xa);
Serial.print(" Ya= ");
Serial.println(Ya);
}
if (Xa == 99 && Ya == 99) { // Не было попадания, генерируем случайный ход
newXY:
Xa = random(0, 10); // Случайные координаты корабля
Ya = random(0, 10);
if (battlefield_player[Ya][Xa] == 2 || battlefield_player[Ya][Xa] == 3) goto newXY;
Serial.print("Ход компьютера ");
Serial.print("Xa= ");
Serial.print(Xa);
Serial.print(" Ya= ");
Serial.println(Ya);
}
while (1) { // Ждем ответ игрока на запрошенные координаты
if (Serial.available() > 0) {
player_response = Serial.parseInt();
if (player_response < 1) player_response = 1;
if (player_response > 3) player_response = 3;
Serial.print("Ответ получен ");
Serial.println(player_response);
break;
}
}
if (player_response == 3) { // Если промахнулись, отдаем ход игроку, а результат записываем в массив
order_of_progress = !order_of_progress;
Serial.println("Компьютер промахнулся");
battlefield_player[Ya][Xa] = 3;
}
if (player_response == 1) { // Ранил, записываем в массив, очередь хода не меняется
Serial.println("Ранил, компьютер ходит опять");
battlefield_player[Ya][Xa] = 1;
goto replay2;
}
if (player_response == 2) { // Убил, записываем в массив, очередь хода не меняется, меняем все 1 (ранения) на 2 (убил)
Serial.println("Убил, компьютер ходит опять");
battlefield_player[Ya][Xa] = 2;
for (int k = 0; k < 10; k++) {
for (int m = 0; m < 10; m++) {
if (battlefield_player[k][m] == 1) battlefield_player[k][m] = 2;
}
}
// окружаем 2 ореолом из 3, что бы не стрелять в окрестностях корабля
for (int k = 0; k < 10; k++) {
for (int m = 0; m < 10; m++) {
if (battlefield_player[k][m] == 2) {
if (k + 1 < 10 && battlefield_player[k + 1][m] == 0) battlefield_player[k + 1][m] = 3;
if (k - 1 >= 0 && battlefield_player[k - 1][m] == 0) battlefield_player[k - 1][m] = 3;
if (m + 1 < 10 && battlefield_player[k][m + 1] == 0) battlefield_player[k][m + 1] = 3;
if (m - 1 >= 0 && battlefield_player[k][m - 1] == 0) battlefield_player[k][m - 1] = 3;
if (k + 1 < 10 && battlefield_player[k + 1][m + 1] == 0 && m + 1 < 10) battlefield_player[k + 1][m + 1] = 3;
if (m - 1 >= 0 && battlefield_player[k + 1][m - 1] == 0 && k + 1 < 10) battlefield_player[k + 1][m - 1] = 3;
if (k - 1 >= 0 && battlefield_player[k - 1][m - 1] == 0 && m - 1 >= 0) battlefield_player[k - 1][m - 1] = 3;
if (m + 1 < 10 && battlefield_player[k - 1][m + 1] == 0 && k - 1 >= 0) battlefield_player[k - 1][m + 1] = 3;
}
}
}
////////// Проверим, а не победил ли компьютер
int w = total_tonnage;
for (int k = 0; k < 10; k++) {
for (int m = 0; m < 10; m++) {
if (battlefield_player[k][m] == 2) {
w = w - 1;
if (w == 0) {
Serial.println("Компьютер победил");
while (1);
}
}
}
}
/////// Посмотрим, что там окружилось 3
for (int i = 9; i >= 0; i--) { // Посмотрим, что получилось
for (int j = 0; j < 10; j++) {
//Serial.print(" ");
Serial.print(battlefield_player[i][j]);
}
Serial.println();
}
Serial.println();
} // Конец условия, если ответ игрока 2 - убил
} // Конец хода компьютера
А я поддержу мнение, что данную задачу целесообразно решать через объекты.
По сути, игровое поле может оказаться полезным лишь на стадии расстановки кораблей, а для самой игры поле не нужно . От слова "совсем". Есть корабль с набором полей и методов и он сам помнит свое состояние, осуществляет проверки и отвечает на допустимые запросы о своем состоянии.
На очередном шаге придумываем очередную пару координат, сообщаем их в цикле всем кораблям, они отвечают, скажем:
0 - не попал,
1 - ранил,
2 - убил,
3 - давно затонул.
Анализируем ответ и принимаем решение, что делать дальше.
Эх, хорошо... Все проблемы решены, единственный недостаток, когда ардуина ходит, она не учитывает, а влезет ли, например, 4 палубный корабль в те поля, куда она стреляет. Но добивать корабли она кажется стала правильно. Ну и код прилагаю, вдруг кому понадобится. Т.к. задача хоть и тривиальная, да и задается на всех олимпиадах на которых не лень, но более менее простого кода я не нашел. А разбираться в 2000 строках кода чего то так себе затея.
int battlefield_computer[10][10]; // Поле компьютера
int battlefield_player[10][10]; // Поле игрока
byte order_of_progress = 1; // Флаг очередности хода, 1 - игрок, 0 - компьютер
int total_tonnage; // Общее кол-во клеток-кораблей
void ship_arrangement(); // Функция расстановки кораблей, передаем размер и кол-во
void player_move(); // Функция хода игрока
void arduino_move(); // Функция хода компьютера
void setup() {
Serial.begin(9600); // Открываем последовательное соединение
randomSeed(analogRead(0)); // Запускаем функцию рандом случайным образом
for (int i = 0; i < 10; i++) { // заполним поле нулями
for (int j = 0; j < 10; j++) {
battlefield_computer[i][j] = 0;
battlefield_player[i][j] = 0;
}
}
//////////////////// Расставим корабли
ship_arrangement(4, 1); // Передаем размер корабля и кол-во
ship_arrangement(3, 2); // Передаем размер корабля и кол-во
ship_arrangement(2, 3); // Передаем размер корабля и кол-во
ship_arrangement(1, 4); // Передаем размер корабля и кол-во
for (int i = 0; i < 10; i++) { // Заменим 2 в полях вокруг корабля на 0
for (int j = 0; j < 10; j++) {
if (battlefield_computer[j][i] == 2) battlefield_computer[j][i] = 0;
}
}
//////////////////// Закончили расстановку
for (int i = 9; i >= 0; i--) { // Посмотрим, что получилось
for (int j = 0; j < 10; j++) {
//Serial.print(" ");
Serial.print(battlefield_computer[i][j]);
}
Serial.println();
}
Serial.println();
Serial.print("Общий тоннаж ");
Serial.println(total_tonnage);
} // Конец void setup()
void loop() {
if (order_of_progress == 1) {
Serial.println("Ход игрока");
player_move();
}
else arduino_move();
} // Конец void loop()
void ship_arrangement(int ship_size, int quantity) { // Функция расстановки кораблей
total_tonnage = total_tonnage + ship_size * quantity; // Кол-во клеток занятых кораблями
for (int t = 0; t < quantity; t++) { // Кол-во повторов равно кол-ву кораблей
label:
int x = random(0, 10); // Случайные координаты корабля
int y = random(0, 10);
uint8_t Direction = random(0, 2); // Случайное направление корабля
if (Direction == 1) { // Расположим корабль по оси Х (j)
for (int j = 0; j < ship_size ; j++) { // Проверяем свободны ли поля (т.е. равно ли оно 0)
if (battlefield_computer[y][x + j] == 0 && x + j < 10) { // Если условие не выполняется, то переносимся на начало
}
else {
goto label;
}
}
for (int i = 0; i < ship_size ; i++) battlefield_computer[y][x + i] = 1; // Если проверка прошла успешно, рисуем корабль
// А когда нарисовали корабль, заполним область вокруг
for (int i = 0; i < ship_size ; i++) {
if (y + 1 < 10) battlefield_computer[y + 1][x + i] = 2;
if (y - 1 >= 0) battlefield_computer[y - 1][x + i] = 2;
}
if (x - 1 >= 0) {
battlefield_computer[y][x - 1] = 2;
if (y - 1 >= 0) battlefield_computer[y - 1][x - 1] = 2;
if (y + 1 < 10) battlefield_computer[y + 1][x - 1] = 2;
}
if (x + ship_size < 10) {
battlefield_computer[y][x + ship_size] = 2;
if (y - 1 >= 0) battlefield_computer[y - 1][x + ship_size] = 2;
if (y + 1 < 10) battlefield_computer[y + 1][x + ship_size] = 2;
}
// Закончили заполнять область вокруг
} // Конец расположения корабля по оси Х (j)
else //Если корабль не расположен по оси Х
{ // Расположим корабль по оси Y (i)
for (int i = 0; i < ship_size ; i++) { // Проверяем свободны ли поля (т.е. равно ли оно 0)
if (battlefield_computer[y + i][x] == 0 && y + i < 10) { // Если условие не выполняется, то переносимся на начало
}
else {
goto label;
}
}
for (int i = 0; i < ship_size ; i++) battlefield_computer[y + i][x] = 1; // Если проверка прошла успешно, рисуем корабль
// А когда нарисовали корабль, заполним область вокруг
for (int i = 0; i < ship_size ; i++) {
if (x + 1 < 10) battlefield_computer[y + i][x + 1] = 2;
if (x - 1 >= 0) battlefield_computer[y + i][x - 1] = 2;
}
if (y - 1 >= 0) {
battlefield_computer[y - 1][x] = 2;
if (x - 1 >= 0) battlefield_computer[y - 1][x - 1] = 2;
if (x + 1 < 10) battlefield_computer[y - 1][x + 1] = 2;
}
if (y + ship_size < 10) {
battlefield_computer[y + ship_size][x] = 2;
if (x - 1 >= 0) battlefield_computer[y + ship_size][x - 1] = 2;
if (x + 1 < 10) battlefield_computer[y + ship_size][x + 1] = 2;
}
// Закончили заполнять область вокруг
}// Конец расположения корабля по оси Y (i)
}
}
void player_move() {
int Xp, Yp; // Координаты хода игрока
while (1) { // Ждем координату по Х
if (Serial.available() > 0) {
Xp = Serial.parseInt();
if (Xp < 0) Xp = 0;
if (Xp > 9) Xp = 9;
break;
}
}
while (1) { // Ждем координату по Y
if (Serial.available() > 0) {
Yp = Serial.parseInt();
if (Yp < 0) Yp = 0;
if (Yp > 9) Yp = 9;
Serial.print("Ход сделан ");
Serial.print(Xp);
Serial.print(" ");
Serial.print(Yp);
Serial.println();
break;
}
}
if (battlefield_computer[Yp][Xp] == 0) {
Serial.println("Промах, ход переходит компьютеру ");
order_of_progress = !order_of_progress;
}
int kill; // Вспомогательный счетчик
kill = 0;
if (battlefield_computer[Yp][Xp] == 1 || battlefield_computer[Yp][Xp] == 2) { // Если есть попадание или стреляем второй раз в раненый корабль
battlefield_computer[Yp][Xp] = 2; // Заменяем 1 на 2, что бы показать что корабль ранен
for (int i = 1; i < 10; i++) { // Пройдемся по полям в поисках 0 или 1 по оси Х++
if (Xp + i < 10) {
if (battlefield_computer[Yp][Xp + i] == 1) {
goto label;
// Serial.println("Ранен");
}
if (battlefield_computer[Yp][Xp + i] == 0) {
kill++;
break;
}
}
else { // Конец поля, корабль потоплен
kill++;
break;
}
} // Закончили хождения по оси Х++
for (int i = 1; i < 10; i++) { // Пройдемся по полям в поисках 0 или 1 по оси Х--
if (Xp - i >= 0) {
if (battlefield_computer[Yp][Xp - i] == 1) {
goto label;
// Serial.println("Ранен");
}
if (battlefield_computer[Yp][Xp - i] == 0) {
kill++;
break;
}
}
else { // Конец поля, корабль потоплен
kill++;
break;
}
} // Закончили хождения по оси Х--
for (int i = 1; i < 10; i++) { // Пройдемся по полям в поисках 0 или 1 по оси Y++
if (Yp + i < 10) {
if (battlefield_computer[Yp + i][Xp] == 1) {
goto label;
// Serial.println("Ранен");
}
if (battlefield_computer[Yp + i][Xp] == 0) {
kill++;
break;
}
}
else { // Конец поля, корабль потоплен
kill++;
break;
}
} // Закончили хождения по оси Y++
for (int i = 1; i < 10; i++) { // Пройдемся по полям в поисках 0 или 1 по оси Y--
if (Yp - i >= 0) {
if (battlefield_computer[Yp - i][Xp] == 1) {
goto label;
// Serial.println("Ранен");
}
if (battlefield_computer[Yp - i][Xp] == 0) {
kill++;
break;
}
}
else { // Конец поля, корабль потоплен
kill++;
break;
}
} // Закончили хождения по оси Y--
if (1 > 2) {
label:
Serial.println("Ранен");
}
// Serial.println(kill);
if (kill == 4) Serial.println("Убил"); // Если вокруг одни нули (через 2 перескакиваем и ищем 0 или 1)
} // Закончили проверку потоплен ли корабль
int w; // Проверим, а не победили ли мы за последний ход
w = 0;
for (int i = 0; i < 10; i++) { // скопируем поле компьютера во вспомогательное поле
for (int j = 0; j < 10; j++) {
if (battlefield_computer[i][j] == 1) w++;
}
}
if (w == 0) {
Serial.println("Победа");
while (1);
}
} // Конец функции стрельбы игрока
void arduino_move() { // Ход компьютера
//battlefield_player[10][10]; // Поле игрока
//order_of_progress
//total_tonnage; // Общее кол-во клеток-кораблей
int player_response = 0; // Переменная ответа игрока (3 - промах, 2 - убил, 1 - ранил)
int Xa = 99, Ya = 99; // Координаты хода компьютера
// int flag = 0; // Флаг, 1 - было попадание до начала хода, 0 - не было попаданий
// Проверяем есть ли прежние попадания (1)
replay2:
//////// введем элементы ИИ (проставим 3 вокруг двух и более раненых элементов корабля, для задания направления стрельбы)
for (int k = 0; k < 10; k++) {
for (int m = 0; m < 10; m++) {
if (battlefield_player[k][m] == 1 && battlefield_player[k + 1][m] == 1 && k + 1 < 10) {
if (m + 1 < 10) battlefield_player[k + 1][m + 1] = 3;
if (m - 1 >= 0) battlefield_player[k + 1][m - 1] = 3;
if (m + 1 < 10) battlefield_player[k][m + 1] = 3;
if (m - 1 >= 0) battlefield_player[k][m - 1] = 3;
}
if (battlefield_player[k][m] == 1 && battlefield_player[k - 1][m] == 1 && k - 1 >= 0) {
if (m + 1 < 10) battlefield_player[k - 1][m + 1] = 3;
if (m - 1 >= 0) battlefield_player[k - 1][m - 1] = 3;
if (m + 1 < 10) battlefield_player[k][m + 1] = 3;
if (m - 1 >= 0) battlefield_player[k][m - 1] = 3;
}
if (battlefield_player[k][m] == 1 && battlefield_player[k][m + 1] == 1 && m + 1 < 10) {
if (k + 1 < 10) battlefield_player[k + 1][m + 1] = 3;
if (k - 1 >= 0) battlefield_player[k - 1][m + 1] = 3;
if (k + 1 < 10) battlefield_player[k + 1][m] = 3;
if (k - 1 >= 0) battlefield_player[k - 1][m] = 3;
}
if (battlefield_player[k][m] == 1 && battlefield_player[k][m - 1] == 1 && m - 1 >= 0) {
if (k + 1 < 10) battlefield_player[k + 1][m - 1] = 3;
if (k - 1 >= 0) battlefield_player[k - 1][m - 1] = 3;
if (k + 1 < 10) battlefield_player[k + 1][m] = 3;
if (k - 1 >= 0) battlefield_player[k - 1][m] = 3;
}
}
}
// Посмотрим, что там окружилось:
for (int i = 9; i >= 0; i--) { // Посмотрим, что получилось
for (int j = 0; j < 10; j++) {
//Serial.print(" ");
Serial.print(battlefield_player[i][j]);
}
Serial.println();
}
Serial.println();
//////// ввели элементы ИИ
int X1 = 1, X2 = 1, Y1 = 1, Y2 = 1;
for (int k = 0; k < 10; k++) {
for (int m = 0; m < 10; m++) {
if (battlefield_player[k][m] == 1) { // нашли старое попадание
for (int i = 0; i < 10; i++) {
if (X1 == 1) {
if (k + i < 10 && battlefield_player[k + i][m] == 3) {
X1 = 0;
goto z;
}
else {
if (k + i < 10 && battlefield_player[k + i][m] == 0) {
Xa = m;
Ya = k + i;
break;
}
}
}
z:
if (X2 == 1) {
if (k - i >= 0 && battlefield_player[k - i][m] == 3) {
X2 = 0;
goto h;
}
else {
if (k - i >= 0 && battlefield_player[k - i][m] == 0) {
Xa = m;
Ya = k - i;
break;
}
}
}
h:
if (Y1 == 1) {
if (m + i < 10 && battlefield_player[k][m + i] == 3) {
Y1 = 0;
goto p;
}
else {
if (m + i < 10 && battlefield_player[k][m + i] == 0) {
Xa = m + i;
Ya = k;
break;
}
}
}
p:
if (Y2 == 1) {
if (m - i >= 0 && battlefield_player[k][m - i] == 3) {
Y2 = 0;
break;
}
else {
if (m - i >= 0 && battlefield_player[k][m - i] == 0) {
Xa = m - i;
Ya = k;
break;
}
}
}
}
}
}
} // Конец цикла, вкотором мы стреляли по раненому кораблю
if (Xa != 99 && Ya != 99) {
Serial.print("Ход компьютера рядом со старым попаданием ");
Serial.print("Xa= ");
Serial.print(Xa);
Serial.print(" Ya= ");
Serial.println(Ya);
}
if (Xa == 99 && Ya == 99) { // Не было попадания, генерируем случайный ход
newXY:
Xa = random(0, 10); // Случайные координаты корабля
Ya = random(0, 10);
if (battlefield_player[Ya][Xa] == 2 || battlefield_player[Ya][Xa] == 3) goto newXY;
Serial.print("Ход компьютера ");
Serial.print("Xa= ");
Serial.print(Xa);
Serial.print(" Ya= ");
Serial.println(Ya);
}
while (1) { // Ждем ответ игрока на запрошенные координаты
if (Serial.available() > 0) {
player_response = Serial.parseInt();
if (player_response < 1) player_response = 1;
if (player_response > 3) player_response = 3;
Serial.print("Ответ получен ");
Serial.println(player_response);
break;
}
}
if (player_response == 3) { // Если промахнулись, отдаем ход игроку, а результат записываем в массив
order_of_progress = !order_of_progress;
Serial.println("Компьютер промахнулся");
battlefield_player[Ya][Xa] = 3;
}
if (player_response == 1) { // Ранил, записываем в массив, очередь хода не меняется
Serial.println("Ранил, компьютер ходит опять");
battlefield_player[Ya][Xa] = 1;
goto replay2;
}
if (player_response == 2) { // Убил, записываем в массив, очередь хода не меняется, меняем все 1 (ранения) на 2 (убил)
Serial.println("Убил, компьютер ходит опять");
battlefield_player[Ya][Xa] = 2;
for (int k = 0; k < 10; k++) {
for (int m = 0; m < 10; m++) {
if (battlefield_player[k][m] == 1) battlefield_player[k][m] = 2;
}
}
// окружаем 2 ореолом из 3, что бы не стрелять в окрестностях корабля
for (int k = 0; k < 10; k++) {
for (int m = 0; m < 10; m++) {
if (battlefield_player[k][m] == 2) {
if (k + 1 < 10 && battlefield_player[k + 1][m] == 0) battlefield_player[k + 1][m] = 3;
if (k - 1 >= 0 && battlefield_player[k - 1][m] == 0) battlefield_player[k - 1][m] = 3;
if (m + 1 < 10 && battlefield_player[k][m + 1] == 0) battlefield_player[k][m + 1] = 3;
if (m - 1 >= 0 && battlefield_player[k][m - 1] == 0) battlefield_player[k][m - 1] = 3;
if (k + 1 < 10 && battlefield_player[k + 1][m + 1] == 0 && m + 1 < 10) battlefield_player[k + 1][m + 1] = 3;
if (m - 1 >= 0 && battlefield_player[k + 1][m - 1] == 0 && k + 1 < 10) battlefield_player[k + 1][m - 1] = 3;
if (k - 1 >= 0 && battlefield_player[k - 1][m - 1] == 0 && m - 1 >= 0) battlefield_player[k - 1][m - 1] = 3;
if (m + 1 < 10 && battlefield_player[k - 1][m + 1] == 0 && k - 1 >= 0) battlefield_player[k - 1][m + 1] = 3;
}
}
}
////////// Проверим, а не победил ли компьютер
int w = total_tonnage;
for (int k = 0; k < 10; k++) {
for (int m = 0; m < 10; m++) {
if (battlefield_player[k][m] == 2) {
w = w - 1;
if (w == 0) {
Serial.println("Компьютер победил");
while (1);
}
}
}
}
/////// Посмотрим, что там окружилось 3
/* for (int i = 9; i >= 0; i--) { // Посмотрим, что получилось
for (int j = 0; j < 10; j++) {
//Serial.print(" ");
Serial.print(battlefield_player[i][j]);
}
Serial.println();
}
Serial.println();
*/
} // Конец условия, если ответ игрока 2 - убил
} // Конец хода компьютера
А слабо сделать физический Тетрис? Чтобы реальные тетраминошки падали? Я вот давно думаю. Мож систему магнитов какую? Может, чтобы падали в жидкости, чтобы помедленнее? Всякий бред в голову приходит.
Это можно сделать на подобии гидравлического компьютера: поле представляет собой кубы с отверстиями для перетока жидкости, а открывая и закрывая отдельные "перетоки" между кубами можно управлять формой фигуры, давлением поддавки регулировать скорость "падения" фигуры.
Не то что бы я опять обделался, но близко. Код более менее работает, но есть 1 нюанс. По которому и прошу помощи: не знаю как дать понять Ардуине, что если корабль вертикальный, то и стрелять нужно вертикально (и с горизонтальными те же проблемы). Сейчас ардуина просто обстреливает окружающие клетки (верх, низ, право, лево) с учетом ранее произведенных попаданий/промахов (т.е. по два раза в одно и то же место не стреляет и не отстает, пока не добьет корабль игрока). По сути проблема в строках 271-239. Но играть уже кажется можно... Хреново, но можно.
А я поддержу мнение, что данную задачу целесообразно решать через объекты.
По сути, игровое поле может оказаться полезным лишь на стадии расстановки кораблей, а для самой игры поле не нужно . От слова "совсем". Есть корабль с набором полей и методов и он сам помнит свое состояние, осуществляет проверки и отвечает на допустимые запросы о своем состоянии.
На очередном шаге придумываем очередную пару координат, сообщаем их в цикле всем кораблям, они отвечают, скажем:
0 - не попал,
1 - ранил,
2 - убил,
3 - давно затонул.
Анализируем ответ и принимаем решение, что делать дальше.
Эх, хорошо... Все проблемы решены, единственный недостаток, когда ардуина ходит, она не учитывает, а влезет ли, например, 4 палубный корабль в те поля, куда она стреляет. Но добивать корабли она кажется стала правильно. Ну и код прилагаю, вдруг кому понадобится. Т.к. задача хоть и тривиальная, да и задается на всех олимпиадах на которых не лень, но более менее простого кода я не нашел. А разбираться в 2000 строках кода чего то так себе затея.
Обратите внимание, вы объявили прототип функции, но не указали параметры. Это не правильно.
006 void ship_arrangement(); // Функция расстановки кораблей, передаем размер и кол-во
Arduino IDE не требует предварительного объявления функций, и наверное поэтому нет сообщения об ошибке.
Пипец- дальше будет спейсквест? Или тетрис?
А слабо сделать физический Тетрис? Чтобы реальные тетраминошки падали? Я вот давно думаю. Мож систему магнитов какую? Может, чтобы падали в жидкости, чтобы помедленнее? Всякий бред в голову приходит.
Это можно сделать на подобии гидравлического компьютера: поле представляет собой кубы с отверстиями для перетока жидкости, а открывая и закрывая отдельные "перетоки" между кубами можно управлять формой фигуры, давлением поддавки регулировать скорость "падения" фигуры.
Если непонятно, могу нарисовать набросок