Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

JavaScript

Babel is required to process package imports. If you need a different preprocessor remove all packages first.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML Settings

Here you can Sed posuere consectetur est at lobortis. Donec ullamcorper nulla non metus auctor fringilla. Maecenas sed diam eget risus varius blandit sit amet non magna. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.

HTML

            
              .flex-center.my-container
	.main-box
		-for(i=1; i<9; i++)
			.button
				.flex-center.transition.btn-child= i
		-for(j=1; j<9; j++)
			.flex-center.empty= j

	.end-game
		h1 Congratulation
		p You've Ended game successfully
		button.transition.again Play Again
	p.more For more pen 
		a(href="https://codepen.io/wall-e",target="_blank")
			|click here
            
          
!

CSS

            
              //calculations for width & height
$btn: 76px
$btnBorder: 3px
$btnPad: 5px
$period: $btn + 2 * $btnBorder + $btnPad * 2
$box: 3 * $period

//colors
$boxBg: #03a9f4
$btnBg: #560d0d
$bodyBg: #e88200
$paddingCol: #b8afff
$txtCol: #ff0

*
	-webkit-box-sizing: border-box
	-moz-box-sizing: border-box
	box-sizing: border-box

body
	margin: 0
	background: $bodyBg
	text-align: center

.flex-center
	display: -webkit-box
	display: -ms-flexbox
	display: flex
	align-items: center
	justify-content: center

.my-container
	align-items: center
	justify-content: center
	min-height: 95vh

.main-box
	display: inline-block
	width: $box
	height: $box
	max-width: 100%
	position: relative
	background: $boxBg

.empty
	height: $period
	width: $period
	position: absolute
	
.transition	
	-webkit-transition: all 0.2s linear
	-moz-transition: all 0.2s linear
	-ms-transition: all 0.2s linear
	-o-transition: all 0.2s linear
	transition: all 0.2s linear

.button
	background: $paddingCol
	border: $btnBorder solid $boxBg
	padding: $btnPad
	position: absolute
	cursor: pointer
	z-index: 2

.button:hover .btn-child
	background: $txtCol
	color: $btnBg
	box-shadow: 0 0 10px $btnBg

.btn-child
	height: $btn
	width: $btn
	background: $btnBg
	color: $txtCol

.btn-child, .empty	
	font-size: $btn / 2.5
	font-weight: bold
	-webkit-user-select: none
	user-select: none

@for $i from 1 through 9
	.button:nth-child(#{$i})
		left: $period * (($i - 1)%3)
	.empty:nth-child(#{$i+8})
		left: $period * (($i - 1)%3)

.end-game
	display: none

.again
	background: $boxBg / 1.2
	color: $btnBg / 1.02
	font-weight: bold
	border: 2px solid $btnBg
	padding: 5px 15px

.again:hover
	background: $boxBg / 2
	color: $btnBg * 2.5
	border-color: $btnBg * 1.5

.more
	align-self: flex-end
	position: absolute
	padding-bottom: 10px







            
          
!

JS

            
              $(document).ready(function(){
	
	var card = $('.button');
	var index = 0;
	var emptyPosTop;
	var emptyPosLeft;
	var pos = new Array (9);

	card.each(function(){
		var topVal = card.outerWidth()*i(index/3);
		var t = $(this);
		pos[index] = new Array(2);
		
		//set top position of each button (left position is set by sass)
		$(this).css( 'top', topVal )//.children('div').html(rn[index]);
		pos[index] = [f(t.css('top')), f(t.css('left'))];	//saving positions
		index++;
	});
	
	emptyPosTop = f( card.outerWidth()*parseInt(index/3) );
	emptyPosLeft = f($('.button:nth-child(' + index + ')').css('left')) + f(card.outerWidth());
	pos[index] = [emptyPosTop, emptyPosLeft];
	
	index = 0;
	$('.empty').each(function(){
		$(this).css('top', card.outerWidth()*i(index/3));
		index++;
	});
	
	Shuffle ();
	
	card.bind('click', ClickFunc);
	
	$('.again').click(function(){
		card.bind('click', ClickFunc);
		$('.end-game').css('display', 'none');
		card.removeClass('transition');	//removing transition before shuffling
		Shuffle ();
	});
	
	// shuffle to get a valid shuffled board
	function Shuffle ()
	{
		for(var i=0; i<100; i++)
		{
			var possibleMovingCard = [];
			for(var j=1; j<9; j++)
			{
				var b = $( NthChild(j) );
				if(IsValidCard( f(b.css('top')), f(b.css('left')), [emptyPosTop, emptyPosLeft] ))
				{
					possibleMovingCard.push( NthChild(j) );
				}
			}
			var rndm = RandomInt(0,possibleMovingCard.length-1);
			var movingCard = $(possibleMovingCard[rndm]);
			var temp = [f(movingCard.css('top')), f(movingCard.css('left'))];

			//moving to empty position
			movingCard.css({
				'top' : emptyPosTop,
				'left' : emptyPosLeft
			});

			emptyPosTop = temp[0];
			emptyPosLeft = temp[1];
		}
		
		//adding transition at first will break some card's positions
		card.addClass('transition');
	}
	
	//click function
	function ClickFunc ()
	{
		Swap ($(this), [emptyPosTop, emptyPosLeft]);
		setTimeout(function() {   //calls click event after a certain time
			CheckGame();
		}, 1000);
	}
	
	//move card to empty position
	function Swap (_card, ep)	//selected card, emptyposition
	{
		var thisTop = f(_card.css('top'));
		var thisLeft = f(_card.css('left'));
		
		if(IsValidCard(thisTop, thisLeft, ep))
		{
			var temp = [ thisTop, thisLeft ];
			_card.css({	//go to empty position
				'top' : ep[0],
				'left' : ep[1]
			});
			
			//save the new empty position
			emptyPosTop = temp[0];
			emptyPosLeft = temp[1];	
		}
	}
	
	//check the card is valid to move or not
	function IsValidCard (ct, cl, e)	//card top, card left, empty position
	{
		return (
				//top to bottom & bottom to top
				Math.abs(e[0] - ct) == card.outerWidth() && 
				cl == e[1]
			) || (
				// left to right & right to bottom
				ct == e[0] &&
				Math.abs(e[1] - cl) == card.outerWidth()
			)
	}
	
	//check game is ended or not
	function CheckGame ()
	{
		var count = 0;
		for(var i=0; i<8; i++)
		{
			var b = $ (NthChild(i+1) );
			if(
				f(b.css('top')) == pos[i][0] &&
				f(b.css('left')) == pos[i][1]
			)
			{
				count++;
			}
			else
			{
				count = 0;
				return;
			}
		}
		
		if(count == 8)
			EndGame ();
	}
	
	//after ending game
	function EndGame ()
	{
		$('.button').unbind( "click" );
		$('.end-game').css('display', 'block');
	}
	
	//nth child of button class as string
	function NthChild (num)
	{
		return '.button:nth-child(' + num + ')';
	}
	
	//parse to integer
	function i (param)
	{
		return parseInt(param);
	}

	//parse to float
	function f (param)
	{
		return parseFloat(param);
	}

	//random integer number
	function RandomInt (min, max) {
			return Math.floor(Math.random() * (max - min + 1)) + min;
	}
});


            
          
!
999px

Console