Title: "implementing Einstein chess game with HTML + CSS + JavaScript"
author: Sun-Wind
date: December 30, 2021
Background: this post will realize the implementation of Einstein chess game based on the front-end language.
Whisper BB: check it. This should be the first post to realize Einstein chess based on the front-end language in the whole network. It should be the beginning.
design sketch
Considering that you may not know about Einstein chess (in fact, you should have known it more or less)
In theory, we should introduce it
The rules are as follows:
- The chessboard is 5 × 5 square chessboard, the square is the chess position, and the upper left corner is the Red Square departure area; The lower right corner is the blue departure area;
- There are 6 square pieces in the red and blue squares, marked with numbers 1-6 respectively. At the beginning, the chess pieces of both sides can be placed freely in the chess position in the departure area;
- Both sides roll the dice in turn, and then move the pieces corresponding to the numbers displayed on the dice. If the corresponding pieces have been removed from the chessboard, you can move the pieces that are greater than or less than this number and closest to this number;
- The moving direction of the Red Square chessmen is right, down and right down, one space at a time; The moving direction of the blue square chess piece is left, up and left, one space at a time;
- If there is a piece on the target position where the piece moves, remove (eat) the piece from the chessboard. Sometimes eating one's own chess pieces is also a strategy, because it can increase the opportunity and flexibility of other chess pieces;
- The party who reaches the corner of the opponent's departure area first or eats all the opponent's chess pieces wins;
- The result of the game is only victory and defeat, not draw.
- Each disc takes 3 minutes for each party, and the overtime is judged as negative; The two sides can play up to 7 sets in each round, and take turns to take the lead (Party A takes the lead in 145 sets and Party B takes the lead in 2367 sets). There is no rest between the two sets, and the winner is the first four sets.
Knowledge to be mastered in advance
- css selector
- Absolute position
- css box model
- Animation effect
- js basic syntax
- Events in js
css selector
Generally used to select elements and define their styles
Absolute position
The four values of position: static, relative, absolute and fixed
Since only absolute positions are used, we mainly introduce the absolute attribute
absolute: the element will be separated from the document flow. If the offset is set, it will affect the location of other elements
Analysis of absolute positioning principle:
1. When the parent element does not set relative positioning or absolute positioning, the element is positioned relative to the root element (i.e. html element) (the parent element does not).
2. If the parent element has set relative positioning or absolute positioning, the element will be positioned relative to the nearest parent element that has set relative or absolute positioning (or the nearest parent element that is not static, because the element is static by default).
You can think of the entire screen as a coordinate system, px is the unit length
For example, the following code
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <style> h2 { position:absolute; left:100px; top:150px; } </style> </head> <body> <h2>This is an absolutely positioned title</h2> <p>Absolute positioning,An element can be placed anywhere on the page. Place 100 pages to the left under the title px And 150 from the top of the page px Element..</p> </body> </html>
The renderings are shown below
css box model
All HTML elements can be regarded as boxes. In CSS, the term "box model" is used for design and layout.
CSS box model is essentially a box that encapsulates the surrounding HTML elements, including margins, borders, padding, and actual content.
The box model allows us to place elements in the space between other elements and the surrounding element frame.
The following picture illustrates the box model:
- Margin - clears the area outside the border, which is transparent.
- Border - a border around the inside margin and outside the content.
- Padding - clears the area around the content, and the padding is transparent.
- Content of the box (content), and image of the box.
Total element width = width + left fill + right fill + left border + right border + left margin + right margin
Total element height = height + top fill + bottom fill + top border + bottom border + top margin + bottom margin
Like this one below
div { width: 300px; border: 25px solid green; padding: 25px; margin: 25px; }
In fact, 300px (width) + 50px (left + right padding) + 50px (left + right border) + 50px (left + right margin) = 450px
Animation effect
To create CSS3 animation, you need to understand the @ keyframes rule.
@The keyframes rule is to create animation.
@A CSS style and animation specified in the keyframes rule will be gradually changed from the current style to the new style.
as
@keyframes myfirst { from {background: red;} to {background: yellow;} }
The meaning of this animation is obviously to change the background color from red to yellow
Now you can animate the block
div { animation: myfirst 5s; }
You must define the name of the animation and the duration of the animation. If the duration of is omitted, the animation will not run because the default value is 0.
Use percentage to specify the time when the change occurs, or use the keywords "from" and "to", which are equivalent to 0% and 100%.
0% is the beginning of the animation and 100% is the completion of the animation.
For best browser support, we should always define 0% and 100% selectors.
js basic syntax
Here are just some grammars that need to be used in this post
JavaScript display data
JavaScript can output data in different ways:
- Use window Alert() pops up a warning box.
- Use document The write () method writes the content to the HTML document.
- Use innerHTML to write to HTML elements.
- Use console Log() is written to the browser's console.
js variable
Creating variables in JavaScript is often referred to as "declared" variables.
We use the var keyword to declare variables:
var carname;
After a variable is declared, the variable is empty (it has no value).
If you need to assign a value to a variable, you can use the equal sign or assign a value to it at the time of declaration
JavaScript has dynamic types. This means that the same variables can be used as different types:
var x; // x is undefined var x = 5; // Now x is a number var x = "John"; // Now x is a string
JavaScript has only one numeric type. Numbers may or may not have a decimal point:
var x1=34.00; //Write with a decimal point var x2=34; //Write without decimal point
Note that the division in js is based on decimal division, which is different from c + +
In terms of statements, c + + and js are almost the same
Array js
Array subscripts are zero based, so the first entry is [0], the second is [1], and so on.
Create array
var cars=new Array(); cars[0]="Saab"; cars[1]="Volvo"; cars[2]="BMW";
js function
A function is a code block wrapped in curly braces. The keyword function is used earlier:
function functionname() { // Execute code }
When the function is called, the code inside the function is executed.
Functions can be called directly when an event occurs (such as when the user clicks a button), and can be called by JavaScript anywhere.
You can send as many parameters as you want, separated by commas (,):
js event
HTML events are things that happen on HTML elements.
JavaScript can trigger these events when JavaScript is used in HTML pages.
The following are examples of HTML events:
- The HTML page has finished loading
- When the HTML input field changes
- HTML button clicked
Events can be used to handle form validation, user input, user behavior and browser actions:
- Event triggered when a page is loaded
- Event triggered when a page is closed
- The user clicks the button to execute the action
- Verify the legitimacy of user input
wait...
Design ideas
The interface design of ainstein chess is relatively simple. It mainly uses JavaScript to add div blocks and specify the absolute position. During initialization, each block is marked with id to point to the absolute number of the block (that is, its own inherent attributes, which will not affect the position of the pieces with the layout disorder of the back players.
At the same time, it also paves the way for the subsequent mapping of number and block number. When adding div block, set its style (such as absolute position, etc.) for this block, and set an ans global variable outside to count the block number.
Because players can layout freely at the beginning of the game, we use click events to code the numbers they want on each block. Similarly, place a counter cnt in the outermost layer, count while clicking, select the block with querySelector, and modify the style of the block (such as color, etc.).
Similarly, the same changes are made to player 2.
Similarly, we also need to remove the click event added to each block to prevent affecting the movement of subsequent pieces. (this removal operation is encapsulated in the "start game" button).
Set the random number button and define the global variable play. When the value is 1, it means player 1, and when the value is 2, it means player 2.
For player 1 and player 2 respectively. Every time you start random, use the built-in function of Math library to generate a random number, then add a div block, put the random number on this block, and change the style and animation of the block.
After the user starts the game, click the random number before playing chess each time and re declare the two Array arrays player1 and player2.
This array indicates whether each numbered piece is alive, and then.
Then use an Array. The effect of this Array is the absolute position (block number) of the block mapped by each number.
In this way, we can know the block number of the clicked block, move it by clicking, and search the generated random number. If the nearest chess piece survives, we can find its mapped block number through the mapp array, then add a click event to this element, and search its three moves at the same time. If these three moves are legal, Add click events to the corresponding blocks respectively.
It is convenient for users to move, and the value of play can be changed at the same time.
After the second click event, add a condition to judge the victory. If the position of the corresponding block is the opposite color, or no chess pieces in the player array survive, this is the condition for victory.
Chess flow chart
code implementation
<!DOCTYPE html> <html lang='en'> <head> <meta charset="UTF-8"> <title>Einstein chess</title> <style> [class~=big] { position: absolute; left: 300px; top: 200px; border: 10px black solid; width: 600px; height: 600px; } [class~=an] { position: absolute; left: 1200px; top: 600px; width: 100px; height: 100px; border-radius: 50%; } [class~=bn]{ position: absolute; left: 1200px; top: 800px; width: 200px; height: 50px; } [class~=tip]{ position:absolute; left:350px; top:100px; width:500px; height:100px; border:1px black solid; box-shadow:0 9px 14px 0 rgb(240, 192, 35); text-align: center; font-size:50px; font-weight: normal; } [class~=tips]{ position:absolute; border:1px black solid; left:1000px; top:0px; width:500px; height:600px; font-size: 20px; } [class~=saizi]{ position:absolute; border:1px black solid; width: 100px; height:100px; left:1100px; top:600px; text-align: center; background:white; font-size:60px; border-radius: 20%; } @keyframes button1 { 0%{background-color:rgb(117, 114, 106);box-shadow: 0 0 9px rgb(6, 34, 33);} 100%{background-color: rgb(230, 167, 31);box-shadow: 0 0 9px rgb(6, 34, 33);} } @keyframes white_show{ 0%{background-color:gray;box-shadow: 0 0 9px rgb(6, 34, 33);} 100%{background-color: white;box-shadow: 0 0 9px rgb(247, 198, 36);} } @keyframes blue_show { 0%{background-color:gray;box-shadow: 0 0 9px rgb(6, 34, 33);} 100%{background-color: skyblue;box-shadow: 0 0 9px rgb(235, 175, 48);} } /* @keyframes white_none { 0%{background-color:white;} 100%{background-color: gray;} } @keyframes blue_none { 0%{background-color: skyblue;} 100%{background-color: gray;} } */ </style> </head> <body bgcolor = "gray"> <div class = "tips"> Einstein chess: <p>1.The chessboard is 5×5 The square is the chess position, and the upper left corner is the white starting area; The lower right corner is the blue departure area;</p> <p>2.There are 6 square pieces in the red and blue squares, marked with numbers 1-6 respectively. At the beginning, the chess pieces of both sides can be placed freely in the chess position in the departure area;</p> <p>3.Both sides roll the dice in turn, and then move the pieces corresponding to the numbers displayed on the dice. If the corresponding pieces have been removed from the chessboard, you can move the pieces that are greater than or less than this number and closest to this number;</p> <p>4.The moving direction of the white square chess pieces is right, down and right down, one space at a time; The moving direction of the blue square chess piece is left, up and left, one space at a time;</p> <p>5.If there is a piece on the target position where the piece moves, remove (eat) the piece from the chessboard.</p> <p>6.The party who reaches the corner of the opponent's departure area first or eats all the opponent's chess pieces wins;</p> </div> <div class = "tip"> </div> <div class="big"> </div> <button class="an">random number</button> <div class = "saizi"></div> <button class="bn">Start the game</button> <script> var cnt = 1;//Counter var ans = 1;//Number of squares var click2 = 0;//It means the first one hasn't finished yet var ram = 0;//Store random number var val;//Save weights var play = 1;//Indicates the number of players, var mapp1 = new Array(7);//Mapping from number to number var mapp2 = new Array(7); var player1 = new Array(7);//Are the pieces on the field alive var player2 = new Array(7); var flag = 0;//Identify whether it is completed randomly var tc, tn; //Save the color and number of the previous box var sel;//Saves the last selected element var big = document.querySelector(".big"); var an = document.querySelector(".an"); var bn = document.querySelector(".bn"); var tip = document.querySelector(".tip"); var saizi = document.querySelector(".saizi"); bn.addEventListener("click", clear); an.addEventListener("click", star); for (var i = 1; i <= 6; ++i) { player1[i] = 1; player2[i] = 1; } for (var i = 0; i < 5; ++i) for (var j = 0; j < 5; ++j) { div = document.createElement("div"); div.setAttribute("class", "Block" + ans); div.setAttribute("id", ans); div.style.border = "2px black solid"; div.style.width = "98px"; div.style.height = "98px"; div.style.position = "absolute"; div.style.textAlign = "center"; div.style.left = 50 + j * 100 + "px"; div.style.top = 50 + i * 100 + "px"; div.style.fontSize = "50px"; big.appendChild(div); ans++; } for (ans = 1; ans <= 11; ++ans) { var temp = document.querySelector(".Block" + ans); temp.addEventListener("click", clickblock1); } for (cnt = 15; cnt <= 25; ++cnt) { var temp = document.querySelector(".Block" + cnt); // console.log(temp); temp.addEventListener("click", clickblock2); } ans = 1; cnt = 1;//Reset to facilitate subsequent counting function clear(){ for (var i = 1; i <= 11; ++i) { var temp = document.querySelector(".Block" + i); temp.removeEventListener("click", clickblock1); } for (var j = 15; j <= 25; ++j) { var temp = document.querySelector(".Block" + j); // console.log(temp); temp.removeEventListener("click", clickblock2); } } function clickblock1(e) { e.target.textContent = ans; mapp1[ans] = e.target.id; console.log(e.target.id); ans++; e.target.style.backgroundColor = "white"; } function clickblock2(e) { e.target.textContent = cnt; mapp2[cnt] = e.target.id; cnt++; e.target.style.backgroundColor = "skyblue"; } function star() { ram = Math.floor(Math.random() * 6 + 1); console.log(ram); // console.log(mapp1); // for(var i = 1; i <= 25; ++i){ // var id = document.getElementById(i); // id.addEventListener("click", clickmove); // } saizi.textContent = ram; saizi.style.animation = "button1 2s infinite"; var div = document.createElement("div"); div.style.backgroundColor = "gray"; div.style.width = "170px"; div.style.height = "100px"; div.style.borderRadius = "50px"; div.style.textAlign = "center"; div.textContent = "You can only move and" + ram + "Closest number"; div.style.color = "red"; div.style.position = "absolute"; div.style.top = "100px"; div.style.left = "-30px"; an.appendChild(div); if(play == 1){ tip.textContent = "It's Bai Fang's turn to play chess"; tip.style.animation = "white_show 5s infinite"; } else{ tip.textContent = "It's Blue's turn to play chess"; tip.style.animation = "blue_show 5s infinite"; } if (play == 1) { for (var i = 0; i < 6; ++i) { if (ram - i >= 1 && player1[ram - i] == 1) { var id = document.getElementById(mapp1[ram - i]); id.addEventListener("click", clickmove); var exp1 = mapp1[ram - i] - 1; var y = exp1 % 5; var x = (exp1 - y)/ 5; console.log("coordinate" + x + "" + y); if (y + 1 < 5) { exp1 = x * 5 + y + 2; console.log(exp1); var temp = document.getElementById(exp1); temp.addEventListener("click", clickmove); } if (x + 1 < 5) { exp1 = (x + 1) * 5 + y + 1; console.log(exp1); var temp = document.getElementById(exp1); temp.addEventListener("click", clickmove); } if (y + 1 < 5 && x + 1 < 5) { exp1 = (x + 1) * 5 + y + 2; console.log(exp1); var temp = document.getElementById(exp1); temp.addEventListener("click", clickmove); } flag = 1; } if (ram + i <= 6 && player1[ram + i] == 1 && i != 0) { var id = document.getElementById(mapp1[ram + i]); id.addEventListener("click", clickmove); var exp1 = mapp1[ram + i] - 1; var y = exp1 % 5; var x = (exp1 - y)/ 5; console.log("coordinate" + x + "" + y); if (y + 1 < 5) { exp1 = x * 5 + y + 2; console.log(exp1); var temp = document.getElementById(exp1); temp.addEventListener("click", clickmove); } if (x + 1 < 5) { exp1 = (x + 1) * 5 + y + 1; console.log(exp1); var temp = document.getElementById(exp1); temp.addEventListener("click", clickmove); } if (y + 1 < 5 && x + 1 < 5) { exp1 = (x + 1) * 5 + y + 2; console.log(exp1); var temp = document.getElementById(exp1); temp.addEventListener("click", clickmove); } flag = 1; } if (flag) {flag = 0;break;} } play = 2; } else { for (var i = 0; i < 6; ++i) { if (ram - i >= 1 && player2[ram - i] == 1) { var id = document.getElementById(mapp2[ram - i]); id.addEventListener("click", clickmove); var exp1 = mapp2[ram - i] - 1; var y = exp1 % 5; var x = (exp1 - y)/ 5; console.log("coordinate" + x + "" + y); console.log(exp1); if (y - 1 >= 0) { exp1 = x * 5 + y; console.log(exp1); var temp = document.getElementById(exp1); temp.addEventListener("click", clickmove); } if (x - 1 >= 0) { exp1 = (x - 1) * 5 + y + 1; console.log(exp1); var temp = document.getElementById(exp1); temp.addEventListener("click", clickmove); } if (y - 1 >= 0 && x - 1 >= 0) { exp1 = (x - 1) * 5 + y; console.log(exp1); var temp = document.getElementById(exp1); temp.addEventListener("click", clickmove); } flag = 1; } if (ram + i <= 6 && player2[ram + i] == 1 && i != 0) { var id = document.getElementById(mapp2[ram + i]); id.addEventListener("click", clickmove); var exp1 = mapp2[ram + i] - 1; var y = exp1 % 5; var x = (exp1 - y)/ 5; console.log("coordinate" + x + "" + y); if (y -1 >= 0) { exp1 = x * 5 + y; console.log(exp1); var temp = document.getElementById(exp1); temp.addEventListener("click", clickmove); } if (x -1 >= 0) { exp1 = (x - 1) * 5 + y + 1; console.log(exp1); var temp = document.getElementById(exp1); temp.addEventListener("click", clickmove); } if (y - 1 >= 0 && x - 1 >= 0) { exp1 = (x - 1) * 5 + y; console.log(exp1); var temp = document.getElementById(exp1); temp.addEventListener("click", clickmove); } flag = 1; } if (flag) {flag = 0;break;} } play = 1; } } function clickmove(e) { if (click2) { console.log("Second click"); //Do not change the block number if (e.target.textContent != "") { if (e.target.style.backgroundColor == 'white') { player1[e.target.textContent]--; // mapp1[e.target.textContent] = e.target.id; } else { player2[e.target.textContent]--; // mapp2[e.target.textContent] = e.target.id; } } e.target.textContent = tn; e.target.style.backgroundColor = tc; if(tc == "white"){ mapp1[tn] = e.target.id; } if(tc == "skyblue"){ mapp2[tn] = e.target.id; } click2 = 0; console.log(mapp1); console.log(mapp2); console.log(player1); console.log(player2); //Judge the outcome var win1 = document.getElementById("1"); var win2 = document.getElementById("25"); if(win1.style.backgroundColor == "skyblue"){ alert("Blue square victory"); location.reload(); } if(win2.style.backgroundColor == "white"){ alert("White Fang Shengli"); location.reload(); } var rw = 1,bw = 1; for(var i = 1; i <= 6; ++i){ if(player1[i]) {bw = 0;break;} } for(var i = 1; i <= 6; ++i){ if(player2[i]) {rw = 0; break;} } if(rw) { alert("White Fang Shengli"); location.reload(); } if(bw){ alert("Blue square victory"); location.reload(); } } else { console.log("First click"); sel = e.target; tc = e.target.style.backgroundColor; tn = e.target.textContent; e.target.style.backgroundColor = "gray"; e.target.textContent = ""; click2 = 1; } } </script> </body> </html>