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 @@
+
+
+
+
+
+
+
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);
+ }
+})();