Created
July 31, 2014 12:41
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.*; | |
import java.awt.Color; | |
import java.awt.image.*; | |
import javax.imageio.*; | |
import java.io.*; | |
import java.util.stream.*; | |
import static java.util.stream.Stream.*; | |
public class Intermediate173 { | |
public static final int HEIGHT = 512; | |
public static final int WIDTH = 512; | |
private List<Color> color; | |
private String rules; | |
private int x, y; | |
private int heading; | |
private int[] colorData; | |
public Intermediate173(String rules, int steps) { | |
//Initialize stuff. | |
color = chooseColors(rules.length()); | |
this.rules = rules; | |
x = HEIGHT / 2; | |
y = WIDTH / 2; | |
heading = 90; //north | |
colorData = initColorData(); | |
//Do things. | |
step(steps); | |
saveImage(); | |
} | |
public static void main(String[] args) { | |
int steps = Integer.parseInt(args[1]); | |
new Intermediate173(args[0], steps); | |
} | |
private void step(int n) { | |
while (n > 0) { | |
if (rotateAnt() == -1) { | |
System.out.println("Edge reached."); | |
break; | |
} | |
incrementColor(); | |
moveAntForward(); | |
n--; | |
} | |
} | |
private void moveAntForward() { | |
switch (heading) { | |
case 90: y--; break; | |
case 180: x--; break; | |
case 270: y++; break; | |
case 0: x++; break; | |
default: throw new RuntimeException("Bad heading."); | |
} | |
} | |
private void incrementColor() { | |
Color antLocation = antLocation(); | |
for (int i = 0; i < color.size(); i++) | |
if (antLocation.equals(color.get(i))) | |
setPixel(x, y, color.get(inc(i))); | |
} | |
private int inc(int n) { | |
n = n + 1 >= color.size() ? 0 : n + 1; | |
return n; | |
} | |
private int rotateAnt() { | |
Color antLocation = antLocation(); | |
if (antLocation == null) | |
return -1; | |
switch (getRule(antLocation)) { | |
case "L": rotateCounterClockwise(); break; | |
case "R": rotateClockwise(); break; | |
default: throw new RuntimeException ("Not L or R?!"); | |
} | |
return 1; | |
} | |
private Color antLocation() { | |
if (inBounds(x, y)) | |
return new Color(colorData[flatten(x, y)]); | |
else | |
return null; | |
} | |
private String getRule(Color c) { | |
for (int i = 0; i < color.size(); i++) | |
if (color.get(i).equals(c)) | |
return new Character(rules.charAt(i)).toString(); | |
return null; | |
} | |
private void rotateClockwise() { | |
heading = heading + 90 > 270 ? 0 : heading + 90; | |
} | |
private boolean inBounds(int x, int y) { | |
return x >= 0 && x < WIDTH | |
&& y >= 0 && y < HEIGHT; | |
} | |
private void setPixel(int x, int y, Color c) { | |
if (inBounds(x, y)) | |
colorData[flatten(x, y)] = c.getRGB(); | |
} | |
private int[] initColorData() { | |
int[] colorData = new int[HEIGHT * WIDTH]; | |
for (int i = 0; i < colorData.length; i++) | |
colorData[i] = color.get(0).getRGB(); | |
return colorData; | |
} | |
private int flatten(int x, int y) { | |
return y * WIDTH + x; | |
} | |
private void saveImage() { | |
BufferedImage image = new BufferedImage( | |
WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB); | |
image.setRGB(0, 0, WIDTH, HEIGHT, colorData, 0, WIDTH); | |
File f = new File("output.png"); | |
try { | |
ImageIO.write(image, "PNG", f); | |
} catch(IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
private void rotateCounterClockwise() { | |
heading = heading - 90 < 0 ? 270 : heading - 90; | |
} | |
private List<Color> chooseColors(int quantity) { | |
float step = 1.0f / quantity; | |
List<Color> colors = Stream.iterate(step, f -> f + step) | |
.limit(quantity) | |
.map(f -> new Color(Color.HSBtoRGB(0.8f, 0.75f, f))) | |
.collect(Collectors.toList()); | |
return colors; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment