Giter Club home page Giter Club logo

students-tutorial-fifteen-puzzle-game's Introduction

15 game

Idea of implementation is declarative approach to rerender UI whenever state is changed. Representation of state is array 4x4 and renderer for the game is renderGame function. Whenever state is changed we will call renderGame with new state;

State of game

State of the game will be represented by array of arrays

const fifteen = [
	[1, 2, 3, 4],
	[5, 6, 7, 8],
	[9, 10, 11, 12],
	[13, 14, null, 15]
];

Where every number is a cell of game and null is a an empty cell.

With the state above UI will look:

img example

getXY

getXY function which returns object with current position of an empty cell, as an argument it takes state of game (array of arrays)

const getXY = (source) => {
	const y = source.findIndex(arr => arr.includes(null));
	const x = source[y].findIndex(x => x === null);
	return { y, x };
};
const fifteen = [
	[1, 2, 3, 4],
	[5, 6, 7, 8],
	[9, 10, 11, 12],
	[13, 14, null, 15]
];
const xy = getXY(fifteen); // {y: 3, x: 2} it means current position of an empty cell - fifteen[3][2]

Game is finished when state is equal to:

[
	[1, 2, 3, 4],
	[5, 6, 7, 8],
	[9, 10, 11, 12],
	[13, 14, 15, null]
];

shuffleState

shuffleState function which returns shuffled state, it takes as an argument state of the game. Use this function when you start new game;

const shuffleState = (state) => {
	const suffleArr = (inputArr) => {
		const arr = [...inputArr];
		for (var j, x, i = arr.length; i; j = parseInt(Math.random() * i), x = arr[--i], arr[i] = arr[j], arr[j] = x);
		return arr;
	}
	const flattenArr = state.reduce((acc, val) => {
		return [...acc, ...val]
	}, []);
	const shuffledArr = suffleArr(flattenArr);
	return [
		shuffledArr.slice(0,4),
		shuffledArr.slice(4,8),
		shuffledArr.slice(8,12),
		shuffledArr.slice(12,16),
	]
}

Render UI

Use functions bellow to render UI for the game.

renderRow

renderRow function which returns string that represents html content for one row, as an argument it takes an array of values. This function is going to be used in the function that will return html for all rows.

/*
example  of argument
const arr = [1, 2, 3, 4]
*/

const renderRow = (arr) =>
	`<div class='square'>${arr.join('</div><div class=\'square\'>')}</div>`

renderRows

renderRows function which returns string that represents html content for all rows. As an argument it takes array of array of values.

/*
 example  of argument
 
 const arr = [
	[1, 2, 3, 4],
	[5, 6, 7, 8],
	...
 ]
*/

const renderRows = (arr) => {
	return arr.reduce((acc, current) => {
		return acc + renderRow(current);
	}, '');
};

renderGame

renderGame function which renders into the dom UI for the game, it takes 2 arguments, first - array of arrays of values, second argument is a place (dom node) where game will be rendered, by default it is a div with 'app' id. When you use this function make sure you have this dom node in the html file.

const renderGame = (shuffledArray, domNode = document.getElementById('app')) => {
	const rows = renderRows(shuffledArray).replace(
		'<div class=\'square\'></div>',
		'<div class=\'square empty\'></div>'
	);
	domNode.innerHTML = rows;
};

When we have our UI is rendered we need to add styles so our html content looks like a game.

Styles

Add styles.css file with the following styles:

body {
	font-family: sans-serif;
	}
  
#app {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: scale(1.3) translate(-50%, -50%) skew(0deg, 3deg);
	padding: 4px;
	background: #fff;
	display: flex;
	width: 208px;
	height: 208px;
	flex-wrap: wrap;
	box-shadow: 0px 10px 1px #ddd, 5px 10px 20px #ccc;
}

.square {
	display: flex;
	color: #fff;
	flex-direction: column;
	justify-content: center;
	margin: 1px;
	align-items: center;
	width: 50px;
	height: 50px;
	border-radius: 5px;
	background-color: #06c;
}

.square.empty {
	background-color: #fff;
}

Import css file into your js file.

Controls

Add to the document event listener for keydown event. You should react when one of the arrows button (use keycode to check if it's arrow button) is pressed. Idea is you should swap empty cell (null value in the state) with the neighbor cell depending on which arrow button is pressed and then rerender Game (use renderGame function). For example, given that empty cell has position {y: 3, x: 2} and up arrow is pressed you should swap with cell that has posiiton {y: 4, x: 2} (let's say it is 11) so empty cell becomes {y: 4, x: 2} and 11 becomes {y: 3, x: 2}, when you did swap then rerender the game. Code example:

document.addEventListener('keydown', e => {
		const xyOfEmptyCell = getXY(stateOfGame);
		if (e.keyCode === 38) {
			// up arrow
			if (xyOfEmptyCell.y === 3) return; // figure out why we have this checking
			const nextY = xyOfEmptyCell.y + 1;
			const nextX = xyOfEmptyCell.x;
			stateOfGame[xyOfEmptyCell.y][xyOfEmptyCell.x] = stateOfGame[nextY][nextX];
			stateOfGame[nextY][nextX] = null;
			renderGame(stateOfGame);
		}
});

Winning state

Write function which checks if game is finished (user won), if user won - do alert with congratulation message, after user close alert new game is started automatically.

Let's begin

...

const fifteen = [
  [1, 2, 3, 4],
  [5, 6, 7, 8],
  [9, 10, 11, 12],
  [13, 14, null, 15]
];

const state = shuffleState(fifteen);
renderGame(state);

document.addEventListener('keydown', (e) => {
	...
});

...

Bonus

  • Investigate implementation of functions in this tutorial.
  • Use eslint for this project.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.