I want to randomly assign a class at two boxes.
But even with indexOf(randomIndex) === -1) Math.random is duplicating the numbers.
If you refresh you will see that the boxes are changing classes but sometimes they both have the same class, this should happened.
var grid = document.getElementById("grid-box");
for (var i = 0; i <= 1; i++) {
var square = document.createElement("div");
square.className = 'square';
square.id = 'square' + i;
grid.appendChild(square);
}
var weaponTwo = [];
while (weaponTwo.length < 1) {
var randomIndex = parseInt(2 * Math.random());
if (weaponTwo.indexOf(randomIndex) === -1) {
weaponTwo.push(randomIndex);
var drawWtwo = document.getElementById('square' + randomIndex);
$(drawWtwo).addClass("w2")
}
};
var weapon3 = [];
while (weapon3.length < 1) {
var randomIndex = parseInt(2 * Math.random());
if (weapon3.indexOf(randomIndex) === -1) {
weapon3.push(randomIndex);
var draw3 = document.getElementById('square' + randomIndex);
$(draw3).addClass("w3")
}
};
#grid-box {
width: 420px;
height: 220px;
}
#grid-box>div.square {
font-size: 1rem;
vertical-align: top;
display: inline-block;
width: 10%;
height: 10%;
box-sizing: border-box;
border: 1px solid #000;
}
.w2 {
background-color: red;
}
.w3 {
background-color: blue;
}
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<div id="grid-box"></div>
You are using two different arrays for storing the weapons. Use same array so that the number is not repeated.
var grid = document.getElementById("grid-box");
for (var i = 0; i <= 1; i++) {
var square = document.createElement("div");
square.className = 'square';
square.id = 'square' + i;
grid.appendChild(square);
}
var weaponTwo = [];
while (weaponTwo.length < 1) {
var randomIndex = parseInt(2 * Math.random());
if (weaponTwo.indexOf(randomIndex) === -1) {
weaponTwo.push(randomIndex);
var drawWtwo = document.getElementById('square' + randomIndex);
$(drawWtwo).addClass("w2")
}
};
while (weaponTwo.length < 2) {
var randomIndex = parseInt(2 * Math.random());
if (weaponTwo.indexOf(randomIndex) === -1) {
weaponTwo.push(randomIndex);
var draw3 = document.getElementById('square' + randomIndex);
$(draw3).addClass("w3")
}
};
#grid-box {
width: 420px;
height: 220px;
}
#grid-box>div.square {
font-size: 1rem;
vertical-align: top;
display: inline-block;
width: 10%;
height: 10%;
box-sizing: border-box;
border: 1px solid #000;
}
.w2 {
background-color: red;
}
.w3 {
background-color: blue;
}
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<div id="grid-box"></div>
Better Approach : You can create an array of classes and then shuffle it using this alogrithm. Then you can pop from the array and add to classes one by one.
Related
I have a graph that is rendering its values as a div inside the body element with a class according to their number values. This is working fine. But next I need to sort the divs according to their number values or background color. BUT, it needs to start on the lower left corner of the page and fan out upwards to towards the right as the numbers increase. Basically just like a line graph.
I'd like to stay away from libraries if at all possible.
How would I approach this? Thank you all.
let interval = setInterval(makeDivs, 5);
function makeDivs(){
let cont = checkHeight();
if(cont){
let div = document.createElement('div');
let randNum = Math.random() * 100;
if(randNum < 20) { div.classList.add('blue') }
if(randNum >= 20 && randNum < 40) { div.classList.add('green') }
if(randNum >= 40 && randNum < 60) { div.classList.add('yellow') }
if(randNum >= 60 && randNum < 80) { div.classList.add('orange') }
if(randNum >= 80 && randNum < 101) { div.classList.add('red') }
div.textContent = randNum.toFixed(2);
document.querySelector('body').appendChild(div);
} else {
alert('done');
clearInterval(interval);
sortDivs(); // Begin sorting divs
}
}
function checkHeight(){
let w = window.innerHeight;
let b = document.querySelector('body').offsetHeight;
if(b < w) {
return true;
} else {
return false;
}
}
function sortDivs(){
document.querySelector("body div:last-child").remove();
alert('sorting now...')
}
* { box-sizing: border-box;}
body { width: 100vw; margin: 0; padding: 0; display: flex; flex-wrap: wrap; align-items: end;}
body div { width: calc(10% + 1px); text-align: center; border: 1px solid #ddd; margin: -1px 0 0 -1px; padding: 10px;}
body div.blue { background: aqua; }
body div.green { background: green; }
body div.yellow { background: yellow; }
body div.orange { background: orange; }
body div.red { background: red; }
UPDATE!!!
So I have this so far based on the feed back down below. The problem now is the sorting is only happening laterally and not on an angle (spreading right and to the top).
let interval = setInterval(makeDivs, 10);
function makeDivs(){
let cont = checkHeight();
if(cont){
let div = document.createElement('div');
let randNum = Math.random() * 100;
if(randNum < 20) { div.classList.add('blue') }
if(randNum >= 20 && randNum < 40) { div.classList.add('green') }
if(randNum >= 40 && randNum < 60) { div.classList.add('yellow') }
if(randNum >= 60 && randNum < 80) { div.classList.add('orange') }
if(randNum >= 80 && randNum < 101) { div.classList.add('red') }
div.textContent = randNum.toFixed(2);
document.querySelector('.outPut').appendChild(div);
} else {
clearInterval(interval);
document.querySelector(".outPut div:last-child").remove();
compileArrays(); // Begin sorting divs
}
}
function checkHeight(){
let w = window.innerHeight;
let b = document.querySelector('.outPut').offsetHeight;
if(b < w) {
return true;
} else {
return false;
}
}
function compileArrays(){
let divs = document.querySelectorAll('.outPut div');
let bArr = [], gArr = [], yArr = [], oArr = [], rArr = [];
divs.forEach( (d) => {
if( d.classList.contains('blue') ){ bArr.push(d) }
if( d.classList.contains('green') ){ gArr.push(d) }
if( d.classList.contains('yellow') ){ yArr.push(d) }
if( d.classList.contains('orange') ){ oArr.push(d) }
if( d.classList.contains('red') ){ rArr.push(d) }
});
let finalArr = sortArray(bArr).concat(sortArray(gArr)).concat(sortArray(yArr)).concat(sortArray(oArr)).concat(sortArray(rArr));
newDom(finalArr);
}
function sortArray(arr){
let newArr = arr;
newArr.sort( (a, b) => {
return a.innerText - b.innerText;
});
return newArr;
}
function newDom(arr){
let b = document.querySelector('.outPut');
b.innerHTML = '';
arr.reverse();
arr.forEach((a) => {
b.appendChild(a);
});
}
* { box-sizing: border-box;}
body { width: 100vw; height: 100vh; margin: 0; padding: 0; display: flex; align-items: flex-end;}
body .outPut { flex: 1; display: flex; flex-wrap: wrap; flex-direction:row-reverse; }
body .outPut div { width: calc(10% + 1px); text-align: center; border: 1px solid #ddd; margin: -1px 0 0 -1px; padding: 10px;}
body .outPut div.blue { background: aqua; }
body .outPut div.green { background: #44df15; }
body .outPut div.yellow { background: yellow; }
body .outPut div.orange { background: orange; }
body .outPut div.red { background: red; }
<div class="outPut"></div>
Supposed you already have a mechanism to organise such DIVs in a grid as shown, the following should give you what you are looking for:
var items = divList.filter((div) => div.nodeType == 1); // get rid of the whitespace text nodes
items.sort(function(a, b) {
return a.innerHTML == b.innerHTML
? 0
: (a.innerHTML > b.innerHTML ? 1 : -1);
});
Then, place them back in the DOM as needed, example:
for (i = 0; i < items.length; ++i) {
divList.appendChild(items[i]);
}
This worked with the first code example!!!
try this sortDivs function:
function sortDivs() {
document.querySelector("body div:last-child").remove();
alert('sorting now...')
let toSort = document.getElementsByTagName("div")
toSort = Array.prototype.slice.call(toSort, 0)
toSort.sort((a, b) => {
let aord = parseFloat(a.textContent);
let bord = parseFloat(b.textContent);
return bord - aord;
})
document.body.innerHTML = ""
for(var i = 0, l = toSort.length; i < l; i++) {
document.querySelector('body').appendChild(toSort[i]);
}
}
and in the css file set flex-wrap to wrap-reverse. Hope I could help :)
PS: please, implement some else if instead of doing only if
Here is a small fiddle with my sample code demonstrating a simple solution in pure JavaScript and absolute CSS positioning for what you are trying to achieve. Link
As some pointed out already, there might be a library, that already provides a better and complete solution for this - I did not research if it is so.
Code:
file.js
var container = document.getElementById("container")
var results = [1,2,3,4,5,6,7,8]
//you can pre-calculate the order of the distances
//here already orderdered array [distanec][X-axis][Y-axis]
var distances =[[0,0,0],
[1,1,0],
[1,0,1],
[1.414, 1,1],
[2,0,2],
[2,2,0],
[2.234, 2,1],
[2.234, 1,2]]
for (i = 0; i < results.length; i++){
var newDiv = document.createElement("div")
newDiv.className = "result"
newDiv.innerHTML = results[i]
newDiv.style.left = distances[i][1]*20 + "px"
newDiv.style.bottom = distances[i][2]*20 + "px"
container.appendChild(newDiv)
}
function setColor(element){
// set class based on value - you already have this part
}
style.css
#container {
border: 4px;
border-color: red;
border-style: solid;
height: 200px;
width: 200px;
position: relative;
}
.result{
border: 2px;
width: 20px;
height: 20px;
position: absolute;
border-color: blue;
border-style: solid;
text-align: center;
}
site.html
<div id="container">
</div>
Output:
I want to add 10 points when blue box goes into brown box.
I tried to set score = 0 and points to add = 10 but it doesn't work.
I alert '+10 points' and it shows me the alert so I guess the problem is the DOM ?!?
Any suggestions ?
Thanks !
let moveCounter = 0;
let score = 0;
let obs = 10;
document.getElementById('score').textContent = '0';
var grid = document.getElementById("grid-box");
for (var i = 1; i <= 49; i++) {
var square = document.createElement("div");
square.className = 'square';
square.id = 'square' + i;
grid.appendChild(square);
}
var obstacles = [];
while (obstacles.length < 10) {
var randomIndex = parseInt(49 * Math.random());
if (obstacles.indexOf(randomIndex) === -1) {
obstacles.push(randomIndex);
var drawObstacle = document.getElementById('square' + randomIndex);
$(drawObstacle).addClass("ob")
}
}
var playerOne = [];
while (playerOne.length < 1) {
var randomIndex = parseInt(49 * Math.random());
if (playerOne.indexOf(randomIndex) === -1) {
playerOne.push(randomIndex);
var drawPone = document.getElementById('square' + randomIndex);
$(drawPone).addClass("p-0")
}
}
var addPoints = $('#score');
$('#button_right').on('click', function() {
if ($(".p-0").hasClass("ob")) {
alert('add +10 points !!!')
addPoints.text( parseInt(addPoints.text()) + obs );
}
moveCounter += 1;
if ($(".p-0").hasClass("ob")) {
}
$pOne = $('.p-0')
$pOneNext = $pOne.next();
$pOne.removeClass('p-0');
$pOneNext.addClass('p-0');
});
#grid-box {
width: 400px;
height: 400px;
margin: 0 auto;
font-size: 0;
position: relative;
}
#grid-box>div.square {
font-size: 1rem;
vertical-align: top;
display: inline-block;
width: 10%;
height: 10%;
box-sizing: border-box;
border: 1px solid #000;
}
.ob {
background-color: brown;
}
.p-0 {
background-color: blue;
}
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<div id="grid-box">
</div>
<div class="move">
<button id="button_right">right</button><br>
</div>
<div id="score">
</div>
Thank you very much! I am new to JavaScript/ JQuery
Thank you very much!
You are trying to change the HTML inside of the div with id "score".
Selecting the css element using $("#id") retrieves the DOM element and not its contents so adding the score directly to it has no consequences.
What you want to do is: update the score variable and then set the HTML inside the div to the score value.
So instead of just:
addPoints += obs
you should
score += obs
addPoints.html(score)
I have a yellow box in a grid. When click button 'UP' the yellow box is going one box UP. How can I stop the yellow box when it arrives at the edge? I do not want it to go out of the grid.
let moveCounter = 0;
var grid = document.getElementById("grid-box");
for (var i = 1; i <= 100; i++) {
var square = document.createElement("div");
square.className = 'square';
square.id = 'square' + i;
grid.appendChild(square);
}
var playerTwo = [];
while (playerTwo.length < 1) {
var randomIndex = parseInt(99 * Math.random());
if (playerTwo.indexOf(randomIndex) === -1) {
playerTwo.push(randomIndex);
var drawPtwo = document.getElementById('square' + randomIndex);
$(drawPtwo).addClass("p-1")
}
};
$('#button_up').on('click', function() {
moveCounter += 1;
$pOne = $('.p-1')
var id = $pOne.attr('id')
var idNumber = +id.slice(6);
var idMove = idNumber - 10
var idUpMove = 'square' + idMove;
$pOne.removeClass('p-1');
$('#' + idUpMove).addClass('p-1');
});
#grid-box {
width: 400px;
height: 400px;
margin: 0 auto;
font-size: 0;
position: relative;
}
#grid-box>div.square {
font-size: 1rem;
vertical-align: top;
display: inline-block;
width: 10%;
height: 10%;
box-sizing: border-box;
border: 1px solid #000;
}
.p-1{
background-color: yellow;
}
<div id="grid-box"></div>
<div class="move">
<button id="button_up">UP</button>
<br>
</div>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
I am new to Javascript / jQuery. Any help will be much appreciated ! Thank you
let moveCounter = 0;
var grid = document.getElementById("grid-box");
for (var i = 1; i <= 100; i++) {
var square = document.createElement("div");
square.className = 'square';
square.id = 'square' + i;
grid.appendChild(square);
}
var playerTwo = [];
while (playerTwo.length < 1) {
var randomIndex = parseInt(99 * Math.random());
if (playerTwo.indexOf(randomIndex) === -1) {
playerTwo.push(randomIndex);
var drawPtwo = document.getElementById('square' + randomIndex);
$(drawPtwo).addClass("p-1")
}
};
$('#button_up').on('click', function() {
moveCounter += 1;
$pOne = $('.p-1')
var id = $pOne.attr('id')
var idNumber = +id.slice(6);
var idMove = idNumber - 10;
if(idMove < 0){idMove +=10;}
var idUpMove = 'square' + idMove;
$pOne.removeClass('p-1');
$('#' + idUpMove).addClass('p-1');
});
#grid-box {
width: 400px;
height: 400px;
margin: 0 auto;
font-size: 0;
position: relative;
}
#grid-box>div.square {
font-size: 1rem;
vertical-align: top;
display: inline-block;
width: 10%;
height: 10%;
box-sizing: border-box;
border: 1px solid #000;
}
.p-1{
background-color: yellow;
}
<div id="grid-box"></div>
<div class="move">
<button id="button_up">UP</button>
<br>
</div>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
Here I have added the condition which restrict box to out of the grid
if(idMove < 0){idMove +=10;}
if movable position is in the minus then it again initialise it existing position.
You can add a check to stop it from moving out of the squares
var idMove = idNumber - 10
if(idMove > 0){
// do all the moving stuffs
}
$('#button_up').on('click', function() {
moveCounter += 1;
$pOne = $('.p-1')
var id = $pOne.attr('id')
var idNumber = +id.slice(6);
var idMove = idNumber - 10;
if(idMove > 0) {
var idUpMove = 'square' + idMove;
$pOne.removeClass('p-1');
$('#' + idUpMove).addClass('p-1');
}
});
You can use an if statement to check idMove > 0) If it is, then you can move your square, if it isn't then you shouldn't move your square. it will be undefined, and so you can run your code only when pOne's id is not undefined.
See example below:
let moveCounter = 0;
var grid = document.getElementById("grid-box");
for (var i = 1; i <= 100; i++) {
var square = document.createElement("div");
square.className = 'square';
square.id = 'square' + i;
grid.appendChild(square);
}
var playerTwo = [];
while (playerTwo.length < 1) {
var randomIndex = parseInt(99 * Math.random());
if (playerTwo.indexOf(randomIndex) === -1) {
playerTwo.push(randomIndex);
var drawPtwo = document.getElementById('square' + randomIndex);
$(drawPtwo).addClass("p-1")
}
};
$('#button_up').on('click', function() {
moveCounter += 1;
$pOne = $('.p-1')
var id = $pOne.attr('id')
var idNumber = +id.slice(6);
var idMove = idNumber - 10
if (idMove > 0) {
var idUpMove = 'square' + idMove;
$pOne.removeClass('p-1');
$('#' + idUpMove).addClass('p-1');
}
});
#grid-box {
width: 400px;
height: 400px;
margin: 0 auto;
font-size: 0;
position: relative;
}
#grid-box>div.square {
font-size: 1rem;
vertical-align: top;
display: inline-block;
width: 10%;
height: 10%;
box-sizing: border-box;
border: 1px solid #000;
}
.p-1 {
background-color: yellow;
}
<div id="grid-box">
</div>
<div class="move">
<button id="button_up">UP</button><br>
</div>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
I'm creating a minefiled game and I'm trying to put 10 bombs in a random location each time. The problem is that sometimes 2 or more bombs can be placed in the same block, resulting in less than 10 bombs in the game. How can I prevent this?
I've already tried saving all the bombs locations in an array and each time compare the new bomb location to all the past ones, but id didn't work.
Here is my code:
var number_of_blocks = 0;
var number_of_bombs = 10;
var minefield_width = 500;
var minefield_height = 500;
var block_width = 50;
var block_height = 50;
var bombs = [];
number_of_blocks = (minefield_width * minefield_height) / (block_width * block_height);
$("#new_game").click(function() {
create_blocks();
create_bombs();
});
function random(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
function create_blocks() {
//Create the "normal blocks".
for (var i = 0; i < number_of_blocks; i++) {
var block = document.createElement("div");
block.style.width = block_width + "px";
block.style.height = block_height + "px";
block.className = "block";
block.id = "b" + i;
block.onclick = function() {
console.log(this.id);
this.style.backgroundColor = "#ddd";
};
document.getElementById("field").appendChild(block);
}
}
function create_bombs() {
//Select a "normal block" and transform it into a "bomb block".
for (var i = 0; i < number_of_bombs; i++) {
var random_block = bombs_do_not_repeat();
var bomb = document.getElementById(random_block);
bomb.style.backgroundColor = "red";
bomb.classList.add("bomb");
bomb.onclick = function() {
alert("GAME OVER");
};
bombs[i] = random_block;
}
}
function bombs_do_not_repeat() {
//Should prevent a 'bomb block' to go inside the same 'block' more than 1 time. Example:
//CORRECT: bombs[] = "b1", "b2", "b3", "b4", "b5";
//INCORRECT: bombs[] = "b1", "b1", "b3", "b4", "b4";
var random_num = "b" + random(1, number_of_blocks);
for (var j = 0; j < bombs.length; j++) {
if (random_num == bombs[j]) {
console.info("random_num = " + random_num + " && bombs[" + j + "] = " + bombs[j]);
bombs_do_not_repeat();
}
}
return random_num;
}
* {
list-style: none;
font-family: sans-serif;
margin: 0px;
}
#field {
width: 500px;
height: 500px;
border: solid 1px black;
margin: 0px auto;
margin-top: 50px;
overflow: auto;
background-color: #ccc;
}
.block {
background-color: #aaa;
border: solid 1px #000;
box-sizing: border-box;
float: left;
cursor: pointer;
}
.block:hover {
background-color: #eee
}
.block:active {
background-color: #ddd
}
#container {
overflow: auto;
}
#menu {
width: 100%;
height: auto;
background-color: #333;
overflow: auto;
}
#menu li {
float: left;
text-align: center;
width: 100px;
color: white;
cursor: pointer;
}
#menu li:hover {
background-color: #555
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<div id="container">
<div id="menu">
<ul>
<li id="new_game">New Game</li>
</ul>
</div>
<div id="field"></div>
</div>
</body>
</html>
SOLVED:
function bombs_do_not_repeat(){
//Should prevent a 'bomb block' to go inside the same 'block' more than 1 time. Example:
//CORRECT: bombs[] = "b1", "b2", "b3", "b4", "b5";
//INCORRECT: bombs[] = "b1", "b1", "b3", "b4", "b4";
var random_num = "b" + random(1,number_of_blocks);
for(var j = 0; j < bombs.length; j++){
if(random_num == bombs[j]){
console.info("random_num = " + random_num + " && bombs[" + j + "] = " + bombs[j]);
return random_num = bombs_do_not_repeat();
}
}
return random_num;
}
You're recursively calling bombs_do_not_repeat(), but always ignoring the recursive result and just going with whatever was selected first whether it's a repeat or not.
I suspect you mean to assign the result of the recursion:
random_num = bombs_do_not_repeat();
I suggest you to change your function to this
function bombs_do_not_repeat() {
var check = false;
var random_num;
do{
random_num = "b" + random(1, number_of_blocks);
for (var j = 0; j < bombs.length && !check; j++) {
if (random_num == bombs[j]) {
console.info("random_num = " + random_num + " && bombs[" + j + "] = " + bombs[j]);
check = true;
}
}
}while(check);
return random_num;
}
Instead of creating each random number prepare a random (shuffled) array. Something like this.
var number_of_blocks = 0;
var number_of_bombs = 10;
var minefield_width = 500;
var minefield_height = 500;
var block_width = 50;
var block_height = 50;
var bombs = [];
var blockArr = []; //helper array
number_of_blocks = (minefield_width * minefield_height) / (block_width * block_height);
$("#new_game").click(function() {
//reset blockArr and bombs
bombs = [];
blockArr = [];
//clean the field
document.getElementById('field').innerHTML = '';
create_blocks();
//blockArr is now fillewd
bombs = blockArr.sort(function() {
return Math.random() < 0.5 ? -1 : 1;
}) //shuffle
.slice(0, number_of_bombs);
//for debug purpose
//console.log(bombs);
create_bombs();
});
//function random(min, max) {//obsolete
// return Math.floor(Math.random() * (max - min)) + min;
//}
function create_blocks() {
//Create the "normal blocks".
for (var i = 0; i < number_of_blocks; i++) {
//fill blockArr in the samee loop
blockArr.push(i);
var block = document.createElement("div");
block.style.width = block_width + "px";
block.style.height = block_height + "px";
block.className = "block";
block.id = "b" + i;
block.onclick = function() {
console.log(this.id);
this.style.backgroundColor = "#ddd";
};
document.getElementById("field").appendChild(block);
}
}
function create_bombs() {
//Select a "normal block" and transform it into a "bomb block".
for (var i = 0; i < number_of_bombs; i++) {
//var random_block = bombs_do_not_repeat(); //no need
var bomb = document.getElementById('b' + bombs[i]); //random_block);
bomb.style.backgroundColor = "red";
bomb.classList.add("bomb");
bomb.onclick = function() {
alert("GAME OVER");
};
//bombs[i] = random_block;
}
}
/*
function bombs_do_not_repeat() { //obsolete
//Should prevent a 'bomb block' to go inside the same 'block' more than 1 time. Example:
//CORRECT: bombs[] = "b1", "b2", "b3", "b4", "b5";
//INCORRECT: bombs[] = "b1", "b1", "b3", "b4", "b4";
var random_num = "b" + random(1, number_of_blocks);
for (var j = 0; j < bombs.length; j++) {
if (random_num == bombs[j]) {
console.info("random_num = " + random_num + " && bombs[" + j + "] = " + bombs[j]);
bombs_do_not_repeat();
}
}
return random_num;
}
*/
* {
list-style: none;
font-family: sans-serif;
margin: 0px;
}
#field {
width: 500px;
height: 500px;
border: solid 1px black;
margin: 0px auto;
margin-top: 50px;
overflow: auto;
background-color: #ccc;
}
.block {
background-color: #aaa;
border: solid 1px #000;
box-sizing: border-box;
float: left;
cursor: pointer;
}
.block:hover {
background-color: #eee
}
.block:active {
background-color: #ddd
}
#container {
overflow: auto;
}
#menu {
width: 100%;
height: auto;
background-color: #333;
overflow: auto;
}
#menu li {
float: left;
text-align: center;
width: 100px;
color: white;
cursor: pointer;
}
#menu li:hover {
background-color: #555
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<div id="container">
<div id="menu">
<ul>
<li id="new_game">New Game</li>
</ul>
</div>
<div id="field"></div>
</div>
</body>
</html>
Could anyone give me a hint on how to generate a chess board (8x8) using JavaScript, using a table tags or ?
I've got the following so far:
<DOCTYPE html>
<html>
<head>
<style>
div
{
border:1px solid black;
width:20px;
height:20px;
}
</style>
</head>
<body>
<script type="text/javascript">
// create a chess table 8x8.
var count = 0;
while (count < 64)
{
if (count % 2 == 0)
{
if (count % 8 == 0 && count !=0)
{
document.write('<br/><div style="background-color:#000000;float:left;"> </div>');
}
else
{
document.write('<div style="background-color:#000000;float:left;"> </div>');
}
}
else
{
document.write('<div style="background-color:#FFFFFF;float:left;"> </div>');
}
/*
*/
count++;
}
</script>
</body>
</html>
I tried to assign black and white to each odd and even number respectively, but it doesn't work this way.
Thank you in advance.
I can not test it at this moment but this should work. This code creates a 8x8 table in which black cells are tagged with "black" class and white cells are tagged with "white" class. Use CSS to give them color. I hope it helps.
var table = document.createElement("table");
for (var i = 1; i < 9; i++) {
var tr = document.createElement('tr');
for (var j = 1; j < 9; j++) {
var td = document.createElement('td');
if (i%2 == j%2) {
td.className = "white";
} else {
td.className = "black";
}
tr.appendChild(td);
}
table.appendChild(tr);
}
document.body.appendChild(table);
At some point for me, this became code golf:
http://jsfiddle.net/4Ap4M/
JS:
for (var i=0; i< 64; i++){
document.getElementById("mainChessBoard").appendChild(document.createElement("div")).style.backgroundColor = parseInt((i / 8) + i) % 2 == 0 ? '#ababab' : 'white';
}
HTML:
<div id="mainChessBoard">
</div>
CSS:
#mainChessBoard
{
width:160px;
height:160px;
border:1px solid black;
}
div
{
width:20px;
height:20px;
float:left;
}
This is the basic foundation to build your chess board.
You can check out the chess board pattern in the console.
var chessBoard = function(size){
var hash = '#'
var space = '_'
for (var i = 0; i < size; i++)
{
hash += '\n'
for (var j = 0; j < size; j++)
{
if((i +j) % 2 == 0)
{
hash += space
}
else
{
hash += "#"
}
};
};
console.log(hash)
}(8)
You can generate boards of any size you want, and this way is pretty easy to change the size of the squares and the colors. you don't need to change anything else.
It is good practice to keep appearance on the stylesheet.
Also don't use document.write
http://jsfiddle.net/YEJ9A/1/
Javascript
var x=8;
var y=8;
var chessBoard = document.getElementById("chessBoard");
for (var i=0; i<y; i++){
var row = chessBoard.appendChild(document.createElement("div"));
for (var j=0; j<x; j++){
row.appendChild(document.createElement("span"));
}
}
CSS
#chessBoard span{
display: inline-block;
width: 32px;
height: 32px;
}
#chessBoard div:nth-child(odd) span:nth-child(even),
#chessBoard div:nth-child(even) span:nth-child(odd){
background-color: black;
}
#chessBoard div:nth-child(even) span:nth-child(even),
#chessBoard div:nth-child(odd) span:nth-child(odd){
background-color: silver;
}
May be you want to do it with divs, not with the table. So here is the solution for it.
$(document).ready(function() {
for (var i = 1; i <= 8; i++) {
var divRow = $("<div>", {
class: "row",
});
for (var j = 1; j <= 8; j++) {
var div = $("<div>", {
class: "square"
});
if (i % 2 == j % 2) {
$(div).addClass("white");
} else {
$(div).addClass("black");
}
divRow.append(div);
}
$("#board").append(divRow);
}
});
#board {
margin: 0;
width: 256px;
height: 256px;
border: solid 1px #333;
}
#board .row {
margin: 0;
}
.square {
height: 32px;
width: 32px;
background: #efefef;
float: left;
}
.square.white {
background: #fff;
}
.square.black {
background: #333;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div id="board"></div>
A little modernization, using css variables, css attr() and dataset attributes.
This allows to tweak themes, and keep stuffs simple.
const cols = {0:"A", 1:"B", 2:"C", 3:"D", 4:"E", 5:"F", 6:"G", 7:"H"}
const table = document.createElement("table");
table.className = "board";
for (let i = 1; i < 9; i++) {
let tr = document.createElement('tr');
tr.dataset.line = i
for (let j = 1; j < 9; j++) {
let td = document.createElement('td');
td.dataset.col = cols[j-1];
td.dataset.line = i;
td.className = (i%2 === j%2) ? "white square" : "black square";
tr.appendChild(td);
}
table.appendChild(tr);
}
document.querySelector("div").appendChild(table);
:root {
--size: 640px;
--backcolor: darkslategray;
--dark: grey;
--light: white;
--legend: azure;
--hover: lightgreen
}
.board {
width: var(--size);
height: var(--size);
border: 32px solid;
border-color: var(--backcolor);
border-radius: 0.2rem;
}
.square {
border: 1px black solid;
}
.white{
background: var(--light);
}
.black{
background: var(--dark)
}
.board tr::before {
content: attr(data-line);
position: absolute;
margin: 1.8rem 0 0rem -1.5rem;
font-size: larger;
color: var(--legend);
}
.board tr::after {
content: attr(data-line);
position: absolute;
margin: 1.8rem 0 0rem 0.8rem;
font-size: larger;
color: var(--legend);
}
.board tr:first-child > td::before {
content: attr(data-col);
position: absolute;
margin: -4rem 0 0rem 1.6rem;
font-size: larger;
color: var(--legend);
}
.board tr:last-child > td::after {
content: attr(data-col);
position: absolute;
margin: 2.6rem 0 0rem 1.6rem;
font-size: larger;
color: var(--legend);
}
td:hover {
background: var(--hover);
cursor: pointer
}
<div></div>
The following code will print chess board using only HTML and JavaScript.
<script>
document.write("<table border='1' width='200' height='200'>");
for(var i=1; i<=8; i++)
{
document.write("<tr>");
for(var j=1; j<=8; j++)
{
if((i+j)%2!=0)
{
document.write("<td bgcolor='white'></td>");
}
else
{
document.write("<td bgcolor='black'></td>");
}
}
document.write("</tr>");
}
document.write("</table>");
</script>
You should try this one this will really work
<DOCTYPE html>
<html>
<head>
<style>
.chessBoard {
display: inline-block;
border: 2px solid lightGray;
}
.chessBoard div {
line-height: 1px;
}
.chessBoard span {
display: inline-block;
width: 32px;
height: 32px;
background-color: snow;
}
</style>
</head>
<body>
<div class="chessBoard" id="chessBoardNormal"></div>
<div class="chessBoard" id="chessBoardRandom"></div>
<script>
function colorNormal(x, y, color) {
var chessBoard = document.getElementById("chessBoardNormal");
for (var i = 0; i < x; i++) {
var row = chessBoard.appendChild(document.createElement("div"));
for (var j = 0; j < y; j++) {
var span = document.createElement('span');
if (i & 1) { // odd
if (j & 1) { // white
} else { // black
span.style.backgroundColor = color;
}
} else { // even
if (j & 1) { // black
span.style.backgroundColor = color;
}
}
row.appendChild(span);
}
}
}
function colorRandom(x, y) {
colorNormal(8, 8, Math.random() > .5 ? 'black' : '#CFD65C');
}
function getRandomHexColor() {
return '#' + Math.floor(Math.random() * 16777215).toString(16);
}
colorNormal(8, 8, 'black');
</script>
</body>
</html>
My idea is simple, if row is even then start with white piece otherwise start with black piece.
HTML:
<div id="mainChessBoard"></div>
Javascript:
const fragment = document.createDocumentFragment();
const board = document.getElementById("mainChessBoard");
const size = 8;
for (let i = 0; i < size; i++) {
let start = i % 2 === 0 ? 0 : 1; // if row is even then start with white otherwise start with black;
for (let j = 0; j < size; j++) {
const div = document.createElement('div');
div.classList.add(start === 1 ? "black" : "white");
fragment.appendChild(div);
start = start === 1 ? 0 : 1;
}
}
board.appendChild(fragment);
Here's a plain JS copy-paste solution. I know it's not that clean in terms of conditioning but it does the job comprehensibly and it's quite straight forward. Field size is easily adjustable as well.
const fieldSize = 50;
const whiteField = document.createElement("div");
whiteField.style = `height:${fieldSize}px;width:${fieldSize}px;background-color:white;display:inline-block`;
const blackField = document.createElement("div");
blackField.style = `height:${fieldSize}px;width:${fieldSize}px;background-color:black;display:inline-block`;
for (let i = 0; i < 8; i++) {
for (let j = 0; j < 8; j++)
i % 2 === 0 ?
j % 2 === 0 ?
document.body.appendChild(blackField.cloneNode(true)) :
document.body.appendChild(whiteField.cloneNode(true)) :
j % 2 === 0 ?
document.body.appendChild(whiteField.cloneNode(true)) :
document.body.appendChild(blackField.cloneNode(true));
document.body.appendChild(document.createElement("br"));
}
We can always think of a better performance, here's the DOM optimized solution using documentFragments -
// main container
let container = document.querySelector("#main");
// a fragment object to store a 2-D mesh of rows and columns
let fragment = new DocumentFragment();
for (let i = 0; i < 8; i++) {
// a fragment object to store a single row with 8 columns
let rowFragment = new DocumentFragment();
for (let j = 0; j < 8; j++) {
// div element for a column
let col = document.createElement("div");
col.style.border = "1px solid";
if ((i + j) % 2 == 0) col.style.background = "black";
else col.style.background = "white";
// adding column in a document fragment
rowFragment.appendChild(col);
}
// adding row in a main fragment
fragment.appendChild(rowFragment);
}
// adding fragment to a DOM one time - this will update the DOM only once
container.appendChild(fragment);
.container {
display: flex;
width: 416px; /* width + horizontal border of each cell ((50 + 2) * 8) */
height: 416px; /* height + vertical border of each cell ((50 + 2) * 8) */
}
div {
flex-wrap: wrap; /* to fit 8 cells in a row as per the width */
width: 50px;
height: 50px;
}
<div class="container" id="main"></div>
Here, the DocumentFragment creates an object of elements we add, but it isn't a part of the active document tree unless we append it to any other DOM node.
Javascript:
var i, j, clas;
for (i = 0; i < 8; i++) {
for (j = 0; j < 8; j++) {
clas = '';
if (j === 0) clas = 'first ';
else if (j === 7) clas = 'last ';
clas += (i % 2 == j % 2) ? 'white' : 'black';
var field = document.createElement('div');
field.className = clas;
document.body.appendChild(field);
}
}
CSS:
div {
float: left;
width: 20px;
height: 20px;
}
.first {
clear: left;
}
.black {
background: black;
}
.white {
background: red;
}
Sample: http://jsfiddle.net/YJnXG/2/
You mean like this?
.... html.....
<table>
<tr>
<script language='javascript'>
<!--
alternate();
//-->
</script>
</tr>
</table>
....more html.....
function alternate()
{
var numOfCells = 6;
var num = 0;
for (i = 0; i < numOfCells ; i++)
{
txt = "<td bgColor='";
txt += (num % 2 == 0) ? 'red' : 'black';
txt += "'>"
document.write(txt);
num++;
}
}
The % sign is mod; it returns the remainder of a division. the "(...) ? ... : ...;" construction is like an if/else. If the condition is true, the first option -- else the second.