Skip to content

Instantly share code, notes, and snippets.

@wlib
Created April 19, 2021 18:43
Show Gist options
  • Select an option

  • Save wlib/06b59a8f7ababe9cb006ebdbe1e38991 to your computer and use it in GitHub Desktop.

Select an option

Save wlib/06b59a8f7ababe9cb006ebdbe1e38991 to your computer and use it in GitHub Desktop.

Revisions

  1. wlib created this gist Apr 19, 2021.
    92 changes: 92 additions & 0 deletions consolePuzzle.mjs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,92 @@
    const { pipe } = await import("https://unpkg.com/[email protected]/src/util/index.mjs")
    const { listen, map, filter, forEach, tap } = await import("https://unpkg.com/[email protected]/src/util/iterable/async.mjs")

    const makePuzzle = (n = 4) => {
    const solvedPuzzle =
    [...Array(n)]
    .map((_, rowI) =>
    [...Array(n)].map((_, colI) => rowI * n + colI + 1)
    )
    solvedPuzzle[n - 1][n - 1] = null

    return [...Array(100)]
    .map(() =>
    ["up", "down", "left", "right"][Math.floor(Math.random() * 4)]
    )
    .reduce((puzzle, direction) => move(puzzle, direction), solvedPuzzle)
    }

    const move = (puzzle, direction) => {
    const result = puzzle.map(row => [...row])
    const emptyRow = puzzle.findIndex(row => row.includes(null))
    const emptyCol = puzzle[emptyRow].indexOf(null)

    const [fromRow, fromCol] =
    ({
    up: [emptyRow + 1, emptyCol ],
    down: [emptyRow - 1, emptyCol ],
    left: [emptyRow , emptyCol + 1],
    right: [emptyRow , emptyCol - 1]
    })[direction]

    if (puzzle[fromRow]?.[fromCol]) {
    result[emptyRow][emptyCol] = puzzle[fromRow][fromCol]
    result[fromRow][fromCol] = null
    }

    return result
    }

    const display = puzzle => {
    console.clear()

    if (puzzle.flat().slice(0, -1).every((n, i) => n == i + 1)) {
    const name = puzzle.flat().slice(0, -1).length
    console.log(`You solved the "${name} puzzle" in ${moves} moves!`)
    return
    }

    const maxWidth = Math.max(
    ...puzzle.flat()
    .map(n => (n || "").toString().length)
    )

    const table = puzzle
    .map(row =>
    row
    .map(n =>
    (n || "").toString()
    .padStart(maxWidth + 1)
    .padEnd(maxWidth + 2)
    )
    .join("")
    )
    .map(row => "\n" + row + "\n")
    .join("")

    console.log(table)
    }

    let currentPuzzle = makePuzzle(
    parseInt(prompt("Choose your difficulty level", 4))
    )
    let moves = 0
    display(currentPuzzle)

    pipe(
    listen(document, "keydown"),
    map(({ key }) =>
    ({
    ArrowUp: "up",
    ArrowDown: "down",
    ArrowLeft: "left",
    ArrowRight: "right"
    })[key]
    ),
    filter(direction => direction != undefined),
    forEach(direction => {
    currentPuzzle = move(currentPuzzle, direction)
    moves++
    display(currentPuzzle)
    })
    )