Make a simple minesweeper game with jquery

This is a small minesweeper game that I made on my own whim when I was learning jquery. The main knowledge used is html5, css3, javascript and jquery. The jquery version used is jquery-1.6.4.min, code files and libraries You can click this link to download the file: Minesweeper game code and resources made with jquery . The following are my main ideas and codes when I was making this small game.

Preparation

First of all, we need to clarify the rules of the game and use this to determine the function, and we need to know what we want the interface of the game to look like. This minesweeper game of mine was adapted from one of my classroom experiments. Originally it was just a bunch of grids that could change colors.

Here is my train of thought
  1. First of all, 81 grids should be placed on the webpage. All grids have a uniform style, but the id of each grid is composed of row number and column number, which is easy to find (the grid here is made with p tags).
  2. If 10 mines are placed in 81 grids, the coordinates of the mines are naturally recorded in the array instead of being reflected in the grid.
  3. A span tag element is placed in each grid to record the number. The default is 0. The function of the number represents the number of mines around. Those who have played minesweeper should know it.
  4. Add a number to each span tag by judging according to the position of the mine, so that the value of the span tag element around each mine is increased by 1.
  5. Add the mouse click event of the grid. When the grid is clicked, the judgment is made. If the grid is a mine, the game is over. If it is not a mine, the grid is opened (the situation here is more complicated, and will be explained in detail below, because it involves mines. The automatic opening grid, that is, when the grid you click does not have any numbers, the game will automatically open the surrounding grids for you until it is surrounded by numbers).

Realization of specific functions

Let’s define some required styles first. Here we mainly focus on the style of the grid (p tag), the style after the grid is clicked, and the style after the mine is clicked. Here I put the style of the grid that is normally clicked on in the highlight class, set the background color to gold, and the color of the mine that is clicked on is red, and put it in the lowlight class. The p tag only needs to set a little margin and border width, and then set the float to float to the left. Because we need to turn 81 grids into a 9*9 arrangement, and each row of grids must be placed in a div, so there is also a div style set.

<style type="text/css">
	body {
    
     width:760px; }
	div {
    
     margin:5px 10px; clear:both; }
	p {
    
     float:left; margin:3px; width:30px; height:30px; border:2px solid black; text-align:center; display:table;}
	.highlight {
    
     background-color:gold; }
	.lowlight{
    
    background-color:red;}
</style>

Then introduce the jquery library file. Remember to put the jquery file and the web page file in the same folder.

<script src="jquery-1.6.4.min.js" type="text/javascript"></script>

After defining the style, you can place grids on the page. Here I use two for loops, the first one is used to generate div (representing a row), and the second one is used to generate p (grid) in div.

//产生一个9*9的格子地图
		for(var i=0;i<9;i++){
    
    
			$("body").append("<div id='"+i+"i'></div>");
			for(var j=0;j<9;j++){
    
    
				$("#"+i+"i").append("<p id='"+i+"i"+j+"j'><span style='display:table-cell;vertical-align:middle;visibility:hidden;'>0</span></p>");
			}
		}

Haha, do you feel that the definition of the span tag is very long, here is an explanation of why so many style attributes are given to the span tag, where display: table-cell means that the span will be displayed as a table cell, and the parent element of the span is the p tag In the style, display: table is defined (see the first paragraph of code). These two display attributes and vertical-align can make the span tag vertically centered. To put it bluntly, this attribute is for good-looking use. visibility:hidden, this attribute is to hide the span tag, why should it be hidden? Because we don't want to see the numbers in the grid before we click the grid, and the numbers represent the number of mines around.

In this way, we have defined the grid, and then 10 mines are generated. Here I define two one-dimensional arrays, which are used to store the row number and column number (from 0 to 8) of the mines. The Math.floor() function is used to generate integers, and Math.random() is used to generate random numbers. These two functions are used together to generate random integers.

var aa=[0];	//地雷横坐标
		var bb=[0];	//地雷纵坐标
		var flag=true;	//判断是否产生了重复坐标
		//产生不重复的10个整数并存入aa,bb数组中,作为地雷坐标
		for(var i=0;i<10;i++){
    
    
			aa[i]=Math.floor(Math.random()*9);
			bb[i]=Math.floor(Math.random()*9);
			for(var j=0;j<i;j++){
    
    
				if(aa[i]==aa[j]&&bb[i]==bb[j]){
    
    
					i--;
					flag=false;
					break;
				}
			}
			if(flag==false){
    
    
				flag=true;
			}else{
    
    
				console.log(aa[i],bb[i]);
			}
		}

Here the console.log() function is only used for debugging. You can open the web page during the test and press F12 to view the generated mine coordinates in the Console.

After the mine is generated, it is necessary to assign values ​​to the surrounding span elements according to the coordinates of the mine. Since the value of all span elements is 0 at the beginning, what we need to do is to add +1 to the value of each span element around the mine. Of course, we need to get the value of the span element first, then +1, and then assign it. The code here is not complicated, it just looks long.

//给每个地雷周围的格子加数字,数字代表周围地雷数
		var z=[""];			//记录地雷周围p的id;
		for(var i=0;i<10;i++){
    
    
			x=aa[i];
			x1=x-1;
			x2=x+1;
			y=bb[i];
			y1=y-1;
			y2=y+1;
			//获取每个p的id;
			z[0]="#"+x1+"i"+y1+"j";
			z[1]="#"+x1+"i"+y+"j";
			z[2]="#"+x1+"i"+y2+"j"
			z[3]="#"+x+"i"+y1+"j";
			z[4]="#"+x+"i"+y2+"j";
			z[5]="#"+x2+"i"+y1+"j";
			z[6]="#"+x2+"i"+y+"j";
			z[7]="#"+x2+"i"+y2+"j";
			$(z[0]).children().html(Number($(z[0]).children().html())+1);
			$(z[1]).children().html(Number($(z[1]).children().html())+1);
			$(z[2]).children().html(Number($(z[2]).children().html())+1);
			$(z[3]).children().html(Number($(z[3]).children().html())+1);
			$(z[4]).children().html(Number($(z[4]).children().html())+1);
			$(z[5]).children().html(Number($(z[5]).children().html())+1);
			$(z[6]).children().html(Number($(z[6]).children().html())+1);
			$(z[7]).children().html(Number($(z[7]).children().html())+1);
		}

The last step is the most important, which is to add a click event to the p tag. Let me first show the flow chart of the p tag click event.
insert image description here
The logic in the second half here is a bit complicated, and I may not express it clearly. All in all, it is a recursive call process. When the detection function checkBlank() finds that the value of a certain grid around the clicked grid is 0, it will check this grid. Call the checkBlank() function to retest. For example, if you click a grid with a value of 0 (this is the protagonist), checkBlank() will first check the grid in the upper left corner of the grid. If the value of the grid in the upper left corner is also 0 and has not been opened, it will If it is not a landmine, then the grid in the upper left corner becomes a new protagonist, and the checkBlank() function will first check the new protagonist. This is used to simulate minesweeping, click on a grid without mines around, and then the system will automatically open all the blank grids for you. Below is the code for that function.

var zz=[""];		//记录地雷所在p的id
		for(var i=0;i<10;i++){
    
    
			zz[i]=aa[i]+"i"+bb[i]+"j";
		}
		//p标签点击事件
		jQuery("p").click(function(){
    
    		
			var k=$(this).parent().index();		//p所在行
			var n=$(this).attr("id");			//p的id
			var	t=$(this).parent().children("#"+n+"").index();	//p所在列
			var gameOver=false;			//游戏结束的标志
			for(var i=0;i<10;i++){
    
    
				if(k==aa[i]&&t==bb[i]){
    
    
					gameOver=true;
				}
			}
			if(gameOver==true){
    
    	
				for(var i=0;i<10;i++){
    
    
					$("#"+aa[i]+"i"+bb[i]+"j").addClass("lowlight");
				}
				setTimeout(alertGame,100);
				function alertGame(){
    
    
					alert("你输了");
					setTimeout(window.location.reload());		//刷新页面
				}
			}else{
    
    
				$(this).children().css("visibility","visible");		//显示格子周围地雷数
				$(this).addClass("highlight");		//设置格子背景色为高亮
				if(Number($(this).children(0).html())==0){
    
    
					var currentBlank=$(this);
					checkBlank(currentBlank);
				}
			}
			
			//检测空白格子是否需要被翻开
			function checkBlank(aBlank){
    
    
				var a=aBlank.index();
				var b=a-1;
				var c=a+1;
				var d=aBlank.parent().prev().children(":eq("+b+")").children();
				judge(d);
				d=aBlank.parent().prev().children(":eq("+a+")").children();
				judge(d);
				d=aBlank.parent().prev().children(":eq("+c+")").children();
				judge(d);
				d=aBlank.parent().next().children(":eq("+b+")").children();
				judge(d);
				d=aBlank.parent().next().children(":eq("+a+")").children();
				judge(d);
				d=aBlank.parent().next().children(":eq("+c+")").children();
				judge(d);
				d=aBlank.prev().children();
				judge(d);
				d=aBlank.next().children();
				judge(d);
				//主要的判断函数,若满足两个条件则可以被翻开,1.格子内span元素的visibility属性为hidden. 2.格子不是地雷
				function judge(e){
    
    
					if(Number(e.html())!=0&&e.css("visibility")=="hidden"&&checkBoom(e.parent())==false){
    
    
						e.css("visibility","visible");
						e.parent().addClass("highlight");
					}else if(Number(e.html())==0&&e.css("visibility")=="hidden"&&checkBoom(e.parent())==false){
    
    
						e.css("visibility","visible");
						e.parent().addClass("highlight");
						checkBlank(e.parent());
					}	
				}
				function checkBoom(f){
    
    
					var g=f.attr("id");
					var gg=false;
					for(var i=0;i<10;i++){
    
    
						if(g==zz[i]){
    
    
							gg=true;
							break;
						}
					}
					return gg;
				}
			}
		});

After writing this, our minesweeper game is complete, but there are still many things that can be improved in this small game. I didn't continue to work on it. You can try it yourself. For example, the judgment of game victory conditions and the function of marking mines. If you need resources, you can click the link below to download.
Minesweeper game code and resources made with jquery
The following is the complete code

<!DOCTYPE html >
<html>
<head>
<meta charset="utf-8"/>
<title>扫雷</title>
<style type="text/css">
	body {
    
     width:760px; }
	div {
    
     margin:5px 10px; clear:both; }
	p {
    
     float:left; margin:3px; width:30px; height:30px; border:2px solid black; text-align:center; display:table;}
	.highlight {
    
     background-color:gold; }
	.lowlight{
    
    background-color:red;}
</style>
<script src="../jquery-1.6.4.min.js" type="text/javascript"></script>
<script>
	jQuery(document).ready(function(){
    
    
		//产生一个9*9的格子地图
		for(var i=0;i<9;i++){
    
    
			$("body").append("<div id='"+i+"i'></div>");
			for(var j=0;j<9;j++){
    
    
				$("#"+i+"i").append("<p id='"+i+"i"+j+"j'><span style='display:table-cell;vertical-align:middle;visibility:hidden;'>0</span></p>");
			}
		}
		var aa=[0];	//地雷横坐标
		var bb=[0];	//地雷纵坐标
		var flag=true;	//判断是否产生了重复坐标
		//产生不重复的10个整数并存入aa,bb数组中,作为地雷坐标
		for(var i=0;i<10;i++){
    
    
			aa[i]=Math.floor(Math.random()*9);
			bb[i]=Math.floor(Math.random()*9);
			for(var j=0;j<i;j++){
    
    
				if(aa[i]==aa[j]&&bb[i]==bb[j]){
    
    
					i--;
					flag=false;
					break;
				}
			}
			if(flag==false){
    
    
				flag=true;
			}else{
    
    
				console.log(aa[i],bb[i]);
			}
		}
		//给每个地雷周围的格子加数字,数字代表周围地雷数
		var z=[""];			//记录地雷周围p的id;
		for(var i=0;i<10;i++){
    
    
			x=aa[i];
			x1=x-1;
			x2=x+1;
			y=bb[i];
			y1=y-1;
			y2=y+1;
			//获取每个p的id;
			z[0]="#"+x1+"i"+y1+"j";
			z[1]="#"+x1+"i"+y+"j";
			z[2]="#"+x1+"i"+y2+"j"
			z[3]="#"+x+"i"+y1+"j";
			z[4]="#"+x+"i"+y2+"j";
			z[5]="#"+x2+"i"+y1+"j";
			z[6]="#"+x2+"i"+y+"j";
			z[7]="#"+x2+"i"+y2+"j";
			$(z[0]).children().html(Number($(z[0]).children().html())+1);
			$(z[1]).children().html(Number($(z[1]).children().html())+1);
			$(z[2]).children().html(Number($(z[2]).children().html())+1);
			$(z[3]).children().html(Number($(z[3]).children().html())+1);
			$(z[4]).children().html(Number($(z[4]).children().html())+1);
			$(z[5]).children().html(Number($(z[5]).children().html())+1);
			$(z[6]).children().html(Number($(z[6]).children().html())+1);
			$(z[7]).children().html(Number($(z[7]).children().html())+1);
		}
		var zz=[""];		//记录地雷所在p的id
		for(var i=0;i<10;i++){
    
    
			zz[i]=aa[i]+"i"+bb[i]+"j";
		}
		//p标签点击事件
		jQuery("p").click(function(){
    
    		
			var k=$(this).parent().index();		//p所在行
			var n=$(this).attr("id");			//p的id
			var	t=$(this).parent().children("#"+n+"").index();	//p所在列
			var gameOver=false;			//游戏结束的标志
			for(var i=0;i<10;i++){
    
    
				if(k==aa[i]&&t==bb[i]){
    
    
					gameOver=true;
				}
			}
			if(gameOver==true){
    
    	
				for(var i=0;i<10;i++){
    
    
					$("#"+aa[i]+"i"+bb[i]+"j").addClass("lowlight");
				}
				setTimeout(alertGame,100);
				function alertGame(){
    
    
					alert("你输了");
					setTimeout(window.location.reload());		//刷新页面
				}
			}else{
    
    
				$(this).children().css("visibility","visible");		//显示格子周围地雷数
				$(this).addClass("highlight");		//设置格子背景色为高亮
				if(Number($(this).children(0).html())==0){
    
    
					var currentBlank=$(this);
					checkBlank(currentBlank);
				}
			}
			
			//检测空白格子是否需要被翻开
			function checkBlank(aBlank){
    
    
				var a=aBlank.index();
				var b=a-1;
				var c=a+1;
				var d=aBlank.parent().prev().children(":eq("+b+")").children();
				judge(d);
				d=aBlank.parent().prev().children(":eq("+a+")").children();
				judge(d);
				d=aBlank.parent().prev().children(":eq("+c+")").children();
				judge(d);
				d=aBlank.parent().next().children(":eq("+b+")").children();
				judge(d);
				d=aBlank.parent().next().children(":eq("+a+")").children();
				judge(d);
				d=aBlank.parent().next().children(":eq("+c+")").children();
				judge(d);
				d=aBlank.prev().children();
				judge(d);
				d=aBlank.next().children();
				judge(d);
				//主要的判断函数,若满足两个条件则可以被翻开,1.格子内span元素的visibility属性为hidden. 2.格子不是地雷
				function judge(e){
    
    
					if(Number(e.html())!=0&&e.css("visibility")=="hidden"&&checkBoom(e.parent())==false){
    
    
						e.css("visibility","visible");
						e.parent().addClass("highlight");
					}else if(Number(e.html())==0&&e.css("visibility")=="hidden"&&checkBoom(e.parent())==false){
    
    
						e.css("visibility","visible");
						e.parent().addClass("highlight");
						checkBlank(e.parent());
					}	
				}
				function checkBoom(f){
    
    
					var g=f.attr("id");
					var gg=false;
					for(var i=0;i<10;i++){
    
    
						if(g==zz[i]){
    
    
							gg=true;
							break;
						}
					}
					return gg;
				}
			}
		});	
	});
</script>
</head>
<body>
	
</body>
</html>

Guess you like

Origin blog.csdn.net/zhulong16/article/details/102321210