diff --git a/README.md b/README.md new file mode 100644 index 0000000..4ea2fbf --- /dev/null +++ b/README.md @@ -0,0 +1,62 @@ +# nonogram-puzzle + +You'll be making a nonogram puzzle (Hanjie, Number Grid, Pi-Cross, etc) and allow the user to play the game by filling, unfilling, or clearing tiles of a nonogram puzzle. You do not need to know how these puzzles work to complete the project. + +## Objective + +Complete the UI of a nonogram puzzle. Practice DOM manipulation using JavaScript by completing several functions. + +We have provided the HTML (```project.html```) and CSS (```project.css```) that you will need for this project. You will be writing JavaScript code in a file called ```project.js``` and make it possible to play the puzzle. + +## Prerequisites + +To complete this project, students should have the following: +* Basic understanding of JS (arrays, objects, for loops, functions, if statements, this) + +## Your Challenge + +### Getting started + +1. Download this project from GitHub. + +2. Open the JavaScript file (```project.js```). You will be writing JavaScript code here. + +3. Open ```project.html``` on your web browser to understand what you will be adding functionality to. + +### Part I: Make an alert pop up when a user clicks a tile + +If a user clicks on any tile, an alert pops up with a message. Complete the function ```setUpTiles``` by: + +1. Selecting every tile in the grid and implementing an ```onclick``` event handler to each tile. + +(Hint: Every tile in the grid has the class ```.box```) + +2. If any tile is clicked on, an alert pops up with the message ***"You clicked a tile!"***. Use the ```alert``` function. + +### Part II: Make a single tile turn black when its clicked + +If a user clicks on any tile, it will turn black and become filled. You can complete this by updating and completing two functions: + +1. Complete the function ```changeBoxMark``` so that a single tile is filled in when a user clicks on it. There is a class, ```.filled```, that handles the styling for you in the ```css``` file. + +(Hint: Utilize the function's ```this``` keyword.) + +2. Update the function ```setUpTiles``` so that the ```changeBoxMark``` function is called whenever a single tile is clicked on. You should also remove the alert pop up in ```setUpTiles``` function. + +### Part III: Implement fill toggling + +If a user clicks on a white tile, it will turn black (or become filled). If a user clicks a black tile, it will turn white (or become unfilled). Modify your ```changeBoxMark``` function so that toggling between unfilled and filled tiles is possible. + +1. You will need to implement ```if-else``` statements in the ```changeBoxMark``` function to change black tiles to white tiles and vice versa. There is no "unfilled" class for the tiles. You can clear a filled tile by simply removing the ```.filled``` class. + +### Part IV: Add functionality to the "Clear" button + +When the "Clear" button is clicked, the user will be asked to confirm their choice and if the choice is "OK" all filled tiles will be unfilled. + +1. Complete the function ```clearPuzzle``` by selecting every tile and removing the class ```.filled``` + +(Hint: Every tile in the grid has the class ```.box```) + +2. Add a ```confirm``` message in the function ```clearPuzzle``` so that the user has a second chance to decide if they want to clear their tiles. The message should say ***"Are you sure you want to clear the puzzle?"***. The tiles will clear only if the users confirms ```OK```. + +Original project made by Paul Cleverdon and his team of developers (2018). diff --git a/project.css b/project.css new file mode 100644 index 0000000..6731088 --- /dev/null +++ b/project.css @@ -0,0 +1,121 @@ +/* + * This is the stylesheet for Nonogram Puzzle, adapted from a project I completed when I was a student (just like you!) + * + * Feel free to dig around after you are done with the JavaScript practice. + * Most of the things here should look familiar and can be changed to create nonogram puzzles of different sizes. + * + * - Michelle + */ + +body { + font-family: Helvetica, Arial, sans-serif; + font-size: 10pt; + text-align: center; +} + +h1 { + font-size: 26pt; + margin-bottom: 40px; +} + +.box { + border: 1px solid #111; +} + +.box:hover { + box-shadow: 0px 0px 3px 3px #111; + cursor: pointer; +} + +.box, .col-num-box, .row-num-box { + line-height: 24pt; +} + +.box, .col-num-box, #empty-square, #left-nums, #top-nums { + float: left; +} + +.clear, #left-nums, #puzzle { + clear: both; +} + +.col-num-box, #top-nums { + border-left: 1px solid black; + border-right: 1px solid black; +} + +#empty-square { + border-top: 3px solid black; + background-color: #111; +} + +#clear { + font-size: 18pt; + margin-top: 20px; + padding: 5px; +} + +.filled { + background-color: #000; +} + +#grid { + border: 1px solid #000; + border-right: 2px solid #000; + display: table; +} + +#puzzle { + display: inline-block; +} + +.left-row, .row-num-box { + float: right; +} + +#left-nums, .left-row { + border-top: 1px solid #000; + border-bottom: 1px solid #000; +} + +#left-nums, #empty-square { + border-left: 3px solid #000; +} + +#top-nums { + border-top: 3px solid #000; +} + +.thick-right-border { + border-right: 2px solid black; +} + +.thick-top-border { + border-top: 2px solid black; +} + +.horizontal-divider { + border-bottom: 2px solid black; +} + +.vertical-divider { + border-left: 2px solid black; +} + +.five #left-nums, .five .left-row, .five #empty-square { + width: 210px; +} + +.five .box, .five .col-num-box, .five .row-num-box { + width: 70px; + height: 70px; + line-height: 70px; +} + +.five #empty-square { + height: 210px; +} + +.five { + font-size: 18pt; +} diff --git a/project.html b/project.html new file mode 100644 index 0000000..15116bd --- /dev/null +++ b/project.html @@ -0,0 +1,105 @@ + + + + + + Nonograms! + + + + +

Nonogram Puzzle!

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
1
+
+
+
5
+
1
+
5
+
+
3
+
+
+
+
+
1
+
1
+
1
+
+
+
1
+
1
+
+
+
1
+
3
+
+
+
1
+
1
+
1
+
+
+
1
+
1
+
1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+ + diff --git a/project.js b/project.js new file mode 100644 index 0000000..5eec835 --- /dev/null +++ b/project.js @@ -0,0 +1,70 @@ +/* + * NAME: YOUR NAME HERE + * + * DATE: December 18, 2021 + * + * FILE: project.js + * + * DESCRIPTION: + * Starter file to help get you started with Nonogram Puzzle. + * + */ + +(function() { + "use strict"; + + /* + * DO NOT DELETE THIS CODE + * + * Sets up the various event listeners on the page, including + * click behavior for each puzzle grid square and the + * functionality for clearing a puzzle. + */ + window.onload = function() { + setUpTiles(); + id("clear").onclick = clearPuzzle; + }; + + /* BEGIN WRITING YOUR CODE BELOW */ + + /* + * Write comments for this function! + */ + function clearPuzzle() { + + } + + /* + * Write comments for this function! + */ + function changeBoxMark() { + + } + + /* + * Write comments for this function! + */ + function setUpTiles() { + + } + + /* HELPER FUNCTIONS (OPTIONAL) */ + + /** + * Returns the element that has the ID attribute with the specified value. + * @param {string} id - element ID + * @return {object} DOM object of given id. + */ + function id (id) { + return document.getElementById(id); + } + + /** + * Returns the array of elements that match the given CSS selector. + * @param {string} query - CSS query selector + * @return {object[]} array of DOM objects matching the query. + */ + function select (query) { + return document.querySelectorAll(query); + } +})(); diff --git a/solution.js b/solution.js new file mode 100644 index 0000000..603a9f0 --- /dev/null +++ b/solution.js @@ -0,0 +1,86 @@ +/* + * NAME: YOUR NAME HERE + * + * DATE: December 18, 2021 + * + * FILE: solution.js + * + * DESCRIPTION: + * Solution to Part IV of Nonogram Puzzle and + * the working solution for the entire project + * + */ + +(function() { + "use strict"; + + /* + * DO NOT DELETE THIS CODE + * + * Sets up the various event listeners on the page, including + * click behavior for each puzzle grid square and the + * functionality for clearing a puzzle. + */ + window.onload = function() { + setUpTiles(); + id("clear").onclick = clearPuzzle; + }; + + /* BEGIN WRITING YOUR CODE BELOW */ + + /* + * SOLUTION TO PART IV: Add functionality to the "Clear" + * button and a confirm message. + */ + function clearPuzzle() { + if (confirm("Are you sure you want to clear the puzzle?")) { + let tiles = select(".box"); + for (let i = 0; i < tiles.length; i++) { + tiles[i].classList.remove("filled"); + } + } + } + + /* + * SOLUTION FROM PART III: Implement fill toggling + */ + function changeBoxMark() { + if (this.classList.contains("filled")) { + this.classList.remove("filled"); + } else { + this.classList.add("filled"); + } + } + + /* + * SOLUTION TO PART II: Call the changeBoxMark function when a + * tile is clicked. + */ + function setUpTiles() { + let tiles = select(".box"); + for (let i = 0; i < tiles.length; i++) { + let div = tiles[i]; + div.onclick = changeBoxMark; + } + } + + /* HELPER FUNCTIONS (OPTIONAL) */ + + /** + * Returns the element that has the ID attribute with the specified value. + * @param {string} id - element ID + * @return {object} DOM object of given id. + */ + function id (id) { + return document.getElementById(id); + } + + /** + * Returns the array of elements that match the given CSS selector. + * @param {string} query - CSS query selector + * @return {object[]} array of DOM objects matching the query. + */ + function select (query) { + return document.querySelectorAll(query); + } +})(); diff --git a/solution1.js b/solution1.js new file mode 100644 index 0000000..ffbddec --- /dev/null +++ b/solution1.js @@ -0,0 +1,60 @@ +/* + * NAME: YOUR NAME HERE + * + * DATE: December 18, 2021 + * + * FILE: solution1.js + * + * DESCRIPTION: + * Solution to Part I of Nonogram Puzzle + * + */ + +(function() { + "use strict"; + + /* + * DO NOT DELETE THIS CODE + * + * Sets up the various event listeners on the page, including + * click behavior for each puzzle grid square. + */ + window.onload = function() { + setUpTiles(); + }; + + /* BEGIN WRITING YOUR CODE BELOW */ + + /* + * PART I: Make an alert pop up when a user clicks a tile + */ + function setUpTiles() { + let tiles = select(".box"); + for (let i = 0; i < tiles.length; i++) { + let div = tiles[i]; + div.onclick = function() { + alert("You clicked a tile!"); + }; + } + } + + /* HELPER FUNCTIONS (OPTIONAL) */ + + /** + * Returns the element that has the ID attribute with the specified value. + * @param {string} id - element ID + * @return {object} DOM object of given id. + */ + function id (id) { + return document.getElementById(id); + } + + /** + * Returns the array of elements that match the given CSS selector. + * @param {string} query - CSS query selector + * @return {object[]} array of DOM objects matching the query. + */ + function select (query) { + return document.querySelectorAll(query); + } +})(); diff --git a/solution2.js b/solution2.js new file mode 100644 index 0000000..e311a95 --- /dev/null +++ b/solution2.js @@ -0,0 +1,65 @@ +/* + * NAME: YOUR NAME HERE + * + * DATE: December 18, 2021 + * + * FILE: solution2.js + * + * DESCRIPTION: + * Solution to Part II of Nonogram Puzzle + */ + +(function() { + "use strict"; + + /* + * DO NOT DELETE THIS CODE + * + * Sets up the various event listeners on the page, including + * click behavior for each puzzle grid square. + */ + window.onload = function() { + setUpTiles(); + }; + + /* BEGIN WRITING YOUR CODE BELOW */ + + /* + * SOLUTION TO PART II: Make a single tile black when clicked + */ + function changeBoxMark() { + this.classList.add("filled"); + } + + /* + * SOLUTION TO PART II: Call the changeBoxMark function when a + * tile is clicked and remove the alert pop up. + */ + function setUpTiles() { + let tiles = select(".box"); + for (let i = 0; i < tiles.length; i++) { + let div = tiles[i]; + div.onclick = changeBoxMark; + } + } + + /* HELPER FUNCTIONS (OPTIONAL) */ + + /** + * Returns the element that has the ID attribute with the specified value. + * @param {string} id - element ID + * @return {object} DOM object of given id. + */ + function id (id) { + return document.getElementById(id); + } + + /** + * Returns the array of elements that match the given CSS selector. + * @param {string} query - CSS query selector + * @return {object[]} array of DOM objects matching the query. + */ + function select (query) { + return document.querySelectorAll(query); + } +})(); diff --git a/solution3.js b/solution3.js new file mode 100644 index 0000000..7602b3d --- /dev/null +++ b/solution3.js @@ -0,0 +1,70 @@ +/* + * NAME: YOUR NAME HERE + * + * DATE: December 18, 2021 + * + * FILE: solution3.js + * + * DESCRIPTION: + * Solution to Part III of Nonogram Puzzle + * + */ + +(function() { + "use strict"; + + /* + * DO NOT DELETE THIS CODE + * + * Sets up the various event listeners on the page, including + * click behavior for each puzzle grid square. + */ + window.onload = function() { + setUpTiles(); + }; + + /* BEGIN WRITING YOUR CODE BELOW */ + + /* + * SOLUTION TO PART III: Implement fill toggling + */ + function changeBoxMark() { + if (this.classList.contains("filled")) { + this.classList.remove("filled"); + } else { + this.classList.add("filled"); + } + } + + /* + * SOLUTION FROM PART II: Call the changeBoxMark function when a + * tile is clicked. + */ + function setUpTiles() { + let tiles = select(".box"); + for (let i = 0; i < tiles.length; i++) { + let div = tiles[i]; + div.onclick = changeBoxMark; + } + } + + /* HELPER FUNCTIONS (OPTIONAL) */ + + /** + * Returns the element that has the ID attribute with the specified value. + * @param {string} id - element ID + * @return {object} DOM object of given id. + */ + function id (id) { + return document.getElementById(id); + } + + /** + * Returns the array of elements that match the given CSS selector. + * @param {string} query - CSS query selector + * @return {object[]} array of DOM objects matching the query. + */ + function select (query) { + return document.querySelectorAll(query); + } +})();