📜 ⬆️ ⬇️

Knight's move using canvas

image
View .

Working in one of the companies where there is little understanding in programming and site building, and the main list of tasks comes down to the fact that it is necessary to upload the news to a corporate site, I sometimes get lists of interesting tasks from my superiors. It’s useless to argue about the effectiveness and the need to bring them to the site; the authorities do not hear the arguments of reason from the height of the high nest, you have to take on projects that nobody needs and don't carry them out.

One of such tasks was the knight's move. Its essence is that it is necessary to find the route of a chess knight, passing through all the fields of the board one time. I decided to implement the task using canvas, a little jQuery, with a view to making a plugin in the future.

I will try to describe all the logic of their actions. At first there were a lot of ideas in my head, I rummaged a bit in search engines and once again making sure that it is still better to write myself, and in general it will be useful for developing and consolidating knowledge, I started to work with the idea that the main thing to start, and there goes .
')
In general, the HTML markup itself is pretty simple.

<!doctype html> <html> <head> <meta charset="utf-8"> <title> </title> <link rel="stylesheet" type="text/css" href="css/style.css"> </head> <body> <div class="chess"> <canvas id="chess">Updet!</canvas> </div> <div class="info"> <p> : 1<p> <p> : 0<p> </div> </body> <script src="js/jQuery.js"></script> <script src="js/script.js"></script> </html> 


The styles are also simple, the only thing worth mentioning is the picture of the chessboard decided to fill through the background.

 * { margin: 0px; padding: 0px; } body, html { height: 100%; } .chess { margin: auto; position: relative; width: 600px; height: 600px; } .chess canvas { margin: 28px 0 0 58px; background: url(../images/chess-block.png) no-repeat; } .kon { position: absolute; width: 52px; height: 98px; background: url(../images/kon.png) no-repeat; } 


Further, the code is only javaScript, create the init init function, which will create a canvas object. We create 3 global elements (2 of which are arrays), which is generally not very good, but still the test implementation and the main one works. The value that the init function takes is the initial and then subsequent points of the chess knight's coordinates, x and y, respectively, correspond to the coordinates along the x axis and along the x axis. At the first call, they are undefined (undefined), so we equate them with initial values, in our case it is 60 (x) and 480 (y) which is equal to the lower right corner of the chess board (A1).

Next, we enter the coordinates of the current position of the knight into the arr array, this is to allow us to remember all the moves of the knight so that in the future it is impossible to walk on them.

Next, create the canvas itself, then determine the potential moves, do it based on the knight's positions on the chessboard. The cell itself is equal to 60px, hence the expression of the type [x + 60 * 2, y + 60], that is, two cells above and one cell to the right side, as we know, the horse goes with the letter “G”. We write all the options into the v1 array, then iterate over the possible moves and create an object in each of our potential cells using the rect functions.

Thanks to the same rect functions, we create an object in the cells where the horse has already been.

 var ctx; var arr=[];var v1=[]; var error=0; function rect(color, x, y, width, height,opecity) { this.color = color; //   this.x = x; //   this.y = y; //   this.width = width; //  this.height = height; //  this.draw = function() //    { ctx.beginPath(); ctx.globalAlpha = opecity; ctx.fillStyle = this.color; ctx.fillRect(this.x, this.y, this.width, this.height); } this.clear = function(){ ctx.clearRect(this.x, this.y, this.width, this.height); } } function init(p,h){ (p===undefined) ? x=60 : x=p; (h===undefined) ? y=480 : y=h; // 1 - . if (x < 60 ) x = 60;if (x > 480 ) x = 480; if (y < 60 ) y = 60;if (y > 480 ) y = 480; //    arr.push([x,y]); //,   var chess = document.getElementById("chess"); var width = chess.width = 600; var height = chess.height = 600; ctx = chess.getContext('2d'); ctx.clearRect(0,0,width,height); //   (  )  8  v1 = [ [x+60*2, y+60], [x+60*2, y-60], [x+60, y+60*2], [x-60, y+60*2], [x+60, y-60*2], [x-60, y-60*2], [x-60*2, y-60], [x-60*2, y+60] ]; //   for(var v=0;v<v1.length;v++){ if(v1[v][0]>59 && v1[v][0]<481 && v1[v][1]>59 && v1[v][1]<481) { var f = new rect('#ffe800',v1[v][0],v1[v][1],60,60,0.4); f.draw(); } } // ,    for (var i=0;i<arr.length;i++) { var f = new rect('#f00',arr[i][0],arr[i][1],60,60,1); f.draw(); } //  imkago(x,y); } init(); 


At the very end, we call the imkago (x, y) function, which creates a knight on the chessboard. It is quite simple, create a picture and insert it into the canvas. The position of the knight is taken from the init functions of the init.

 function imkago(x,y) { var kon = new Image(); kon.src = 'images/kon.png'; kon.onload = function() { ctx.beginPath(); ctx.globalAlpha = 1; ctx.drawImage(kon, x+3, y-45); } } 


The last thing to do was to give the opportunity to move the horse, and only by the rules of chess, that is, the letter "G", while at the same time to prohibit the ability to walk in the cells, which the horse has already visited.

First we get the position of the click. By simple mathematical actions we get the exact coordinates on the chessboard. (x = (Math.floor (x / 60)) * 60 and y = (Math.floor (y / 60)) * 60).

Then we compare with the for loop (var j = 0; j <arr.length; j ++) the presence in the array with the cells where the horse visited with the coordinates of the cell that we received when clicking. if they are, return false.

Last we compare the obtained coordinates when clicking with an array of potential moves, if they coincide, we call the function init with the new coordinates for the knight.

  $('#chess').click(function(event){ var x = event.pageX - this.offsetLeft-$('.chess').offset().left; var y = event.pageY - this.offsetTop; x = (Math.floor(x/60))*60; y = (Math.floor(y/60))*60; //,   .   ,   for (var j=0;j<arr.length;j++) { if (arr[j][0]==x && arr[j][1]==y){ error++; $(".info").html("<p> : "+arr.length+"<p><p> : "+error+"<p>"); return false; } } for(var v=0;v<v1.length;v++){ if(v1[v][0]==x && v1[v][1]==y) { init(x,y); } } $(".info").html("<p> : "+arr.length+"<p><p> : "+error+"<p>"); }) 


Complete javaScript code
javaScript
 var ctx; var arr=[];var v1=[]; var error=0; function rect(color, x, y, width, height,opecity) { this.color = color; //   this.x = x; //   this.y = y; //   this.width = width; //  this.height = height; //  this.draw = function() //    { ctx.beginPath(); ctx.globalAlpha = opecity; ctx.fillStyle = this.color; ctx.fillRect(this.x, this.y, this.width, this.height); } this.clear = function(){ ctx.clearRect(this.x, this.y, this.width, this.height); } } function init(p,h){ (p===undefined) ? x=60 : x=p; (h===undefined) ? y=480 : y=h; // 1 - . if (x < 60 ) x = 60;if (x > 480 ) x = 480; if (y < 60 ) y = 60;if (y > 480 ) y = 480; //    arr.push([x,y]); //,   var chess = document.getElementById("chess"); var width = chess.width = 600; var height = chess.height = 600; ctx = chess.getContext('2d'); ctx.clearRect(0,0,width,height); //   (  )  8  v1 = [ [x+60*2, y+60], [x+60*2, y-60], [x+60, y+60*2], [x-60, y+60*2], [x+60, y-60*2], [x-60, y-60*2], [x-60*2, y-60], [x-60*2, y+60] ]; //   for(var v=0;v<v1.length;v++){ if(v1[v][0]>59 && v1[v][0]<481 && v1[v][1]>59 && v1[v][1]<481) { var f = new rect('#ffe800',v1[v][0],v1[v][1],60,60,0.4); f.draw(); } } // ,   for (var i=0;i<arr.length;i++) { var f = new rect('#f00',arr[i][0],arr[i][1],60,60,1); f.draw(); } //  imkago(x,y); } init(); function imkago(x,y) { var kon = new Image(); kon.src = 'images/kon.png'; kon.onload = function() { ctx.beginPath(); ctx.globalAlpha = 1; ctx.drawImage(kon, x+3, y-45); } } $('#chess').click(function(event){ var x = event.pageX - this.offsetLeft-$('.chess').offset().left; var y = event.pageY - this.offsetTop; x = (Math.floor(x/60))*60; y = (Math.floor(y/60))*60; //,   .   ,   for (var j=0;j<arr.length;j++) { if (arr[j][0]==x && arr[j][1]==y){ error++; $(".info").html("<p> : "+arr.length+"<p><p> : "+error+"<p>"); return false; } } for(var v=0;v<v1.length;v++){ if(v1[v][0]==x && v1[v][1]==y) { init(x,y); } } $(".info").html("<p> : "+arr.length+"<p><p> : "+error+"<p>"); }) 



In general, it turned out not very cumbersome, but the code is far from perfect and not universal. More suited to the concept of logic and the basics of programming in javaScript. I hope the article will be useful to someone, thank you.

Source: https://habr.com/ru/post/205894/


All Articles