It's been a while since I did anything with JavaScript. I made a tile puzzle game to help me brush up. You can find it here: https://compucademy.net/tile-puzzle/
I would like some feedback on my use of JS, HTML and CSS. Anything would be helpful - structure, best practices, overall approach, suggestions for improvement etc.
Any input much appreciated.
document.addEventListener( 'DOMContentLoaded', () => {
const n = 16;
const initialTileArray = [];
for ( let i = 0; i < n; i++ ) {
initialTileArray.push( String( i + 1 ) );
}
const board = document.querySelector( '.game-board' );
const audio = document.getElementById( 'audio' );
const resetButton = document.getElementById( 'reset-btn' );
const scrambleButton = document.getElementById( 'scramble-btn' );
let selectedTiles = [];
let clickNumber = 0;
let scrambledTileValues = [];
resetButton.addEventListener( 'click', resetGame );
scrambleButton.addEventListener( 'click', scrambleTiles );
function resetGame() {
board.innerHTML = '';
scrambledTileValues = initialTileArray.slice( 0 );
createBoard();
}
function scrambleTiles() {
board.innerHTML = '';
scrambledTileValues.sort( () => 0.5 - Math.random() );
createBoard();
}
function createBoard() {
for ( let i = 0; i < scrambledTileValues.length; i++ ) {
const tile = document.createElement( 'div' );
tile.setAttribute( 'data-pos', i + 1 );
tile.classList.add( 'game-tile', 'game-blue', 'text-center' );
tile.addEventListener( 'click', processTile );
board.appendChild( tile );
tile.innerHTML = scrambledTileValues[i];
}
}
function checkWin() {
const tiles = board.childNodes;
const config = [];
for ( var i = 0; i < tiles.length; i++ ) {
config.push( tiles[i].innerHTML );
}
return JSON.stringify( config ) === JSON.stringify( initialTileArray );
}
function playSuccessSound() {
audio.play();
}
function processTile() {
const tilePos = this.getAttribute( 'data-pas' );
if ( clickNumber === 0 || clickNumber === 1 ) {
this.classList.remove( 'game-blue' );
this.classList.add( 'game-red' );
selectedTiles.push( this );
clickNumber += 1;
} else if ( clickNumber === 2 ) {
selectedTiles.push( this );
for ( var i = 0; i < selectedTiles.length; i++ ) {
selectedTiles[i].classList.remove( 'game-red' );
selectedTiles[i].classList.add( 'game-blue' );
}
window.console.log( this.getAttribute( 'data-pos' ) );
const val0 = selectedTiles[0].innerHTML;
const val1 = selectedTiles[1].innerHTML;
const val2 = selectedTiles[2].innerHTML;
selectedTiles[0].innerHTML = val2;
selectedTiles[1].innerHTML = val0;
selectedTiles[2].innerHTML = val1;
selectedTiles = [];
clickNumber = 0;
if ( checkWin() ) {
playSuccessSound();
}
}
}
resetGame();
} );
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<link rel="stylesheet" href="css/style.css"/>
<title>Tile Puzzle 3 | 3-Cycles</title>
</head>
<body>
<div class="container">
<div class="row mb-3 justify-content-center">
<h1>Tile Puzzle 3 | 3-Cycles</h1>
</div>
<div class="row mb-3 justify-content-center">
<p>Click 3 tiles to cycles their positions and solve the puzzle</p>
</div>
<div class="row justify-content-center">
<div class="col-">
<div class="game-board d-flex flex-wrap"></div>
</div>
</div>
<div class="row justify-content-center">
<button id="reset-btn" type="button" class="mt-3 game-btn">Reset</button>
<button id="scramble-btn" type="button" class="mt-3 game-btn">Scramble</button>
</div>
</div>
<audio id="audio" src="assets/Success-sound-effect.mp3"></audio>
<script src="scripts/puzzle3.js"></script>
</body>
</html>
body {
font-family: monospace, monospace;
}
.game-board {
width: 408px;
flex-wrap: wrap;
}
.game-tile {
font-family: monospace, monospace;
font-size: 50px;
color: white;
width:100px;
border: 1px solid white;
}
.game-btn {
font-family: monospace, monospace;
color: white;
font-size: 36px;
border: none;
padding: 0 5px;
background: green;
}
.game-btn:focus {
outline: none;
}
.game-blue {
background: blue;
}
.game-red {
background: red;
}
```