Sometimes ago I created a sliding puzzle using DML, which is in fact mainly Javascript.
I was curious to see other implementations.
For recall here is my version : Sliding
<html lang="de"> <head> <meta charset="utf-8"> <title>title</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="https://efpage.de/DML/DML_homepage/lib/DML-min.js"></script> </head> <body> <script> function sleep (ms) { return new Promise((r,err) => { setTimeout(r,ms) }) } class Board { cssCell = ` background:blueviolet;height:100px; width:100px; margin:2px;cursor:pointer;flex: 0 0 100px; display:flex;align-items: center; justify-content: center;color: orange; ` cssBoard = ` padding:5px;display:flex; flex-wrap:wrap;background:orange; width:416px;margin:0 auto; ` checkValidBoard () { function checkPos (c) { return c.dataset.pos == c.dataset.curpos } return this.cells.every(checkPos); } findDirectionToMove(cell) { const [getCol,getRow] = [(pos) => pos%4,(pos) => Math.trunc(pos/4)] const cellpos = Number(cell.dataset.curpos); const emptyCellpos = Number(this.emptyCell.dataset.curpos); const rowcolEmpty = [getRow(emptyCellpos), getCol(emptyCellpos)]; const rowcolCell = [getRow(cellpos), getCol(cellpos)]; const sameColOrRow = (rowcolEmpty[0] == rowcolCell[0] ) || (rowcolEmpty[1] == rowcolCell[1]); if (!sameColOrRow) return; const directions = { [ cellpos - 1] : "left", [ cellpos + 1] : "right", [ cellpos - 4] : "up", [ cellpos + 4] : "down" } let posdir = Object.keys(directions).find(pos => pos == emptyCellpos); return (directions[posdir]); } findOpositeDirection(direction) { if (direction == "up") { return "down" } if (direction == "down") { return "up" } if (direction == "left") { return "right" } if (direction = "right") { return "left" } } moveCell (cell) { const direction = this.findDirectionToMove(cell); if (!direction) return; const amount = 104; const duration = 200; const coef = { 'left' : -1, 'right' : 1, 'down' : 1, 'up' : -1 } const oppositeDirection = this.findOpositeDirection(direction); const cssTranslate = (cell, direction) => { if (direction == 'left' || direction == 'right') { cell.dataset.dx = Number(cell.dataset.dx) + amount * coef[direction] } if (direction == 'up' || direction == 'down') { cell.dataset.dy = Number(cell.dataset.dy) + amount * coef[direction] } return `translate(${cell.dataset.dx}px, ${cell.dataset.dy}px )` } cell.animate( {transform: cssTranslate(cell, direction)}, {duration: duration, fill: "forwards"}); this.emptyCell.animate( {transform: cssTranslate(this.emptyCell, oppositeDirection)}, {duration: duration, fill: "forwards"} ); let temp = this.emptyCell.dataset.curpos; this.emptyCell.dataset.curpos = cell.dataset.curpos; cell.dataset.curpos = temp; if (cell.dataset.pos != cell.dataset.curpos) { cell.style.background = "deeppink"; cell.style.color = "white"; } else { cell.style.background = "blueviolet"; } } createCells () { // fills cells array with cell element this.cells = [...Array(16)].map((_, i) => { let options = { style : this.cssCell, ["data-pos"] : i, ["data-curpos"] : i, ["data-dx"] : 0, ["data-dy"] : 0 } let content = h1(`${i}`); let cell = create("div", options, content); cell.onclick = () => this.moveCell(cell); return cell; }); // empty cell customisation this.emptyCell = this.cells[15]; this.emptyCell.style.background = "rgba(255,0,0,0.0)"; this.emptyCell.style.zIndex = 0; this.emptyCell.style.color = "transparent"; } displayBoard () { selectBase(div("")); print("<h1 style='text-align:center'>Sliding Puzzle</h1>"); unselectBase(); selectBase(div("", {style: this.cssBoard})); this.cells.map(appendBase); unselectBase(); selectBase(div("", "text-align:center;margin-top:20px")); button("Shuffle") .onclick = () => this.shuffle(); unselectBase(); } moveCellByCurpos(cellpos) { let cell = this.cells.find(cell => cell.dataset.curpos == cellpos); this.moveCell(cell); } async shuffle () { for (let i = 0; i < 200; i++) { const emptyPos = Number(this.emptyCell.dataset.curpos); const validPos = [ emptyPos - 1, emptyPos + 1, emptyPos - 4, emptyPos + 4 ].filter(pos => {return (pos >= 0) && (pos <= 15); }) const randomPos= validPos[Math.floor(Math.random()*validPos.length)]; await sleep(10); this.moveCellByCurpos(randomPos); } } start () { this.createCells (); this.displayBoard(); } } let game = new Board() game.start() game.shuffle() </script> </body> </html>
Top comments (0)