284 lines
12 KiB
HTML
284 lines
12 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Baba Is You Solver</title>
|
|
<style>
|
|
#body {
|
|
border: 1px solid black;
|
|
border-collapse: collapse;
|
|
}
|
|
#body td {
|
|
border: 1px solid black;
|
|
width: 40px;
|
|
height: 40px;
|
|
color: white;
|
|
text-align: center;
|
|
font-family: "Ubuntu", sans-serif;
|
|
}
|
|
td.mark::before {
|
|
content: "*";
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<table id="body"></table>
|
|
<script>
|
|
var CellTypes = {
|
|
"empty": {
|
|
"color": "black",
|
|
"props": [],
|
|
"has": ""
|
|
},
|
|
"text": {
|
|
"color": "black",
|
|
"props": ["push"],
|
|
"has": ""
|
|
},
|
|
"hedge": {
|
|
"color": "darkgreen",
|
|
"props": ["stop"],
|
|
"has": ""
|
|
},
|
|
"bug": {
|
|
"color": "brown",
|
|
"props": ["defeat"],
|
|
"has": ""
|
|
},
|
|
"keke": {
|
|
"color": "orange",
|
|
"props": ["you"],
|
|
"has": ""
|
|
},
|
|
"fungus": {
|
|
"color": "gold",
|
|
"props": ["melt"],
|
|
"has": "flag"
|
|
},
|
|
"tree": {
|
|
"color": "lightgreen",
|
|
"props": ["pull"],
|
|
"has": ""
|
|
},
|
|
"beld": {
|
|
"color": "grey",
|
|
"props": ["shift"],
|
|
"has": ""
|
|
}
|
|
}
|
|
|
|
function cellType(name)
|
|
{
|
|
cell = {
|
|
type: name.split("_")[0],
|
|
content: "",
|
|
mark: false,
|
|
facing: (name.split("_").length == 2) ? name.split("_")[1] : "n"
|
|
}
|
|
return cell;
|
|
}
|
|
|
|
function cellText(name)
|
|
{
|
|
cell = {
|
|
type: "text",
|
|
text: name.replace(/-/, ""),
|
|
content: name.replace(/-/, "<br/>"),
|
|
mark: false,
|
|
props: []
|
|
}
|
|
return cell;
|
|
}
|
|
|
|
var LEVEL = [
|
|
[cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("hedge"), cellText("fun-gus"), cellText("has"), cellText("fl-ag"), cellType("hedge"), cellText("bug"), cellText("is"), cellText("def-eat"), cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("empty"), cellText("fun-gus"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), ],
|
|
[cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("empty"), cellText("is"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), ],
|
|
[cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("empty"), cellType("empty"), cellText("be-lt"), cellText("is"), cellText("sh-ift"), cellType("hedge"), cellType("empty"), cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("empty"), cellText("me-lt"), cellType("empty"), cellType("fungus"), cellType("empty"), cellType("empty"), ],
|
|
[cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("bug"), cellType("bug"), cellType("bug"), cellType("bug"), cellType("bug"), cellType("hedge"), cellType("empty"), cellType("hedge"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), ],
|
|
[cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("hedge"), cellType("empty"), cellType("hedge"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), ],
|
|
[cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("hedge"), cellType("empty"), cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("empty"), cellType("hedge"), ],
|
|
[cellType("hedge"), cellType("hedge"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("keke"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("beld_e"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("hedge"), ],
|
|
[cellType("hedge"), cellType("hedge"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("hedge"), ],
|
|
[cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), ],
|
|
[cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), ],
|
|
[cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellText("tr-ee"), cellText("is"), cellText("pu-ll"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), ],
|
|
[cellType("hedge"), cellType("hedge"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), ],
|
|
[cellType("hedge"), cellType("hedge"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("tree"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), ],
|
|
[cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("hedge"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), ],
|
|
[cellText("ke-ke"), cellText("is"), cellText("you"), cellType("hedge"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), cellType("empty"), ],
|
|
]
|
|
|
|
function drowTable(level){
|
|
var body = document.getElementById("body");
|
|
|
|
for (let y = 0; y < level.length; y++) {
|
|
let row = document.createElement("tr");
|
|
for (let x = 0; x < level[y].length; x++) {
|
|
let cell = document.createElement("td");
|
|
cell.id = `cell${x}x${y}`;
|
|
cell.classList.add("type-" + level[y][x].type);
|
|
cell.innerHTML = level[y][x].content;
|
|
cell.style.backgroundColor = CellTypes[level[y][x].type].color;
|
|
if (level[y][x].type == "text")
|
|
{
|
|
cell.classList.add("text-" + level[y][x].text);
|
|
}
|
|
if (level[y][x].mark)
|
|
{
|
|
cell.classList.add("mark");
|
|
}
|
|
row.appendChild(cell);
|
|
}
|
|
body.appendChild(row);
|
|
}
|
|
}
|
|
|
|
function solveMoveStep(level, x, y)
|
|
{
|
|
function checkMove(level, x, y, dir)
|
|
{
|
|
for (let i = 0; i < CellTypes[level[y][x].type].props.length; i++) {
|
|
const prop = CellTypes[level[y][x].type].props[i];
|
|
switch (prop)
|
|
{
|
|
case 'stop':
|
|
case 'defeat':
|
|
return false;
|
|
|
|
case 'shift':
|
|
if (
|
|
((dir == 'n') && (level[y][x].facing == 's'))
|
|
|| ((dir == 'e') && (level[y][x].facing == 'w'))
|
|
|| ((dir == 's') && (level[y][x].facing == 'n'))
|
|
|| ((dir == 'w') && (level[y][x].facing == 'e'))
|
|
)
|
|
{
|
|
return false;
|
|
}
|
|
break;
|
|
|
|
case 'push':
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
solution = {
|
|
n: ((y > 0) && checkMove(level, x, y-1, "n")),
|
|
e: ((x < level[y].length-1) && checkMove(level, x+1, y, "e")),
|
|
s: ((y < level.length-1) && checkMove(level, x, y+1, "s")),
|
|
w: ((x > 0) && checkMove(level, x-1, y, "w"))
|
|
}
|
|
// console.log(`solution for (${x}, ${y}) is `, solution);
|
|
return solution;
|
|
}
|
|
|
|
function getCellCords(level, x, y, dir)
|
|
{
|
|
switch (dir)
|
|
{
|
|
case 'n':
|
|
if (y > 0)
|
|
return [x, y-1];
|
|
else
|
|
return NaN;
|
|
case 'e':
|
|
if (x < level[x].length-1)
|
|
return [x+1, y];
|
|
else
|
|
return NaN;
|
|
case 's':
|
|
if (y < level[y].length-1)
|
|
return [x, y-1];
|
|
else
|
|
return NaN;
|
|
case 'w':
|
|
if (x > 0)
|
|
return [x-1, y];
|
|
else
|
|
return NaN;
|
|
}
|
|
}
|
|
|
|
function move(level, x, y, dir)
|
|
{
|
|
newX, newY = getCellCords(level, x, y, dir);
|
|
for (let i = 0; i < CellTypes[level[newY][newX].type].props.length; i++) {
|
|
const prop = CellTypes[level[newY][newX].type].props[i];
|
|
switch (prop)
|
|
{
|
|
case 'stop':
|
|
return false;
|
|
|
|
case 'defeat':
|
|
if (level[newY][newX].type != "text")
|
|
{
|
|
level[newY][newX].content = "/";
|
|
}
|
|
return false;
|
|
|
|
case 'shift':
|
|
dirs = "nesw";
|
|
dirNum = indexOf(dirs, dir);
|
|
shiftDirNum = indexOf(level[newY][newX].facing, dir);
|
|
if (((dirNum + 2) % 4) == shiftDirNum)
|
|
{ // is facing into eachother
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
let shift = move(level, newX, newY, level[newY][newX].facing);
|
|
if (shift !== false)
|
|
{
|
|
return shift;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'push':
|
|
return false;
|
|
}
|
|
}
|
|
return [newX, newY];
|
|
}
|
|
|
|
function solveStep(level, x, y, solveFn)
|
|
{
|
|
var solution = solveFn(level, x, y);
|
|
if (solution.n && !level[y-1][x].mark)
|
|
{
|
|
level[y-1][x].mark = true;
|
|
solveStep(level, x, y-1, solveFn);
|
|
}
|
|
|
|
if (solution.e && !level[y][x+1].mark)
|
|
{
|
|
level[y][x+1].mark = true;
|
|
solveStep(level, x+1, y, solveFn);
|
|
}
|
|
|
|
if (solution.s && !level[y+1][x].mark)
|
|
{
|
|
level[y+1][x].mark = true;
|
|
solveStep(level, x, y+1, solveFn);
|
|
}
|
|
|
|
if (solution.w && !level[y][x-1].mark)
|
|
{
|
|
level[y][x-1].mark = true;
|
|
solveStep(level, x-1, y, solveFn);
|
|
}
|
|
}
|
|
|
|
function solve(level, x, y, solveFn)
|
|
{
|
|
solveStep(level, x, y, solveFn);
|
|
drowTable(level)
|
|
}
|
|
|
|
solve(LEVEL, 8, 6, solveMoveStep);
|
|
</script>
|
|
</body>
|
|
</html> |