zeja
Erfahrenes Mitglied
Unterstützt werden alle Eingabeformate. Diese werden an ihrere Endung erkannt.
Java:
package de.tutorials.quiz9;
import java.awt.Color;
import java.awt.Desktop;
import java.awt.Graphics2D;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import javax.imageio.ImageIO;
import de.tutorials.quiz9.TurtleFile.Type;
public class PaintingTurtle {
private static class RecoverPoint {
private int anglePosition;
private Point2D.Double point;
public RecoverPoint(Point2D.Double point, int anglePosition) {
this.point = (Point2D.Double) point.clone( );
this.anglePosition = anglePosition;
}
}
public static BufferedImage createImage(final TurtleFile turtleFile)
throws IOException {
// Iteration über die Aktionen durchführen
final List<TurtleAction> actions = expandActions(turtleFile);
final BufferedImage image = new BufferedImage(turtleFile.getWidth( ),
turtleFile.getHeight( ), BufferedImage.TYPE_INT_BGR);
final Graphics2D graphics = image.createGraphics( );
// Bild Hintergrund weiß und Vordergrund schwarz
graphics.setBackground(Color.WHITE);
graphics
.clearRect(0, 0, turtleFile.getWidth( ), turtleFile.getHeight( ));
graphics.setColor(Color.BLACK);
// Wieviele unterschiedliche Winkel können vorkommen?
final int count = (int) Math.round(360.0 / turtleFile.getAngle( ));
// Alle benötigten Vektoren vorberechnen
final Point2D.Double[] vectors = new Point2D.Double[count];
for (int i = 0; i < count; i++) {
double angle = i * turtleFile.getAngle( );
double rad = Math.toRadians(angle);
double cos = Math.cos(rad);
double sin = Math.sin(rad);
double newX = turtleFile.getStep( ) * cos; // + 0 * -sin
double newY = turtleFile.getStep( ) * sin; // + 0 * cos
vectors[i] = new Point2D.Double(newX, newY);
}
// Blickrichtung
int angleCount = 0;
// Ausgangspunkt
final Point2D.Double point = new Point2D.Double(turtleFile.getxPos( ),
turtleFile.getHeight( ) - turtleFile.getyPos( ));
// STACK für Markierungen
final Stack<RecoverPoint> stack = new Stack<RecoverPoint>( );
// Aktionen ausführen
for (TurtleAction action : actions) {
// Vorwärts
if (action == TurtleAction.FORWARD) {
final Point2D.Double vector = vectors[angleCount];
graphics.drawLine(rint(point.x), rint(point.y), rint(point.x
+ vector.x), rint(point.y + vector.y));
point.setLocation(point.x + vector.x, point.y + vector.y);
}
// Linksdrehung
else if (action == TurtleAction.TURN_LEFT) {
if (angleCount == 0) {
angleCount = count - 1;
}
else {
angleCount--;
}
}
// Rechtsdrehung
else if (action == TurtleAction.TURN_RIGHT) {
if (angleCount == count - 1) {
angleCount = 0;
}
else {
angleCount++;
}
}
// Markierung setzen
else if (action == TurtleAction.MARK) {
stack.push(new RecoverPoint(point, angleCount));
}
// zu letzter Markierung zurückspringen
else if (action == TurtleAction.REWIND) {
final RecoverPoint recover = stack.pop( );
point.setLocation(recover.point.x, recover.point.y);
angleCount = recover.anglePosition;
}
}
return image;
}
private static int rint(double d) {
return (int) Math.round(d);
}
private static List<TurtleAction> expandActions(final TurtleFile turtleFile) {
List<TurtleAction> actions = new ArrayList<TurtleAction>(turtleFile
.getStartList( ));
// Iterationen durchführen
for (int i = 0; i < turtleFile.getIterations( ); i++) {
// Neue Aktionsliste
final List<TurtleAction> newActions = new ArrayList<TurtleAction>( );
for (TurtleAction action : actions) {
final RouletteList rouletteList = turtleFile
.getReplaceList(action);
if (rouletteList != null) {
newActions.addAll(rouletteList.get( ));
}
else {
newActions.add(action);
}
}
actions = newActions;
}
return actions;
}
public static void create(File in, boolean show) throws IOException {
final String name = in.getName( );
final String suffix = name.substring(name.lastIndexOf(".") + 1);
final Type type = Type.valueOf(suffix.toUpperCase( ));
final TurtleFile turtleFile = TurtleFile.read(in, type);
final BufferedImage image = createImage(turtleFile);
final File imageFile = new File(name + ".png");
ImageIO.write(image, "png", imageFile);
if (show) {
Desktop.getDesktop( ).open(imageFile);
}
}
public static void main(String[] args) throws IOException {
final File in = new File(".");
for (File f : in.listFiles( )) {
if (f.getName( ).contains("turtle") && !f.getName( ).endsWith("png")) {
create(f, false);
}
}
}
}
Java:
package de.tutorials.quiz9;
public class TurtleAction {
public static final TurtleAction TURN_LEFT = new TurtleAction("+");
public static final TurtleAction TURN_RIGHT = new TurtleAction("-");
public static final TurtleAction FORWARD = new TurtleAction("F");
public static final TurtleAction MARK = new TurtleAction("[");
public static final TurtleAction REWIND = new TurtleAction("]");
private String id;
public TurtleAction(String id) {
this.id = id;
}
@Override
public String toString() {
return id;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode( ));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof TurtleAction)) {
return false;
}
TurtleAction other = (TurtleAction) obj;
if (id == null) {
if (other.id != null) {
return false;
}
}
else if (!id.equals(other.id)) {
return false;
}
return true;
}
}
Java:
package de.tutorials.quiz9;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class TurtleFile {
private int width;
private int height;
private int xPos;
private int yPos;
private int step;
private double angle;
private List<TurtleAction> startList = new ArrayList<TurtleAction>( );
private int iterations;
private Map<TurtleAction, RouletteList> replaceMap = new HashMap<TurtleAction, RouletteList>( );
public enum Type {
A, B, B1, B2
}
// Breite Höhe
// x-Position y-Position
// Schrittweite
// Drehwinkel
// Liste der Aktionen
// * +: Linksdrehung (gegen den Uhrzeigersinn)
// * -: Rechtsdrehung (im Uhrzeigersinn)
// * F: Vorwärtsbewegung in Blickrichtung (Forward)
public static TurtleFile read(File file, Type type) throws IOException {
final BufferedReader reader = new BufferedReader(new FileReader(file));
String[] split = reader.readLine( ).split(" ");
final TurtleFile turtleFile = new TurtleFile( );
turtleFile.width = Integer.parseInt(split[0]);
turtleFile.height = Integer.parseInt(split[1]);
split = reader.readLine( ).split(" ");
turtleFile.xPos = Integer.parseInt(split[0]);
turtleFile.yPos = Integer.parseInt(split[1]);
turtleFile.step = Integer.parseInt(reader.readLine( ));
turtleFile.angle = Double.parseDouble(reader.readLine( ));
if (type == Type.A) {
readA(reader, turtleFile);
}
else if (type == Type.B) {
readB(reader, turtleFile);
}
else if (type == Type.B1) {
readB1(reader, turtleFile);
}
else if (type == Type.B2) {
readB2(reader, turtleFile);
}
reader.close( );
return turtleFile;
}
private static void readA(BufferedReader reader, TurtleFile turtleFile)
throws IOException {
String[] split = reader.readLine( ).split("");
List<TurtleAction> actionList = new ArrayList<TurtleAction>( );
addToList(split, actionList);
turtleFile.startList = actionList;
turtleFile.iterations = 0;
}
private static void readCommonB(BufferedReader reader, TurtleFile turtleFile)
throws IOException {
String[] split = reader.readLine( ).split("");
addToList(split, turtleFile.startList);
turtleFile.iterations = Integer.parseInt(reader.readLine( ));
}
private static void readB(BufferedReader reader, TurtleFile turtleFile)
throws IOException {
readCommonB(reader, turtleFile);
String[] split = reader.readLine( ).split("");
List<TurtleAction> replaceList = new ArrayList<TurtleAction>( );
addToList(split, replaceList);
turtleFile.replaceMap.put(TurtleAction.FORWARD, RouletteList
.createSingleton(replaceList));
}
private static void readB1(final BufferedReader reader,
final TurtleFile turtleFile) throws IOException {
readCommonB(reader, turtleFile);
String line;
while ((line = reader.readLine( )) != null) {
String[] split = line.split(" ");
final TurtleAction action = toAction(split[0]);
List<TurtleAction> replaceList = new ArrayList<TurtleAction>( );
addToList(split[1].split(""), replaceList);
turtleFile.replaceMap.put(action, RouletteList
.createSingleton(replaceList));
}
}
private static void readB2(BufferedReader reader, TurtleFile turtleFile)
throws IOException {
readCommonB(reader, turtleFile);
Map<TurtleAction, List<FactorList>> map = new HashMap<TurtleAction, List<FactorList>>( );
String line;
while ((line = reader.readLine( )) != null) {
final String[] split = reader.readLine( ).split(" ");
final TurtleAction action = toAction(split[0]);
int prop = Integer.parseInt(split[1]);
List<TurtleAction> replaceList = new ArrayList<TurtleAction>( );
addToList(split[2].split(""), replaceList);
List<FactorList> list = map.get(action);
if (list == null) {
list = new ArrayList<FactorList>( );
map.put(action, list);
}
list.add(new FactorList(prop, replaceList));
}
for (Map.Entry<TurtleAction, List<FactorList>> entry : map.entrySet( )) {
turtleFile.replaceMap.put(entry.getKey( ), RouletteList
.createForFactorList(entry.getValue( )));
}
}
private static void addToList(String[] split,
final List<TurtleAction> actionList) {
for (String s : split) {
if (s.length( ) > 0) {
actionList.add(toAction(s));
}
}
}
private static TurtleAction toAction(String s) {
if ("+".equals(s)) {
return TurtleAction.TURN_LEFT;
}
else if ("-".equals(s)) {
return TurtleAction.TURN_RIGHT;
}
else if ("F".equals(s)) {
return TurtleAction.FORWARD;
}
else if ("[".equals(s)) {
return TurtleAction.MARK;
}
else if ("]".equals(s)) {
return TurtleAction.REWIND;
}
return new TurtleAction(s);
}
/**
* @return the width
*/
public int getWidth() {
return width;
}
/**
* @return the height
*/
public int getHeight() {
return height;
}
/**
* @return the xPos
*/
public int getxPos() {
return xPos;
}
/**
* @return the yPos
*/
public int getyPos() {
return yPos;
}
/**
* @return the step
*/
public int getStep() {
return step;
}
/**
* @return the angle
*/
public double getAngle() {
return angle;
}
public List<TurtleAction> getStartList() {
return startList;
}
public int getIterations() {
return iterations;
}
public RouletteList getReplaceList(TurtleAction action) {
return replaceMap.get(action);
}
}
Java:
package de.tutorials.quiz9;
import java.util.List;
class FactorList {
int probability;
List<TurtleAction> replaceList;
public FactorList(int probability, List<TurtleAction> replaceList) {
this.probability = probability;
this.replaceList = replaceList;
}
}
Java:
package de.tutorials.quiz9;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
public class RouletteList {
private final List<List<TurtleAction>> replaceLists = new ArrayList<List<TurtleAction>>( );
private final Random random = new Random( );
private RouletteList() {
}
public static RouletteList createSingleton(List<TurtleAction> replaceList) {
RouletteList list = new RouletteList( );
list.replaceLists.add(replaceList);
return list;
}
public static RouletteList createForFactorList(List<FactorList> factorLists) {
RouletteList list = new RouletteList( );
// Ersetzungslisten entsprechend ihrer Anzahl in die Liste
// hinzufügen
for (FactorList factorList : factorLists) {
for (int i = 0; i < factorList.probability; i++) {
list.replaceLists.add(new ArrayList<TurtleAction>(
factorList.replaceList));
}
}
// Einmal durchmischen
Collections.shuffle(list.replaceLists);
return list;
}
public List<TurtleAction> get() {
// Ziehen aus der Liste in der die Ersetzungen entsprechend
// der Wahrscheinlichkeiten vorhanden sind.
// Jeder Ersetzung kommt durch das zufällige ziehen
// entsprechend ihrer Wahrscheinlichkeit dran.
return replaceLists.get(random.nextInt(replaceLists.size( )));
}
}