日常の進捗

主に自分のための,行為とその習慣化の記録

Mod:Coding Challenge #10.3+10.4: Maze Generator with p5.js - Part 3+4

勢いでパート3と4を見て一気に書いてしまった。改変したところは、上下左右の壁面境界の判定、迷路が完成したところでsaveFrameすること、マウスクリックで初期化すること、色を毎回変えていることあたり。

こんな感じの迷路が生成される。

f:id:takawo:20170910075349p:plain f:id:takawo:20170910075353p:plain f:id:takawo:20170910075358p:plain f:id:takawo:20170910075402p:plain f:id:takawo:20170910081618p:plain

コード

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;
    }
  }
}

リファレンス