I am working on simple game (classic number game) with JavaScript
in which a container div with display Flex contains 9 divs
8 divs are blue with numbers inside from 1 to 8 and 1 div is white without any content
each time the page loaded the divs are ordered randomly
image of the game
and the empty div is placed randomly too.
the mission is to rearrange the numbers from 1 to 8 that when you click on any div that is visually neighbor (above, beneath, left or right)
to the empty div
they are switch their positions
in this image the divs that are allowed to move are 4,7,5
How I can make it with javaScript or jquery ?
here is my code:
$(document).ready(function(){
var arr = [];
for(i=1;i<9;i )
{
arr.push(i);
}
arr.push("");
function shuffleArray(array)
{
for (let i = array.length - 1; i > 0; i--)
{
const j = Math.floor(Math.random() * (i 1));
[array[i], array[j]] = [array[j], array[i]];
}
}
shuffleArray(arr);
for(i=0;i<9;i )
{
divContent.innerHTML = "<div class='tile'>" arr[i] "</div>"
}
var tile = document.getElementsByClassName("tile");
var n = 0;
while (n < tile.length)
{
if (tile[n].textContent != (n 1))
break;
tile[n].style.color = "yellow";
n ;
}
for(i=0;i<tile.length;i )
{
if(!tile[i].textContent)
{
tile[i].style.backgroundColor = "#fff";
tile[i].classList.add("whitt");
}
tile[i].style.color = "#fff";
}
$('.tile').click(function (evt) {
var $div = $(evt.target).closest('.tile');
$div.next('.tile').after($div).animate({opacity: 0.9, top:'100'}, 500 );
for(i=0;i<tile.length;i )
{
if(!tile[i].textContent)
{
tile[i].style.backgroundColor = "#fff";
tile[i].classList.add("whitt");
}
tile[i].style.color = "#fff";
}
n = 0;
while (n < tile.length)
{
tile[n].style.color = "#fff";
if (tile[n].textContent != (n 1))
break;
tile[n].style.color = "yellow";
n ;
}
});
});
.flexDiv{
display:flex;
flex-wrap: wrap;
width:310px;
border:1px solid black;
}
.tile{
position:relative;
background:#08088A;
text-align:center;
width:29%;
margin:1px;
font-size:75px;
font-weight:bold;
color:#fff;
padding:5px;
}
.wh{
background:#fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<div id="divContent" ></div>
CodePudding user response:
Yours has some really cool animations. I cheated and just swap two DOM elements by cloning so I don't think I can animate it. I also didn't try to do anything clever to say where tiles can move. I just made an array of possible moves and every time a tile is clicked, I get a list of possible moves and I check each one to see if it's the empty square. If it is, swap the tiles.
window.addEventListener("DOMContentLoaded", () => {
const tiles = [1, 2, 3, 4, 5, 6, 7, 8, null];
const shuffle = arr => {
for (let i = 0; i < arr.length; i ) {
const j = Math.floor(Math.random() * arr.length);
[arr[i], arr[j]] = [arr[j], arr[i]];
}
};
shuffle(tiles);
const getPositions = pos => [
[1, 3],
[0, 2, 4],
[1, 5],
[0, 4, 6],
[1, 3, 5, 7],
[2, 4, 8],
[3, 7],
[4, 6, 8],
[5, 7]
][pos];
const swap = (elA, elB) => {
const cloneA = elA.cloneNode(true);
const cloneB = elB.cloneNode(true);
elB.parentNode.replaceChild(cloneA, elB);
elA.parentNode.replaceChild(cloneB, elA);
return cloneA;
};
const board = document.getElementById("board");
const tileClick = event => {
const p = Array.from(event.target.parentNode.children).indexOf(
event.target
);
const positions = getPositions(p);
const move = positions.reduce((p, c) => {
const node = board.childNodes[c];
if (node && node.dataset.name === "empty") p = c;
return p;
}, null);
if (move !== null)
swap(board.childNodes[p], board.childNodes[move]).addEventListener(
"click",
tileClick
);
// TODO: check for winning board
};
tiles.forEach((tile, idx) => {
const tileEl = document.createElement("div");
tileEl.classList.add("tile");
tileEl.innerHTML = tile;
tileEl.dataset.name = tile ? tile : "empty";
board.appendChild(tileEl);
tileEl.addEventListener("click", tileClick);
});
});
#board {
display: grid;
padding: 10px;
gap: 10px;
grid-template-columns: repeat(3, 100px);
box-sizing: border-box;
height: 340px;
width: 340px;
border: 1px solid black;
user-select: none;
}
.tile {
display: flex;
align-items: center;
justify-content: center;
height: 100px;
width: 100px;
font-size: xx-large;
background-color: blue;
color: white;
cursor: pointer;
user-select: none;
}
.tile:empty {
background-color: white;
cursor: unset;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.min.css" rel="stylesheet" />
<div id="board"></div>
CodePudding user response:
I have personally used ::before and ::after CSS selectors to add textContent before and after given a element .Do check out the w3schools CSS reference.
