Skip to content

Instantly share code, notes, and snippets.

Created November 6, 2014 14:00
Show Gist options
  • Save anonymous/c37b050df57691a79c6c to your computer and use it in GitHub Desktop.
Save anonymous/c37b050df57691a79c6c to your computer and use it in GitHub Desktop.
Solution for sharkverse's maze solving challenge
// Code by @MetaGlitch
int size = 601;
int fps = 20;
int numFrames = 40;
int samplesPerFrame = 24;
float exposure = 0.7; // exposure time in frames. >1 allowed for blending multiple frames
float subFrameAttenuation = 1; // 1 for weighting every subframe the same. <1 for attenuation effect.
boolean looping = true; // false: t=1 on the last frame; true: t=1-1/nummFrames on last frame.
boolean recording = true;
MazeData maze;
void setup_() {
size(size, size, P2D);
noStroke();
smooth(8);
int m = millis();
maze = new MazeData("maze.png");
println("load time: " + (millis()-m) + "ms");
m = millis();
maze.solve();
println("solve time: " + (millis()-m) + "ms");
}
void draw_() {
background(0);
stroke(#ff0000); strokeWeight(1);
float tt = map(t, 0.1,0.9, 0,1);
maze.draw(0,0, tt);
}
float pingpong(float t) {
return 1-2*abs(t-0.5);
}
// Code by @MetaGlitch
import java.util.*;
public class MazeData {
public PImage mazeImg;
public Room[][] rooms;
public Room start;
public Room end;
public ArrayList<Room> path;
public MazeData(String imgpath) {
mazeImg = loadImage(imgpath);
mazeImg.loadPixels();
int[] pix = mazeImg.pixels;
int w = mazeImg.width/2;
int h = mazeImg.height/2;
rooms = new Room[w][h];
for(int x=0; x<w; x++) for(int y=0; y<h; y++) {
color c = pix[toXY(2*x+1, 2*y+1, mazeImg.width)];
if (c != #000000) {
rooms[x][y] = new Room(x,y);
}
if (c == #ff0000) {
start = rooms[x][y];
}
if (c == #00ff00) {
end = rooms[x][y];
}
}
for(int x=0; x<w; x++) for(int y=0; y<h; y++) {
Room room = rooms[x][y];
if (pix[toXY(2*x+1 + 1, 2*y+1, mazeImg.width)] != #000000) room.neighbors.add(rooms[x+1][y]);
if (pix[toXY(2*x+1 - 1, 2*y+1, mazeImg.width)] != #000000) room.neighbors.add(rooms[x-1][y]);
if (pix[toXY(2*x+1, 2*y+1 + 1, mazeImg.width)] != #000000) room.neighbors.add(rooms[x][y+1]);
if (pix[toXY(2*x+1, 2*y+1 - 1, mazeImg.width)] != #000000) room.neighbors.add(rooms[x][y-1]);
}
}
public void solve() {
Stack<Room> stack = new Stack<Room>();
path = new ArrayList<Room>();
Room curr = start;
curr.visited = true;
do {
if (curr.neighbors.size()>0) {
stack.push(curr);
//int i = (int)(curr.neighbors.size()*Math.random());
int i = 0;
int x = curr.x, y = curr.y;
curr = curr.neighbors.remove(i);
curr.visited = true;
if (curr == end) {
path.addAll(stack);
path.add(curr);
return;
}
} else {
curr = stack.pop();
}
// remove visited neighbors
for(int i=curr.neighbors.size()-1; i>=0; i--) { if (curr.neighbors.get(i).visited) curr.neighbors.remove(i); }
} while (stack.size()>0 || curr.neighbors.size()>0);
}
public void draw(int x, int y, float t) {
image(mazeImg,x,y);
Room lastRoom = null;
int num = path.size();
int i = 0;
for(Room room : path) {
if (lastRoom != null && t>=(i*1.0/num)) {
line(x+2*lastRoom.x+1, y+2*lastRoom.y+1, x+2*room.x+1, y+2*room.y+1);
}
lastRoom = room;
i++;
}
}
int toXY(int x, int y, int w) {
return y*w + x;
}
}
public class Room {
public int x;
public int y;
public boolean visited;
public ArrayList<Room> neighbors = new ArrayList<Room>();
public Room(int x, int y) {
this.x = x;
this.y = y;
visited = false;
}
}
public class Segment {
public int x,y;
public int x2,y2;
public Segment(int x, int y, int x2, int y2) {
this.x = x;
this.y = y;
this.x2 = x2;
this.y2 = y2;
}
}
// Code by @MetaGlitch
float t;
float[][] result;
void setup() {
setup_();
result = new float[width*height][3];
}
void draw() {
if (!recording) {
if (mousePressed) {
frameRate(60);
t = mouseX*1.0/width;
if (mouseButton == LEFT) t = constrain(t, 0, 1);
} else {
frameRate(fps);
t = float((frameCount-1)%numFrames) / numFrames;
}
draw_();
} else { // sub frame rendering inspired by @beesandbombs
for (int i=0; i<width*height; i++) for (int a=0; a<3; a++) result[i][a] = 0;
float divider = 0;
for (int sa=0; sa<samplesPerFrame; sa++) {
t = map(frameCount-1 + exposure*sa/samplesPerFrame, 0, numFrames, 0, 1) % 1;
pushMatrix();
draw_();
popMatrix();
loadPixels();
float weight = pow(subFrameAttenuation, samplesPerFrame-sa-1);
divider += weight;
for (int i=0; i<pixels.length; i++) {
result[i][0] += weight * (pixels[i] >> 16 & 0xff);
result[i][1] += weight * (pixels[i] >> 8 & 0xff);
result[i][2] += weight * (pixels[i] & 0xff);
}
}
loadPixels();
for (int i=0; i<pixels.length; i++)
pixels[i] = 0xff << 24 |
int(result[i][0]*1.0/divider) << 16 |
int(result[i][1]*1.0/divider) << 8 |
int(result[i][2]*1.0/divider);
updatePixels();
saveFrame("frames/f###.png");
if (frameCount==numFrames)
exit();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment