All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.badlogic.gdx.ai.btree.utils.DistributionAdapters Maven / Gradle / Ivy

There is a newer version: 1.8.2
Show newest version
/*******************************************************************************
 * Copyright 2014 See AUTHORS file.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/

package com.badlogic.gdx.ai.btree.utils;

import java.util.StringTokenizer;

import com.badlogic.gdx.ai.utils.random.ConstantDoubleDistribution;
import com.badlogic.gdx.ai.utils.random.ConstantFloatDistribution;
import com.badlogic.gdx.ai.utils.random.ConstantIntegerDistribution;
import com.badlogic.gdx.ai.utils.random.ConstantLongDistribution;
import com.badlogic.gdx.ai.utils.random.Distribution;
import com.badlogic.gdx.ai.utils.random.DoubleDistribution;
import com.badlogic.gdx.ai.utils.random.FloatDistribution;
import com.badlogic.gdx.ai.utils.random.GaussianDoubleDistribution;
import com.badlogic.gdx.ai.utils.random.GaussianFloatDistribution;
import com.badlogic.gdx.ai.utils.random.IntegerDistribution;
import com.badlogic.gdx.ai.utils.random.LongDistribution;
import com.badlogic.gdx.ai.utils.random.TriangularDoubleDistribution;
import com.badlogic.gdx.ai.utils.random.TriangularFloatDistribution;
import com.badlogic.gdx.ai.utils.random.TriangularIntegerDistribution;
import com.badlogic.gdx.ai.utils.random.TriangularLongDistribution;
import com.badlogic.gdx.ai.utils.random.UniformDoubleDistribution;
import com.badlogic.gdx.ai.utils.random.UniformFloatDistribution;
import com.badlogic.gdx.ai.utils.random.UniformIntegerDistribution;
import com.badlogic.gdx.ai.utils.random.UniformLongDistribution;
import com.badlogic.gdx.utils.ObjectMap;

/** @author davebaol */
public class DistributionAdapters {

	/** Thrown to indicate that the application has attempted to convert a string to one of the distribution types, but that the
	 * string does not have the appropriate format.
	 * 
	 * @author davebaol */
	public static class DistributionFormatException extends RuntimeException {

		/** Constructs a DistributionFormatException with no detail message. */
		public DistributionFormatException () {
			super();
		}

		/** Constructs a DistributionFormatException with the specified detail message.
		 *
		 * @param s the detail message. */
		public DistributionFormatException (String s) {
			super(s);
		}

		/** Constructs a DistributionFormatException with the specified detail message and cause.
		 * 

* Note that the detail message associated with cause is not automatically incorporated in this * exception's detail message. * * @param message the detail message (which is saved for later retrieval by the {@link Throwable#getMessage()} method). * @param cause the cause (which is saved for later retrieval by the {@link Throwable#getCause()} method). (A null * value is permitted, and indicates that the cause is nonexistent or unknown.) */ public DistributionFormatException (String message, Throwable cause) { super(message, cause); } /** Constructs a DistributionFormatException with the specified cause and a detail message of * (cause==null ? null : cause.toString()) (which typically contains the class and detail message of cause * ). This constructor is useful for exceptions that are little more than wrappers for other throwables. * * @param cause the cause (which is saved for later retrieval by the {@link Throwable#getCause()} method). (A null * value is permitted, and indicates that the cause is nonexistent or unknown.) */ public DistributionFormatException (Throwable cause) { super(cause); } } public abstract static class Adapter { final String category; final Class type; public Adapter (String category, Class type) { this.category = category; this.type = type; } public abstract D toDistribution (String[] args); public abstract String[] toParameters (D distribution); public static double parseDouble (String v) { try { return Double.parseDouble(v); } catch (NumberFormatException nfe) { throw new DistributionFormatException("Not a double value: " + v, nfe); } } public static float parseFloat (String v) { try { return Float.parseFloat(v); } catch (NumberFormatException nfe) { throw new DistributionFormatException("Not a float value: " + v, nfe); } } public static int parseInteger (String v) { try { return Integer.parseInt(v); } catch (NumberFormatException nfe) { throw new DistributionFormatException("Not an int value: " + v, nfe); } } public static long parseLong (String v) { try { return Long.parseLong(v); } catch (NumberFormatException nfe) { throw new DistributionFormatException("Not a long value: " + v, nfe); } } } public abstract static class DoubleAdapter extends Adapter { public DoubleAdapter (String category) { super(category, DoubleDistribution.class); } } public abstract static class FloatAdapter extends Adapter { public FloatAdapter (String category) { super(category, FloatDistribution.class); } } public abstract static class IntegerAdapter extends Adapter { public IntegerAdapter (String category) { super(category, IntegerDistribution.class); } } public abstract static class LongAdapter extends Adapter { public LongAdapter (String category) { super(category, LongDistribution.class); } } private static final ObjectMap, Adapter> adapters = new ObjectMap, Adapter>(); static { // // Constant distributions // adapters.put(ConstantDoubleDistribution.class, new DoubleAdapter("constant") { @Override public ConstantDoubleDistribution toDistribution (String[] args) { if (args.length != 1) throw invalidNumberOfArgumentsException(args.length, 1); return new ConstantDoubleDistribution(parseDouble(args[0])); } @Override public String[] toParameters (ConstantDoubleDistribution distribution) { return new String[] {Double.toString(distribution.getValue())}; } }); adapters.put(ConstantFloatDistribution.class, new FloatAdapter("constant") { @Override public ConstantFloatDistribution toDistribution (String[] args) { if (args.length != 1) throw invalidNumberOfArgumentsException(args.length, 1); return new ConstantFloatDistribution(parseFloat(args[0])); } @Override public String[] toParameters (ConstantFloatDistribution distribution) { return new String[] {Float.toString(distribution.getValue())}; } }); adapters.put(ConstantIntegerDistribution.class, new IntegerAdapter("constant") { @Override public ConstantIntegerDistribution toDistribution (String[] args) { if (args.length != 1) throw invalidNumberOfArgumentsException(args.length, 1); return new ConstantIntegerDistribution(parseInteger(args[0])); } @Override public String[] toParameters (ConstantIntegerDistribution distribution) { return new String[] {Integer.toString(distribution.getValue())}; } }); adapters.put(ConstantLongDistribution.class, new LongAdapter("constant") { @Override public ConstantLongDistribution toDistribution (String[] args) { if (args.length != 1) throw invalidNumberOfArgumentsException(args.length, 1); return new ConstantLongDistribution(parseLong(args[0])); } @Override public String[] toParameters (ConstantLongDistribution distribution) { return new String[] {Long.toString(distribution.getValue())}; } }); // // Gaussian distributions // adapters.put(GaussianDoubleDistribution.class, new DoubleAdapter("gaussian") { @Override public GaussianDoubleDistribution toDistribution (String[] args) { if (args.length != 2) throw invalidNumberOfArgumentsException(args.length, 2); return new GaussianDoubleDistribution(parseDouble(args[0]), parseDouble(args[1])); } @Override public String[] toParameters (GaussianDoubleDistribution distribution) { return new String[] {Double.toString(distribution.getMean()), Double.toString(distribution.getStandardDeviation())}; } }); adapters.put(GaussianFloatDistribution.class, new FloatAdapter("gaussian") { @Override public GaussianFloatDistribution toDistribution (String[] args) { if (args.length != 2) throw invalidNumberOfArgumentsException(args.length, 2); return new GaussianFloatDistribution(parseFloat(args[0]), parseFloat(args[1])); } @Override public String[] toParameters (GaussianFloatDistribution distribution) { return new String[] {Float.toString(distribution.getMean()), Float.toString(distribution.getStandardDeviation())}; } }); // // Triangular distributions // adapters.put(TriangularDoubleDistribution.class, new DoubleAdapter("triangular") { @Override public TriangularDoubleDistribution toDistribution (String[] args) { switch (args.length) { case 1: return new TriangularDoubleDistribution(parseDouble(args[0])); case 2: return new TriangularDoubleDistribution(parseDouble(args[0]), parseDouble(args[1])); case 3: return new TriangularDoubleDistribution(parseDouble(args[0]), parseDouble(args[1]), parseDouble(args[2])); default: throw invalidNumberOfArgumentsException(args.length, 1, 2, 3); } } @Override public String[] toParameters (TriangularDoubleDistribution distribution) { return new String[] {Double.toString(distribution.getLow()), Double.toString(distribution.getHigh()), Double.toString(distribution.getMode())}; } }); adapters.put(TriangularFloatDistribution.class, new FloatAdapter("triangular") { @Override public TriangularFloatDistribution toDistribution (String[] args) { switch (args.length) { case 1: return new TriangularFloatDistribution(parseFloat(args[0])); case 2: return new TriangularFloatDistribution(parseFloat(args[0]), parseFloat(args[1])); case 3: return new TriangularFloatDistribution(parseFloat(args[0]), parseFloat(args[1]), parseFloat(args[2])); default: throw invalidNumberOfArgumentsException(args.length, 1, 2, 3); } } @Override public String[] toParameters (TriangularFloatDistribution distribution) { return new String[] {Float.toString(distribution.getLow()), Float.toString(distribution.getHigh()), Float.toString(distribution.getMode())}; } }); adapters.put(TriangularIntegerDistribution.class, new IntegerAdapter("triangular") { @Override public TriangularIntegerDistribution toDistribution (String[] args) { switch (args.length) { case 1: return new TriangularIntegerDistribution(parseInteger(args[0])); case 2: return new TriangularIntegerDistribution(parseInteger(args[0]), parseInteger(args[1])); case 3: return new TriangularIntegerDistribution(parseInteger(args[0]), parseInteger(args[1]), Float.valueOf(args[2])); default: throw invalidNumberOfArgumentsException(args.length, 1, 2, 3); } } @Override public String[] toParameters (TriangularIntegerDistribution distribution) { return new String[] {Integer.toString(distribution.getLow()), Integer.toString(distribution.getHigh()), Float.toString(distribution.getMode())}; } }); adapters.put(TriangularLongDistribution.class, new LongAdapter("triangular") { @Override public TriangularLongDistribution toDistribution (String[] args) { switch (args.length) { case 1: return new TriangularLongDistribution(parseLong(args[0])); case 2: return new TriangularLongDistribution(parseLong(args[0]), parseLong(args[1])); case 3: return new TriangularLongDistribution(parseLong(args[0]), parseLong(args[1]), parseDouble(args[2])); default: throw invalidNumberOfArgumentsException(args.length, 1, 2, 3); } } @Override public String[] toParameters (TriangularLongDistribution distribution) { return new String[] {Long.toString(distribution.getLow()), Long.toString(distribution.getHigh()), Double.toString(distribution.getMode())}; } }); // // Uniform distributions // adapters.put(UniformDoubleDistribution.class, new DoubleAdapter("uniform") { @Override public UniformDoubleDistribution toDistribution (String[] args) { switch (args.length) { case 1: return new UniformDoubleDistribution(parseDouble(args[0])); case 2: return new UniformDoubleDistribution(parseDouble(args[0]), parseDouble(args[1])); default: throw invalidNumberOfArgumentsException(args.length, 1, 2); } } @Override public String[] toParameters (UniformDoubleDistribution distribution) { return new String[] {Double.toString(distribution.getLow()), Double.toString(distribution.getHigh())}; } }); adapters.put(UniformFloatDistribution.class, new FloatAdapter("uniform") { @Override public UniformFloatDistribution toDistribution (String[] args) { switch (args.length) { case 1: return new UniformFloatDistribution(parseFloat(args[0])); case 2: return new UniformFloatDistribution(parseFloat(args[0]), parseFloat(args[1])); default: throw invalidNumberOfArgumentsException(args.length, 1, 2); } } @Override public String[] toParameters (UniformFloatDistribution distribution) { return new String[] {Float.toString(distribution.getLow()), Float.toString(distribution.getHigh())}; } }); adapters.put(UniformIntegerDistribution.class, new IntegerAdapter("uniform") { @Override public UniformIntegerDistribution toDistribution (String[] args) { switch (args.length) { case 1: return new UniformIntegerDistribution(parseInteger(args[0])); case 2: return new UniformIntegerDistribution(parseInteger(args[0]), parseInteger(args[1])); default: throw invalidNumberOfArgumentsException(args.length, 1, 2); } } @Override public String[] toParameters (UniformIntegerDistribution distribution) { return new String[] {Integer.toString(distribution.getLow()), Integer.toString(distribution.getHigh())}; } }); adapters.put(UniformLongDistribution.class, new LongAdapter("uniform") { @Override public UniformLongDistribution toDistribution (String[] args) { switch (args.length) { case 1: return new UniformLongDistribution(parseLong(args[0])); case 2: return new UniformLongDistribution(parseLong(args[0]), parseLong(args[1])); default: throw invalidNumberOfArgumentsException(args.length, 1, 2); } } @Override public String[] toParameters (UniformLongDistribution distribution) { return new String[] {Long.toString(distribution.getLow()), Long.toString(distribution.getHigh())}; } }); } ObjectMap, Adapter> map; ObjectMap, ObjectMap>> typeMap; public DistributionAdapters () { this.map = new ObjectMap, Adapter>(); this.typeMap = new ObjectMap, ObjectMap>>(); for (ObjectMap.Entry, Adapter> e : adapters.entries()) add(e.key, e.value); } public final void add (Class clazz, Adapter adapter) { map.put(clazz, adapter); ObjectMap> m = typeMap.get(adapter.type); if (m == null) { m = new ObjectMap>(); typeMap.put(adapter.type, m); } m.put(adapter.category, adapter); } @SuppressWarnings("unchecked") public T toDistribution (String value, Class clazz) { StringTokenizer st = new StringTokenizer(value, ", \t\f"); if (!st.hasMoreTokens()) throw new DistributionFormatException("Missing ditribution type"); String type = st.nextToken(); ObjectMap> categories = typeMap.get(clazz); Adapter converter = (Adapter)categories.get(type); if (converter == null) throw new DistributionFormatException("Cannot create a '" + clazz.getSimpleName() + "' of type '" + type + "'"); String[] args = new String[st.countTokens()]; for (int i = 0; i < args.length; i++) args[i] = st.nextToken(); return converter.toDistribution(args); } @SuppressWarnings({"rawtypes", "unchecked"}) public String toString (Distribution distribution) { Adapter adapter = map.get(distribution.getClass()); String args[] = adapter.toParameters(distribution); String out = adapter.category; for (String a : args) out += "," + a; return out; } private static DistributionFormatException invalidNumberOfArgumentsException (int found, int... expected) { String message = "Found " + found + " arguments in triangular distribution; expected "; if (expected.length < 2) message += expected.length; else { String sep = ""; int i = 0; while (i < expected.length - 1) { message += sep + expected[i++]; sep = ", "; } message += " or " + expected[i]; } return new DistributionFormatException(message); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy