Faster maze generation for acmaze
parent
3606267aec
commit
d61d3e2cea
|
|
@ -5665,8 +5665,8 @@
|
||||||
{ "id": "acmaze",
|
{ "id": "acmaze",
|
||||||
"name": "AccelaMaze",
|
"name": "AccelaMaze",
|
||||||
"shortName":"AccelaMaze",
|
"shortName":"AccelaMaze",
|
||||||
"version":"0.01",
|
"version":"0.02",
|
||||||
"description": "Tilt the watch to roll a ball through a maze",
|
"description": "Tilt the watch to roll a ball through a maze.",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"tags": "game",
|
"tags": "game",
|
||||||
"supports" : ["BANGLEJS2"],
|
"supports" : ["BANGLEJS2"],
|
||||||
|
|
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
0.01: New App!
|
0.01: New App!
|
||||||
|
0.02: Faster maze generation
|
||||||
|
|
|
||||||
|
|
@ -35,21 +35,56 @@ function Maze(n) {
|
||||||
this.walls[cell] = WALL_RIGHT|WALL_DOWN;
|
this.walls[cell] = WALL_RIGHT|WALL_DOWN;
|
||||||
this.groups[cell] = cell;
|
this.groups[cell] = cell;
|
||||||
}
|
}
|
||||||
|
// Candidates of walls to break when digging the maze.
|
||||||
|
// If candidate failed (breaking it would create a loop),
|
||||||
|
// it would never succeed, so no need to retry it.
|
||||||
|
let candidates_down = [],
|
||||||
|
candidates_right = [];
|
||||||
|
for (let r=0 ; r<n; r++) {
|
||||||
|
for (let c=0; c<n; c++) {
|
||||||
|
let cell = n*r+c;
|
||||||
|
if (r<(n-1)) { // Don't break wall down for bottom row.
|
||||||
|
candidates_down.push(cell);
|
||||||
|
}
|
||||||
|
if (c<(n-1)) { // Don't break wall right for rightmost column.
|
||||||
|
candidates_right.push(cell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
let from_group, to_group;
|
let from_group, to_group;
|
||||||
let ngroups = n*n;
|
let ngroups = n*n;
|
||||||
while (--ngroups) {
|
while (--ngroups) {
|
||||||
// Abort if BTN1 pressed [grace period for menu]
|
// Abort if BTN1 pressed [grace period for menu]
|
||||||
// (for some reason setWatch() fails inside constructor)
|
// (for some reason setWatch() fails inside constructor)
|
||||||
if (ngroups<n*n-4 && digitalRead(BTN1)) {
|
if (ngroups<n*n-16 && digitalRead(BTN1)) {
|
||||||
aborting = true;
|
aborting = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
from_group = to_group = -1;
|
from_group = to_group = -1;
|
||||||
while (from_group<0) {
|
while (from_group<0) {
|
||||||
if (Math.random()<0.5) { // try to break a wall right
|
let trying_down = false;
|
||||||
let r = Math.floor(Math.random()*n);
|
if (Math.random()<0.5 || !candidates_right.length) {
|
||||||
let c = Math.floor(Math.random()*(n-1));
|
trying_down = true;
|
||||||
let cell = r*n+c;
|
}
|
||||||
|
let candidates = trying_down ? candidates_down : candidates_right;
|
||||||
|
candidate_index = Math.floor(Math.random()*candidates.length),
|
||||||
|
cell = candidates.splice(candidate_index, 1)[0],
|
||||||
|
r = Math.floor(cell/n),
|
||||||
|
c = cell%n;
|
||||||
|
if (trying_down) { // try to break a wall down
|
||||||
|
if (this.groups[cell]!=this.groups[cell+n]) {
|
||||||
|
this.walls[cell] &= ~WALL_DOWN;
|
||||||
|
g.clearRect(
|
||||||
|
this.margin+c*this.wall_length+1,
|
||||||
|
this.margin+(r+1)*this.wall_length,
|
||||||
|
this.margin+(c+1)*this.wall_length-1,
|
||||||
|
this.margin+(r+1)*this.wall_length
|
||||||
|
);
|
||||||
|
g.flip(); // show progress.
|
||||||
|
from_group = this.groups[cell];
|
||||||
|
to_group = this.groups[cell+n];
|
||||||
|
}
|
||||||
|
} else { // try to break a wall right
|
||||||
if (this.groups[cell]!=this.groups[cell+1]) {
|
if (this.groups[cell]!=this.groups[cell+1]) {
|
||||||
this.walls[cell] &= ~WALL_RIGHT;
|
this.walls[cell] &= ~WALL_RIGHT;
|
||||||
g.clearRect(
|
g.clearRect(
|
||||||
|
|
@ -62,21 +97,6 @@ function Maze(n) {
|
||||||
from_group = this.groups[cell];
|
from_group = this.groups[cell];
|
||||||
to_group = this.groups[cell+1];
|
to_group = this.groups[cell+1];
|
||||||
}
|
}
|
||||||
} else { // try to break a wall down
|
|
||||||
let r = Math.floor(Math.random()*(n-1));
|
|
||||||
let c = Math.floor(Math.random()*n);
|
|
||||||
let cell = r*n+c;
|
|
||||||
if (this.groups[cell]!=this.groups[cell+n]) {
|
|
||||||
this.walls[cell] &= ~WALL_DOWN;
|
|
||||||
g.clearRect(
|
|
||||||
this.margin+c*this.wall_length+1,
|
|
||||||
this.margin+(r+1)*this.wall_length,
|
|
||||||
this.margin+(c+1)*this.wall_length-1,
|
|
||||||
this.margin+(r+1)*this.wall_length
|
|
||||||
);
|
|
||||||
from_group = this.groups[cell];
|
|
||||||
to_group = this.groups[cell+n];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (let cell = 0; cell<n*n; cell++) {
|
for (let cell = 0; cell<n*n; cell++) {
|
||||||
|
|
@ -253,7 +273,6 @@ let maze_interval = setInterval(
|
||||||
function() {
|
function() {
|
||||||
if (maze) {
|
if (maze) {
|
||||||
if (digitalRead(BTN1) || maze.status==STATUS_ABORTED) {
|
if (digitalRead(BTN1) || maze.status==STATUS_ABORTED) {
|
||||||
console.log(`aborting ${start_time}`);
|
|
||||||
maze = null;
|
maze = null;
|
||||||
start_time = duration = 0;
|
start_time = duration = 0;
|
||||||
aborting = false;
|
aborting = false;
|
||||||
|
|
@ -270,7 +289,7 @@ let maze_interval = setInterval(
|
||||||
duration = Date.now()-start_time;
|
duration = Date.now()-start_time;
|
||||||
g.setFontAlign(0,0).setColor(g.theme.fg);
|
g.setFontAlign(0,0).setColor(g.theme.fg);
|
||||||
g.setFont("Vector",18);
|
g.setFont("Vector",18);
|
||||||
g.drawString(`Solved in\n ${timeToText(duration)} \nClick to play again`, g.getWidth()/2, g.getHeight()/2, true);
|
g.drawString(`Solved ${maze.n}X${maze.n} in\n ${timeToText(duration)} \nClick to play again`, g.getWidth()/2, g.getHeight()/2, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 25);
|
}, 25);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue