/*
* Datei: StaticMethods.java
* Autor(en): Lukas König, http://haibo.iteye.com/blog/322239 (unten)
* Java-Version: 6.0
* Erstellt (vor): 04.10.2008
*
* (c) This file and the EAS (Easy Agent Simulation) framework containing it
* is protected by Creative Commons by-nc-sa license. Any altered or
* further developed versions of this file have to meet the agreements
* stated by the license conditions.
*
* In a nutshell
* -------------
* You are free:
* - to Share -- to copy, distribute and transmit the work
* - to Remix -- to adapt the work
*
* Under the following conditions:
* - Attribution -- You must attribute the work in the manner specified by the
* author or licensor (but not in any way that suggests that they endorse
* you or your use of the work).
* - Noncommercial -- You may not use this work for commercial purposes.
* - Share Alike -- If you alter, transform, or build upon this work, you may
* distribute the resulting work only under the same or a similar license to
* this one.
*
* + Detailed license conditions (Germany):
* http://creativecommons.org/licenses/by-nc-sa/3.0/de/
* + Detailed license conditions (unported):
* http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en
*
* This header must be placed in the beginning of any version of this file.
*/
package eas.miscellaneous;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Desktop;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.lang.reflect.Array;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.zip.Deflater;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import java.util.zip.Inflater;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.FontMapper;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfTemplate;
import com.lowagie.text.pdf.PdfWriter;
import eas.math.fundamentalAlgorithms.type2grammars.ConstantsEarley;
import eas.math.geometry.Rectangle2D;
import eas.miscellaneous.system.FileNamePostfixFilter;
import eas.miscellaneous.system.windowFrames.StaticWindow;
import eas.plugins.Plugin;
import eas.plugins.standard.eaPlugin.StandardPluginForEA;
import eas.plugins.standard.eaPlugin.xmlRecording.XMLAufnLesen;
import eas.plugins.standard.eaPlugin.xmlRecording.XMLAufnSpeichern;
import eas.simulation.Wink;
import eas.simulation.event.EASEvent;
import eas.simulation.spatial.sim2D.marbSimulation.EnvironmentEA;
import eas.simulation.spatial.sim2D.marbSimulation.RobEA;
import eas.simulation.spatial.sim2D.marbSimulation.endlAutomat.EndlicherAutomat;
import eas.simulation.spatial.sim2D.marbSimulation.endlAutomat.GlobaleMARBVariablen;
import eas.simulation.spatial.sim2D.marbSimulation.endlAutomat.RobCode;
import eas.simulation.spatial.sim2D.marbSimulation.endlAutomat.Transition;
import eas.simulation.spatial.sim2D.marbSimulation.endlAutomat.ZInfo;
import eas.simulation.spatial.sim2D.marbSimulation.endlAutomat.conditions.CompLeaf;
import eas.simulation.spatial.sim2D.marbSimulation.endlAutomat.conditions.Condition;
import eas.simulation.spatial.sim2D.marbSimulation.endlAutomat.conditions.ConstLeaf;
import eas.simulation.spatial.sim2D.marbSimulation.endlAutomat.conditions.InnerNode;
import eas.simulation.spatial.sim2D.marbSimulation.statistik.PopSnapshot;
import eas.simulation.spatial.sim2D.marbSimulation.statistik.RobSnapshot;
import eas.simulation.spatial.sim2D.marbSimulation.translator.Translator;
import eas.simulation.spatial.sim2D.marbSimulation.translator.script.ConstantsScript;
import eas.simulation.spatial.sim2D.marbSimulation.translator.script.ScriptInterpreter;
import eas.simulation.spatial.sim2D.marbSimulation.translator.versionOhneErgKante.ConstantsTranslatorWOC;
import eas.simulation.spatial.sim2D.standardEnvironments.AbstractEnvironment2D;
import eas.startSetup.GlobalVariables;
import eas.startSetup.ParCollection;
import eas.startSetup.SingleParameter;
import eas.startSetup.marbBuilder.Vis;
import eas.startSetup.marbBuilder.graph.Knoten;
import eas.statistics.logging.AbstractMsg;
import eas.statistics.logging.MsgDebug;
import eas.statistics.logging.MsgError;
import eas.statistics.logging.MsgInfo;
import eas.statistics.logging.MsgOutput;
import eas.statistics.logging.MsgStage1;
import eas.statistics.logging.MsgWarning;
/**
* Implementiert einige nützliche Methoden, die keiner anderen Klasse
* zugeordnet werden können.
*
* @author Lukas König
*/
public class StaticMethods {
/**
* Ungültiger Modus, der an Stellen zu verwenden ist, wo eine
* Kennzeichnung notwendig ist, dass der Translator in der aktuellen
* Form nicht benutzt werden sollte.
*/
public static final int MODUS_UNGUELTIG = -1;
/**
* Verhaltensautomaten-Modus.
*/
public static final int MODUS_VERHALTEN = 0;
/**
* übersetzermodus.
*/
public static final int MODUS_TRANSLATOR = 1;
/**
* Log-Stufe Stage1.
*/
public static final int LOG_STAGE1 = -1;
/**
* Log-Stufe Output.
*/
public static final int LOG_OUTPUT = 0;
/**
* Log-Stufe Debug.
*/
public static final int LOG_DEBUG = 1;
/**
* Log-Stufe Info.
*/
public static final int LOG_INFO = 2;
/**
* Log-Stufe Warning.
*/
public static final int LOG_WARNING = 3;
/**
* Log-Stufe Error.
*/
public static final int LOG_ERROR = 4;
/**
* Der Zeichensatz zum Zeichnen des Inputfeldes.
*/
public static final char[] ZEICHEN_INPUT = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 0-9
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 10-19
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 20-29
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 30-39
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 40-49
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 50-59
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 60-69
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 70-79
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 80-89
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 90-99
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 100-109
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 110-119
'0', '1', '.', '3', '°', '5', '6', ' ', '#', '9', // 120-129
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 130-139
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 140-149
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 150-159
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 160-169
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 170-179
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 180-189
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 190-199
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 200-209
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 210-219
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 220-229
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 230-239
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 240-249
'0', '1', '2', '3', '4', '5'}; // 250-255
/**
* Die Prioritätenliste für die verschiedenen Farben des Inputfeldes.
*/
public static final int[] PRIORITAET_INPUT = {128,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
120, 121, 123, 125, 126, 127, 129,
130, 131, 132, 133, 134, 135, 136, 137, 138, 139,
140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
160, 161, 162, 163, 164, 165, 166, 167, 168, 169,
170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
180, 181, 182, 183, 184, 185, 186, 187, 188, 189,
190, 191, 192, 193, 194, 195, 196, 197, 198, 199,
210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
220, 221, 222, 223, 224, 225, 226, 227, 228, 229,
230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
240, 241, 242, 243, 244, 245, 246, 247, 248, 249,
250, 251, 252, 253, 254, 255,
124, 122,
};
/**
* Der Zeichensatz zum Zeichnen des Inputfeldes.
*/
public static final char[] ZEICHEN_FELD = {
' ', '§', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 0-9
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 10-19
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 20-29
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 30-39
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 40-49
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 50-59
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 60-69
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 70-79
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 80-89
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 90-99
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 100-109
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 110-119
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 120-129
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 130-139
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 140-149
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 150-159
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 160-169
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 170-179
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 180-189
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 190-199
' ', ' ', ' ', ' ', ' ', ' ', ' ', '°', ' ', ' ', // 200-209
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 210-219
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 220-229
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 230-239
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 240-249
' ', ' ', ' ', ' ', '#', 'R'}; // 250-255
/**
* Die Prioritätenliste für die verschiedenen Farben des Inputfeldes.
*/
public static final int[] PRIORITAET_FELD = {1, 255, 254, 207, 0};
/**
* überlagerung des Default-Konstruktors.
*/
public StaticMethods() {
}
public static int intAt(List<Integer> list, int num) {
if (num < 0 || num >= list.size()) {
return 0;
}
return list.get(num);
}
/**
* Konvertiert eine Translator-Standardsequenz aus Zeiten, als im Programm
* noch keine ergänzenden Kanten existiert haben und somit die Befehle
* verschoben waren, in einen äquivalente Standardsequenz im neuen
* Programm.
*
* @return
*/
public static ArrayList<Integer> convertTransFromFMGWithoutCompletingTransitionsToAequivalentNew(final List<Integer> oldTranslator) {
int i = 0;
ArrayList<Integer> result = new ArrayList<Integer>(oldTranslator.size());
int resSeq;
for (int seq : oldTranslator) {
resSeq = seq;
if (intAt(oldTranslator, i - 2) == 0 && intAt(oldTranslator, i - 3) == 0 && intAt(oldTranslator, i - 4) == 0) {
// Wir sind an zweiter Stelle Y am Beginn eines Zustands: 0, 0, 0, X, Y.
if (seq >= 106) {
resSeq = seq + 1;
}
}
result.add(resSeq);
i++;
}
return result;
}
/**
* Schreibt zwei Strings in die Konsole und kennzeichnet ihre Unterschiede.
*
* @param s1 Der erste String.
* @param s2 Der zweite String.
* @param params Die Parameter.
*/
public static void unterscheide(
final String s1,
final String s2,
final ParCollection params) {
String unterschiede = "";
if (s1.equals(s2)) {
unterschiede = "Strings sind identisch.";
} else {
for (int i = 0; i < s1.length() || i < s2.length(); i++) {
if (s1.length() <= i || s2.length() <= i) {
unterschiede += "-";
} else {
if (s1.charAt(i) == s2.charAt(i)) {
unterschiede += " ";
} else {
unterschiede += "#";
}
}
}
}
StaticMethods.log(
StaticMethods.LOG_INFO,
//"\n(" + s1.length() + "): " +
s1 + "\n",
params,
"plain",
null);
StaticMethods.log(
StaticMethods.LOG_INFO,
//"(" + s2.length() + "): " +
s2 + "\n",
params,
"plain",
null);
StaticMethods.log(
StaticMethods.LOG_INFO,
unterschiede + "\n",
params,
"plain",
null);
}
/**
* Zerlegt einen String in Tokens, wobei <code>trenn</code>
* als Trennsymbol verwendet wird. Am Beginn und am Ende des Strings
* müssen (und dürfen!) keine Trennsymbole stehen. Das Trennzeichen
* darf leer sein (in diesem Ausnahmefall steht das Trennzeichen
* doch am Anfang und gleichzeitig am Ende des Strings).
* <P>
* BSP1: zerlege("a/b/c/d", "/") => [a, b, c, d]
* BSP2: zerlege("abcdefg", "") => [a, b, c, d, e, f, g]
* BSP3: zerlege("a-+-b-+-c-+-d, "-+-") => [a, b, c, d]
*
* NUTZE BESSER: String.split(.)
*
* @param text Die zu zerlegende Sequenz.
* @param trenn Die Trennsequenz.
*
* @return Die Zerlegung in einer <code>ArrayList</code>.
*/
@Deprecated
public static ArrayList<String> zerlege(final String text,
final String trenn) {
ArrayList<String> seq = new ArrayList<String>();
int end = 0;
int anf = 0;
int trennLen = trenn.length();
while (end < text.length()) {
while (end + trennLen < text.length()
&& !text.substring(end, end + trennLen).equals(trenn)) {
end++;
}
if (end + trennLen >= text.length()) {
end = end + trennLen;
}
if (anf != 0) {
anf = anf + trennLen;
}
if (trennLen == 0 && anf == 0) {
end++;
}
if (text.substring(anf, end).equals(ConstantsEarley.EPSILON)) {
end = end + 0;
} else {
seq.add(text.substring(anf, end));
}
anf = end;
end++;
}
if (trenn.equals("") && text.length() > 1) {
seq.add(text.substring(anf, text.length()));
}
return seq;
}
/**
* Erzeugt eine Liste aus Zahlen aus einer bereinigten Stringsequenz.
*
* @param seq Die bereinigte Stringsequenz.
*
* @return Die Liste aus Zahlen.
*/
public static LinkedList<Integer> listSeqAusString(final String seq) {
ArrayList<String> zerlegt;
LinkedList<Integer> liste = new LinkedList<Integer>();
if (seq.equals("")) {
return liste;
}
zerlegt = StaticMethods.zerlege(seq.substring(1), " ");
for (int i = 0; i < zerlegt.size(); i++) {
liste.add(Integer.parseInt(zerlegt.get(i)));
}
return liste;
}
/**
* Erzeugt eine Liste aus Zahlenlisten aus einer Liste bereinigter
* Stringsequenzen.
*
* @param seq Die bereinigten Stringsequenzen.
*
* @return Die Listen aus Zahlen.
*/
@SuppressWarnings(value = { "unchecked" })
public static LinkedList<Integer>[] listSeqAusStrings(final String[] seq) {
LinkedList<Integer>[] listen = new LinkedList[seq.length];
for (int i = 0; i < seq.length; i++) {
listen[i] = StaticMethods.listSeqAusString(seq[i]);
}
return listen;
}
/**
* Erzeugt eine bereinigte Stringsequenz aus einer Liste von Zahlen.
*
* @param seq Liste von Zahlen.
*
* @return Die bereinigte Stringsequenz.
*/
public static String stringAusListSeq(final List<Integer> seq) {
EndlicherAutomat ea = new EndlicherAutomat();
return ea.bereinige(ea.ausgabe(seq));
}
/**
* Erzeugt eine Liste bereinigter Stringsequenzen aus einer Liste von
* Zahlen-Listen.
*
* @param seqs Liste von Zahlen-Listen.
*
* @return Die bereinigte Stringsequenz.
*/
public static String[] stringAusListSeqs(
final List<Integer>[] seqs) {
String[] codes = new String[seqs.length];
for (int i = 0; i < seqs.length; i++) {
codes[i] = StaticMethods.stringAusListSeq(seqs[i]);
}
return codes;
}
/**
* Klont ein beliebiges (serialisierbares) Objekt.
*
* @param o Das zu klonende Objekt.
*
* @return Das geklonte Objekt.
*/
public static Object seriaClone(final Object o) {
try {
// Serialisieren des Objekts
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream(out);
os.writeObject(o);
os.flush();
// Deserialisieren des Objekts
ByteArrayInputStream in = new ByteArrayInputStream(out
.toByteArray());
ObjectInputStream is = new ObjectInputStream(in);
Object ret = is.readObject();
is.close();
os.close();
return ret;
} catch (Exception e) {
throw new RuntimeException("Objekt nicht serialisierbar:\n" + o);
}
}
/**
* Erzeugt eine normierte Byte-Zahl aus einem Integer. Der Integer muss
* einen Byte-Wert speichern. Die Ausgabe ist ein String der Länge drei,
* wobei bei Zahlen der Länge < 3 vorne mit Nullen aufgefüllt wird.
*
* @param z Die zu normierende Zahl als Integer.
*
* @return Die normierte Zahl als String.
*/
public static String normZahl(final int z) {
return StaticMethods.normZahl(z, 3);
}
/**
* Erzeugt eine normierte Zahl aus einem Integer. Dabei werden führende
* Nullen eingefügt. Die Zahl darf nicht länger als n sein.
*
* @param z Die zu normierende Zahl als Integer.
* @param n Die Anzahl der Stellen.
*
* @return Die normierte Zahl als String.
*/
public static String normZahl(
final long z,
final int n) {
final String zahl = "" + z;
String nullen = "";
if (zahl.length() <= n) {
for (int i = 0; i < n - zahl.length(); i++) {
nullen = "0" + nullen;
}
} else {
throw new RuntimeException("Zahl kann nicht normiert werden.");
}
return nullen + zahl;
}
/**
* Testet, ob <code>c</code> eine Ziffer aus {0, ..., 9} ist.
*
* @param c Der zutestende Character.
*
* @return <code>true</code>, gdw. <code>c</code> eine Ziffer ist.
*/
public static boolean istZiff(final char c) {
return c == '0' || c == '1' || c == '2' || c == '3' || c == '4'
|| c == '5' || c == '6' || c == '7' || c == '8' || c == '9';
}
/**
* Gibt die (erste) Position eines Strings in einem Array zurück.
* Führende 0'en und Groß- Kleinschreibung werden ignoriert.
*
* @param strArray Der Array, in dem der String gesucht werden soll.
* @param str Der String, der gesucht werden soll.
*
* @return Die (erste) Position des Strings im Array. Falls der String
* nicht im Aray vorkommt, wird -1 zurückgegeben.
*/
public static int posSuch(final String[] strArray,
final String str) {
boolean zahl = true;
try {
for (int i = 0; i < str.length(); i++) {
if (!istZiff(str.charAt(i))) {
zahl = false;
}
}
if (zahl) {
return Integer.parseInt(str);
}
for (int i = 0; i < strArray.length; i++) {
if ((strArray[i].toLowerCase()).equals(str.toLowerCase())) {
return i;
}
}
return -1;
} catch (NumberFormatException e) {
return -1;
}
}
/**
* Gibt zurück, ob zwei Zahlen "ungefähr" gleich sind. Die maximale
* Unterscheidung zwischen ihnen wird auch übergeben.
*
* @param a Die erste der zu vergleichenden Zahlen.
* @param b Die zweite der zu vergleichenden Zahlen.
* @param max Die maximale Unterscheidung.
*
* @return Ob "a ~ b".
*/
public static boolean ungefGleich(final int a,
final int b,
final int max) {
return Math.abs(a - b) <= max;
}
/**
* Testet, ob ein Zeichen ein Sonderzeichen aus den in der Klasse
* Konstanten definierten Zeichen ist.
*
* @param c Das zu testende Zeichen.
*
* @return <code>true</code>, gdw. das Zeichen ein Sonderzeichen ist.
*/
public static boolean istSonderzeichen(final char c) {
return c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.EING
|| c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.FALSE
|| c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.GL
|| c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.GR
|| c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.GRGL
|| c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KA
|| c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KL
|| c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KLGL
|| c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KZ
|| c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.ODER
|| c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.TRUE
|| c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.UGL
|| c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.UND
|| c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.UNGF
|| c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.NUNGF;
}
/**
* Testet, ob ein Zeichen ein Operator ist.
*
* @param c Das zu überprüfende Zeichen.
*
* @return Ob c ein Operator ist.
*/
public static boolean istOper(final char c) {
return
c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.GL
|| c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.GR
|| c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.GRGL
|| c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.UNGF
|| c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KL
|| c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KLGL
|| c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.ODER
|| c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.NUNGF
|| c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.UGL
|| c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.UND;
}
/**
* Testet, ob ein Zeichen ein Operator ist.
*
* @param c Das zu überprüfende Zeichen.
*
* @return Ob c ein Operator ist.
*/
public static boolean istOperator(final int c) {
return
c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.GL_CODE
|| c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.GR_CODE
|| c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.GRGL_CODE
|| c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.UNGF_CODE
|| c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KL_CODE
|| c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KLGL_CODE
|| c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.ODER_CODE
|| c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.NUNGF_CODE
|| c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.UGL_CODE
|| c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.UND_CODE;
}
/**
* Testet, ob ein Zeichen ein boolescher Operator ist.
*
* @param c Das zu überprüfende Zeichen.
*
* @return Ob c ein boolescher Operator ist.
*/
public static boolean istBoolOperator(final int c) {
return c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.UND
|| c == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.ODER;
}
/**
* Erzeugt eine <code>Condition</code> aus einer Text-Bedingung, die
* nicht formatiert sein muss.
*
* @param bedingung Die (möglicherweise unformatierte) Bedingung.
*
* @return Die Condition.
*/
public static Condition ausBed(final String bedingung) {
return ausFormatBed(EndlicherAutomat.formatBed(bedingung));
}
/**
* Erzeugt eine <code>Condition</code> aus einer Text-Bedingung.
* <P>
* Kommentar: Beizeiten verbessern - läuft bisher mit quadratischer
* Laufzeit in der Anzahl der Operatoren.
* => Verbesserung durch Umwandeln in Postfix.
*
* @param bedingung Die Textbedingung.
*
* @return Die <code>Condition</code>.
*/
public static Condition ausFormatBed(final String bedingung) {
int klammerAuf = 1;
if (bedingung.length() == 3) {
if (bedingung.charAt(1)
== eas.simulation.spatial.sim2D.marbSimulation.Konstanten.TRUE) {
return new ConstLeaf(true);
} else if (bedingung.charAt(1)
== eas.simulation.spatial.sim2D.marbSimulation.Konstanten.FALSE) {
return new ConstLeaf(false);
}
}
if (bedingung.charAt(1) != eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KA) {
int op1;
int op2;
boolean sens1;
boolean sens2;
char op;
int i = 4;
if (bedingung.charAt(1) == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.EING) {
sens1 = true;
op1 = Integer.parseInt(bedingung.substring(3, 6));
} else {
sens1 = false;
op1 = Integer.parseInt(bedingung.substring(0, 3));
}
while (!StaticMethods.istOper(bedingung.charAt(i))) {
i++;
}
op = bedingung.charAt(i);
if (bedingung.charAt(i + 3)
== eas.simulation.spatial.sim2D.marbSimulation.Konstanten.EING) {
sens2 = true;
op2 = Integer.parseInt(bedingung.substring(i + 5, i + 8));
} else {
sens2 = false;
op2 = Integer.parseInt(bedingung.substring(i + 2, i + 5));
}
return new CompLeaf(op1, op2, sens1, sens2, op);
}
for (int i = 4; i < bedingung.length(); i += 3) {
if (bedingung.charAt(i) == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KA) {
klammerAuf++;
} else if (bedingung.charAt(i)
== eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KZ) {
klammerAuf--;
} else if (klammerAuf == 1
&& istBoolOperator(bedingung.charAt(i))) {
return new InnerNode(ausFormatBed(bedingung.substring(3,
i - 1)),
ausFormatBed(bedingung.substring(i + 2,
bedingung.length() - 3)),
bedingung.charAt(i));
}
}
throw new RuntimeException("Keine gültige Textbedingung.");
}
/**
* Erzeugt einen Vektor aus <code>Condition</code>s aus einem Vektor aus
* Text-Bedingungen.
*
* @param beds Die Textbedingungen.
*
* @return Die <code>Condition</code>s.
*/
public static Condition[] ausFormatBeds(final String[] beds) {
Condition[] conds = new Condition[beds.length];
for (int i = 0; i < beds.length; i++) {
conds[i] = StaticMethods.ausFormatBed(beds[i]);
}
return conds;
}
/**
* Erzeugt Conditions aus einer Liste von unformatierten Bedingungen.
*
* @param beds Die Bedingungen.
*
* @return Die Conditions.
*/
public static Condition[] ausBeds(final String[] beds) {
Condition[] conds = new Condition[beds.length];
for (int i = 0; i < beds.length; i++) {
conds[i] = StaticMethods.ausBed(beds[i]);
}
return conds;
}
/**
* Schreibt einen Log-Eintrag in die Konsole (siehe überladene Methode).
* Der Zusatzparameter wird als "" übergeben.
*
* @param stufe Die Stufe des Logs.
* @param s Der auszugebende String.
* @param params Die Parameter.
*/
public static void log(final int stufe,
final String s,
final ParCollection params) {
StaticMethods.log(stufe, s, params, "", null);
}
/**
* Gibt eine als Message gegebene Nachricht aus, wobei der Zeitstempel mit
* ausgegeben wird. Das Message-Objekt wird an die erzeugte
* Ausgabenachricht angehängt.
*
* @param msg Die Nachricht.
* @param params Der Parametersatz.
*/
public static void log(
final AbstractMsg msg,
final ParCollection params) {
StaticMethods.log(
msg.getStufe(),
"[Nachrichtenstempel: "
+ msg.getDatum()
+ "] "
+ msg.getMessage(),
params,
"",
msg);
}
public static void logError(
final String s,
final ParCollection params) {
StaticMethods.log(StaticMethods.LOG_ERROR, s, params);
}
public static void logWarning(
final String s,
final ParCollection params) {
StaticMethods.log(StaticMethods.LOG_WARNING, s, params);
}
public static void logInfo(
final String s,
final ParCollection params) {
StaticMethods.log(StaticMethods.LOG_INFO, s, params);
}
public static void logDebug(
final String s,
final ParCollection params) {
StaticMethods.log(StaticMethods.LOG_DEBUG, s, params);
}
public static void logOutput(
final String s,
final ParCollection params) {
StaticMethods.log(StaticMethods.LOG_OUTPUT, s, params);
}
public static void logStage1(
final String s,
final ParCollection params) {
StaticMethods.log(StaticMethods.LOG_STAGE1, s, params);
}
/**
* Produces and stores a logging message and optionally prints it to the
* console.
*
* The logging levels:<BR>
* -1: STAGE1 <BR>
* 0 : OUTPUT <BR>
* 1 : DEBUG <BR>
* 2 : INFO <BR>
* 3 : WARNING <BR>
* 4 : ERROR <BR>
*
* @param stufe Die Stufe des Logs.
* @param s Der auszugebende String.
* @param params Die Parameter.
* @param zusatzPar Ein Zusatzparameter. Bisher definiert:
* - "plain" => Ausgabe ohne Logstufe und newline.
* @param zusatz Ein zusätzliches Objekt, das die Mitteilung genauer
* spezifiziert.
*/
public static void log(final int stufe,
final String s,
final ParCollection params,
final String zusatzPar,
final Object zusatz) {
int logParStufe;
AbstractMsg msg = null;
ParCollection parameters = params;
if (parameters == null) {
parameters = GlobalVariables.getPrematureParameters();
}
if (parameters != null && parameters.getLogOutputLevel() != null) {
logParStufe = parameters.getLogOutputLevel().intValue();
} else {
logParStufe = 0;
}
// Ausgabe des Loggings.
if (stufe >= logParStufe) {
if (!zusatzPar.toLowerCase().equals("plain")) {
System.out.println();
System.out.print(new Date() + " - ");
if (stufe == StaticMethods.LOG_STAGE1) {
System.out.print("STAGE1: ");
} else if (stufe == LOG_OUTPUT) {
System.out.print("OUTPUT: ");
} else if (stufe == LOG_DEBUG) {
System.out.print("DEBUG : ");
} else if (stufe == LOG_INFO) {
System.out.print("INFO : ");
} else if (stufe == LOG_WARNING) {
System.out.print("WARN : ");
} else if (stufe == LOG_ERROR) {
System.out.print("ERROR : ");
} else {
System.out.print("[N.A.]: ");
}
}
System.out.print(s);
}
// Speichern des Loggings.
if (stufe == LOG_OUTPUT) {
msg = new MsgOutput(s, System.currentTimeMillis(), zusatz);
} else if (stufe == LOG_DEBUG) {
msg = new MsgDebug(s, System.currentTimeMillis(), zusatz);
} else if (stufe == LOG_INFO) {
msg = new MsgInfo(s, System.currentTimeMillis(), zusatz);
} else if (stufe == LOG_WARNING) {
msg = new MsgWarning(s, System.currentTimeMillis(), zusatz);
} else if (stufe == LOG_ERROR) {
msg = new MsgError(s, System.currentTimeMillis(), zusatz);
} else if (stufe == LOG_STAGE1) {
msg = new MsgStage1(s, System.currentTimeMillis(), zusatz);
}
parameters.addMsg(msg);
}
/**
* Lädt ein Bild und gibt es zurück.
*
* @param datName Der Dateiname.
*
* @return Das Bild.
*/
public static BufferedImage loadImage(final String datName) {
File dat = new File(datName);
try {
BufferedImage image = ImageIO.read(dat);
return image;
} catch (IOException e) {
// StackTraceElement[] stack = e.getStackTrace();
// for (int i = 0; i < stack.length; i++) {
// SonstMeth.log(SonstMeth.LOG_DEBUG,
// e.getStackTrace()[i].toString(),
// pars);
// }
StaticMethods.log(StaticMethods.LOG_INFO,
"Bitmapdatei nicht geladen: " + dat,
GlobalVariables.getPrematureParameters());
return new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
// throw new RuntimeException("\nBitmapdatei nicht geladen.");
}
}
/**
* Liest eine Bitmapdatei in ein Array aus Pixelfarben.
*
* @param pars Die Parameter.
*
* @return 2D-Array aus Pixelfarben.
*/
public static byte[][] liesImage(final String datName) {
try {
BufferedImage img = loadImage(datName);
byte[] a = new byte[1];
byte[][] aa = new byte[img.getWidth()][img.getHeight()];
for (int j = 0; j < aa[0].length; j++) {
for (int i = 0; i < aa.length; i++) {
img.getRaster().getDataElements(i, j, 1, 1, a);
aa[i][j] = a[0];
}
}
return aa;
} catch (final Exception e) {
// SonstMeth.log(
// SonstMeth.LOG_ERROR,
// "Bitmap-Feld nicht geladen: "
// + pars.getStdPfad()
// + File.separatorChar
// + pars.getUmgebungDatname(),
// pars);
byte[][] aa = new byte[1][1];
return aa;
}
}
/**
* Speichert einen Text in eine Textdatei.
*
* @param verz Das Verzeichnis.
* @param datName Die Datei.
* @param text Der zu speichernde Text.
* @param params Die Parameter.
*/
public static void speichereTextDatei(final String verz,
final String datName,
final String text,
final ParCollection params) {
FileWriter f1 = null;
try {
f1 = new FileWriter(verz + File.separator + datName);
f1.write(text);
f1.close();
} catch (IOException e) {
if (params != null) {
log(StaticMethods.LOG_INFO, "Fehler beim Erstellen der Text-Datei: " + verz + File.separator + datName, params);
}
// throw new RuntimeException(e);
}
}
/**
* Speichert mehrere Zeilen Text aus einer ArrayList in eine Textdatei.
*
* @param verz Das Verzeichnis.
* @param datName Die Datei.
* @param text Der zu speichernde Text.
* @param params Die Parameter.
*/
public static void speichereTextAusArray(
final String verz,
final String datName,
final List<String> text,
final ParCollection params) {
FileWriter f1 = null;
Iterator<String> it = text.iterator();
try {
f1 = new FileWriter(verz + File.separator + datName);
while (it.hasNext()) {
f1.write(it.next() + "\n");
}
f1.close();
} catch (IOException e) {
if (params != null) {
log(StaticMethods.LOG_INFO, "Fehler beim Erstellen der Text-Datei: " + verz + File.separator + datName, params);
}
// throw new RuntimeException("Datei konnte nicht erstellt werden.");
}
}
/**
* Speichert mehrere Zeilen Text aus einer ArrayList in eine Textdatei.
*
* @param verz Das Verzeichnis.
* @param datName Die Datei.
* @param text Der zu speichernde Text.
* @param params Die Parameter.
*/
public static void speichereTextAusArray(
final String verz,
final String datName,
final String[] text,
final ParCollection params) {
ArrayList<String> liste = new ArrayList<String>(text.length);
for (String s : text) {
liste.add(s);
}
StaticMethods.speichereTextAusArray(verz, datName, liste, params);
}
public static LinkedList<String> liesTextArray(
final File datei,
final ParCollection params) {
return liesTextArray(datei, params, false);
}
public static LinkedList<String> liesTextArray(
final File datei,
final ParCollection params,
final boolean quiet) {
String pfad = datei.getParent();
String dateiname = datei.getName();
LinkedList<String> textArray = StaticMethods.liesTextArray(pfad, dateiname, params, quiet);
return textArray;
}
public static LinkedList<String> liesTextArray(
final String verz,
final String datName,
final ParCollection params) {
return liesTextArray(verz, datName, params, false);
}
/**
* Liest zeilenweise Text aus einer Textdatei und gibt einen String-Array
* der gesamten Datei zurück.
*
* @param verz The directory path.
* @param datName The file name.
* @param params The parameter collection.
* @param quiet If NO error message is logged in error case.
*
* @return Der zeilenweise gelsene Text aus der Datei.
*/
public static LinkedList<String> liesTextArray(
final String verz,
final String datName,
final ParCollection params,
final boolean quiet) {
String zwisch;
LinkedList<String> textArray = new LinkedList<String>();
try {
BufferedReader f1 =
new BufferedReader(
new FileReader(verz + File.separator + datName));
zwisch = f1.readLine();
while (zwisch != null) {
textArray.add(zwisch);
zwisch = f1.readLine();
}
f1.close();
} catch (IOException e) {
if (!quiet) {
log(StaticMethods.LOG_INFO,
"Text file could not be read: "
+ verz + File.separator + datName + "\n" + e,
params);
throw new RuntimeException(
"Text file could not be read.");
}
}
return textArray;
}
public static LinkedList<String[]> readCSVFile(
final File datei,
final String separator,
final ParCollection params) {
String pfad = datei.getParent();
String dateiname = datei.getName();
return readCSVFile(pfad, dateiname, separator, params);
}
/**
* @param verz
* @param datName
* @param separator
* @param params
* @return
*/
public static LinkedList<String[]> readCSVFile(
final String verz,
final String datName,
final String separator,
final ParCollection params) {
LinkedList<String> rawData = StaticMethods.liesTextArray(
verz, datName, params);
LinkedList<String[]> data
= new LinkedList<String[]>();
for (String s : rawData) {
data.add(s.split(separator));
}
return data;
}
/**
* Extrahiert die Fitness einer bestimmten Population aus einer Aufnahme.
*
* @param a Die Aufnahme.
* @param popNum Die Nummer der Population.
*
* @return Die Fitnesswerte der Roboter der Population als String.
*/
public static String extrEinzelPopFitness(final XMLAufnSpeichern a,
final int popNum) {
String s = "";
PopSnapshot p = a.getPops().get(popNum);
RobSnapshot[] robs = p.getRobSchnapp();
for (int i = 0; i < robs.length; i++) {
s = s + robs[i].getFitness();
if (i < robs.length - 1) {
s = s + "_";
}
}
return s;
}
/**
* Extrahiert die Zusatzwerte der aktuellen Aufnahme.
*
* @param aufn Die Aufnahme.
*
* @return Die gespeicherten Zusatzinformationen (Kollisionen und GP).
*/
public static String extrZusatz(final XMLAufnLesen aufn) {
LinkedList<AbstractMsg> msgs
= aufn.getParams().getMsgs(
null,
Long.MIN_VALUE,
Long.MAX_VALUE);
String s = "";
long old = Long.MIN_VALUE;
long akt;
for (AbstractMsg m : msgs) {
akt = m.getDatum();
if (akt < old) {
throw new RuntimeException(
"Falsche Reihenfolge der Nachrichten");
}
if (m.getZusatz() != null
&& m.getZusatz().toString().charAt(0) == '[') {
String[] zusaetze = m.getZusatz().toString().replaceAll("\\[",
"").replaceAll("\\]", "").replaceAll(" ", "")
.split(",");
ArrayList<Long> zus = new ArrayList<Long>(zusaetze.length);
for (String zusatz : zusaetze) {
zus.add(Long.parseLong(zusatz));
}
for (Long l : zus) {
s += l + ";";
}
s += "\n";
}
old = akt;
}
return s;
}
/**
* Bennent eine Datei um.
*
* @param quelle Name der Quelldatei.
* @param ziel Name der Zieldatei.
* @param params Die Parameter.
*/
public static void renameDAT(final String quelle,
final String ziel,
final ParCollection params) {
String pfad = params.getStdDirectory();
File quellDatei = new File(pfad + File.separator + quelle);
File zielDatei = new File(pfad + File.separator + ziel);
if (quellDatei.renameTo(zielDatei)) {
return;
} else {
throw new RuntimeException("Datei konnte nicht umbenannt werden");
}
}
/**
* Bennent alle Dateien im Standardverzeichnis um. Dabei wird die
* Dateinamenerweiterung von ext1 auf ext2 geändert.
*
* @param ext1 Die Quelldateiendung.
* @param ext2 Die Zieldateiendung.
* @param params Die Parameter
*/
public static void renameALL(final String ext1,
final String ext2,
final ParCollection params) {
File pfad = new File(params.getStdDirectory());
String[] alleDat = pfad.list(new FileNamePostfixFilter(ext1));
String neuName;
if (alleDat == null) {
return;
}
for (int i = 0; i < alleDat.length; i++) {
neuName = alleDat[i].substring(0,
alleDat[i].length() - 4)
+ "." + ext2;
renameDAT(alleDat[i], neuName, params);
}
}
/**
* löscht den String mit dem angegebenen Namen.
*
* @param datNam Der Dateiname.
* @param params Die Parameter.
*/
public static boolean deleteDAT(final String datNam) {
File datei = new File(datNam);
if (datei.delete()) {
return true;
} else {
GlobalVariables.getPrematureParameters().logDebug("Cannot delete file: '" + datei.getAbsolutePath() + "'.");
return false;
}
}
/**
* löscht alle Dateien mit der angegebenen Erweiterung aus dem
* Standardverzeichnis.
*
* @param ext Die Erweiterung.
* @param params Die Parameter.
*/
public static void deleteALL(final String ext,
final ParCollection params) {
File pfad = new File(params.getStdDirectory());
String[] alleDat = pfad.list(new FileNamePostfixFilter(ext));
if (alleDat == null) {
return;
}
for (int i = 0; i < alleDat.length; i++) {
deleteDAT(params.getStdDirectory() + File.separator + alleDat[i]);
}
}
/**
* Gibt zurück, ob ein Element in einem Array enthalten ist.
*
* @param array Das Array, in dem das Element gesucht werden soll.
* @param element Das Element, das gesucht werden soll.
*
* @return Ob das Element in dem Array enthalten ist.
*/
public static boolean enthaelt(final int[] array,
final int element) {
for (int i = 0; i < array.length; i++) {
if (array[i] == element) {
return true;
}
}
return false;
}
/**
* @param feld Das Feld.
* @param x X-Koordinate.
* @param y Y-Koordinate.
* @param rasterX Zugriffsraster.
* @param rasterY Zugriffsraster.
* @param farben Array, in dem die Farben zurückgegeben werden.
*
* @return Die Verteilung der Farben im Feld.
*/
private static long[] pixGes(final byte[][] feld,
final int x,
final int y,
final int rasterX,
final int rasterY,
final long[] farben) {
int startX = x;
int startY = y;
int endeX = x + rasterX;
int endeY = y + rasterY;
for (int i = 0; i < farben.length; i++) {
farben[i] = 0;
}
if (startX < 0) {
startX = 0;
}
if (startY < 0) {
startY = 0;
}
if (endeX > feld.length) {
endeX = feld.length;
}
if (endeY > feld[0].length) {
endeY = feld[0].length;
}
for (int i = startX; i < endeX; i += 1) {
for (int j = startY; j < endeY; j += 1) {
farben[feld[i][j] + 128]++;
}
}
return farben;
}
/**
* @param feld Das Feld.
* @param rasterX Das Raster, je größer desto enger.
* @param rasterY Das Raster, je größer desto enger.
* @param zeichen Die den Farben zugeordneten Zeichen (das Array muss
* 256 Felder haben.
* @param prioritaet Nach welcher Priorität die Farben genommen werden.
*
* @return Die Umgebung als Stringausgabe.
*/
public static String feldAusgabe(final byte[][] feld,
final int rasterX,
final int rasterY,
final char[] zeichen,
final int[] prioritaet) {
String s = "";
boolean gesetzt;
long[] farben = new long[256];
if (zeichen.length != 256) {
throw new RuntimeException("Ein Array hat eine falsche Länge: ("
+ zeichen.length);
}
for (int j = 0; j < feld[0].length; j += rasterY) {
for (int i = 0; i < feld.length; i += rasterX) {
pixGes(feld, i, j, rasterX, rasterY, farben);
gesetzt = false;
for (int k = 0; k < prioritaet.length; k++) {
if (farben[prioritaet[k]] > 0) {
s = s + zeichen[prioritaet[k]];
gesetzt = true;
break;
}
}
if (!gesetzt) {
s = s + " ";
}
}
s = s + "\n";
}
return s;
}
/**
* Gibt entweder den übergebenen String-Vektor zurück oder erzeugt einen
* Vektor gleicher Länge mit leeren Strings abhängig von der Variable
* <code>aut</code>.
*
* @param origSeqs Die Originalstrings.
* @param aut Ob die Originalstrings zurückgegeben werden sollen.
*
* @return Die Originalstrings oder leere Strings.
*/
public static String[] erzeugeSeqs(final String[] origSeqs,
final boolean aut) {
if (aut) {
return origSeqs;
} else {
return new String[origSeqs.length];
}
}
/**
* Gibt entweder den übergebenen Condition-Vektor zurück oder erzeugt
* einen Vektor gleicher Länge mit leeren Conditions abhängig von der
* Variable <code>aut</code>.
*
* @param origSeqs Die Originalstrings.
* @param aut Ob die Originalstrings zurückgegeben werden sollen.
*
* @return Die Originalstrings oder leere Strings.
*/
public static Condition[] erzeugeConds(final Condition[] origSeqs) {
return origSeqs;
}
/**
* Speichert die Datei <code>in</code> in die Datei <code>out</code>,
* wobei eine GZ-Kompression verwendet wird.
*
* @param in Der Dateiname der Inputdatei.
* @param out Der Dateiname der Outputdatei.
* @param inLoeschen Ob die Originaldatei gelöscht werden soll.
*/
public static void packeDatei(
final String in,
final String out,
final boolean inLoeschen) {
int read = 0;
byte[] data = new byte[1024];
try {
// Original-Datei mit Stream verbinden
File f = new File(in);
FileInputStream inP = new FileInputStream(f);
// Ausgabedatei erstellen
GZIPOutputStream outP =
new GZIPOutputStream(
new FileOutputStream(out));
// Alle Daten der Original-Datei in die Ausgabedatei schreiben
while ((read = inP.read(data, 0, 1024)) != -1) {
outP.write(data, 0, read);
}
inP.close();
outP.close();
if (inLoeschen) {
f.delete(); // Original-Datei löschen
}
} catch (final Exception e) {
e.printStackTrace();
}
}
/**
* Speichert die Datei <code>in</code> in die Datei <code>out</code>,
* wobei eine GZ-Entkompression verwendet wird.
*
* @param in Der Dateiname der Inputdatei.
* @param out Der Dateiname der Outputdatei.
* @param inLoeschen Ob die Originaldatei gelöscht werden soll.
*
* @return Ob die Datei entpackt wurde.
*/
public static boolean entpackeDatei(final String in,
final String out,
final boolean inLoeschen) {
String source = in, destination = out;
InputStream is = null;
OutputStream os = null;
try {
is = new GZIPInputStream(new FileInputStream(source));
os = new FileOutputStream(destination);
byte[] buffer = new byte[8192];
for (int length = is.read(buffer);
length != -1;
length = is.read(buffer)) {
os.write(buffer, 0, length);
}
if (inLoeschen) {
(new File(source)).delete();
}
} catch (final IOException e) {
StaticMethods.log(StaticMethods.LOG_WARNING,
"Datei nicht entpackt: " + in,
null);
return false;
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
StaticMethods.log(StaticMethods.LOG_WARNING,
"Datei nicht entpackt: " + in,
null);
return false;
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
StaticMethods.log(StaticMethods.LOG_WARNING,
"Datei nicht entpackt: " + in,
null);
return false;
}
}
}
return true;
}
/**
* Erzeugt einen einzigen Automaten aus den übergebenen Einzelautomaten
* mit Aktivierungsbedingungen.
*
* @param endAuts Die Automaten.
* @param conds Die zugehörigen Bedingungen.
*
* @return Gesamtautomat, dessen Verhalten zu dem der übergebenen Einzel-
* automaten äquivalent ist.
*/
@SuppressWarnings({ "unchecked", "rawtypes" } )
public static EndlicherAutomat gesamtAutomat(
final EndlicherAutomat[] endAuts,
final Condition[] conds,
final ParCollection params) {
HashMap[] knotZuord = new HashMap[endAuts.length];
EndlicherAutomat neu = new EndlicherAutomat();
int lfdNr = 1;
ArrayList<Integer> knot;
ArrayList<Integer> knot1;
Iterator<Integer> it, it1;
Iterator<Transition> it3;
Integer aktKnNum;
Knoten aktKn;
ZInfo info;
Knoten zielKn;
Integer zielKnNum;
Condition aktBed;
Condition neuBed = null;
Condition zwischBed;
int numOrig1, numOrig2;
int idlBefehl;
EndlicherAutomat[] endAs = new EndlicherAutomat[endAuts.length];
LinkedList<Transition> trans;
Transition tran;
String[] args = {"log 4"};
if (conds == null
|| endAuts.length != conds.length
|| endAuts.length == 0) {
ParCollection parColl = GlobalVariables.getPrematureParameters();
parColl.overwriteParameterList(args);
StaticMethods.log(StaticMethods.LOG_ERROR,
"Gesamtautomat konnte nicht erzeugt werden.",
parColl);
}
for (int i = 0; i < endAs.length; i++) {
endAs[i] = new EndlicherAutomat();
if (params.getParValueBoolean("UseTranslatorWITHCompletingTransitions")) {
endAs[i].generateFromSequence(
endAuts[i].erzeugeStringSeq(),
eas.simulation.spatial.sim2D.marbSimulation.translator.ConstantsTranslator.getStdTranslatorBE(params),
false, params);
} else {
endAs[i].generateFromSequence(
endAuts[i].erzeugeStringSeq(),
ConstantsTranslatorWOC.getStdTranslatorBE(params),
false, params);
}
if (endAs[i].istLeer()) {
endAs[i].einfuegenKnoten(Integer.MAX_VALUE,
StaticMethods.posSuch(
eas.simulation.ConstantsSimulation.getBefehlNamenArray(params),
"stp"),
1,
1);
endAs[i].setStart(endAs[i].holeKnoten(Integer.MAX_VALUE));
}
}
// Neue Knoten zuordnen.
for (int i = 0; i < endAs.length; i++) {
knotZuord[i] = new HashMap<Integer, Integer>();
knot = new ArrayList<Integer>(endAs[i].holAdj().keySet());
it = knot.iterator();
while (it.hasNext()) {
aktKnNum = it.next();
aktKn = endAs[i].holeKnoten(aktKnNum);
info = aktKn.getInfo();
neu.einfuegenKnoten(lfdNr,
info.getAktion(),
info.getParam(),
info.getAlter());
knotZuord[i].put(aktKnNum, lfdNr);
lfdNr++;
}
}
// Neue Kanten INTER Automaten zuordnen.
for (int i = 0; i < endAs.length; i++) {
zielKn = endAs[i].holeStartzustand();
if (zielKn != null) {
zielKnNum = (Integer) knotZuord[i].get(zielKn.holeName());
neuBed = StaticMethods.ausFormatBed(conds[i].formatted());
for (int j = 0; j < i; j++) {
zwischBed = StaticMethods.ausFormatBed(conds[j].formatted());
zwischBed.negiere();
neuBed = new InnerNode(neuBed,
zwischBed,
eas.simulation.spatial.sim2D.marbSimulation.Konstanten.UND);
}
for (int j = 0; j < endAs.length; j++) {
if (j != i) {
knot = new ArrayList<Integer>(
endAs[j].holAdj().keySet());
it = knot.iterator();
while (it.hasNext()) {
aktKnNum = (Integer) knotZuord[j].get(it.next());
neu.einfuegKante(aktKnNum, zielKnNum, neuBed, 1);
}
}
}
}
}
// Neue Kanten INTRA Automaten zuordnen.
for (int i = 0; i < endAs.length; i++) {
knot1 = new ArrayList<Integer>(endAs[i].holAdj().keySet());
it1 = knot1.iterator();
while (it1.hasNext()) {
numOrig1 = it1.next();
aktKnNum = (Integer) knotZuord[i].get(numOrig1);
aktKn = endAs[i].holeKnoten(numOrig1);
if (aktKn.getInfo() != null
&& aktKn.getInfo().getBedingungen() != null) {
trans = aktKn.getInfo().getBedingungen();
it3 = trans.iterator();
while (it3.hasNext()) {
tran = it3.next();
numOrig2 = tran.getFolgezustand();
zielKnNum = (Integer) knotZuord[i].get(numOrig2);
aktBed = tran.getCond();
if (aktBed != null) {
neu.einfuegKante(aktKnNum, zielKnNum, aktBed, 1);
}
}
}
}
}
// true - Kanten zu den einzelnen Startknoten einfügen.
for (int i = 0; i < endAs.length; i++) {
zielKn = endAs[i].holeStartzustand();
if (zielKn != null) {
zielKnNum = (Integer) knotZuord[i].get(zielKn.holeName());
knot = new ArrayList<Integer>(endAs[i].holAdj().keySet());
it = knot.iterator();
while (it.hasNext()) {
aktKnNum = (Integer) knotZuord[i].get(it.next());
neu.einfuegKante(aktKnNum,
zielKnNum,
StaticMethods.ausBed("t"),
1);
}
}
}
// Einen IDLE-Startknoten einfügen.
idlBefehl = StaticMethods.posSuch(eas.simulation.ConstantsSimulation.getBefehlNamenArray(params),
"IDL");
neu.einfuegenKnoten(lfdNr, idlBefehl, 1, 1);
neu.setStart(neu.holeKnoten(lfdNr));
for (int i = 0; i < conds.length; i++) {
if (i > 0) {
neuBed = conds[i];
} else {
neuBed = StaticMethods.ausFormatBed(conds[i].formatted());
for (int j = 1; j < conds.length; j++) {
zwischBed = StaticMethods.ausFormatBed(conds[j].formatted());
zwischBed.negiere();
neuBed = new InnerNode(
neuBed,
zwischBed,
eas.simulation.spatial.sim2D.marbSimulation.Konstanten.ODER);
}
}
if (conds.length == 1) {
neuBed = StaticMethods.ausBed("t");
}
if (endAs[i].holeStartzustand() != null) {
neu.einfuegKante(lfdNr,
(Integer)
knotZuord[i].get(endAs[i].holeStartzustand().holeName()),
neuBed,
1);
}
}
return neu;
}
/**
* Die berechneten Wahrscheinlichkeiten.
*/
private static HashMap<String, Double> berConds;
/**
* Die Anzahl der Iterationen.
*/
private static HashMap<String, Long> berCondsIt;
/**
* Gibt eine probabilistische Abschätzung des prozentualen Anteils an
* wahren Belegungen der Bedingung zurück.
*
* @param cond Die Bedingung.
* @param erstmalig Wie viele Iterationen beim ersten Mal.
* @param spaeter Wie viele Iterationen ab dem zweiten Mal.
*
* @return Prozentualer Anteil an wahren Belegungen.
*/
public static double condStrength(final Condition cond,
final long erstmalig,
final long spaeter) {
long iterat;
Condition c = cond.simplify();
Random rand = new Random();
HashSet<Integer> sensors = cond.aktSens();
int[] sens;
int max = 0;
double value;
boolean vorhanden = false;
String cForm = c.formatted();
double newVal;
Iterator<Integer> it = sensors.iterator();
while (it.hasNext()) {
int zwisch = it.next();
if (zwisch > max) {
max = zwisch;
}
}
sens = new int[max];
if (StaticMethods.berConds == null) {
berConds = new HashMap<String, Double>();
berCondsIt = new HashMap<String, Long>();
}
if (berConds.containsKey(cForm)) {
iterat = spaeter;
vorhanden = true;
} else {
iterat = erstmalig;
}
value = 0;
for (long i = 0; i < iterat; i++) {
it = sensors.iterator();
while (it.hasNext()) {
sens[it.next() - 1] = rand.nextInt(256);
}
if (c.evaluiereSens(sens)) {
value++;
}
}
if (vorhanden) {
double oldVal = StaticMethods.berConds.get(cForm);
long oldIt = StaticMethods.berCondsIt.get(cForm);
newVal = (oldVal * oldIt + value) / (oldIt + spaeter);
StaticMethods.berConds.put(cForm, newVal);
StaticMethods.berCondsIt.put(cForm, oldIt + spaeter);
} else {
value /= erstmalig;
StaticMethods.berConds.put(cForm, value);
StaticMethods.berCondsIt.put(cForm, erstmalig);
newVal = value;
}
return newVal;
}
/**
* @param modus Der Modus (übersetzer oder Verhalten).
*
* @return Die minimale Befehlsnummer je nach Modus.
*/
public static int minBef(final int modus) {
if (modus == StaticMethods.MODUS_VERHALTEN) {
return eas.simulation.ConstantsSimulation.MIN_INST_BEH;
} else if (modus == StaticMethods.MODUS_TRANSLATOR) {
return eas.simulation.ConstantsSimulation.minInstTranslator();
} else {
return -1;
}
}
/**
* @param modus Der Modus (Übersetzer oder Verhalten).
*
* @return Die maximale Befehlsnummer je nach Modus.
*/
public static int maxBef(final int modus, final ParCollection params) {
int anzGen = GlobaleMARBVariablen.GENERISCHE_ZUSTAENDE.size();
if (modus == StaticMethods.MODUS_VERHALTEN) {
return eas.simulation.ConstantsSimulation.MAX_INST_BEH
+ anzGen;
} else if (modus == StaticMethods.MODUS_TRANSLATOR) {
return eas.simulation.ConstantsSimulation.maxInstTranslator(params);
} else {
return -1;
}
}
public static LinkedList<Integer> verboteneBefehle(final int modus, final ParCollection params) {
LinkedList<Integer> verboten = new LinkedList<Integer>();
if (modus == StaticMethods.MODUS_TRANSLATOR
&& !params.getParValueBoolean("UseTranslatorWITHCompletingTransitions")) {
verboten.add(106);
}
return verboten;
}
/**
* @param modus Der Modus (Übersetzer oder Verhalten).
*
* @return Die minimale Variablennummer je nach Modus.
*/
public static int minVar(final int modus) {
if (modus == StaticMethods.MODUS_VERHALTEN) {
return ConstantsScript.MIN_VAR_BEH;
} else if (modus == StaticMethods.MODUS_TRANSLATOR) {
return ConstantsScript.MIN_VAR_TRANS;
} else {
return -1;
}
}
/**
* @param modus Der Modus (übersetzer oder Verhalten).
*
* @return Die maximale Variablennummer je nach Modus.
*/
public static int maxVar(final int modus) {
int anzSens = 0;
anzSens = GlobaleMARBVariablen.anzahlGenerischerSensoren;
if (modus == StaticMethods.MODUS_VERHALTEN) {
return ConstantsScript.MAX_VAR_BEH + anzSens;
} else if (modus == StaticMethods.MODUS_TRANSLATOR) {
return ConstantsScript.MAX_VAR_TRANS;
} else {
return -1;
}
}
/**
* Gibt eine gleichverteilte Zufallszahl aus
* {min, min + 1, ..., max}
* zurück.
*
* @param min Das Minimum.
* @param max Das Maximum.
* @param rand Der Zufallsgenerator.
* @return Gleichverteilte Zufallszahl zwischen min und max.
*/
public static int glVertZwischen(
final int min,
final int max,
final Random rand) {
if (min > max) {
throw new RuntimeException(
"Fehler in Methode glVertZwischen: min > max");
}
return Math.abs(rand.nextInt()) % (max - min + 1) + min;
}
/**
* Gibt eine Zahl zurück, die modulo des angegebenen Bereichs der
* eingegebenen Zahl entspricht.
*
* Beispiel (min = 3, max = 7, zahl = i, f = modZwischen):
* i : -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...
* f(i, min, max): 4, 5, 6, 7, 3, 4, 5, 6, 7, 3, 4, 5, ...
*
* @param zahl Die Zahl.
* @param min Der Beginn des Bereichs.
* @param max Das Ende des Bereichs.
*
* @return Zahl, die der Eingabe modulo des Bereichs entspricht.
*/
public static int modZwischen(
final int zahl,
final int min,
final int max) {
return modZwischen(zahl, min, max, null);
}
/**
* Gibt eine Zahl zurück, die modulo des angegebenen Bereichs der
* eingegebenen Zahl entspricht. Dabei können auch "verbotene" Zahlen
* angegeben werden, die nicht zurückgegeben werden dürfen.
*
* Beispiel (min = 3, max = 7, v = {5}, zahl = i, f = modZwischen):
* i : -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...
* f(i, min, max, v): 3, 4, 6, 7, 3, 4, 6, 7, 3, 4, 6, 7, ...
*
* @param zahl Die Zahl.
* @param min Der Beginn des Bereichs.
* @param max Das Ende des Bereichs.
* @param verboten Verbotene Zahlen, die nicht zurückgegeben werden
* dürfen.
*
* @return Zahl, die der Eingabe modulo des Bereichs entspricht.
*/
public static int modZwischen(
final int zahl,
final int min,
final int max,
final List<Integer> verboten) {
if (verboten == null || verboten.size() == 0) {
if (min > max) {
throw new RuntimeException(
"Fehler in Methode modZwischen: min > max");
}
if (zahl >= min) {
return (zahl - min) % (max - min + 1) + min;
} else {
return -(StaticMethods.modZwischen(-zahl, -max, -min));
}
} else {
int zwischenWert = StaticMethods.modZwischen(zahl, min, max);
if (verboten.contains(zwischenWert)) {
return StaticMethods.modZwischen(zahl + 1, min, max, verboten);
} else {
return zwischenWert;
}
// Collections.sort(verboten);
// int diff = 0;
//
// for (int i : verboten) {
// if (i >= min && i <= max) {
// diff++;
// }
// }
//
// // Als "Index" der gewünschten Zahl (ab min) interpretierbar.
// int zwischenWert = modZwischen(zahl, min, max - diff);
//
// for (int i : verboten) {
// if (i >= min && i <= zwischenWert) {
// zwischenWert++;
// }
// }
//
// return zwischenWert;
}
}
/**
* Speichert den als Sequenz übergebenen Automaten in einem
* Standardverzeichnis und unter einem Standardnamen. Achtung: die Methode
* erzeugt ein Vis-Objekt mit zugehörigem Roboter und ist daher
* ineffizient ==> sparsam gebrauchen.
*
* @param seqOrig Die Sequenz.
* @param augabeDat Der Name der Ausgabedatei.
* @param params Die Parameter.
*/
public static void saveAutPNG(
final String seqOrig,
final String augabeDat,
final ParCollection params) {
String[] seqs = new String[1];
String seq
= eas.simulation.spatial.sim2D.marbSimulation.endlAutomat.EndlicherAutomat.bereinigeStatic(seqOrig);
seqs[0] = seq;
Vis zwisch = new Vis("", seqs, null, 1, params, null, null);
zwisch.getRob().erzeugeAusSequenz(0, seq, null, false);
zwisch.savePNGandPDF(augabeDat);
}
/**
* Gibt den Dateinamen ohne Erweiterung zurück (Internet).
*
* @param fileName
* Der Dateiname.
*
* @return Der Dateiname ohne Erweiterung.
*/
public static String datNamOhneErw(final String fileName) {
File tmpFile = new File(fileName);
tmpFile.getName();
int whereDot = tmpFile.getName().lastIndexOf('.');
if (0 < whereDot && whereDot <= tmpFile.getName().length() - 2) {
return StaticMethods.datNamOhneErw(tmpFile.getName()
.substring(0, whereDot));
// extension = filename.substring(whereDot+1);
}
return fileName;
}
/**
* Gibt den Dateinamen ohne HINTERSTE Erweiterung zurück (Internet).
*
* @param fileName Der Dateiname.
*
* @return Der Dateiname ohne HINTERSTE Erweiterung.
*/
public static String datNamOhneHintErw(final String fileName) {
File tmpFile = new File(fileName);
tmpFile.getName();
int whereDot = tmpFile.getName().lastIndexOf('.');
if (0 < whereDot && whereDot <= tmpFile.getName().length() - 2) {
return tmpFile.getName().substring(0, whereDot);
// extension = filename.substring(whereDot+1);
}
return fileName;
}
/**
* Gibt einen String des Stack-Traces einer Exception zurück.
*
* @param e Die Exception.
*
* @return Der Stack-Trace.
*/
public static String getStackTrace(final Exception e) {
String s = "";
for (StackTraceElement einzEl : e.getStackTrace()) {
s += "\n" + einzEl.toString();
}
return s;
}
/**
* Kompressor.
*/
private static Deflater compressor;
/**
* Dekompressor.
*/
private static Inflater decompressor;
/**
* Komprimiert einen Byte-Array.
*
* @param input Byte-Array.
* @param params Der Parametersatz.
*
* @return Komprimierter Array.
* @throws Exception Fehler.
*/
public static byte[] compressByteStream(
final byte[] input,
final ParCollection params) throws Exception {
// Compressor with highest level of compression
if (compressor == null) {
compressor = new Deflater();
compressor.setLevel(Deflater.BEST_COMPRESSION);
}
// Give the compressor the data to compress
compressor.setInput(input);
compressor.finish();
// Create an expandable byte array to hold the compressed data.
// It is not necessary that the compressed data will be smaller than
// the uncompressed data.
ByteArrayOutputStream bos = new ByteArrayOutputStream(input.length);
// Compress the data
byte[] buf = new byte[input.length + 100];
while (!compressor.finished()) {
int count = compressor.deflate(buf);
bos.write(buf, 0, count);
}
try {
bos.close();
} catch (Exception e) {
StaticMethods.log(
StaticMethods.LOG_ERROR,
"Kompression fehlgeschlagen: " + e,
params);
throw e;
}
// Get the compressed data
byte[] compressedData = bos.toByteArray();
compressor = null;
return compressedData;
}
/**
* Dekomprimiert einen Byte-Array.
*
* @param input Byte-Array.
* @param params Der Parametersatz.
*
* @return Dekomprimierter Array.
* @throws Exception Fehlerbehandlung.
*/
public static byte[] decompressByteStream(
final byte[] input,
final ParCollection params) throws Exception {
// Initialize decompressor.
if (decompressor == null) {
decompressor = new Inflater();
}
decompressor.setInput(input); // Give the decompressor the data to decompress.
decompressor.finished();
// Create an expandable byte array to hold the decompressed data.
// It is not necessary that the decompressed data will be larger than
// the compressed data.
ByteArrayOutputStream bos = new ByteArrayOutputStream(input.length);
// Decompress the data
byte[] buf = new byte[input.length + 100];
try {
while (!decompressor.finished())
{
bos.write(buf, 0, decompressor.inflate(buf));
}
bos.close();
} catch (Exception e) {
StaticMethods.log(
StaticMethods.LOG_ERROR,
"Dekompression fehlgeschlagen: " + e,
params);
throw e;
}
decompressor = null;
// Get the decompressed data.
return bos.toByteArray();
}
/**
* Dekomprimiert einen String.
*
* @param input String.
* @param params Der Parametersatz.
*
* @return Dekomprimierter String.
* @throws Exception Fehler.
*/
public static String decompressString(
final String input,
final ParCollection params) throws Exception {
return new String(StaticMethods.decompressByteStream(
input.getBytes(),
params));
}
/**
* Komprimiert einen String.
*
* @param input String.
* @param params Der Parametersatz.
*
* @return Komprimierter String.
* @throws Exception Fehler.
*/
public static String compressString(
final String input,
final ParCollection params) throws Exception {
return new String(StaticMethods.compressByteStream(
input.getBytes(),
params));
}
/**
* @param dateiname Der Dateiname.
*
* @return Die Endung des Dateinamens (nach dem letzten Punkt).
* Falls es keinen Punkt gibt: "".
*/
public static String datEndung(final String dateiname) {
if (dateiname.split("\\.").length > 0) {
return dateiname.split("\\.")[dateiname.split("\\.").length - 1];
} else {
return "";
}
}
/**
* Erzeugt eine einfache Ausgabe aus einer Liste:
* [e1, e2, e3] ==> e1,e2,e3
*
* @param liste Die Liste.
*
* @return Die einfache Ausgabe der Liste.
*/
public static String ListToString(final List<?> liste) {
String ausgabe = "";
for (int i = 0; i < liste.size() - 1; i++) {
ausgabe += liste.get(i) + ",";
}
if (liste.size() > 0) {
ausgabe += liste.get(liste.size() - 1);
}
return ausgabe;
}
/**
* Returns an ImageIcon, or null if the path was invalid.
*
* @param path Pfad der Image-Datei.
* @param description Beschreibung der Datei.
*/
public static ImageIcon createImageIcon(
final String path,
final String description) {
return new ImageIcon(path, description);
}
/**
* Erzeugt einen Roboter aus einem RobCode.
*
* @param robcode Der Robcode.
* @param umg Die Umgebung, die zum Roboter gehört. Achtung: der
* Roboter wird nicht automatisch platziert.
* @param params Der Parametersatz.
* @param rand Der Zufallsgenerator.
*
* @return Der Roboter.
*/
public static RobEA robcodeToRob(
final RobCode robcode,
final EnvironmentEA umg,
final ParCollection params,
final Random rand) {
Translator[] transs = new Translator[1];
if (params.getParValueBoolean("UseTranslatorWITHCompletingTransitions")) {
transs[0] = eas.simulation.spatial.sim2D.marbSimulation.translator.ConstantsTranslator.getStdTranslatorBE(params);
} else {
transs[0] = ConstantsTranslatorWOC.getStdTranslatorBE(params);
}
RobEA rob = new RobEA(
robcode.getVStdCodes(),
null,
umg,
robcode.getId(),
params,
rand,
false,
new ScriptInterpreter(params, StaticMethods.MODUS_VERHALTEN),
transs,
StaticMethods.convertPluginsToStdPluginsForEA(params.getPlugins(), params));
return rob;
}
/**
* Löscht ein ganzes Verzeichnis rekursiv mit allem Inhalt
* (oder eine Datei).
*
* @param dir Das zu löschende Verzeichnis-
*
* @return Ob das Verzeichnis gelöscht werden konnte.
*/
public static boolean delDir(File dir){
if (dir.isDirectory()){
String[] entries = dir.list();
for (int x=0;x<entries.length;x++){
File aktFile = new File(dir.getPath(),entries[x]);
delDir(aktFile);
}
return dir.delete();
}
else{
return dir.delete();
}
}
public static StaticWindow showImage(
final BufferedImage img,
final String name) {
return showImage(img, name, true);
}
public static StaticWindow showImage(
final BufferedImage img,
final String name,
final boolean display) {
StaticWindow w = new StaticWindow(
"Static Image View [" + name + "]",
img.getWidth(null) + 50,
img.getHeight(null) + 50,
display);
JScrollPane jsp = new JScrollPane(new JLabel(new ImageIcon(img)));
w.getContentPane().add(jsp);
if (display) {
w.setVisible(true);
}
return w;
}
/**
* Normalizes a vector such that the minimal entry is exactly min and the
* maximal entry is exactly max, while the other entries are scaled in a
* linear way in between.
*
* @param vector The vector to normalize.
* @param desiredMin The future minimal value.
* @param desiredMax The future maximal value.
*
* @return The normalized vector.
*/
public static Double[] normalize(Double[] vector, double desiredMin, double desiredMax) {
double foundMin = Double.POSITIVE_INFINITY;
double foundMax = Double.NEGATIVE_INFINITY;
for (double d : vector) {
if (d < foundMin) {
foundMin = d;
}
if (d > foundMax) {
foundMax = d;
}
}
return normalize(vector, foundMin, foundMax, desiredMin, desiredMax);
}
/**
* Normalizes a vector such that the minimal entry is exactly min and the
* maximal entry is exactly max, while the other entries are scaled in a
* linear way in between.
*
* @param vector The vector to normalize.
* @param desiredMin The future minimal value.
* @param desiredMax The future maximal value.
* @param vecMin The minimal value in the vector.
* @param vecMax The maximal value in the vector.
*
* @return The normalized vector.
*/
public static Double[] normalize(
Double[] vector,
double vecMin,
double vecMax,
double desiredMin,
double desiredMax) {
Double[] normalized = new Double[vector.length];
double factor = (desiredMax - desiredMin) / (vecMax - vecMin);
double newMin = (vecMin + vecMin) * factor - desiredMin;
if (factor == Double.POSITIVE_INFINITY || factor == Double.NEGATIVE_INFINITY || factor == Double.NaN) {
for (int i = 0; i < vector.length; i++) {
normalized[i] = (desiredMax + desiredMin) / 2;
}
} else {
for (int i = 0; i < vector.length; i++) {
normalized[i] = (vector[i] + vecMin) * factor - newMin;
}
}
return normalized;
}
/*
* Im folgenden wird durch einen Code aus dem Internet das "Unmögliche"
* möglich gemacht: Zur Laufzeit bestimmen, über welche Generics eine
* Klasse instantiiert worden ist. Für ein Beispiel siehe Methode
* getActualAgentType der Klasse AbstractEnvironment.
* Code-Herkunft: http://haibo.iteye.com/blog/322239
*/
public static Class<?> getClass(Type type) {
if (type instanceof Class) {
return (Class<?>) type;
} else if (type instanceof ParameterizedType) {
return getClass(((ParameterizedType) type).getRawType());
} else if (type instanceof GenericArrayType) {
Type componentType = ((GenericArrayType) type)
.getGenericComponentType();
Class<?> componentClass = getClass(componentType);
if (componentClass != null) {
return Array.newInstance(componentClass, 0).getClass();
} else {
return null;
}
} else {
return null;
}
}
/**
* Get the actual type arguments a child class has used to extend a generic
* base class.
*
* @param baseClass
* the base class
* @param childClass
* the child class
* @return a list of the raw classes for the actual type arguments.
*/
public static <T> List<Class<?>> getTypeArguments(
Class<T> baseClass,
Class<? extends T> childClass) {
Map<Type, Type> resolvedTypes = new HashMap<Type, Type>();
Type type = childClass;
// start walking up the inheritance hierarchy until we hit baseClass
while (!baseClass.equals(getClass(type))) {
if (type instanceof Class) {
// there is no useful information for us in raw types, so just
// keep going.
type = ((Class<?>) type).getGenericSuperclass();
} else {
ParameterizedType parameterizedType = (ParameterizedType) type;
Class<?> rawType = (Class<?>) parameterizedType.getRawType();
Type[] actualTypeArguments = parameterizedType
.getActualTypeArguments();
TypeVariable<?>[] typeParameters = rawType.getTypeParameters();
for (int i = 0; i < actualTypeArguments.length; i++) {
resolvedTypes.put(typeParameters[i], actualTypeArguments[i]);
}
if (!rawType.equals(baseClass)) {
type = rawType.getGenericSuperclass();
}
}
}
// finally, for each actual type argument provided to baseClass,
// determine (if possible)
// the raw class for that type argument.
Type[] actualTypeArguments;
if (type instanceof Class) {
actualTypeArguments = ((Class<?>) type).getTypeParameters();
} else {
actualTypeArguments = ((ParameterizedType) type)
.getActualTypeArguments();
}
List<Class<?>> typeArgumentsAsClasses = new ArrayList<Class<?>>();
// resolve types by chasing down type variables.
for (Type baseType : actualTypeArguments) {
while (resolvedTypes.containsKey(baseType)) {
baseType = resolvedTypes.get(baseType);
}
typeArgumentsAsClasses.add(getClass(baseType));
}
return typeArgumentsAsClasses;
}
/**
* Konvertiert eine Liste von Plugins in eine Liste von StandardEA-Plugins.
* Dabei werden
* - Plugins, die schon EAPlugins sind, einfach gecastet;
* - Plugins, die auf EnvironmentEA arbeiten, umgewandelt, indem ein neues
* PluginEA erzeugt wird, das die Methoden des alten Plugins aufruft;
* - alle übrigen Plugins ignoriert und NICHT zur Liste hinzugefügt.
*
* @param plugins Die Liste der zu konvertierenden Plugins.
* @param params Die Parameter.
*
* @return Die konvertierte Liste von Plugins.
*/
public static List<StandardPluginForEA> convertPluginsToStdPluginsForEA(
List<Plugin<?>> plugins,
ParCollection params) {
LinkedList<StandardPluginForEA> stdPlug = new LinkedList<StandardPluginForEA>();
if (plugins == null) {
return stdPlug;
}
for (Plugin<?> p : plugins) {
try {
StandardPluginForEA plugEA = (StandardPluginForEA) p;
stdPlug.add(plugEA);
} catch (Exception e) {
try {
@SuppressWarnings("unchecked")
final Plugin<EnvironmentEA> pFinal = (Plugin<EnvironmentEA>) p;
StandardPluginForEA plugEA = new StandardPluginForEA() {
private static final long serialVersionUID = -4817871383227727295L;
@Override
public void runDuringSimulation(EnvironmentEA env, Wink simZyk,
ParCollection params) {
pFinal.runDuringSimulation(env, simZyk, params);
}
@Override
public void runBeforeSimulation(EnvironmentEA env, ParCollection params) {
pFinal.runBeforeSimulation(env, params);
}
@Override
public void runAfterSimulation(EnvironmentEA env, ParCollection params) {
pFinal.runAfterSimulation(env, params);
}
@Override
public String id() {
return pFinal.id();
}
@Override
public void handleEvent(EASEvent e, EnvironmentEA env, Wink lastTimeStep,
ParCollection params) {
pFinal.handleEvent(e, env, lastTimeStep, params);
}
@Override
public List<SingleParameter> getParameters() {
return pFinal.getParameters();
}
@Override
public void onSimulationResumed(EnvironmentEA env,
Wink resumeTime, ParCollection params) {
}
};
stdPlug.add(plugEA);
} catch (Exception e1) {
StaticMethods.logWarning(
"Achtung: Plugin '"
+ p.id()
+ "' konnte nicht zu StandardPluginEA konvertiert werden",
params);
}
}
}
StaticMethods.logInfo(
"Plugin-Konvertierung -- "
+ stdPlug.size()
+ " von "
+ plugins.size()
+ " Plugins nach StandardPluginEA konvertiert.",
params);
return stdPlug;
}
/**
* Processes a given string in the (hopefully) same way java does with
* command line parameters, i.e., split at every space except for those
* occuring between two quotation marks.
*
* @param parametersRaw The raw parameter string.
*
* @return A list of parameters as processed by java when reading command
* line parameters.
*/
public static String[] processStringAsCommandLineParameters(final String parsRaw) {
String parametersRaw = parsRaw;
while (parametersRaw.contains("\"\"")) {
parametersRaw = parametersRaw.replaceAll("\"\"", "\"");
}
String[] parameters;
boolean inQuotMarks = false;
String specialString = " tY_NE_ESEL ";
String firstStepProcessedParameters = "";
int finishedUntil = 0;
for (int i = 0; i < parametersRaw.length(); i++) {
if (parametersRaw.charAt(i) == '"') {
inQuotMarks = !inQuotMarks;
firstStepProcessedParameters += parametersRaw.substring(finishedUntil, i);
finishedUntil = i + 1;
} else if (!inQuotMarks && parametersRaw.charAt(i) == ' ') {
firstStepProcessedParameters += parametersRaw.substring(finishedUntil, i) + specialString;
finishedUntil = i + 1;
}
}
if (finishedUntil < parametersRaw.length() - 1) {
firstStepProcessedParameters += parametersRaw.substring(finishedUntil, parametersRaw.length());
}
parameters = firstStepProcessedParameters.split(specialString);
return parameters;
}
/**
* Generates a line chart from data in a cvs file.
* A list of columns to consider can be given (null considers all columns).
* Note that all rows have to have the same number of columns. The entries
* in all non-headings have to be double values, otherwise they are
* ignored.
*
* @param csvFile The cvs file.
* @param columns The columns (first column denoted by 0).
* @param separator The csv separator.
* @param firstRowHeading If the first row contains headings.
*
* @return The chart (null if no data is available).
*/
public static JFreeChart generateChartFromCVS(
File csvFile,
int[] columns,
String separator,
boolean firstRowHeading) {
int[] col;
// Preprocessing.
LinkedList<String[]> csvContent = StaticMethods.readCSVFile(
csvFile,
separator,
GlobalVariables.getPrematureParameters());
if (csvContent == null || csvContent.size() == 0 || (firstRowHeading && csvContent.size() == 1) || csvContent.get(0).length == 0) {
return null;
}
col = columns;
if (col == null) {
col = new int[csvContent.get(0).length];
for (int i = 0; i < csvContent.get(0).length; i++) {
col[i] = i;
}
}
// Chart generation.
XYSeries[] series = new XYSeries[col.length];
XYSeriesCollection dataset = new XYSeriesCollection();
// Create dataset.
for (int i = 0; i < col.length; i++) {
if (firstRowHeading) {
series[i] = new XYSeries(csvContent.get(0)[col[i]]);
} else {
series[i] = new XYSeries("Column " + col[i]);
}
for (int j = 0; j < csvContent.size(); j++) {
if (!firstRowHeading || j > 0) {
try {
series[i].add(j, Double.parseDouble(csvContent.get(j)[col[i]]));
} catch (Exception e) {
}
}
}
dataset.addSeries(series[i]);
}
JFreeChart chart = ChartFactory.createXYLineChart(
"Content of " + csvFile.getName(), // chart title
"", // x axis label
"", // y axis label
dataset, // data
PlotOrientation.VERTICAL,
true, // include legend
true, // tooltips
false // urls
);
return chart;
}
public static JFreeChart generateLineChartFromYAxisData(
String chartTitle,
String xAxisLabel,
String yAxisLabel,
String[] seriesNames,
Double[][] seriesInt) {
XYSeries[] series = new XYSeries[seriesInt.length];
XYSeriesCollection dataset = new XYSeriesCollection();
XYItemRenderer renderer = new XYLineAndShapeRenderer(true, false);
renderer.setSeriesPaint(1, Color.black);
renderer.setSeriesStroke(1, new BasicStroke(0.75f));
renderer.setSeriesPaint(0, Color.red);
renderer.setSeriesStroke(0, new BasicStroke(1.5f));
for (int i = 0; i < seriesInt.length; i++) {
series[i] = new XYSeries(seriesNames[i]);
for (int j = 0; j < seriesInt[i].length; j++) {
try {
series[i].add(j, seriesInt[i][j]);
} catch (Exception e) {
}
}
dataset.addSeries(series[i]);
}
NumberAxis domain = new NumberAxis(xAxisLabel);
NumberAxis range = new NumberAxis(yAxisLabel);
XYPlot plot = new XYPlot(dataset, domain, range, renderer);
JFreeChart chart = new JFreeChart(chartTitle, plot);
return chart;
}
public static void saveImage(BufferedImage img, File file, String format) {
try {
ImageIO.write(img, format, file);
} catch (IOException e) {
}
}
public static void saveEnvironmentViewAsPDF(
File file,
AbstractEnvironment2D<?> env,
FontMapper mapper) {
try {
OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
writeAsPDF(out, env, mapper);
out.close();
} catch (Exception e) {
throw new RuntimeException("Could not generate PDF '" + file.toString() + "'");
}
}
private static void writeAsPDF(OutputStream out, AbstractEnvironment2D<?> env, FontMapper mapper) {
int width = (int) env.getScreenWidth();
int height = (int) env.getScreenHeight();
Rectangle pagesize = new Rectangle(width , height);
Document document = new Document(pagesize, 50, 50, 50, 50);
try {
PdfWriter writer = PdfWriter.getInstance(document, out);
document.addAuthor("EAS-StaticMethods");
document.addSubject("EAS-StandardSubject");
document.open();
PdfContentByte cb = writer.getDirectContent();
PdfTemplate tp = cb.createTemplate(width, height);
Graphics2D g2 = tp.createGraphics(width, height, mapper);
env.getOutsideView(g2);
g2.dispose();
cb.addTemplate(tp, 0, 0);
} catch (DocumentException de) {
System.err.println(de.getMessage());
}
document.close();
}
/**
* Saves a chart as PDF. This code is taken from the JFreeChart documentation.
*/
public static void saveChartAsPDF(File file, JFreeChart chart, int width,
int height, FontMapper mapper) throws IOException {
OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
writeChartAsPDF(out, chart, width, height, mapper);
out.close();
}
/**
* This code is taken from the JFreeChart documentation.
*/
public static void writeChartAsPDF(OutputStream out, JFreeChart chart,
int width, int height, FontMapper mapper) {
Rectangle pagesize = new Rectangle(width, height);
Document document = new Document(pagesize, 50, 50, 50, 50);
try {
PdfWriter writer = PdfWriter.getInstance(document, out);
document.addAuthor("EAS-ChartPlugin");
document.addSubject(chart.getTitle().getText());
document.open();
PdfContentByte cb = writer.getDirectContent();
PdfTemplate tp = cb.createTemplate(width, height);
Graphics2D g2 = tp.createGraphics(width, height, mapper);
java.awt.geom.Rectangle2D r2D = new java.awt.geom.Rectangle2D.Double(0, 0, width, height);
chart.draw(g2, r2D);
g2.dispose();
cb.addTemplate(tp, 0, 0);
} catch (DocumentException de) {
System.err.println(de.getMessage());
}
document.close();
}
public static void appendLineToFile(String line, RandomAccessFile file) {
try {
file.seek(file.length());
file.writeChars(line + "\n");
// file.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static String roundedOutput(double wert, int stellen) {
StringBuilder sb = new StringBuilder(",##0.");
for (int i=0; i<stellen; i++)
sb.append("0");
DecimalFormat df = new DecimalFormat(sb.toString());
df.setRoundingMode(RoundingMode.HALF_UP);
return df.format(wert);
}
public static double round(double wert, int stellen) {
BigDecimal b = new BigDecimal(wert);
return b.setScale(stellen, BigDecimal.ROUND_HALF_UP).doubleValue();
}
// public static void main(String[] args) {
// File dir = new File("Z:/simGrZahraeder");
// File[] files = dir.listFiles(new FilenameFilter() {
// @Override
// public boolean accept(File dir, String name) {
// return name.endsWith(".csv");
// }
// });
//
// for (File f : files) {
// int[] columns1 = new int[] {100};
// int[] columns2 = new int[] {102};
// System.out.println(f);
// JFreeChart chart = StaticMethods.generateChartFromCVS(
// f,
// columns1,
// ";",
// true);
// StaticMethods.saveImage(chart.createBufferedImage(500, 500), new File(f.getPath() + ".fit.png"), "png");
// chart = StaticMethods.generateChartFromCVS(
// f,
// columns2,
// ";",
// true);
// StaticMethods.saveImage(chart.createBufferedImage(500, 500), new File(f.getPath() + ".korr.png"), "png");
// }
//
// System.out.println("Fertig (2 x " + files.length + " Dateien).");
// }
public static String whoCalledMeInitially() {
try {
throw new Exception("Who called me?");
} catch (Exception e) {
StackTraceElement[] stackTrace = e.getStackTrace();
return stackTrace[stackTrace.length - 1].getClassName();
}
}
public static void execCommand(String command) {
try {
Runtime.getRuntime().exec("cmd /c " + command);
Runtime.getRuntime().exec(command);
// System.out.println();
// System.out.println(command);
// System.out.println();
} catch (Exception e) {}
}
public static void openDocument(File document) throws IOException {
Desktop dt = Desktop.getDesktop();
dt.open(document);
}
public static String liesTextAusDatei(File datei, ParCollection params) {
ArrayList<String> daten = new ArrayList<>(liesTextArray(datei, params));
String s = "";
s += daten.get(0);
for (int i = 1; i < daten.size(); i++) {
s += "\n" + daten.get(i);
}
return s;
}
public static void joinThreads(Collection<Thread> threads) {
threads.stream().filter(t -> t != null).forEach(t ->
{try {t.join();} catch (Exception e) {}});
}
private static HashMap<String, Rectangle2D> windowRectangles = new HashMap<>();
private static HashSet<String> windowsLoaded = new HashSet<>();
/**
* After program start, an attempt to load the stored position (even if not
* existing) has to be performed, otherwise this method will not do anything.
*
* @param window The window to store.
*/
public static void storeWindowFramePosition(JFrame window, String id) {
try {
String title = id;
if (!windowsLoaded.contains(title)) {
return;
}
Rectangle2D rect = new Rectangle2D(
window.getX(),
window.getY(),
window.getX() + window.getWidth(),
window.getY() + window.getHeight());
windowRectangles.put(title, rect);
String[] lines = new String[windowRectangles.size()];
int i = 0;
for (String s : windowRectangles.keySet()) {
lines[i] = s + " === " + windowRectangles.get(s);
i++;
}
speichereTextAusArray("./sharedDirectory", "simFrames.dat", lines, GlobalVariables.getPrematureParameters());
} catch (Exception e) {
}
}
public static void loadWindowFramePosition(JFrame window, String id) {
windowsLoaded.add(id);
try {
LinkedList<String> lines = liesTextArray(new File("./sharedDirectory/simFrames.dat"), GlobalVariables.getPrematureParameters());
for (String s : lines) {
String[] ss = s.split(" === ");
String title = ss[0];
Rectangle2D rect = Rectangle2D.parseRectangle2D(ss[1]);
if (title.equals(id)) {
for (int i = 0; i < 10; i++) {
window.setLocation(
(int) rect.upperLeftCorner().x,
(int) rect.upperLeftCorner().y);
window.setSize(
(int) rect.lowerRightCorner().x - (int) rect.upperLeftCorner().x,
(int) rect.lowerRightCorner().y - (int) rect.upperLeftCorner().y);
}
}
windowRectangles.put(title, rect);
}
} catch (Exception e) {
}
}
// Ende gut, alles gut.
}