Skip to content

Commit

Permalink
Added N-Queen Visualizer | Issue #825 (#880)
Browse files Browse the repository at this point in the history
* Update README.md

* Added N-Queen Visualizer

* Update README.md

* Fixes

* Fixes

* Fixes

* enlisting-fixes

---------

Co-authored-by: Avdhesh <[email protected]>
  • Loading branch information
Shariq2003 and Avdhesh-Varshney authored Oct 16, 2024
1 parent afd9f99 commit dc741c6
Show file tree
Hide file tree
Showing 6 changed files with 722 additions and 2 deletions.
67 changes: 67 additions & 0 deletions Vanilla-JS-Projects/Advanced/N-Queen-Visualizer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<h1 align='center'><b>💥 N-Queens Visualiser 💥</b></h1>

<!-- -------------------------------------------------------------------------------------------------------------- -->

<h3 align='center'>Tech Stack Used 🎮</h3>
<!-- enlist all the technologies used to create this project from them (Remove comment using 'ctrl+z' or 'command+z') -->

<div align='center'>

![HTML5](https://img.shields.io/badge/html5-%23E34F26.svg?style=for-the-badge&logo=html5&logoColor=white) ![JavaScript](https://img.shields.io/badge/javascript-%23323330.svg?style=for-the-badge&logo=javascript&logoColor=%23F7DF1E) ![CSS3](https://img.shields.io/badge/css3-%231572B6.svg?style=for-the-badge&logo=css3&logoColor=white) ![TailwindCSS](https://img.shields.io/badge/tailwindcss-%2338B2AC.svg?style=for-the-badge&logo=tailwind-css&logoColor=white)

</div>


![Line](https://github.com/Avdhesh-Varshney/WebMasterLog/assets/114330097/4b78510f-a941-45f8-a9d5-80ed0705e847)

<!-- -------------------------------------------------------------------------------------------------------------- -->

## :zap: Description 📃

<div>
<!-- <p>Add Description of the project</p> -->
<p>Welcome to the **N-Queens Visualiser**! This web application allows you to visualize the classic N-Queens problem, where the objective is to place N queens on an N x N chessboard such that no two queens threaten each other. This is achieved by ensuring that no two queens share the same row, column, or diagonal.</p>
</div>


<!-- -------------------------------------------------------------------------------------------------------------- -->

## :zap: How to run it? 🕹️

<!-- Add steps how to run this project -->
To run this project locally, follow these steps:

1. Fork the repository.

2. Clone the repository to your local computer:
git clone https://github.com/Shariq2003/N-Queen-Visualiser.git

3. Open the project folder in your preferred code editor, now you can view website in live.



<!-- -------------------------------------------------------------------------------------------------------------- -->

## :zap: Screenshots 📸
<!-- add the screenshot of the project (Mandatory) -->

<img src='./screenshot.webp'>


![Line](https://github.com/Avdhesh-Varshney/WebMasterLog/assets/114330097/4b78510f-a941-45f8-a9d5-80ed0705e847)

<!-- -------------------------------------------------------------------------------------------------------------- -->

<h4 align='center'>Developed By <b><i>Shariq</i></b> 👦</h4>
<p align='center'>
<a href='https://www.linkedin.com/in/shariq-sd'>
<img src='https://img.shields.io/badge/linkedin-%230077B5.svg?style=for-the-badge&logo=linkedin&logoColor=white' />
</a>
<a href='https://github.com/Shariq2003'>
<img src='https://img.shields.io/badge/github-%23121011.svg?style=for-the-badge&logo=github&logoColor=white' />
</a>
</p>

<h4 align='center'>Happy Coding 🧑‍💻</h4>

<h3 align="center">Show some &nbsp;❤️&nbsp; by &nbsp;🌟&nbsp; this repository!</h3>
250 changes: 250 additions & 0 deletions Vanilla-JS-Projects/Advanced/N-Queen-Visualizer/chess.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
const numberbox = document.getElementById("numberbox");
const slider = document.getElementById("slider");
const progressBar = document.getElementById("progress-bar")
const playButton = document.getElementById('play-button');
const pauseButton = document.getElementById("pause-button");
const queen = '<i class="fas fa-chess-queen" style="color:#000"></i>';

let isMainContainerVisible = false;

function toggleVisibility() {
const landingPage = document.querySelector('.landing-div');
const mainContainer = document.querySelector('.n-queen');

if (isMainContainerVisible) {
landingPage.style.display = 'none';
mainContainer.style.display = 'flex';
} else {
landingPage.style.display = 'block';
mainContainer.style.display = 'none';
}
}
window.onload = toggleVisibility;
document.getElementById('start-button').onclick = function () {
isMainContainerVisible = true;
toggleVisibility();
};


let n, speed, tempSpeed, q, Board = 0;
let array = [0, 2, 1, 1, 3, 11, 5, 41, 93];

// Used to store the state of the boards;
let pos = {};

speed = (100 - slider.value) * 10;
tempSpeed = speed;
slider.oninput = function () {
progressBar.style.width = this.value + "%";
const sliderValue = parseInt(this.value, 10);
if (sliderValue <= 25) {
progressBar.style.backgroundColor = "green";
slider.className = 'slider green';
} else if (sliderValue > 25 && sliderValue <= 75) {
progressBar.style.backgroundColor = "#ffd200";
slider.className = 'slider yellow';
} else {
progressBar.style.backgroundColor = "red";
slider.className = 'slider red';
}

speed = sliderValue;
speed = (100 - speed) * 10;
};



class Queen {
constructor() {
this.position = Object.assign({}, pos);
this.uuid = [];
}

nQueen = async () => {
Board = 0;
this.position[`${Board}`] = {};
numberbox.disabled = true;
await q.solveQueen(Board, 0, n);
await q.clearColor(Board);
numberbox.disabled = false;
}

isValid = async (board, r, col, n) => {
//Setting the current box color to orange
const table = document.getElementById(`table-${this.uuid[board]}`);
const currentRow = table.firstChild.childNodes[r];
const currentColumn = currentRow.getElementsByTagName("td")[col];
currentColumn.innerHTML = queen;
await q.delay();

// Checking the queen in the same column
for (let i = r - 1; i >= 0; --i) {
const row = table.firstChild.childNodes[i];
const column = row.getElementsByTagName("td")[col];
const value = column.innerHTML;

if (value == queen) {
column.style.backgroundColor = "#ff0000";
currentColumn.innerHTML = "-"
return false;
}
column.style.backgroundColor = "#ddff00";
await q.delay();
}

//Checking the upper left diagonal
for (let i = r - 1, j = col - 1; i >= 0 && j >= 0; --i, --j) {
const row = table.firstChild.childNodes[i];
const column = row.getElementsByTagName("td")[j];
const value = column.innerHTML;

if (value == queen) {
column.style.backgroundColor = "#fb5607";
currentColumn.innerHTML = "-"
return false;
}
column.style.backgroundColor = "#ffca3a";
await q.delay();
}

// Checking the upper right diagonal
for (let i = r - 1, j = col + 1; i >= 0 && j < n; --i, ++j) {
const row = table.firstChild.childNodes[i];
const column = row.getElementsByTagName("td")[j];

const value = column.innerHTML;

if (value == queen) {
column.style.backgroundColor = "#FB5607";
currentColumn.innerHTML = "-"
return false;
}
column.style.backgroundColor = "#ffca3a";
await q.delay();
}
return true;
}

clearColor = async (board) => {
for (let j = 0; j < n; ++j) {
const table = document.getElementById(`table-${this.uuid[board]}`);
const row = table.firstChild.childNodes[j];
for (let k = 0; k < n; ++k)
(j + k) & 1
? (row.getElementsByTagName("td")[k].style.backgroundColor = "#03852e")
: (row.getElementsByTagName("td")[k].style.backgroundColor = "#ffffff");
}
}

delay = async () => {
await new Promise((done) => setTimeout(() => done(), speed));
}

solveQueen = async (board, r, n) => {
if (r == n) {
++Board;
let table = document.getElementById(`table-${this.uuid[Board]}`);
for (let k = 0; k < n; ++k) {
let row = table.firstChild.childNodes[k];
row.getElementsByTagName("td")[this.position[board][k]].innerHTML = queen;
}
this.position[Board] = this.position[board];
return;
}

for (let i = 0; i < n; ++i) {
await q.delay();
// console.log("outside:" + board);
await q.clearColor(board);
if (await q.isValid(board, r, i, n)) {
await q.delay();
// console.log("inside:" + board)
await q.clearColor(board);
let table = document.getElementById(`table-${this.uuid[board]}`);
let row = table.firstChild.childNodes[r];
row.getElementsByTagName("td")[i].innerHTML = queen;

this.position[board][r] = i;

if (await q.solveQueen(board, r + 1, n))
await q.clearColor(board);

await q.delay();
board = Board;
// console.log(this.Board)
table = document.getElementById(`table-${this.uuid[board]}`);
// console.log(JSON.parse(JSON.stringify(table)));
row = table.firstChild.childNodes[r];
row.getElementsByTagName("td")[i].innerHTML = "-";

delete this.position[`${board}`][`${r}`];
}
}
}
}

playButton.onclick = async function visualise() {
const chessBoard = document.getElementById("n-queen-board");
const arrangement = document.getElementById("queen-arrangement");

n = numberbox.value;
q = new Queen();

if (n > 8) {
numberbox.value = "";
alert("Queen value is too large");
return;
} else if (n < 1) {
numberbox.value = "";
alert("Queen value is too small");
return;
}

// Removing all the of previous execution context
while (chessBoard.hasChildNodes()) {
chessBoard.removeChild(chessBoard.firstChild);
}
if (arrangement.hasChildNodes()) {
arrangement.removeChild(arrangement.lastChild)
}

const para = document.createElement("p");
para.setAttribute("class", "queen-info");
para.innerHTML = `For ${n}x${n} board, ${array[n] - 1} arrangements are possible.`;
arrangement.appendChild(para);

//Adding boards to the Div
if (chessBoard.childElementCount === 0) {
for (let i = 0; i < array[n]; ++i) {
q.uuid.push(Math.random());
let div = document.createElement('div');
let table = document.createElement('table');
let header = document.createElement('h4');
// div.setAttribute("id", `div-${100 + uuid[i]}`)
header.innerHTML = `Board ${i + 1} `
table.setAttribute("id", `table-${q.uuid[i]}`);
header.setAttribute("id", `paragraph-${i}`);
chessBoard.appendChild(div);
div.appendChild(header);
div.appendChild(table);
}
}

for (let k = 0; k < array[n]; ++k) {
let table = document.getElementById(`table-${q.uuid[k]}`);
for (let i = 0; i < n; ++i) {
const row = table.insertRow(i); // inserting ith row
row.setAttribute("id", `Row${i} `);
for (let j = 0; j < n; ++j) {
const col = row.insertCell(j); // inserting jth column
(i + j) & 1
? (col.style.backgroundColor = "#FF9F1C")
: (col.style.backgroundColor = "#FCCD90");
col.innerHTML = "-";
col.style.border = "0.3px solid #373f51";
}
}
await q.clearColor(k);
}
await q.nQueen();
};
Loading

0 comments on commit dc741c6

Please sign in to comment.