Лабиринты Java, часть 1: классы Location и Map2D


Давайте поработаем с лабиринтами на Java.Пройдем весь путь от нуля и до решения собственных задач. Конечная цель – это научить компьютер проходить наш маршрут. Научим компьютер алгоритму «А-стар» (A*). В процессе узнаем еще много интересного.

Для начала давайте создадим пару вспомогательных классов. Первый класс – Location – локация. По сути это конкретное место на карте, определяемое координатами:


/**
 * Этот класс представляет конкретное место на 2D-карте.
 * Координаты целочисленные значения.
 **/
public class Location
{
    /** X координата. **/
    public int xCoord;

    /** Y координата. **/
    public int yCoord;


    /** Создает новое местоположение с указанными целыми координатами. **/
    public Location(int x, int y)
    {
        xCoord = x;
        yCoord = y;
    }

    /** Создаем новую локацию с координатами (0, 0). **/
    public Location()
    {
        this(0, 0);
    }
    
    
    public boolean equals(Object obj) {
        
        // Если объект Location?
        if (obj instanceof Location) {
            
            // Приведем другой объект к типу Location, затем сравниваем. Возвращаем true, если они равны.
            Location other = (Location) obj;
            if (xCoord == other.xCoord && yCoord == other.yCoord) {
                return true;
            }
        }
        
        // Если мы попали сюда, то они не равны.  Возвращаем false. 
        return false;
    }
    
    /** Предоставляет хэш-код для каждого местоположения. **/
    public int hashCode() {
        int result = 17; // Некоторое основное значение
        
        // Используем это простое значение для объединения
        result = 37 * result + xCoord;
        result = 37 * result + yCoord;
        return result;
    }
}
Второй класс - Map2D – по сути объединение локаций, карта. Комментарии в коде класса довольно подробные.

/**
 * Этот класс представляет собой простую двухмерную карту, состоящую из квадратных ячеек.
  * Каждая ячейка определяет стоимость прохождения этой ячейки. 
**/

public class Map2D
{
    /** Ширина карты**/
    private int width;

    /** Высота карты. **/
    private int height;

    /**
     * Фактические данные карты, которые необходимы алгоритму поиска пути.     **/

    private int[][] cells;

    /** Стартовая локация **/
    private Location start;

    /** Конечная локация (выход) **/
    private Location finish;


    /**конструктор для новой карты. **/
    public Map2D(int width, int height)
    {
        if (width <= 0 || height <= 0)
        {
            throw new IllegalArgumentException(
                    "width and height must be positive values; got " + width +
                    "x" + height);
        }
        
        this.width = width;
        this.height = height;
        
        cells = new int[width][height];
        
        // Задаем некоторые координаты начала и конца
        start = new Location(0, height / 2);
        finish = new Location(width - 1, height / 2);
    }


    /**
     * Этот вспомогательный метод проверяет указанные координаты, чтобы убедиться, что они
      * в пределах карты. Если координаты не в пределах карты
      * тогда метод генерирует исключение <code> IllegalArgumentException </code>.

     **/

    private void checkCoords(int x, int y)
    {
        if (x < 0 || x > width)
        {
            throw new IllegalArgumentException("x must be in range [0, " + 
                    width + "), got " + x);
        }
        
        if (y < 0 || y > height)
        {
            throw new IllegalArgumentException("y must be in range [0, " + 
                    height + "), got " + y);
        }
    }    
    
    /** Возвращает ширину карты. **/
    public int getWidth()
    {
        return width;
    }
    
    /** Возвращает высоту карты **/
    public int getHeight()
    {
        return height;
    }
    
    /**
     * Возвращает true, если указанные координаты содержатся в пределах площади карты.
      **/
    public boolean contains(int x, int y)
    {
        return (x >= 0 && x < width && y >= 0 && y < height);
    }
    
    
    /** Возвращает true если локация в пределах площади карты. **/
    public boolean contains(Location loc)
    {
        return contains(loc.xCoord, loc.yCoord);
    }
    
    /** Возвращает сохраненное значение стоимости для указанной ячейки. **/
    public int getCellValue(int x, int y)
    {
        checkCoords(x, y);
        return cells[x][y];
    }
    
    /** Возвращает сохраненное значение стоимости для указанной ячейки. **/
    public int getCellValue(Location loc)
    {
        return getCellValue(loc.xCoord, loc.yCoord);
    }
    
    /** Устанавливает значение стоимости для указанной ячейки. **/
    public void setCellValue(int x, int y, int value)
    {
        checkCoords(x, y);
        cells[x][y] = value;
    }
    
    /**
     * Возвращаем начало карты
     **/
    public Location getStart()
    {
        return start;
    }
    
    /**
     * Устанавливаем начало карты.
     **/
    public void setStart(Location loc)
    {
        if (loc == null)
            throw new NullPointerException("loc cannot be null");
        
        start = loc;
    }

    /**
     * Возвращает конец пути
     **/
    public Location getFinish()
    {
        return finish;
    }
    
    /**
     * Устанавливает конечное местоположение для карты. Здесь сгенерированный путь
      * заканчивается.
     **/
    public void setFinish(Location loc)
    {
        if (loc == null)
            throw new NullPointerException("loc cannot be null");
        
        finish = loc;
    }
}
Теперь уже можно с этими двумя классами даже набросать пример кода.

int width = 3;
int height = 3;
		
Location startLoc = new Location(0, 0);
Location finishLoc = new Location(2, 2);
		
Map2D map = new Map2D(width, height);
map.setStart(startLoc);
		
map.setCellValue(1, 0, 0);
map.setCellValue(2, 0, 0);
		
map.setCellValue(0, 1, 0);
map.setCellValue(1, 1, 0);
map.setCellValue(2, 1, 0);
		
map.setCellValue(0, 2, 0);
map.setCellValue(1, 2, 0);
		
map.setFinish(finishLoc);
		
System.out.println(map.hashCode());
Автор этого материала - я - Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.

тегизаметки, программирование, java, утилиты, лабиринт




Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.




Windows Forms: градиент и закругленные кнопки
Как улучшить настроение
PDO и MySQLi: битва API баз данных PHP