Mod:Coding Challenge #10.3+10.4: Maze Generator with p5.js - Part 3+4
勢いでパート3と4を見て一気に書いてしまった。改変したところは、上下左右の壁面境界の判定、迷路が完成したところでsaveFrameすること、マウスクリックで初期化すること、色を毎回変えていることあたり。
こんな感じの迷路が生成される。
コード
float cols, rows, grid; ArrayList<Cell> cells = new ArrayList<Cell>(); ArrayList<Cell> stack = new ArrayList<Cell>(); Cell current; color cc, dc; Boolean isSave = false; void setup() { size(800, 800); colorMode(HSB, 360, 100, 100, 100); frameRate(120); init(); } void draw() { background(0, 0, 25); for (Cell cell : cells) { cell.draw(); } current.isVisited = true; current.highlight(); Cell next = current.checkNeighbors(); if (next != null) { next.isVisited = true; stack.add(current); removeWalls(next, current); current = next; } else if (stack.size() > 0) { current = stack.get(stack.size()-1); stack.remove(current); } else { if (isSave) { cc = dc; current.highlight(); String fileName = "col"+ int(cols) + "_" + "row" + int(rows) +"_" + "grid" + int(grid); saveFrame(fileName+".png"); } cells.clear(); stack.clear(); init(); } } void removeWalls(Cell a, Cell b) { float x = a.i - b.i; float y = a.j - b.j; if (x == 1) { a.walls[3] = false; b.walls[1] = false; } else if (x == -1) { a.walls[1] = false; b.walls[3] = false; } if (y == 1) { a.walls[0] = false; b.walls[2] = false; } else if (y == -1) { a.walls[2] = false; b.walls[0] = false; } } void init() { grid = int(random(2, 10))*5; cols = floor(width/grid); rows = floor(height/grid); float hue = random(360); cc = color(hue, 80, 100); dc = color((hue + 180)%360, 80, 100); for (int j = 0; j < rows; j++) { for (int i = 0; i < cols; i++) { Cell cell = new Cell(i, j); cells.add(cell); } } current = cells.get(0); } void mousePressed() { cells.clear(); stack.clear(); init(); } class Cell { float i, j; Boolean[] walls = new Boolean[4]; Boolean isVisited = false; Cell(float _i, float _j) { i = _i; j = _j; for (int k = 0; k < walls.length; k++) { if (random(1) < 0.5) { walls[k] = true; } else { walls[k] = false; } } if (j == 0) { walls[0] = true; } if (i == cols-1) { walls[1] = true; } if (j == rows-1) { walls[2] = true; } if (i == 0) { walls[3] = true; } } void highlight() { float x = i * grid; float y = j * grid; noStroke(); fill(cc); rect(x, y, grid, grid); } void draw() { float x = i * grid; float y = j * grid; if (isVisited) { fill(dc, 50); noStroke(); rect(x, y, grid, grid); stroke(0, 0, 100); strokeWeight(grid/10); if (walls[0]) { line(x, y, x+grid, y); } if (walls[1]) { line(x+grid, y, x+grid, y+grid); } if (walls[2]) { line(x+grid, y+grid, x, y+grid); } if (walls[3]) { line(x, y, x, y+grid); } } else { fill(0, 0, 0, 50); rect(x, y, grid, grid); } } int index(float i, float j) { if (i < 0 || j < 0 || i > cols-1 || j > rows-1) { return -1; } return int(i + j * cols); } Cell checkNeighbors() { ArrayList<Cell> neighbors = new ArrayList<Cell>(); if (index(i, j-1) != -1) { Cell top = cells.get(index(i, j-1)); if (!top.isVisited) { neighbors.add(top); } } if (index(i, j+1) != -1) { Cell bottom = cells.get(index(i, j+1)); if (!bottom.isVisited) { neighbors.add(bottom); } } if (index(i-1, j) != -1) { Cell left = cells.get(index(i-1, j)); if (!left.isVisited) { neighbors.add(left); } } if (index(i+1, j) != -1) { Cell right = cells.get(index(i+1, j)); if (!right.isVisited) { neighbors.add(right); } } if (neighbors.size() > 0) { int r = floor(random(0, neighbors.size())); return neighbors.get(r); } else { return null; } } }