Learn a jquery plug-in every day-Jiugongge puzzle

A jquery plug-in every day-Jiugongge puzzle

Jiugongge Jigsaw

The Jiugongge puzzle is very interesting to make, but this version is exclusive to the Jiugongge. It can only provide the general idea of ​​the ngongge. Later, we will find a way to make the n*ngongge puzzle!

The effect is as follows
Insert picture description here

Code part

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>做拼图游戏</title>
		<script src="js/jquery-3.4.1.min.js"></script>
		<style>
			*{
     
     
				margin: 0px;
				padding: 0px;
				user-select: none;
			}
			#div{
     
     
				border: 1px  solid lightgray;
				width: 330px;
				height: 330px;
			}
			.item{
     
     
				width: 100px;
				height: 100px;
				overflow: hidden;
				float: left;
				outline: 1px solid lightgray;
				position: absolute;
				transition: all 0.2s linear;
			}
			.img{
     
     
				background: url(img/1.jpg);
				background-position:0 0;
				background-repeat: no-repeat;
				background-size: 300px 300px;
			}
			.i0{
     
     
				background-position: 0px 0px;
			}
			.i1{
     
     
				background-position: -100px 0px;
			}
			.i2{
     
     
				background-position: -200px 0px;
			}
			.i3{
     
     
				background-position: 0px -100px;
			}
			.i4{
     
     
				background-position: -100px -100px;
			}
			.i5{
     
     
				background-position: -200px -100px;
			}
			.i6{
     
     
				background-position: 0px -200px;
			}
			.i7{
     
     
				background-position: -100px -200px;
			}
			.i8{
     
     
				background-position: -200px -200px;
			}
		</style>
	</head>
	<body>
		<div id="div"></div>
	</body>
</html>
<script>
	$(function(){
     
     
		const arr = [0,1,2,3,4,5,6,7];//每个图块显示的位置
		const posrr = [
			{
     
     top:6,left:6},{
     
     top:6,left:116},{
     
     top:6,left:226},
			{
     
     top:116,left:6},{
     
     top:116,left:116},{
     
     top:116,left:226},
			{
     
     top:226,left:6},{
     
     top:226,left:116},{
     
     top:226,left:226},
			]//每个图块的定位
		var temp = 0;
		//获取一个块状序列的数组,必须得有效!
		getarr().forEach(item=>{
     
     
			var $item = $("<div class='item img i"+item+"' data-index='"+temp+"' ></div>");
			$item.appendTo($("#div"));
			$item.css(posrr[temp])
			temp++;
		})
		//点击方向键,拼图自然跟着动,我的想法是
		//每个空余部分都有对应的动作,所以我首先就是找到空缺的位置,然后进行替换动作
		$(document).keydown(function(e){
     
     
			var index =  getIndex();
			//动作效果无非就是通过方向键控制占有位置向空置位置挪动
			//0-1-2
			//3-4-5
			//6-7-8
			if((e.keyCode==87||e.keyCode==38)&&index<6){
     
     //上
				thec(index+3,index);
			}
			if((e.keyCode==65||e.keyCode==37)&&"258".indexOf(index)==-1){
     
     //左
				thec(index+1,index)
			}
			if((e.keyCode==83||e.keyCode==40)&&index>=3){
     
     //下
				thec(index-3,index)
			}
			if((e.keyCode==39||e.keyCode==68)&&"036".indexOf(index)==-1){
     
     //右
				thec(index-1,index);
			}
		})
		function getIndex(){
     
     
			var str = "012345678";
			var $items = $(".item").getarr();
			$items.forEach(item=>{
     
     
				var index = item.attr("data-index");
				str = str.replace(index,"");
			})
			return parseInt(str);
		}
		//进一步优化的替换方式,就是把一个序号位置的替换到新的地方,然后给上新的定位,并且替换掉data-index
		//要挪动的块,要挪动的目标位置
		function thec(i1,i2){
     
     
			the(i1).stop().animate(posrr[i2],200);
			the(i1).attr("data-index",i2);
		}
		//一个根据下标返回控制对象的方法
		function the(index){
     
     
			return $(".item[data-index='"+index+"']");
		}
		//给一个随机顺序的拼图序列,必须经过可解验证
		function getarr(){
     
     
			var flag = true;//为true还是需要循环产生一个新的数组
			while(flag){
     
     
				//随机产生序列
				var arr1  =[0,1,2,3,4,5,6,7];
				var arr2 = [];
				while(arr1.length>0){
     
     
					var index = Math.floor(Math.random()*arr1.length);
					arr2.push(arr1[index]);
					arr1.splice(index,1);
				}
				//然后对序列进行有效验证
				var arr3 = arr2;
				var counts = 0;
				for(var a= 0;a<arr3.length;a++){
     
     
					for(var b = a;b<arr3.length;b++){
     
     
						if(arr3[a]>arr3[b]){
     
     
							counts++;
						}
					}
				}
				//因为第九块空置的就是第九块空置的图块,所以逆序数必须为偶数
				if(counts%2==0){
     
     
					flag =false;
					console.log("有解");
				}else{
     
     
					console.log("无解");
				}
			}
			return arr2;
		}
		//一个将dom伪数组的对象转为jquerydom的数组对象
		$.prototype.getarr = function(){
     
     
			var that =this;
			var arr = [];
			for(var i = 0;i<that.length;i++){
     
     
				var $dom = $(that[i]);
				arr.push($dom);
			}
			return arr;
		}
	})
</script>

Idea explanation

  • First of all, analyze what properties of this thing and what driving actions exist at the same time. I think the parameters necessary for writing are these. A Jiugongge has its own order from the upper left corner to the lower right corner. There should be an array list. For example, Jiugongge may have [2, 1,3,4,9,8,6,7,5] Such a set of data, their subscripts indicate that position, and the value inside represents which part of the block is. To be precise, these are two attributes, one It is the current position, and another is the block in the whole picture.
  • Then it will be easy to say later, we randomly generate an out-of-order array, and then determine one by one which block is in the first block and where it is placed.
  • My position here is managed by an array. This is easier to calculate, but it’s just a nine-square grid, so it’s okay to write it to death.
  • Then there is the action effect. Use the arrow keys to control the movement of each block. Then I think of finding the vacant piece first, and then calculate it based on the relationship between it and the arrow keys. For example, if your vacant is 0, Then the left button is to move the block located at block 1 to the left to 0 and then change its state. If it is up, the block located at block 3 moves to 0. The other directions are really not working, and this movement feels a bit cumbersome, but I Simplified the implementation effect, the beginning is two parameters, one is the vacant parameter involved and the parameter to be moved, which have their own logical relationship, but I won't go into the details and write it clearly by looking at the code.
  • After all the effects are realized, I found that it still doesn't work when I play, because the randomly placed tiles have a half chance of being unsolvable! Then I went to the Internet to find a solution, and I came up with a solution later, but let’s look at the code specifically, I have a more mentality here, but after I figure it out, it’s simple.
  • eat!

  • Updated on the next day. The previous algorithm for determining whether there is a solution is wrong. It has been updated. In fact, it is to determine how many inverse numbers are there, and then know the number of moves of the missing block and the target position with the least number of times, and calculate the same odd or even That's it, because the default block I am missing here is the ninth block, and the vacant block is also the ninth block. The minimum number of moves required for resetting is 0 and it is regarded as an even number, and then the reverse number in my series is even. That’s it. If my initial vacant position is the eighth place, then at least one move is an odd number, so the reverse ordinal number must be an odd number.
  • That's it!

Guess you like

Origin blog.csdn.net/weixin_44142582/article/details/114702090