org.lightjason.examples.pokemon.simulation.environment.CEnvironment.java Source code

Java tutorial

Introduction

Here is the source code for org.lightjason.examples.pokemon.simulation.environment.CEnvironment.java

Source

/**
 * @cond LICENSE
 * ######################################################################################
 * # LGPL License                                                                       #
 * #                                                                                    #
 * # This file is part of the LightJason AgentSpeak(L)                                  #
 * # Copyright (c) 2015-16, Philipp Kraus (philipp@lightjason.org)                      #
 * # This program is free software: you can redistribute it and/or modify               #
 * # it under the terms of the GNU Lesser General Public License as                     #
 * # published by the Free Software Foundation, either version 3 of the                 #
 * # License, or (at your option) any later version.                                    #
 * #                                                                                    #
 * # This program is distributed in the hope that it will be useful,                    #
 * # but WITHOUT ANY WARRANTY; without even the implied warranty of                     #
 * # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                      #
 * # GNU Lesser General Public License for more details.                                #
 * #                                                                                    #
 * # You should have received a copy of the GNU Lesser General Public License           #
 * # along with this program. If not, see http://www.gnu.org/licenses/                  #
 * ######################################################################################
 * @endcond
 */

package org.lightjason.examples.pokemon.simulation.environment;

import org.lightjason.examples.pokemon.CCommon;
import org.lightjason.examples.pokemon.simulation.IElement;
import org.lightjason.examples.pokemon.simulation.algorithm.routing.IRouting;
import org.lightjason.examples.pokemon.simulation.item.IItem;
import cern.colt.matrix.DoubleMatrix1D;
import cern.colt.matrix.ObjectMatrix2D;
import cern.colt.matrix.impl.DenseDoubleMatrix1D;
import cern.colt.matrix.impl.SparseObjectMatrix2D;
import cern.colt.matrix.linalg.Algebra;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TiledMapTile;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;
import com.badlogic.gdx.maps.tiled.tiles.StaticTiledMapTile;

import java.text.MessageFormat;
import java.util.List;
import java.util.logging.Logger;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * environment class
 */
public final class CEnvironment implements IEnvironment {

    /**
     * logger
     */
    private static final Logger LOGGER = Logger.getLogger(CEnvironment.class.getName());
    /**
     * algebra object
     */
    private static final Algebra ALGEBRA = new Algebra();
    /**
     * routing algorithm
     */
    private final IRouting m_routing;
    /**
     * row number
     */
    private final int m_row;
    /**
     * column number
     */
    private final int m_column;
    /**
     * cell size
     */
    private final int m_cellsize;
    /**
     * matrix with object positions
     */
    private final ObjectMatrix2D m_positions;

    /**
     * create environment
     *
     * @param p_cellrows number of row cells
     * @param p_cellcolumns number of column cells
     * @param p_cellsize cell size
     * @param p_routing routing algorithm
     * @param p_obstacles static obstacles
     */
    public CEnvironment(final int p_cellrows, final int p_cellcolumns, final int p_cellsize,
            final IRouting p_routing, final List<? extends IItem> p_obstacles) {
        if ((p_cellcolumns < 1) || (p_cellrows < 1) || (p_cellsize < 1))
            throw new IllegalArgumentException("environment size must be greater or equal than one");

        m_row = p_cellrows;
        m_column = p_cellcolumns;
        m_routing = p_routing;
        m_cellsize = p_cellsize;
        m_positions = new SparseObjectMatrix2D(m_row, m_column);

        // add all obstacles to the position matrix
        p_obstacles.forEach(
                i -> CCommon.inttupelstream(i).forEach(j -> m_positions.setQuick(j.getLeft(), j.getRight(), i)));
        LOGGER.info(MessageFormat.format("create environment with size [{0}x{1}] and cell size [{2}]", m_row,
                m_column, p_cellsize));
    }

    @Override
    public final IEnvironment initialize() {
        m_routing.initialize(m_positions);
        return this;
    }

    @Override
    public final IEnvironment call() {
        return this;
    }

    @Override
    public final int row() {
        return m_row;
    }

    @Override
    public final int column() {
        return m_column;
    }

    @Override
    public final int cellsize() {
        return m_cellsize;
    }

    // --- grid-access (routing & position) --------------------------------------------------------------------------------------------------------------------

    @Override
    public final List<DoubleMatrix1D> route(final DoubleMatrix1D p_start, final DoubleMatrix1D p_end) {
        return m_routing.route(m_positions, p_start, p_end);
    }

    @Override
    public final double routestimatedtime(final Stream<DoubleMatrix1D> p_route, final double p_speed) {
        return m_routing.estimatedtime(p_route, p_speed);
    }

    @Override
    @SuppressWarnings("unchecked")
    public final synchronized IElement move(final IElement p_element, final DoubleMatrix1D p_position) {
        final DoubleMatrix1D l_position = this.clip(new DenseDoubleMatrix1D(p_position.toArray()));

        // check of the target position is free, if not return object, which blocks the cell
        final IElement l_object = (IElement) m_positions.getQuick((int) l_position.getQuick(0),
                (int) l_position.getQuick(1));
        if (l_object != null)
            return l_object;

        // cell is free, move the position and return updated object
        m_positions.set((int) p_element.position().get(0), (int) p_element.position().get(1), null);
        m_positions.set((int) l_position.getQuick(0), (int) l_position.getQuick(1), p_element);
        p_element.position().setQuick(0, l_position.getQuick(0));
        p_element.position().setQuick(1, l_position.getQuick(1));

        return p_element;
    }

    @Override
    @SuppressWarnings("unchecked")
    public final synchronized IElement get(final DoubleMatrix1D p_position) {
        return (IElement) m_positions.getQuick((int) CEnvironment.clip(p_position.get(0), m_row),
                (int) CEnvironment.clip(p_position.get(1), m_column));
    }

    @Override
    public final synchronized IElement remove(final IElement p_object) {
        final DoubleMatrix1D l_position = this.clip(new DenseDoubleMatrix1D(p_object.position().toArray()));
        m_positions.set((int) l_position.get(0), (int) l_position.get(1), null);

        return p_object;
    }

    @Override
    public final synchronized boolean empty(final DoubleMatrix1D p_position) {
        final DoubleMatrix1D l_position = this.clip(new DenseDoubleMatrix1D(p_position.toArray()));
        return m_positions.getQuick((int) l_position.getQuick(0), (int) l_position.getQuick(1)) == null;
    }

    @Override
    public final boolean isinside(final DoubleMatrix1D p_position) {
        return (p_position.getQuick(0) >= 0) && (p_position.getQuick(1) >= 0) && (p_position.getQuick(0) < m_row)
                && (p_position.getQuick(1) < m_column);
    }

    @Override
    public final DoubleMatrix1D clip(final DoubleMatrix1D p_position) {
        // clip position values if needed
        p_position.setQuick(0, CEnvironment.clip(p_position.getQuick(0), m_row));
        p_position.setQuick(1, CEnvironment.clip(p_position.getQuick(1), m_column));

        return p_position;
    }

    /**
     * value clipping
     *
     * @param p_value value
     * @param p_max maximum
     * @return modifed value
     */
    private static double clip(final double p_value, final double p_max) {
        return Math.max(Math.min(p_value, p_max - 1), 0);
    }

    // --- visualization ---------------------------------------------------------------------------------------------------------------------------------------

    @Override
    public final TiledMap map() {
        // create background checkerboard with a tile map
        final Pixmap l_pixmap = new Pixmap(2 * m_cellsize, m_cellsize, Pixmap.Format.RGBA8888);
        l_pixmap.setColor(new Color(0.8f, 0.1f, 0.1f, 0.5f));
        l_pixmap.fillRectangle(0, 0, m_cellsize, m_cellsize);
        l_pixmap.setColor(new Color(0.5f, 0.5f, 0.5f, 0.5f));
        l_pixmap.fillRectangle(m_cellsize, 0, m_cellsize, m_cellsize);

        final Texture l_texture = new Texture(l_pixmap);
        final TiledMapTile l_region1 = new StaticTiledMapTile(
                new TextureRegion(l_texture, 0, 0, m_cellsize, m_cellsize));
        final TiledMapTile l_region2 = new StaticTiledMapTile(
                new TextureRegion(l_texture, m_cellsize, 0, m_cellsize, m_cellsize));

        // create tilemap
        final TiledMap l_map = new TiledMap();
        final TiledMapTileLayer l_layer = new TiledMapTileLayer(m_column, m_row, m_cellsize, m_cellsize);
        l_map.getLayers().add(l_layer);

        IntStream.range(0, m_column).forEach(x -> {
            IntStream.range(0, m_row).forEach(y -> {
                final TiledMapTileLayer.Cell l_cell = new TiledMapTileLayer.Cell();
                l_layer.setCell(x, y, l_cell);
                l_cell.setTile(
                        y % 2 != 0 ? x % 2 != 0 ? l_region1 : l_region2 : x % 2 != 0 ? l_region2 : l_region1);
            });
        });

        return l_map;
    }

}