xxxxxxxxxx
288
let col = 40;
let row = 20;
let cellSizeX, cellsizeY, gridX, gridY;
const colorBack = 'black';
const colorCell = 'lightgrey';
const colorStartE = 'blue'; // edge
const colorStartC = 'cyan'; // corner
const colorConn = 'green';
const colorSepa = 'red';
const colorBlock = 'grey';
const colorPathE = 'orange'; // edge
const colorPathC = 'yellow'; // corner
const blockValue = -1;
const CELL = 'cell', ALL = 'all';
let grid = [];
let startCol, startRow, stopCol, stopRow, currValue;
let isConnected, label = false, corner = false;
this.focus();
function setup() {
createCanvas(windowWidth, windowHeight);
rectMode(CENTER);
textAlign(CENTER, CENTER);
initGrid();
}
function displaySize () {
push();
textSize(120);
fill('white');
stroke('black');
strokeWeight(10);
text(row + ' x ' + col, width / 2, height / 2);
pop();
}
function initGrid() {
cellSizeX = int(width / col);
cellSizeY = int(height / row);
gridX = col * cellSizeX;
gridY = row * cellSizeY;
textSize(0.5 * cellSizeY);
startCol = 1;
startRow = 1;
stopCol = col;
stopRow = row;
createGrid();
setGrid();
background(colorBack);
global();
displaySize();
}
function createGrid() {
for (let c = 0; c <= col + 1; c++) {
grid[c] = [];
for (let r = 0; r <= row + 1; r++) {
grid[c][r] = '';
}
}
}
function setGrid() {
for (let c = 0; c <= col + 1; c++) {
grid[c][0] = blockValue;
grid[c][row + 1] = blockValue;
}
for (let r = 0; r <= row + 1; r++) {
grid[0][r] = blockValue;
grid[col + 1][r] = blockValue;
}
grid[startCol][startRow] = 0;
}
function deleteGrid(what = CELL) {
if (what == CELL) {
for (let c = 1; c <= col; c++) {
for (let r = 1; r <= row; r++) {
if (grid[c][r] > 0) { grid[c][r] = '' }
}
}
}
if (what == ALL) {
for (let c = 1; c <= col; c++) {
for (let r = 1; r <= row; r++) {
if (grid[c][r] != 0) { grid[c][r] = '' }
}
}
}
}
function drawGrid() {
// CELLS
for (let c = 1; c <= col; c++) {
for (let r = 1; r <= row; r++) {
if (grid[c][r] < 0) { fill(colorBlock) }
else { fill(colorCell) }
rect(colToX(c), rowToY(r), cellSizeX, cellSizeY);
}
}
// START CELL
if (corner) { fill(colorStartC) } else { fill(colorStartE) }
rect(colToX(startCol), rowToY(startRow), cellSizeX, cellSizeY);
// STOP CELL
if (isConnected) { fill(colorConn) } else { fill(colorSepa) }
rect(colToX(stopCol), rowToY(stopRow), cellSizeX, cellSizeY);
// LABELS
if (label) {
fill(colorBack);
for (let c = 1; c <= col; c++) {
for (let r = 1; r <= row; r++) {
if (grid[c][r] >= 0) { text(grid[c][r], colToX(c), rowToY(r)); }
}
}
}
}
function colToX(c) { return(c * cellSizeX - cellSizeX / 2) }
function rowToY(r) { return(r * cellSizeY - cellSizeY / 2) }
function xToCol(x) { return(floor(x / cellSizeX) + 1) }
function yToRow(y) { return(floor(y / cellSizeY) + 1) }
function mousePressed() {
let X = mouseX;
let Y = mouseY;
if (X < 0 || X > gridX || Y < 0 || Y > gridY) { return }
let c = xToCol(X);
let r = yToRow(Y);
let g = grid[c][r];
if (c === startCol && r === startRow) { return }
if (c === stopCol && r === stopRow) { return }
if (keyIsDown(SHIFT)) {
grid[startCol][startRow] = '';
startCol = c;
startRow = r;
grid[startCol][startRow] = 0;
deleteGrid();
global();
return;
}
if (keyIsDown(ALT)) {
grid[stopCol][stopRow] = '';
stopCol = c;
stopRow = r;
grid[stopCol][stopRow] = '';
deleteGrid();
global();
return;
}
if (g === blockValue) { grid[c][r] = '' }
else { grid[c][r] = blockValue }
deleteGrid();
global();
}
function mouseDragged() {
let X = mouseX;
let Y = mouseY;
if (!(X > 0 && X < gridX && Y > 0 && Y < gridY)) { return }
let c = xToCol(X);
let r = yToRow(Y);
let g = grid[c][r];
if (c === startCol && r === startRow) { return }
if (c === stopCol && r === stopRow) { return }
if (keyIsDown(CONTROL)) { grid[c][r] = '' }
else { grid[c][r] = blockValue }
deleteGrid();
global();
}
function keyPressed() {
if (keyCode === ESCAPE) { label = !label; drawGrid(); drawPath(); }
if (keyCode === ENTER) {
deleteGrid(ALL);
for (let c = 0; c <= col + 1; c++) {
for (let r = 0; r <= row + 1; r++) {
if (random() < 0.4) { grid[c][r] = blockValue }
}
}
grid[startCol][startRow] = 0;
grid[stopCol][stopRow] = '';
global();
}
if (keyCode === 32) { corner = !corner; deleteGrid(); global(); }
if (keyCode === BACKSPACE) {
deleteGrid(ALL);
global();
displaySize();
}
if (keyIsDown(CONTROL) && keyIsDown(RIGHT_ARROW)) {
col++; initGrid();
}
if (keyIsDown(CONTROL) && keyIsDown(LEFT_ARROW)) {
if (col > 2) {col--; initGrid(); }
}
if (keyIsDown(CONTROL) && keyIsDown(UP_ARROW)) {
row++; initGrid();
}
if (keyIsDown(CONTROL) && keyIsDown(DOWN_ARROW)) {
if (row > 2) {row--; initGrid(); }
}
}
function neighPlus(c, r) {
let db = 0;
if (grid[c][r - 1] === '') { grid[c][r - 1] = currValue + 1; db++; }
if (c === stopCol && r - 1 === stopRow ) { return -1 }
if (grid[c - 1][r] === '') { grid[c - 1][r] = currValue + 1; db++; }
if (c - 1 === stopCol && r === stopRow ) { return -1 }
if (grid[c + 1][r] === '') { grid[c + 1][r] = currValue + 1; db++; }
if (c + 1 === stopCol && r === stopRow ) { return -1 }
if (grid[c][r + 1] === '') { grid[c][r + 1] = currValue + 1; db++; }
if (c === stopCol && r + 1 === stopRow ) { return -1 }
if (corner) {
if (grid[c - 1][r - 1] === '') { grid[c - 1][r - 1] = currValue + 1; db++; }
if (c - 1 === stopCol && r - 1 === stopRow ) { return -1 }
if (grid[c + 1][r - 1] === '') { grid[c + 1][r - 1] = currValue + 1; db++; }
if (c + 1 === stopCol && r - 1 === stopRow ) { return -1 }
if (grid[c - 1][r + 1] === '') { grid[c - 1][r + 1] = currValue + 1; db++; }
if (c - 1 === stopCol && r + 1 === stopRow ) { return -1 }
if (grid[c + 1][r + 1] === '') { grid[c + 1][r + 1] = currValue + 1; db++; }
if (c + 1 === stopCol && r + 1 === stopRow ) { return -1 }
}
return db;
}
function calculGrid() {
let result;
let cont = false;
for (let c = 1; c <= col; c++) {
for (let r = 1; r <= row; r++) {
if (grid[c][r] === currValue) {
result = neighPlus(c, r);
if (result === -1) { isConnected = true; return false; }
if (result > 0) { cont = true }
}
}
}
return cont;
}
function global() {
currValue = 0;
isConnected = false;
while (calculGrid()) { currValue++ }
drawGrid();
if (isConnected) { drawPath() }
}
function drawPath() {
pathCol = stopCol;
pathRow = stopRow;
currValue = grid[pathCol][pathRow] - 1;
while (grid[pathCol][pathRow] > 0) {
nextPathCell(currValue);
currValue--;
drawPathCell(pathCol, pathRow);
}
}
function nextPathCell(v) {
if (grid[pathCol][pathRow - 1] === v) { pathRow--; return; }
if (grid[pathCol - 1][pathRow] === v) { pathCol--; return; }
if (grid[pathCol + 1][pathRow] === v) { pathCol++; return; }
if (grid[pathCol][pathRow + 1] === v) { pathRow++; return; }
if (corner) {
if (grid[pathCol - 1][pathRow - 1] === v) { pathCol--; pathRow--; return; }
if (grid[pathCol + 1][pathRow - 1] === v) { pathCol++; pathRow--; return; }
if (grid[pathCol - 1][pathRow + 1] === v) { pathCol--; pathRow++; return; }
if (grid[pathCol + 1][pathRow + 1] === v) { pathCol++; pathRow++; return; }
}
}
function drawPathCell(c, r) {
if (c === startCol && r === startRow) { return }
if (corner) { fill(colorPathC) } else { fill(colorPathE) }
rect(colToX(c), rowToY(r), cellSizeX, cellSizeY);
if (label) {
fill(colorBack);
text(grid[c][r], colToX(c), rowToY(r));
}
}
function draw() {
noLoop();
}