15puzzle

タイルを動かして、1-15の順番に並べるゲームで、各数字に割り当てるx座標y座標をMathfloorのwidth,heightで割って、配列しています。var moveCountの数字を動かすことによって、ゲームの難易度を変更します。

reference
clientX Property:returns the horizontal coordinate (according to the client area) of the mouse pointer when a mouse event was triggered.The client area is the current window.

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>15puzzle</title>
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<style>
	</style>
</head>
<body>
	<canvas id="stage" width="280" height="280">
		Canvas not supported ...
	</canvas>
	<script>
		(function(){
			'use strict';

			var canvas = document.getElementById('stage');
			var context;
			var image;
			var IMAGE_URL = '15puzzle.png';
			var tiles = [];
			var ROW_COUNT = 4;
			var COL_COUNT = 4;
			var PIC_WIDTH = 280;
			var PIC_HEIGHT = 280;
			var TILE_WIDTH = PIC_WIDTH / COL_COUNT;
			var TILE_HEIGHT = PIC_HEIGHT / ROW_COUNT;
			var UDLR = [
				[ 0, -1],
				[ 0, 1],
				[ -1, 0],
				[ 1, 0],
			];
			var moveCount = 3;

			function initTiles(){
				var row, col;
				for (row = 0; row < ROW_COUNT; row++){
					tiles&#91;row&#93; = &#91;&#93;;
					for (col = 0; col < COL_COUNT; col++){
						tiles&#91;row&#93;&#91;col&#93; = row * COL_COUNT + col;
					}
				}
				tiles&#91;ROW_COUNT - 1&#93;&#91;COL_COUNT - 1&#93; = -1;
			}

			function drawPuzzle(){
				var row, col;
				var sx, sy;
				var dx, dy;

				for (row = 0; row < ROW_COUNT; row++){
					for (col = 0; col < COL_COUNT; col++){
						dx = col * TILE_WIDTH;
						dy = row * TILE_HEIGHT;
						if (tiles&#91;row&#93;&#91;col&#93; === -1){
							context.fillStyle = '#eeeeee';
							context.fillRect(dx, dy, TILE_WIDTH, TILE_HEIGHT);
						}else {
						sx = (tiles&#91;row&#93;&#91;col&#93; % COL_COUNT) * TILE_WIDTH;
						sy = Math.floor((tiles&#91;row&#93;&#91;col&#93; / ROW_COUNT)) * TILE_HEIGHT;
				
						context.drawImage(image, sx, sy, TILE_WIDTH, TILE_HEIGHT, dx, dy, TILE_WIDTH, TILE_HEIGHT);
						}
						
					}
				}
	
				/*context.drawImage(image, 0, 0);*/
			}

			function checkResult(){
				var row, col;
				for (row = 0; row < ROW_COUNT; row++){
					for (col = 0; col < COL_COUNT; col++){
						if (row === ROW_COUNT -1 && col === COL_COUNT -1){
							return true;
						}
						if (tiles&#91;row&#93;&#91;col&#93; !== row * COL_COUNT + col){
							return false;
						}
				}
			}

			}
			function moveBlank(count){
				var blankRow, blankCol;
				var targetPosition;
				var targetRow, targetCol;

				blankRow = ROW_COUNT -1;
				blankCol = COL_COUNT -1;

				while(true){
				targetPosition = Math.floor(Math.random() * UDLR.length);
				targetRow = blankRow + UDLR&#91;targetPosition&#93;&#91;1&#93;;
				targetCol = blankCol + UDLR&#91;targetPosition&#93;&#91;0&#93;;
				if(targetRow < 0 || targetRow >= ROW_COUNT){
					continue;
				}
				if(targetCol < 0 || targetCol >= COL_COUNT){
					continue;
				}
				tiles[blankRow][blankCol] = tiles[targetRow][targetCol];
				tiles[targetRow][targetCol] = -1;
				blankRow = targetRow;
				blankCol = targetCol;
				if(!--count){
					break;
				}
				} 
			}

			if (!canvas.getContext){
				alert('canvas not supported ...');
				return
			}
			context = canvas.getContext('2d');

			image = document.createElement('img');
			image.src = IMAGE_URL;
			image.addEventListener('load', function(){
				initTiles();
				moveBlank(moveCount);
				drawPuzzle();
			});

			canvas.addEventListener('click', function(e){
				var x, y;
				var rect;
				var row, col;
				var i;
				var targetRow, targetCol;
				rect = e.target.getBoundingClientRect();
				x = e.clientX - rect.left;
				y = e.clientY - rect.top;
				row = Math.floor(y / TILE_HEIGHT);
				col = Math.floor(x / TILE_WIDTH);
				if (tiles[row][col] === -1){
					return;
				}
				 for (i = 0; i < UDLR.length; i++) {
       			 targetRow = row + UDLR&#91;i&#93;&#91;1&#93;;
      			  targetCol = col + UDLR&#91;i&#93;&#91;0&#93;;
      			  if (targetRow < 0 || targetRow >= ROW_COUNT) {
      		  	 	 continue;
     			   }
     			  if (targetCol < 0 || targetCol >= COL_COUNT) {
     		     	 continue;
    			    }
					if (tiles[targetRow][targetCol] === -1) {
         			 tiles[targetRow][targetCol] = tiles[row][col];
         			 tiles[row][col] = -1;
       				   drawPuzzle();
       				   if (checkResult()){
       				   	alert('Game Clear!')
       				   }
						break;
					}
				}
			});
		})();
	</script>
</body>
</html>