Бот для игры в "Морской бой"
Я хочу сделать бота для игры в морской бой. И сделал вот такого бота:
int x = new Random().nextInt(10);
int y = new Random().nextInt(10);
if(pole[x][y]==1){// 1 - корабль
pole[x][y]=2;// 2 - уже пристреленный корабль
((ImageView)pole_image[x][y]).setImageResource(R.drawable.patron_in_ship);
boolean ships = true;
for (int[] vr: pole) {
for (int iq: vr) {
if (iq == 1) {
ships = false;
break;
}
}
}
if(ships) new AlertDialog.Builder(this).setTitle("Вы проиграли").setCancelable(false).setPositiveButton("OK", null).create().show();
} else if(pole[x][y]==0){ ((ImageView)pole_image[x][y]).setImageResource(R.drawable.patron_in_empty);}// 0 - пустое место
Но при игре он иногда то работает, то не работает
Подскажите пожалуйста, как сделать бота для игры в Морской бой
Ответы (1 шт):
Автор решения: Вася Воронцов
→ Ссылка
Боту как игроку должно быть известно, где находится "необитаемая зона" (поля, помеченные 2), поэтому их следует исключить из выбора. Кроме этого, необходимо помечать поля рядом с уничтоженным кораблём соответственно. Пришлось создать ArrayList с координатами кораблей:
import java.util.Random;
import java.util.ArrayList;
public class Main {
//x - номер строки
//y - номер столбца
public static int steps = 0;
public static boolean hasShips = true;
public static ArrayList<int[]> occupatedInRow = new ArrayList<int[]>();
public static int[] lastHurt = new int[]{-1, -1};
public static int[] firstHurt = new int[]{-1, -1};
public static boolean isDirectionTop = true;
public static boolean isDirectionSetted = false;
public static int[] calculateShot(int[][] pole) {
Random rnd = new Random();
int[] occupated = new int[0];
int x = -1, y = -1;
boolean isFirstNeeded = false;
if (lastHurt[0] != -1) {
if (isDirectionSetted) {
if (isDirectionTop) {
if (lastHurt[0]-1 >= 0 && pole[lastHurt[0]-1][lastHurt[1]] == 1) {
x = lastHurt[0]-1;
y = lastHurt[1];
} else if (lastHurt[0]+1 < 10 && pole[lastHurt[0]+1][lastHurt[1]] == 1) {
x = lastHurt[0]+1;
y = lastHurt[1];
}
} else {
if (lastHurt[1]-1 >= 0 && pole[lastHurt[0]][lastHurt[1]-1] == 1) {
x = lastHurt[0];
y = lastHurt[1]-1;
} else if (lastHurt[1]+1 < 10 && pole[lastHurt[0]][lastHurt[1]+1] == 1) {
x = lastHurt[0];
y = lastHurt[1]+1;
}
}
} else {
if (lastHurt[0]-1 >= 0 && pole[lastHurt[0]-1][lastHurt[1]] == 1) {
x = lastHurt[0]-1;
y = lastHurt[1];
} else if (lastHurt[0]+1 < 10 && pole[lastHurt[0]+1][lastHurt[1]] == 1) {
x = lastHurt[0]+1;
y = lastHurt[1];
} else if (lastHurt[1]-1 >= 0 && pole[lastHurt[0]][lastHurt[1]-1] == 1) {
x = lastHurt[0];
y = lastHurt[1]-1;
} else if (lastHurt[1]+1 < 10 && pole[lastHurt[0]][lastHurt[1]+1] == 1) {
x = lastHurt[0];
y = lastHurt[1]+1;
}
}
if (x == -1) isFirstNeeded = true;
} else isFirstNeeded = true;
if (isFirstNeeded && firstHurt[0] != -1) {
if (isDirectionSetted) {
if (isDirectionTop) {
if (firstHurt[0]-1 >= 0 && pole[firstHurt[0]-1][firstHurt[1]] == 1) {
x = firstHurt[0]-1;
y = firstHurt[1];
} else if (firstHurt[0]+1 < 10 && pole[firstHurt[0]+1][firstHurt[1]] == 1) {
x = firstHurt[0]+1;
y = firstHurt[1];
}
} else {
if (firstHurt[1]-1 >= 0 && pole[firstHurt[0]][firstHurt[1]-1] == 1) {
x = firstHurt[0];
y = firstHurt[1]-1;
} else if (firstHurt[1]+1 < 10 && pole[firstHurt[0]][firstHurt[1]+1] == 1) {
x = firstHurt[0];
y = firstHurt[1]+1;
}
}
} else {
if (firstHurt[0]-1 >= 0 && pole[lastHurt[0]-1][lastHurt[1]] == 1) {
x = firstHurt[0]-1;
y = firstHurt[1];
} else if (firstHurt[0]+1 < 10 && pole[firstHurt[0]+1][firstHurt[1]] == 1) {
x = firstHurt[0]+1;
y = firstHurt[1];
} else if (firstHurt[1]-1 >= 0 && pole[firstHurt[0]][firstHurt[1]-1] == 1) {
x = firstHurt[0];
y = firstHurt[1]-1;
} else if (firstHurt[1]+1 < 10 && pole[firstHurt[0]][firstHurt[1]+1] == 1) {
x = firstHurt[0];
y = firstHurt[1]+1;
}
}
} else if (isFirstNeeded) {
x = rnd.nextInt(10);
while ((occupated = occupatedInRow.get(x)).length == 10) {
x = rnd.nextInt(10);
}
y = getRandomWithExclusion(rnd, 0, 9, occupatedInRow.get(x));
}
occupatedInRow.set(x, push(occupated, y));
return new int[] {x, y};
}
public static int getRandomWithExclusion(Random rnd, int start, int end, int[] exclude) {
int random = start + rnd.nextInt(end - start + 1 - exclude.length);
for (int ex : exclude) {
if (random < ex) {
break;
}
random++;
}
return random;
}
public static int[] push(int[] array, int num) {
int[] newArray = new int[array.length + 1];
for (int a = 0; a < array.length; a++) {
newArray[a] = array[a];
}
newArray[array.length] = num;
return newArray;
}
public static void shot(int[][] pole, ArrayList<int[]> ships, int x, int y) {
pole[x][y] = 2;
int[] cs = null;
boolean isX = false, isY = false;
for (int a = 0; a < ships.size(); a++) {
int[] ccs = ships.get(a);
if (ccs[0] <= x && ccs[2] >= x && ccs[1] <= y && ccs[3] >= y) {
cs = ccs;
for (int i = cs[0]; i <= cs[2]; i++) {
if (pole[i][y] == 1) {
isX = true;
break;
}
}
for (int j = cs[1]; j <= cs[3]; j++) {
if (pole[x][j] == 1) {
isY = true;
break;
}
}
break;
}
}
if (cs == null) {
System.out.println("Промах!");
lastHurt = new int[]{-1, -1};
} else if (isX || isY) {
System.out.println("Попал!");
if (lastHurt[0] != -1) {
isDirectionSetted = true;
isDirectionTop = (lastHurt[0] - x) != 0;
} else {
isDirectionSetted = false;
firstHurt = new int[]{x, y};
}
lastHurt = new int[]{x, y};
} else {
for (int i = cs[0]-1; i <= cs[2]+1; i++) {
for (int j = cs[1]-1; j <= cs[3]+1; j++) {
pole[i][j] = 2;
}
}
System.out.println("Потопил!");
lastHurt = new int[]{-1, -1};
firstHurt = new int[]{-1, -1};
isDirectionSetted = false;
hasShips = false;
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
if (pole[i][j] == 1) {
hasShips = true;
break;
}
}
}
}
}
public static void main(String[] args) {
//инициализация
for (int a = 0; a < 10; a++) {
occupatedInRow.add(new int[0]);
}
int[][] pole = new int[][] {
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 1, 0, 0, 1, 1, 1, 1, 0, 0},
{0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
};
//массив с координатами кораблей
ArrayList<int[]> ships = new ArrayList<int[]>();
ships.add(new int[]{1, 1, 5, 1});
ships.add(new int[]{4, 4, 4, 7});
//просмотр стрельбы бота
while (hasShips) {
//получение координат
int[] coords = calculateShot(pole);
//выстрел
shot(pole, ships, coords[0], coords[1]);
//вывод
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
System.out.print(pole[i][j] + " ");
}
if (i == coords[0]) System.out.print("x (" + coords[0] + ")");
System.out.println("");
}
String spaces = "";
for (int k = 0; k < coords[1]-1; k++) {
spaces += " ";
}
System.out.println(spaces + " y");
System.out.println(spaces + " (" + coords[1] + ")");
steps++;
try {
Thread.sleep(100);
} catch (Exception e) {}
}
System.out.println("\nХодов сделано: " + steps);
}
}
За getRandomWithExclusion благодарите участника Howard.
P.S. "бот" стреляет наугад, если до этого никуда не попадал, иначе бьёт в окрестности ранения в вычисленном по второму попаданию направлению.