Eight queens question display code

1. introduction

Eight empresses estimate everybody knows what problem is, did not elaborate (do not know Baidu)
The display version mainly depends on vue, so the display and internal logic are separated when writing code, so it's no more difficult than the non display version. The only advantage is that you can try it first, which is more intuitive
I contacted the eight queens question before, but I really began to think about it this afternoon. When I wrote the code, I encountered many holes, whether I dug them or not
After writing, I looked at what I wrote before, and found that I could optimize again, but today I'm too tired

2. Schematic diagram

See below

3. code

See below (a lot of useless code, but it's still that reason. I'm too tired to reorganize it). One thing is better, this code can be used by copying and pasting directly
In other words, just copy the code into a txt file, rename it html, and open it with a browser

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		
		<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
		<script src="http://cdn.static.runoob.com/libs/jquery/1.10.2/jquery.min.js"></script>
		<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
		<title>home page</title>
		<style>
		#main_zone .table{margin:10px;width: 300px;}
		#main_zone .table td{width: 50px;}
		#main_zone .table td input{width:30px;border:none;background-color:transparent;text-align:center;}
		
		.btn-cells{margin: 10px;}
		.print-log{margin: 10px;height: 150px;width:400px;overflow: auto;}
		</style>
	</head>
	<body>
		<main id="main_zone">
			<table class="table table-striped table-bordered table-hover">
				<tbody>
					<tr v-for="(arrFirst,indexFirst) in mainData" >
						<td v-for="(valSecond,indexSecond) in arrFirst" 
							:style="tdStyle(indexFirst,indexSecond)"
							@click="toggleQueen(indexFirst,indexSecond)">
							{{arrFirst[indexSecond]}}
						</td>
					</tr>
				</tbody>
			</table>
			<div class="btn-cells">
				<input type="button" value="Reset" class="btn btn-primary" @click="resetChoice()" />
				<input type="button" value="Calculation" class="btn btn-success" @click="calcChoice()" />
				<input type="button" value="Other" class="btn btn-secondary" @click="otherTest()" />
			</div>
			<div class="print-log">
				<p v-for="(log,index) in logs">{{log}}</p>
			</div>
		</main>
		<script>
		//In order to improve the speed, the next bootstrap plug-in can be put locally:
		//<link href="../../css/bootstrap-3.3.7-dist/css/bootstrap.min.css" rel="stylesheet">
		var vueMain=new Vue({
			el:'#main_zone',
			data:{
				mainData:[
				[11,12,13,14,15,16,17,18],
				[21,22,23,24,25,26,27,28],
				[31,32,33,34,35,36,37,38],
				[41,42,43,44,45,46,47,48],
				[51,52,53,54,55,56,57,58],
				[61,62,63,64,65,66,67,68],
				[71,72,73,74,75,76,77,78],
				[81,82,83,84,85,86,87,88]
				],
				choiceData:[],//Record the node records clicked
				choiceLog:[],//Next, you can select the logs of node collection, which should always be 1 larger than the length of choiceData (the first one is all nodes)
				logs:[]//Print the log information, do not worry about it temporarily
			},
			created:function(){
				//1. The initialization phase will not change
				var arr0=[];
				for(var i=0;i<8;i++){
					for(var j=0;j<8;j++){
						arr0.push({x:i,y:j});
					}
				}
				//console.log(JSON.parse(JSON.stringify(arr0)));
				this.choiceLog.push(arr0);
			},
			computed:{
			},
			methods:{
				//Current level
				curLevel:function(){
					return this.choiceData.length;
				},
				//td style
				tdStyle:function(x,y){
					var okQueenBc='#5cb85c '; / / Green
					var fbQueenBc='#d9534f '; / / red
					var fbOtherBc='#f0ad4e '; / / orange
					var okOtherBc='white';//white
					
					var bc=okOtherBc;
					if(this.hasQueen(x,y)&&!this.forbidArea(x,y)){
						bc=okQueenBc;
					}else if(this.hasQueen(x,y)&&this.forbidArea(x,y)){
						bc=fbQueenBc;
					}else if(!this.hasQueen(x,y)&&this.forbidArea(x,y)){
						bc=fbOtherBc;
					}
					return {
						'background-color':bc,
						cursor:'pointer'
					};
				},
				//Is there a queen
				hasQueen:function(x,y){
					return this.choiceData.some(function(eachChoice){
						return eachChoice.x==x&&eachChoice.y==y;
					});
				},
				//Prohibited area
				forbidArea:function(x,y){
					return this.choiceData.some(function(eachChoice){
						if(eachChoice.x==x&&eachChoice.y==y){
							return false;
						}else if(eachChoice.x==x||eachChoice.y==y){
							return true;
						}else if(eachChoice.x-x==eachChoice.y-y||eachChoice.x-x==y-eachChoice.y){
							return true;
						}
					});
				},
				//There is a forbidden queen
				hasFbQueen:function(){
					var that=this;
					return this.choiceData.some(function(choice){
						return that.hasQueen(choice.x,choice.y)&&that.forbidArea(choice.x,choice.y)
					});
				},
				//There are other ok ones (the non-zero situation is not considered for the moment. If it is considered, the calculation efficiency can be improved to some extent, but the logic is more complex)
				hasOkOther:function(logIndex){
					logIndex=logIndex||0;
					var that=this;
					return this.choiceLog[logIndex].some(function(eachNode){
						return !(that.hasQueen(eachNode.x,eachNode.y)||that.forbidArea(eachNode.x,eachNode.y));
					});
				},
				//Find the next node of a level node and return null if not
				calcNextNode:function(nodeLv){
					var thisNodeLog=this.choiceLog[nodeLv];
					if(nodeLv==this.curLevel()){//Find next node
						if(thisNodeLog.length>0){
							return thisNodeLog[0];
						}else{
							return null;
						}
					}
					var thisNode=this.choiceData[nodeLv];
					var thisNodeIndex=parseInt(this.calcNodeIndex(thisNode,thisNodeLog));
					if(thisNodeIndex==-1||thisNodeIndex>=thisNodeLog.length-1){
						//Returns null when the node cannot be found or is already the last node in the level node collection
						return null;						
					}else{
//						console.log(JSON.stringify(thisNodeLog));
//						console.log(thisNodeIndex+1);
						return thisNodeLog[thisNodeIndex+1];
					}
				},
				//Get the index of the node
				calcNodeIndex:function(thisNode,nodeLog){
					for(var i in nodeLog){
						var eachNode=nodeLog[i];
						if(eachNode.x==thisNode.x&&eachNode.y==thisNode.y){
							return i;
						}
					}
					return -1;
				},
				//Calculate other ok nodes according to choiceData
				calcOtherOkNode:function(){
					var that=this;
					return this.choiceLog[0].filter(function(eachNode){
						return !that.hasQueen(eachNode.x,eachNode.y)&&!that.forbidArea(eachNode.x,eachNode.y);
					});
				},
				//Flip queen (click event)
				toggleQueen:function(x,y){
					if(this.hasQueen(x,y)){
						this.delQueen(x,y);
					}else{
						this.setQueen(x,y);
					}
					var that=this;
					//this.logs.push('current number of Queens: '+ this.choiceData.length+(that.hasFbQueen()?', existing conflict! ':', no conflict! ');
				},
				//Set queen
				setQueen:function(x,y){
					this.choiceData.push({
						x:x,
						y:y
					});
				},
				//Remove queen
				delQueen:function(x,y){
					this.choiceData=this.choiceData.filter(function(eachNode){
						return !(eachNode.x==x&&eachNode.y==y);
					})
				},
				//Try adding queen and updating subsequent logs
				tryAddQueen:function(newNode,newLevel){
					var curLevel=this.choiceData.length;//Current level reached
					newLevel=newLevel||curLevel;//Add next level by default
					//1. Do not consider the check node, but also to reduce the logic complexity (otherwise, consider the historical situation rather than the real-time situation)
					//2. If the level is different, cut data and log
					for(var i=0;i<curLevel-newLevel;i++){
						this.choiceData.pop();
						this.choiceLog.pop();
					}
					//3. Add data and log
					this.choiceData.push(newNode);
					this.choiceLog.push(this.calcOtherOkNode());
//					console.log('try log length:'+this.choiceData.length+','+this.choiceLog.length);
				},
				//Reset
				resetChoice:function(){
					this.choiceData=[];
					this.logs=[];
				},
				//Rollback node settings (only previous levels can be rolled back, otherwise there will be problems)
				rollbackNode:function(nodeLevel){
					if(nodeLevel<0){
						console.error('node level <0 !');
						return false;
					}
//					console.log('rollback level:'+nodeLevel);
					var nextNode=this.calcNextNode(nodeLevel);
//					console.log('next node:'+JSON.stringify(nextNode));
					if(nextNode==null||typeof(nextNode)==='undefined'){
						this.rollbackNode(nodeLevel-1);
					}else{
						this.tryAddQueen(nextNode,nodeLevel);
						this.autoAddNode(8);
					}
				},
				//Automatically add nodes according to the level (true if possible, false if not)
				autoAddNode:function(nodeLevel){
					//It's necessary to distinguish whether it's not in the beginning or in the end
//					if(nodeLv=this.curLevel()+1) {/ / find the next node
//						if(thisNodeLog.length>0){
//							return thisNodeLog[0];
//						}else{
//							return null;
//						}
//					}
					var nextNode=this.calcNextNode(this.curLevel());
//					console.log('next node:'+JSON.stringify(nextNode));
					if(nextNode==null||typeof(nextNode)==='undefined'){
						if(nodeLevel<0){
							console.warning('node level =0 ?');
							return;
						}
						if(!this.rollbackNode(this.curLevel()-1)){
							return ;
						}
					}else{
						this.tryAddQueen(nextNode);
					}
					var that=this;
					if(this.curLevel()<nodeLevel){
//						console.log('curLevel:'+this.curLevel());
						setTimeout(function(){
							that.autoAddNode(nodeLevel);
						},10);
					}
				},
				//lookup
				calcChoice:function(){
					
					//1. Add level 1 queen
					this.autoAddNode(8);
					/*
					 * function dosth(){
					 * 	if(ok){
					 * 		add
					 * 	}else{
					 * 		rollback
					 * 	}
					 * }
					 */
					
//					this.tryAddQueen(this.choiceLog[0][0]);
//					if(this.choiceLog[1].length>0){
//						this.tryAddQueen(this.choiceLog[1][0]);
//						if(this.choiceLog[2].length>0){
//							this.tryAddQueen(this.choiceLog[2][0]);
//						}else{
//							this.tryAddQueen(this.choiceLog[1][1],1);
//						}
//					}else{
//						this.tryAddQueen(this.choiceLog[0][1],0);
//					}
				},
				//Other tests
				otherTest:function(){
					//this.toggleQueen()
					console.log(this.hasOkOther());
				}
			},
		});
			
		</script>		
	</body>
</html>

4. results

I don't know how many asymmetric solutions there are to the eight queens problem. What I'm trying to find out here is this:

Keywords: JSON Vue JQuery npm

Added by mmponline on Tue, 31 Mar 2020 15:41:01 +0300