Created
November 6, 2014 14:00
-
-
Save anonymous/c37b050df57691a79c6c to your computer and use it in GitHub Desktop.
Solution for sharkverse's maze solving challenge
This file contains hidden or 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
// 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); | |
} |
This file contains hidden or 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
// 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; | |
} | |
} |
This file contains hidden or 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
// 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