diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 0186e40..2d07ec4 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -1,10 +1,13 @@
-## Describe your changes
+## Describe your changes (Mandatory)
-## Issue ticket number and link
+## Issue ticket number and link (Mandatory)
+
+## Screenshots of your project, whatever you have added. (Mandatory)
## Checklist before requesting a review
- [ ] I have performed a self-review of my code
-- [ ] If it is a new project, I have added thorough tests.
+- [ ] If it is a new project, I have done thorough tests.
- [ ] Have you updated the README file of the repository and added the name of the project in it?
-- [ ] Have you added a `README.md` file inside the directory of your project and explained it there properly?
+- [ ] Have you added a `README.md` file inside the directory of your project and explained it there properly (with images)?
+- [ ] Have you updated the `script.js` file so that the project is visible in the website?
diff --git a/Hide-show-pass/.DS_Store b/Hide-show-pass/.DS_Store
new file mode 100644
index 0000000..7ae5098
Binary files /dev/null and b/Hide-show-pass/.DS_Store differ
diff --git a/Hide-show-pass/.vscode/settings.json b/Hide-show-pass/.vscode/settings.json
new file mode 100644
index 0000000..3b66410
--- /dev/null
+++ b/Hide-show-pass/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "git.ignoreLimitWarning": true
+}
\ No newline at end of file
diff --git a/Hide-show-pass/Images/.DS_Store b/Hide-show-pass/Images/.DS_Store
new file mode 100644
index 0000000..1d0a3cc
Binary files /dev/null and b/Hide-show-pass/Images/.DS_Store differ
diff --git a/Hide-show-pass/Images/open.png b/Hide-show-pass/Images/open.png
new file mode 100644
index 0000000..1aed309
Binary files /dev/null and b/Hide-show-pass/Images/open.png differ
diff --git a/Hide-show-pass/Images/shut.png b/Hide-show-pass/Images/shut.png
new file mode 100644
index 0000000..d68b40d
Binary files /dev/null and b/Hide-show-pass/Images/shut.png differ
diff --git a/Hide-show-pass/README.md b/Hide-show-pass/README.md
new file mode 100644
index 0000000..f4d6a75
--- /dev/null
+++ b/Hide-show-pass/README.md
@@ -0,0 +1,2 @@
+Hide/Show password
+A project made using HTML, CSS and JS which can be integrated easily to your website for better security when entering password in public spaces.}
\ No newline at end of file
diff --git a/Hide-show-pass/index.html b/Hide-show-pass/index.html
new file mode 100644
index 0000000..af9dcb9
--- /dev/null
+++ b/Hide-show-pass/index.html
@@ -0,0 +1,16 @@
+
+
+
@@ -47,10 +48,15 @@ Open for contributions.
Check this [file](https://github.com/shrey141102/Javascript-projects/blob/main/CONTRIBUTING.md) for steps to contribute.
+Please read the `CONTRIBUTING.md` file carefully before submitting a PR.
+Also, make sure your PR fulfills the required conditions present in the PR template.
+
Please update this README file by adding your project name.
Also remember to add a README inside your project directory explaining what your project is.
+Please avoid adding same projects again and again. (unless it has a very different approach/ui)
+
💻 Built with
Built by people around the globe. 🌐🧑🤝🧑
@@ -60,5 +66,3 @@ Technologies used in the project:
- Javascript
- HTML
- CSS
-
-please feel free to use any technology while building the project. It can be AI or Blockchain or anything. Just remeber that it should be able to work with and intergrate with the website.
diff --git a/Snake_Game/Assets/food.png b/Snake_Game/Assets/food.png
new file mode 100644
index 0000000..680bb05
Binary files /dev/null and b/Snake_Game/Assets/food.png differ
diff --git a/Snake_Game/Assets/grass.jpg b/Snake_Game/Assets/grass.jpg
new file mode 100644
index 0000000..c743b26
Binary files /dev/null and b/Snake_Game/Assets/grass.jpg differ
diff --git a/Snake_Game/Assets/preview.jpg b/Snake_Game/Assets/preview.jpg
new file mode 100644
index 0000000..badbdda
Binary files /dev/null and b/Snake_Game/Assets/preview.jpg differ
diff --git a/Snake_Game/Assets/snake.png b/Snake_Game/Assets/snake.png
new file mode 100644
index 0000000..f957bc8
Binary files /dev/null and b/Snake_Game/Assets/snake.png differ
diff --git a/Snake_Game/README.md b/Snake_Game/README.md
new file mode 100644
index 0000000..8fe28b0
--- /dev/null
+++ b/Snake_Game/README.md
@@ -0,0 +1,2 @@
+# Snake-Game
+Its a basics Javascript snake game using DOM Event
diff --git a/Snake_Game/app.js b/Snake_Game/app.js
new file mode 100644
index 0000000..f946c3f
--- /dev/null
+++ b/Snake_Game/app.js
@@ -0,0 +1,33 @@
+let food =document.querySelector(".food");
+let snake=document.querySelector(".snake");
+let move=document.querySelector("input");
+let h1=document.querySelector("h1");
+let mh=0;
+let mv=0;
+let fh=0;
+let fv=0;
+let count =-1;
+move.addEventListener("keydown",function(event){
+ if(mv==fv&&mh==fh){
+ fv=Math.floor(Math.random()*19)*30;
+ fh=Math.floor(Math.random()*29)*30;
+ food.style.marginTop=`${fv}px`;
+ food.style.marginLeft=`${fh}px`;
+ count++;
+ h1.innerText=`SCORE : ${count}`;
+ }
+ if(event.code=="ArrowUp"&&mv>0){
+ mv-=30;
+ }
+ if(event.code=="ArrowDown"&&mv<560){
+ mv+=30;
+ }
+ if(event.code=="ArrowLeft"&&mh>0){
+ mh-=30;
+ }
+ if(event.code=="ArrowRight"&&mh<860){
+ mh+=30;
+ }
+ snake.style.marginTop=`${mv}px`;
+ snake.style.marginLeft=`${mh}px`;
+});
\ No newline at end of file
diff --git a/Snake_Game/index.html b/Snake_Game/index.html
new file mode 100644
index 0000000..5c26104
--- /dev/null
+++ b/Snake_Game/index.html
@@ -0,0 +1,23 @@
+
+
+
+
+
+ Snake Game
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Sudoku Game/logo.png b/Sudoku Game/logo.png
new file mode 100644
index 0000000..53ff503
Binary files /dev/null and b/Sudoku Game/logo.png differ
diff --git a/Sudoku Game/main.js b/Sudoku Game/main.js
new file mode 100644
index 0000000..bbd3d69
--- /dev/null
+++ b/Sudoku Game/main.js
@@ -0,0 +1,171 @@
+const gameBoard = document.getElementById("gameBoard");
+const squares = document.getElementsByClassName("square");
+const numbers = document.getElementsByClassName("number");
+const solveButton = document.getElementById("solveButton");
+const newGameButton = document.getElementById("newGameButton");
+const eraseButton = document.getElementById("eraseButton");
+const hintButton = document.getElementById("hintButton");
+const hints = document.getElementById("hint");
+const mistakeElement = document.getElementById("mistakes");
+let mistake =0;
+let hintNumber =3;
+
+let level = difficulty.value;
+let board = sudoku.generate(level,false);
+let solvedString = sudoku.solve(board);
+let sudokuString = board;
+let sudokuBoard = stringToArray(sudokuString);
+let sudokuSolved = stringToArray(solvedString);
+
+setupBoard();
+fillBoard(sudokuBoard);
+
+
+function setupBoard() {
+ for (let i=0;isquare.classList.remove("active"));
+ this.classList.add("active");
+}
+
+function fillBoard(board) {
+ for (let i=0;isquare.classList.remove("active"));
+ showAlert(message,color);
+}
+eraseButton.addEventListener("click",function(){
+ let activeSquare = document.querySelector(".active");
+ if(activeSquare==null)return;
+ activeSquare.classList.remove("active");
+ if(activeSquare.classList.contains("filled")) return;
+ activeSquare.innerHTML="";
+});
+
+hintButton.addEventListener ("click",function(){
+ if(hintNumber==0) {
+ showAlert("Oops! You've used all your hints.");
+ return;
+ }
+ let activeSquare = document.querySelector(".active");
+ activeSquare.classList.remove("active");
+ if(activeSquare.classList.contains("filled")) return;
+ let row = parseInt(activeSquare.id.charAt(0));
+ let column = parseInt(activeSquare.id.charAt(1));
+ activeSquare.innerHTML = sudokuSolved[row-1][column-1];
+ activeSquare.classList.add("filled");
+ activeSquare.classList.add("true");
+ hintNumber--;
+ hints.innerHTML = hintNumber+"/3";
+});
+solveButton.addEventListener("click",function(){
+ resetBoard();
+ fillBoard(sudokuSolved);
+});
+newGameButton.addEventListener("click",function(){
+ resetBoard();
+ level = difficulty.value;
+ board = sudoku.generate(level,false);
+ sudokuString = board;
+ solvedString = sudoku.solve(board);
+ sudokuBoard = stringToArray(sudokuString);
+ sudokuSolved = stringToArray(solvedString);
+ setupBoard();
+ fillBoard(sudokuBoard);
+ mistake = 0;
+ mistakeElement.innerHTML = "0/3";
+ hintNumber =3;
+ hints.innerHTML = "3/3";
+});
+
+function resetBoard() {
+ for(let i=0;i units map
+ var SQUARE_PEERS_MAP = null; // Squares -> peers map
+
+ var MIN_GIVENS = 17; // Minimum number of givens
+ var NR_SQUARES = 81; // Number of squares
+
+ // Define difficulties by how many squares are given to the player in a new
+ // puzzle.
+ var DIFFICULTY = {
+ "easy": 62,
+ "medium": 53,
+ "hard": 44,
+ "very-hard": 35,
+ "insane": 26,
+ "inhuman": 17,
+ };
+
+ // Blank character and board representation
+ sudoku.BLANK_CHAR = '.';
+ sudoku.BLANK_BOARD = "...................................................."+
+ ".............................";
+
+ // Init
+ // -------------------------------------------------------------------------
+ function initialize(){
+ /* Initialize the Sudoku library (invoked after library load)
+ */
+ SQUARES = sudoku._cross(ROWS, COLS);
+ UNITS = sudoku._get_all_units(ROWS, COLS);
+ SQUARE_UNITS_MAP = sudoku._get_square_units_map(SQUARES, UNITS);
+ SQUARE_PEERS_MAP = sudoku._get_square_peers_map(SQUARES,
+ SQUARE_UNITS_MAP);
+ }
+
+ // Generate
+ // -------------------------------------------------------------------------
+ sudoku.generate = function(difficulty, unique){
+ /* Generate a new Sudoku puzzle of a particular `difficulty`, e.g.,
+
+ // Generate an "easy" sudoku puzzle
+ sudoku.generate("easy");
+
+
+ Difficulties are as follows, and represent the number of given squares:
+
+ "easy": 61
+ "medium": 52
+ "hard": 43
+ "very-hard": 34
+ "insane": 25
+ "inhuman": 17
+
+
+ You may also enter a custom number of squares to be given, e.g.,
+
+ // Generate a new Sudoku puzzle with 60 given squares
+ sudoku.generate(60)
+
+
+ `difficulty` must be a number between 17 and 81 inclusive. If it's
+ outside of that range, `difficulty` will be set to the closest bound,
+ e.g., 0 -> 17, and 100 -> 81.
+
+
+ By default, the puzzles are unique, uless you set `unique` to false.
+ (Note: Puzzle uniqueness is not yet implemented, so puzzles are *not*
+ guaranteed to have unique solutions)
+
+ TODO: Implement puzzle uniqueness
+ */
+
+ // If `difficulty` is a string or undefined, convert it to a number or
+ // default it to "easy" if undefined.
+ if(typeof difficulty === "string" || typeof difficulty === "undefined"){
+ difficulty = DIFFICULTY[difficulty] || DIFFICULTY.easy;
+ }
+
+ // Force difficulty between 17 and 81 inclusive
+ difficulty = sudoku._force_range(difficulty, NR_SQUARES + 1,
+ MIN_GIVENS);
+
+ // Default unique to true
+ unique = unique || true;
+
+ // Get a set of squares and all possible candidates for each square
+ var blank_board = "";
+ for(var i = 0; i < NR_SQUARES; ++i){
+ blank_board += '.';
+ }
+ var candidates = sudoku._get_candidates_map(blank_board);
+
+ // For each item in a shuffled list of squares
+ var shuffled_squares = sudoku._shuffle(SQUARES);
+ for(var si in shuffled_squares){
+ var square = shuffled_squares[si];
+
+ // If an assignment of a random chioce causes a contradictoin, give
+ // up and try again
+ var rand_candidate_idx =
+ sudoku._rand_range(candidates[square].length);
+ var rand_candidate = candidates[square][rand_candidate_idx];
+ if(!sudoku._assign(candidates, square, rand_candidate)){
+ break;
+ }
+
+ // Make a list of all single candidates
+ var single_candidates = [];
+ for(var si in SQUARES){
+ var square = SQUARES[si];
+
+ if(candidates[square].length == 1){
+ single_candidates.push(candidates[square]);
+ }
+ }
+
+ // If we have at least difficulty, and the unique candidate count is
+ // at least 8, return the puzzle!
+ if(single_candidates.length >= difficulty &&
+ sudoku._strip_dups(single_candidates).length >= 8){
+ var board = "";
+ var givens_idxs = [];
+ for(var i in SQUARES){
+ var square = SQUARES[i];
+ if(candidates[square].length == 1){
+ board += candidates[square];
+ givens_idxs.push(i);
+ } else {
+ board += sudoku.BLANK_CHAR;
+ }
+ }
+
+ // If we have more than `difficulty` givens, remove some random
+ // givens until we're down to exactly `difficulty`
+ var nr_givens = givens_idxs.length;
+ if(nr_givens > difficulty){
+ givens_idxs = sudoku._shuffle(givens_idxs);
+ for(var i = 0; i < nr_givens - difficulty; ++i){
+ var target = parseInt(givens_idxs[i]);
+ board = board.substr(0, target) + sudoku.BLANK_CHAR +
+ board.substr(target + 1);
+ }
+ }
+
+ // Double check board is solvable
+ // TODO: Make a standalone board checker. Solve is expensive.
+ if(sudoku.solve(board)){
+ return board;
+ }
+ }
+ }
+
+ // Give up and try a new puzzle
+ return sudoku.generate(difficulty);
+ };
+
+ // Solve
+ // -------------------------------------------------------------------------
+ sudoku.solve = function(board, reverse){
+ /* Solve a sudoku puzzle given a sudoku `board`, i.e., an 81-character
+ string of sudoku.DIGITS, 1-9, and spaces identified by '.', representing the
+ squares. There must be a minimum of 17 givens. If the given board has no
+ solutions, return false.
+
+ Optionally set `reverse` to solve "backwards", i.e., rotate through the
+ possibilities in reverse. Useful for checking if there is more than one
+ solution.
+ */
+
+ // Assure a valid board
+ var report = sudoku.validate_board(board);
+ if(report !== true){
+ throw report;
+ }
+
+ // Check number of givens is at least MIN_GIVENS
+ var nr_givens = 0;
+ for(var i in board){
+ if(board[i] !== sudoku.BLANK_CHAR && sudoku._in(board[i], sudoku.DIGITS)){
+ ++nr_givens;
+ }
+ }
+ if(nr_givens < MIN_GIVENS){
+ throw "Too few givens. Minimum givens is " + MIN_GIVENS;
+ }
+
+ // Default reverse to false
+ reverse = reverse || false;
+
+ var candidates = sudoku._get_candidates_map(board);
+ var result = sudoku._search(candidates, reverse);
+
+ if(result){
+ var solution = "";
+ for(var square in result){
+ solution += result[square];
+ }
+ return solution;
+ }
+ return false;
+ };
+
+ sudoku.get_candidates = function(board){
+ /* Return all possible candidatees for each square as a grid of
+ candidates, returnning `false` if a contradiction is encountered.
+
+ Really just a wrapper for sudoku._get_candidates_map for programmer
+ consumption.
+ */
+
+ // Assure a valid board
+ var report = sudoku.validate_board(board);
+ if(report !== true){
+ throw report;
+ }
+
+ // Get a candidates map
+ var candidates_map = sudoku._get_candidates_map(board);
+
+ // If there's an error, return false
+ if(!candidates_map){
+ return false;
+ }
+
+ // Transform candidates map into grid
+ var rows = [];
+ var cur_row = [];
+ var i = 0;
+ for(var square in candidates_map){
+ var candidates = candidates_map[square];
+ cur_row.push(candidates);
+ if(i % 9 == 8){
+ rows.push(cur_row);
+ cur_row = [];
+ }
+ ++i;
+ }
+ return rows;
+ }
+
+ sudoku._get_candidates_map = function(board){
+ /* Get all possible candidates for each square as a map in the form
+ {square: sudoku.DIGITS} using recursive constraint propagation. Return `false`
+ if a contradiction is encountered
+ */
+
+ // Assure a valid board
+ var report = sudoku.validate_board(board);
+ if(report !== true){
+ throw report;
+ }
+
+ var candidate_map = {};
+ var squares_values_map = sudoku._get_square_vals_map(board);
+
+ // Start by assigning every digit as a candidate to every square
+ for(var si in SQUARES){
+ candidate_map[SQUARES[si]] = sudoku.DIGITS;
+ }
+
+ // For each non-blank square, assign its value in the candidate map and
+ // propigate.
+ for(var square in squares_values_map){
+ var val = squares_values_map[square];
+
+ if(sudoku._in(val, sudoku.DIGITS)){
+ var new_candidates = sudoku._assign(candidate_map, square, val);
+
+ // Fail if we can't assign val to square
+ if(!new_candidates){
+ return false;
+ }
+ }
+ }
+
+ return candidate_map;
+ };
+
+ sudoku._search = function(candidates, reverse){
+ /* Given a map of squares -> candiates, using depth-first search,
+ recursively try all possible values until a solution is found, or false
+ if no solution exists.
+ */
+
+ // Return if error in previous iteration
+ if(!candidates){
+ return false;
+ }
+
+ // Default reverse to false
+ reverse = reverse || false;
+
+ // If only one candidate for every square, we've a solved puzzle!
+ // Return the candidates map.
+ var max_nr_candidates = 0;
+ var max_candidates_square = null;
+ for(var si in SQUARES){
+ var square = SQUARES[si];
+
+ var nr_candidates = candidates[square].length;
+
+ if(nr_candidates > max_nr_candidates){
+ max_nr_candidates = nr_candidates;
+ max_candidates_square = square;
+ }
+ }
+ if(max_nr_candidates === 1){
+ return candidates;
+ }
+
+ // Choose the blank square with the fewest possibilities > 1
+ var min_nr_candidates = 10;
+ var min_candidates_square = null;
+ for(si in SQUARES){
+ var square = SQUARES[si];
+
+ var nr_candidates = candidates[square].length;
+
+ if(nr_candidates < min_nr_candidates && nr_candidates > 1){
+ min_nr_candidates = nr_candidates;
+ min_candidates_square = square;
+ }
+ }
+
+ // Recursively search through each of the candidates of the square
+ // starting with the one with fewest candidates.
+
+ // Rotate through the candidates forwards
+ var min_candidates = candidates[min_candidates_square];
+ if(!reverse){
+ for(var vi in min_candidates){
+ var val = min_candidates[vi];
+
+ // TODO: Implement a non-rediculous deep copy function
+ var candidates_copy = JSON.parse(JSON.stringify(candidates));
+ var candidates_next = sudoku._search(
+ sudoku._assign(candidates_copy, min_candidates_square, val)
+ );
+
+ if(candidates_next){
+ return candidates_next;
+ }
+ }
+
+ // Rotate through the candidates backwards
+ } else {
+ for(var vi = min_candidates.length - 1; vi >= 0; --vi){
+ var val = min_candidates[vi];
+
+ // TODO: Implement a non-rediculous deep copy function
+ var candidates_copy = JSON.parse(JSON.stringify(candidates));
+ var candidates_next = sudoku._search(
+ sudoku._assign(candidates_copy, min_candidates_square, val),
+ reverse
+ );
+
+ if(candidates_next){
+ return candidates_next;
+ }
+ }
+ }
+
+ // If we get through all combinations of the square with the fewest
+ // candidates without finding an answer, there isn't one. Return false.
+ return false;
+ };
+
+ sudoku._assign = function(candidates, square, val){
+ /* Eliminate all values, *except* for `val`, from `candidates` at
+ `square` (candidates[square]), and propagate. Return the candidates map
+ when finished. If a contradiciton is found, return false.
+
+ WARNING: This will modify the contents of `candidates` directly.
+ */
+
+ // Grab a list of canidates without 'val'
+ var other_vals = candidates[square].replace(val, "");
+
+ // Loop through all other values and eliminate them from the candidates
+ // at the current square, and propigate. If at any point we get a
+ // contradiction, return false.
+ for(var ovi in other_vals){
+ var other_val = other_vals[ovi];
+
+ var candidates_next =
+ sudoku._eliminate(candidates, square, other_val);
+
+ if(!candidates_next){
+ //console.log("Contradiction found by _eliminate.");
+ return false;
+ }
+ }
+
+ return candidates;
+ };
+
+ sudoku._eliminate = function(candidates, square, val){
+ /* Eliminate `val` from `candidates` at `square`, (candidates[square]),
+ and propagate when values or places <= 2. Return updated candidates,
+ unless a contradiction is detected, in which case, return false.
+
+ WARNING: This will modify the contents of `candidates` directly.
+ */
+
+ // If `val` has already been eliminated from candidates[square], return
+ // with candidates.
+ if(!sudoku._in(val, candidates[square])){
+ return candidates;
+ }
+
+ // Remove `val` from candidates[square]
+ candidates[square] = candidates[square].replace(val, '');
+
+ // If the square has only candidate left, eliminate that value from its
+ // peers
+ var nr_candidates = candidates[square].length;
+ if(nr_candidates === 1){
+ var target_val = candidates[square];
+
+ for(var pi in SQUARE_PEERS_MAP[square]){
+ var peer = SQUARE_PEERS_MAP[square][pi];
+
+ var candidates_new =
+ sudoku._eliminate(candidates, peer, target_val);
+
+ if(!candidates_new){
+ return false;
+ }
+ }
+
+ // Otherwise, if the square has no candidates, we have a contradiction.
+ // Return false.
+ } if(nr_candidates === 0){
+ return false;
+ }
+
+ // If a unit is reduced to only one place for a value, then assign it
+ for(var ui in SQUARE_UNITS_MAP[square]){
+ var unit = SQUARE_UNITS_MAP[square][ui];
+
+ var val_places = [];
+ for(var si in unit){
+ var unit_square = unit[si];
+ if(sudoku._in(val, candidates[unit_square])){
+ val_places.push(unit_square);
+ }
+ }
+
+ // If there's no place for this value, we have a contradition!
+ // return false
+ if(val_places.length === 0){
+ return false;
+
+ // Otherwise the value can only be in one place. Assign it there.
+ } else if(val_places.length === 1){
+ var candidates_new =
+ sudoku._assign(candidates, val_places[0], val);
+
+ if(!candidates_new){
+ return false;
+ }
+ }
+ }
+
+ return candidates;
+ };
+
+
+ // Square relationships
+ // -------------------------------------------------------------------------
+ // Squares, and their relationships with values, units, and peers.
+
+ sudoku._get_square_vals_map = function(board){
+ /* Return a map of squares -> values
+ */
+ var squares_vals_map = {};
+
+ // Make sure `board` is a string of length 81
+ if(board.length != SQUARES.length){
+ throw "Board/squares length mismatch.";
+
+ } else {
+ for(var i in SQUARES){
+ squares_vals_map[SQUARES[i]] = board[i];
+ }
+ }
+
+ return squares_vals_map;
+ };
+
+ sudoku._get_square_units_map = function(squares, units){
+ /* Return a map of `squares` and their associated units (row, col, box)
+ */
+ var square_unit_map = {};
+
+ // For every square...
+ for(var si in squares){
+ var cur_square = squares[si];
+
+ // Maintain a list of the current square's units
+ var cur_square_units = [];
+
+ // Look through the units, and see if the current square is in it,
+ // and if so, add it to the list of of the square's units.
+ for(var ui in units){
+ var cur_unit = units[ui];
+
+ if(cur_unit.indexOf(cur_square) !== -1){
+ cur_square_units.push(cur_unit);
+ }
+ }
+
+ // Save the current square and its units to the map
+ square_unit_map[cur_square] = cur_square_units;
+ }
+
+ return square_unit_map;
+ };
+
+ sudoku._get_square_peers_map = function(squares, units_map){
+ /* Return a map of `squares` and their associated peers, i.e., a set of
+ other squares in the square's unit.
+ */
+ var square_peers_map = {};
+
+ // For every square...
+ for(var si in squares){
+ var cur_square = squares[si];
+ var cur_square_units = units_map[cur_square];
+
+ // Maintain list of the current square's peers
+ var cur_square_peers = [];
+
+ // Look through the current square's units map...
+ for(var sui in cur_square_units){
+ var cur_unit = cur_square_units[sui];
+
+ for(var ui in cur_unit){
+ var cur_unit_square = cur_unit[ui];
+
+ if(cur_square_peers.indexOf(cur_unit_square) === -1 &&
+ cur_unit_square !== cur_square){
+ cur_square_peers.push(cur_unit_square);
+ }
+ }
+ }
+
+ // Save the current square an its associated peers to the map
+ square_peers_map[cur_square] = cur_square_peers;
+ }
+
+ return square_peers_map;
+ };
+
+ sudoku._get_all_units = function(rows, cols){
+ /* Return a list of all units (rows, cols, boxes)
+ */
+ var units = [];
+
+ // Rows
+ for(var ri in rows){
+ units.push(sudoku._cross(rows[ri], cols));
+ }
+
+ // Columns
+ for(var ci in cols){
+ units.push(sudoku._cross(rows, cols[ci]));
+ }
+
+ // Boxes
+ var row_squares = ["ABC", "DEF", "GHI"];
+ var col_squares = ["123", "456", "789"];
+ for(var rsi in row_squares){
+ for(var csi in col_squares){
+ units.push(sudoku._cross(row_squares[rsi], col_squares[csi]));
+ }
+ }
+
+ return units;
+ };
+
+
+ // Conversions
+ // -------------------------------------------------------------------------
+ sudoku.board_string_to_grid = function(board_string){
+ /* Convert a board string to a two-dimensional array
+ */
+ var rows = [];
+ var cur_row = [];
+ for(var i in board_string){
+ cur_row.push(board_string[i]);
+ if(i % 9 == 8){
+ rows.push(cur_row);
+ cur_row = [];
+ }
+ }
+ return rows;
+ };
+
+ sudoku.board_grid_to_string = function(board_grid){
+ /* Convert a board grid to a string
+ */
+ var board_string = "";
+ for(var r = 0; r < 9; ++r){
+ for(var c = 0; c < 9; ++c){
+ board_string += board_grid[r][c];
+ }
+ }
+ return board_string;
+ };
+
+
+ // Utility
+ // -------------------------------------------------------------------------
+
+ sudoku.print_board = function(board){
+ /* Print a sudoku `board` to the console.
+ */
+
+ // Assure a valid board
+ var report = sudoku.validate_board(board);
+ if(report !== true){
+ throw report;
+ }
+
+ var V_PADDING = " "; // Insert after each square
+ var H_PADDING = '\n'; // Insert after each row
+
+ var V_BOX_PADDING = " "; // Box vertical padding
+ var H_BOX_PADDING = '\n'; // Box horizontal padding
+
+ var display_string = "";
+
+ for(var i in board){
+ var square = board[i];
+
+ // Add the square and some padding
+ display_string += square + V_PADDING;
+
+ // Vertical edge of a box, insert v. box padding
+ if(i % 3 === 2){
+ display_string += V_BOX_PADDING;
+ }
+
+ // End of a line, insert horiz. padding
+ if(i % 9 === 8){
+ display_string += H_PADDING;
+ }
+
+ // Horizontal edge of a box, insert h. box padding
+ if(i % 27 === 26){
+ display_string += H_BOX_PADDING;
+ }
+ }
+
+ console.log(display_string);
+ };
+
+ sudoku.validate_board = function(board){
+ /* Return if the given `board` is valid or not. If it's valid, return
+ true. If it's not, return a string of the reason why it's not.
+ */
+
+ // Check for empty board
+ if(!board){
+ return "Empty board";
+ }
+
+ // Invalid board length
+ if(board.length !== NR_SQUARES){
+ return "Invalid board size. Board must be exactly " + NR_SQUARES +
+ " squares.";
+ }
+
+ // Check for invalid characters
+ for(var i in board){
+ if(!sudoku._in(board[i], sudoku.DIGITS) && board[i] !== sudoku.BLANK_CHAR){
+ return "Invalid board character encountered at index " + i +
+ ": " + board[i];
+ }
+ }
+
+ // Otherwise, we're good. Return true.
+ return true;
+ };
+
+ sudoku._cross = function(a, b){
+ /* Cross product of all elements in `a` and `b`, e.g.,
+ sudoku._cross("abc", "123") ->
+ ["a1", "a2", "a3", "b1", "b2", "b3", "c1", "c2", "c3"]
+ */
+ var result = [];
+ for(var ai in a){
+ for(var bi in b){
+ result.push(a[ai] + b[bi]);
+ }
+ }
+ return result;
+ };
+
+ sudoku._in = function(v, seq){
+ /* Return if a value `v` is in sequence `seq`.
+ */
+ return seq.indexOf(v) !== -1;
+ };
+
+ sudoku._first_true = function(seq){
+ /* Return the first element in `seq` that is true. If no element is
+ true, return false.
+ */
+ for(var i in seq){
+ if(seq[i]){
+ return seq[i];
+ }
+ }
+ return false;
+ };
+
+ sudoku._shuffle = function(seq){
+ /* Return a shuffled version of `seq`
+ */
+
+ // Create an array of the same size as `seq` filled with false
+ var shuffled = [];
+ for(var i = 0; i < seq.length; ++i){
+ shuffled.push(false);
+ }
+
+ for(var i in seq){
+ var ti = sudoku._rand_range(seq.length);
+
+ while(shuffled[ti]){
+ ti = (ti + 1) > (seq.length - 1) ? 0 : (ti + 1);
+ }
+
+ shuffled[ti] = seq[i];
+ }
+
+ return shuffled;
+ };
+
+ sudoku._rand_range = function(max, min){
+ /* Get a random integer in the range of `min` to `max` (non inclusive).
+ If `min` not defined, default to 0. If `max` not defined, throw an
+ error.
+ */
+ min = min || 0;
+ if(max){
+ return Math.floor(Math.random() * (max - min)) + min;
+ } else {
+ throw "Range undefined";
+ }
+ };
+
+ sudoku._strip_dups = function(seq){
+ /* Strip duplicate values from `seq`
+ */
+ var seq_set = [];
+ var dup_map = {};
+ for(var i in seq){
+ var e = seq[i];
+ if(!dup_map[e]){
+ seq_set.push(e);
+ dup_map[e] = true;
+ }
+ }
+ return seq_set;
+ };
+
+ sudoku._force_range = function(nr, max, min){
+ /* Force `nr` to be within the range from `min` to, but not including,
+ `max`. `min` is optional, and will default to 0. If `nr` is undefined,
+ treat it as zero.
+ */
+ min = min || 0
+ nr = nr || 0
+ if(nr < min){
+ return min;
+ }
+ if(nr > max){
+ return max;
+ }
+ return nr
+ }
+
+ // Initialize library after load
+ initialize();
+
+// Pass whatever the root object is, lsike 'window' in browsers
+})(this);
\ No newline at end of file
diff --git a/script.js b/script.js
index 006fb90..85065b8 100644
--- a/script.js
+++ b/script.js
@@ -235,6 +235,20 @@ const projects = [
link: "./Word Scramble/index.html",
image: "https://dictionary.cambridge.org/external/images/wordscramble-og-image.png"
},
+ {
+ title: "Snake Game",
+ discription:
+ "Its a basics Javascript snake game using DOM Event.",
+ link: "./Snake_Game/index.html",
+ image: "https://w7.pngwing.com/pngs/543/374/png-transparent-snake-2000-classic-nokia-game-slither-worm-snake-a-classic-snake-game-classic-game-snake-ii-snake-food-animals-grass-thumbnail.png"
+ },
+ {
+ title: "Sudoku Game",
+ discription:
+ "Sudoku Game game made using HTML, CSS and JS",
+ link: "./Sudoku Game/index.html",
+ image: "./Sudoku Game/bozhin-karaivanov-yqcWOAHH1Rs-unsplash.jpg"
+ },
{
title: "Background Color Changer",
discription: