Есть ли функция для выбора определенной части 2d массива в Java? - PullRequest
0 голосов
/ 31 октября 2019

Итак, у меня есть школьный проект, в котором есть 2 игрока, и я использую классы для оружия, ловушек и еды, и произвольно размещаю их в определенной части массива. Я построил 2d массив с соответствующим типом класса для каждого из них, каждый из которых соответственно называется WeaponAreaLimits, FoodAreaLimits и TrapAreaLimits.

public class Board{

int[][] weaponAreaLimits = { {-2,2}, {2, 2}, {-2, -2}, {2, -2} };
int[][] foodAreaLimits = { {-3, 3}, {3, 3}, {-3, -3}, {3, -3} };
int[][] trapAreaLimits = { {-4, 4}, {4, 4}, {-4, -4}, {4, -4} }; //These are the specific coordinates that limit the placement of said weapons etc.
....

Суть в том, что оружие может быть внутри коробки, изготовленной из этих точек, но еда должна быть в точках, окружающих оружие, а не внутри коробки, сделанной из - 3,3 3,3 -3,-3 и 3,-3. Я построил метод под названием createRandomFood(), который случайным образом дает свойства Food объектам. Те, на которых я застрял, это x и y, и как использовать только те окружающие точки, а не размещать их там, где их не должно быть. Посмотрите на то, что я написал:

....
public void createRandomFood(){

    for(int i = 1; i < food.length; i++){
        food[i].setId(i + 1);
        food[i].setX; 
        food[i].setY; 
        food[i].setPoints(rand.nextInt(10) + 1); //Ignore the other setters
    }
}

Мой вопрос: есть ли способ или способ устранить эти точки?

Ответы [ 2 ]

0 голосов
/ 31 октября 2019

Хорошо, если я теперь понимаю, сначала ...

Ваши данные пределов могут быть проще, если они представляют прямоугольные пределы. Вам нужно только minX, maxX, minY, maxY. Я хотел бы создать объект для хранения этих:

public class Limits {
    int minX;
    int minY;
    int maxX;
    int maxY;
    public Limits(int x1, y1, x2, y2) {
       minX = x1;
       minY = y1;
       maxX = x2;
       maxY = y2;
    }
}

Тогда ваши объекты станут

Limits weaponAreaLimits = new Limits(-2, -2, 2, 2);
Limits foodAreaLimits = new Limits(-3, -3, 3, 3);
Limits trapAreaLimits = new Limits(-4, -4, 4, 4);

Это работает, потому что прямоугольник может быть определен двумя диагональными углами. В этом случае мы используем нижний левый и верхний правый углы. Вам не нужна каждая вершина.

Теперь вам нужен такой метод:

public boolean setPoints(Item item, Limits includeRange, Limits excludeRange) {
    // These two variables hold the width & height of the box where things can be
    int width = includeRange.maxX - includeRange.minX + 1;
    int height = includeRange.maxY - includeRange.minY + 1;
    int x;
    int y;

    do {
        x = includeRange.minX + (rand() % width);
        y = includeRange.minY + (rand() % height);
        // At this point, x and y are inside the includeRange.
        // We need to make sure they aren't in the disallowed area
    } while ( (excludeRange == null) ||
      (x >= excludeRange.minX && x <= excludeRange.maxX &&
       y >= excludeRange.minY && y <= excludeRange.maxY) );

    // When the above loop exits, you have an x and y that works.
    item.x = x;
    item.y = y;

    return true;
}

Я не запускаю это через компилятор Java, поэтому могут быть синтаксические ошибки. Но в основном мы зацикливаемся, произвольно устанавливая x и y во внешнем блоке, пока не получим случайное значение, которого нет внутри внутреннего блока. Но мы также допускаем нулевое внутреннее поле, чтобы мы могли обращаться с оружием тем же методом.

Теперь, чего здесь не хватает - я не проверяю, чтобы убедиться, что это место не занято чем-то другим. ,Этот метод должен возвращать false, если он не может работать, потому что вся область уже заполнена. Я оставлю это для вас. Представьте, что вы пытались добавить 50 единиц оружия в область, в которой можно удерживать только 25.

Здесь есть куча важных вещей. Помимо базовой структуры кода, есть понимание определения прямоугольника. Внутри этого прямоугольника генерируются случайные числа. И есть код исключения.

Надеюсь, этого достаточно для продвижения вперед.

0 голосов
/ 31 октября 2019

В вашем примере вы должны сгенерировать точку во внешней области (foodAreaLimits), которая не является частью внутренней области (weaponAreaLimits). Правильный подход, вероятно, будет зависеть от формы области, например, что если внутренняя область представляет собой круг, а внешняя область представляет собой треугольник?

Вы можете решить проблему с помощью этого алгоритма:

  1. Создать случайную точку внутри foodAreaLimits
  2. Если она находится вне weaponAreaLimits, этого достаточно.
  3. В противном случае случайным образом выбрать направление. Вы имеете дело только с int, поэтому все просто: запад, восток, север, юг.
  4. Изменяйте координату направления в новой точке, пока не выйдете за пределы weaponAreaLimits. Вы имеете дело с int, поэтому, например, запад означал бы перемещение на {-1, 0}, поэтому выполните food[i].x--.

Вы, вероятно, должны подумать, насколько велики области и каков предмет распределения. Это может быть сложно, если внутренние и внешние области близки по размеру.

...