Can somebody code the following? Data Files needed for the Review Assignments: j
ID: 3702577 • Letter: C
Question
Can somebody code the following?
Data Files needed for the Review Assignments: jpf_hitori_txt.html, jpf_hitori_txt.js, 3 CSS files, 1 JS file, 4 PNG files
The same number cannot be circled more than once in any row or column.
Blocks cannot touch horizontally or vertically, though they may be placed diagonally to one another.
Circled numbers must complete a continuous path throughout the grid; no circled number or group of circled numbers can be isolated from the others by a line of blocks.
Figure 11-51 shows a preview of the Hitori page you will create for Rebecca, with the solution of a sample Hitori puzzle.
Rebecca wants you to create an interface for this puzzle similar to the one you created for the Hanjie puzzle. She already has stored three puzzles in a JavaScript file named jpf_grids3.js, and within that file she has created the following variables:
hitori1Rating through hitori3Rating containing the difficulty ratings of the puzzles
hitori1Numbers through hitori3Numbers containing the numbers in the puzzle grids
hitori1Blocks through hitori3Blocks specifying the location of the blocks in the puzzle grids
Rebecca has provided you with the following functions:
drawHitori(), which writes the HTML code of the puzzle table given the puzzle numbers, location of the puzzle blocks, and the puzzle rating
checkSolution(), which returns an alert box indicating whether the puzzle has been solved
showSolution(), which displays the puzzle solution
Your job will be to complete the application by writing the code that displays the puzzle and provides users with an interface to solve it.
Complete the following:
.4
Insert a command to run the startUp() function when the page is loaded by the browser.
Add the startUp() function, which displays the contents of Puzzle 1 after the page is loaded and sets up the initial event handlers. Within the function, add the following commands:
Change the inner HTML of the element with the ID, “puzzleTitle” to the text “Puzzle 1”.
Call the drawHitori() function using the hitori1Numbers, hitori1Blocks, and hitori1Rating variables as parameter values and store the HTML code returned by the function in the inner HTML of the page element with the ID “puzzle”.
Declare a variable named puzzleButtons referencing the page elements with the class name “puzzles”. Loop through the puzzleButtons object collection and for each button add an event handler that runs the switchPuzzle() function when the button is clicked.
Call the setupPuzzle() function that defines the initial appearance of the first puzzle.
Add an event handler to the Check Solutions button to run the findErrors() function when clicked.
Add an event handler to the Show Solutions button to run the showSolution() function when clicked.
Add the switchPuzzle() function, which switches the page between the three possible Hitori puzzles. Include the event object e as a parameter of the function and add the following commands:
Declare the puzzleID variable equal to the ID of the event object target.
Change the inner HTML of the element with the ID “puzzleTitle” to the value of the value attribute of the event object target.
Create a switch-case structure with the puzzleID variable that loads the appropriate HTML code for each of the three puzzles into the page element with the ID “puzzle”. Use the drawHitori() function to generate the HTML code and assume that puzzleID is limited to the values “puzzle1”, “puzzle2”, and “puzzle3”.
After the switch-case structure, call the setupPuzzle() function to set up the features of the selected puzzle.
Enclose all of the commands in the switchPuzzle() function within an ifstatement that displays a confirm dialog box asking users whether they want to switch puzzles even though their work will be lost. If the confirm dialog box returns a value of true, run the commands within the if statement command block.
Create the setupPuzzle() function to set up the features of the puzzle table. Within the function add the following commands:
Use the querySelectorAll() method to create an object collection of all of the td elements within the hitoriGrid table and save the object collection in the allCells variable.
Create a for loop that loops the allCells object collection and, for each cell, change the background-color style to white, the font color to black, and the border-radius value to 0.
Within the for loop, add a mousedown event listener for each cell in the allCells collection that changes the cell’s appearance depending on whether the Shift key, the Alt key, or no key is pressed by the user. Add the following commands to the anonymous function for the mousedown event:
Change the background color to white, the font color to black, and the border radius to 0 if the user is pressing the Shift key.
Change the background color to black, the font color to white, and the border radius to 0 if the user is pressing the Alt key.
Otherwise, change the background color to rgb(101, 101, 101), the font color to white, and the border radius to 50%.
To avoid inadvertently selecting the text of the table cells, include a command to prevent the default action of the browser in response to the mousedown event.
Rebecca wants a different mouse cursor depending on whether the user is pressing the Shift key, the Alt key, or no key when the mouse pointer moves over a puzzle cell. Within the for loop, add a mouseover event listener for each puzzle cell that runs an anonymous function that
Changes the cursor to the jpf_eraser.png image or the generic cursor named “alias” if the user is pressing the Shift key.
Changes the cursor to the jpf_block.png image or the generic cursor named “cell” if the user is pressing the Alt key.
Otherwise, changes the cursor to the jpf_circle.png image or the generic cursor named “pointer”.
Finally, within the for loop, add an event listener that runs the checkSolution() function in response to the mouseup event to test whether the user has solved the puzzle.
Create the findErrors() function that will highlight incorrect cells by displaying the cell number of an incorrect cell in a red font. Add the following commands:
Create a for loop that goes through all of the cells in the allCells object collection. If the cell belongs to the blocks class but has a background color of rgb(101, 101, 100) or if it belongs to the circles class but has a black background, change the font color to red.
The red font colors should appear only briefly. After the for loop, insert a setTimeout() method with a 1-second interval. Within the setTimeout()method, add an anonymous function that loops through every cell in the allCells collection, changing all cells with a font color of red back to white.
Document your code in the JavaScript file with descriptive comments throughout.
Save your changes to the file and then load jpf_hitori.html in your browser.
Verify that you can switch puzzles by clicking the Puzzle buttons at the top of the page, and that you are prompted to confirm whether you want to change your puzzle. Verify that you can view the complete solution to each puzzle by clicking the Show Solution button.
Verify than you can change a cell to a gray circle by clicking the cell. Verify that you can change a cell to a solid black block by clicking the cell with the Alt key pressed down. Finally, verify that you can restore a cell to black text on a white background by clicking a previously selected cell with the Shift key pressed down.
Verify that the cursor changes shape as you move the mouse pointer over the puzzle cells, changing from a circular cursor to a block cursor when the Alt key is pressed or to an eraser cursor when the Shift key is pressed.
Verify that you can test for errors by clicking the Check Solution button, and that your errors are displayed in a red font for one second.
Solve the first puzzle using the solution provided in Figure 11-51. Verify that you receive a congratulatory message upon successfully completing the puzzle.
You are welcome to solve the second and third puzzles on your own, but they are not part of the assignment.
Explanation / Answer
jpf_hitori.js
"use strict";
var allCells;
// startUp function loads when page loads
window.onload = startUp;
function startUp() {
document.getElementById("puzzleTitle").innerHTML = "Puzzle 1";
document.getElementById("puzzle").innerHTML = drawHitori(hitori1Numbers,hitori1Blocks,hitori1Rating);
var puzzleButtons = document.getElementsByClassName("puzzles");
for (var i = 0; i < puzzleButtons.length; i++) {
puzzleButtons[i].onclick = switchPuzzle;
}
setupPuzzle();
document.getElementById("check").addEventListener("click",findErrors);
document.getElementById("solve").addEventListener("click",showSolution);
}
function switchPuzzle(e) {
if (confirm("You will lose all of your work on the puzzle! Continue?")) {
var puzzleID = this.id;
var puzzleTitle = this.value;
document.getElementById("puzzleTitle").innerHTML = puzzleID;
switch (puzzleID) {
case "puzzle1":
document.getElementById("puzzle").innerHTML =
drawHitori(hitori1Numbers, hitori1Blocks, hitori1Rating);
break;
case "puzzle2":
document.getElementById("puzzle").innerHTML =
drawHitori(hitori2Numbers, hitori2Blocks, hitori2Rating);
break;
case "puzzle3":
document.getElementById("puzzle").innerHTML =
drawHitori(hitori3Numbers, hitori3Blocks, hitori3Rating);
break;
}
setupPuzzle();
}
}
function setupPuzzle() {
var cursorType;
// creating object selection of all td elements
allCells = document.querySelectorAll("table#hitoriGrid td");
for (var i = 0; i < allCells.length; i++ ) {
allCells[i].style.backgroundColor = "white";
allCells[i].style.color = "black";
allCells[i].style.borderRadius = "0";
// Mouse down event listener
allCells[i].addEventListener("mousedown",
function(e) {
if(e.shiftKey) {
e.target.style.backgroundColor = "white";
e.target.style.color = "black";
e.target.style.borderRadius = "0";
}
else if (e.altKey) {
e.target.style.backgroundColor = "black";
e.target.style.color = "white";
e.target.style.borderRadius = "0";
}
else {
e.target.style.backgroundColor = "rgb(101,101,101)";
e.target.style.color = "white";
e.target.style.borderRadius = "50%";
}
e.preventDefault();
});
// window.style = undefined;
// window.style.cursor = cursorType;
document.addEventListener("mouseover",
function(e) {
if(e.shiftKey) {
e.target.style.cursor = "url(images/jpf_eraser.png), alias";
//allCells[i].style.cursor = cursorType;
}
else if (e.altKey) {
e.target.style.cursor = "url(images/jpf_block.png), cell";
//allCells[i].style.cursor = cursorType;
}
else {
e.target.style.cursor = "url(images/jpf_circle.png), pointer";
//allCells[i].style.cursor = cursorType;
}
});
document.addEventListener("mouseup", checkSolution);
}
}
function findErrors() {
for (var i = 0; i < allCells.length;i++) {
if ((allCells[i].className === "blocks" &&
allCells[i].style.backgroundColor === "rgb(101,101,100)")
||
(allCells[i].className === "circles" &&
allCells[i].style.backgroundColor === "black")) {
allCells[i].style.color = "red";
}
}
setTimeout(
function() {
for (var i = 0; i < allCells.length; i++) {
allCells[i].style.color = "white";
}
}
,1000);
}
/* ================================================================= */
function checkSolution() {
/* Set the initial solved state of the puzzle to true */
var solved = true;
for (var i = 0; i < allCells.length; i++) {
var cellColor = allCells[i].style.backgroundColor;
var cellClass = allCells[i].className;
/* A cell is incorrect if it is in the block class and is not black
or in the circle class and is not white */
if ((cellClass == "blocks" && cellColor !== "black") ||
(cellClass == "circles" && cellColor !== "rgb(101, 101, 101)")) {
solved = false;
break;
}
}
/* If solved is still true after the loop, display an alert box */
if (solved) alert("Congratulations! You solved the puzzle!");
}
function showSolution() {
for (var i = 0; i < allCells.length; i++) {
allCells[i].style.color = "";
allCells[i].style.backgroundColor = "";
allCells[i].style.borderRadius = "";
};
}
function drawHitori(numbers, blocks, rating) {
/* Initial HTML String for the Hitori Puzzle */
var htmlString = "";
var totalRows = numbers.length;
var totalCols = numbers[0].length;
htmlString = "<table id='hitoriGrid'>";
htmlString += "<caption>" + rating + "</caption>";
for (var i = 0; i < totalRows; i++) {
htmlString += "<tr>";
for (var j = 0; j < totalCols; j++) {
if (blocks[i][j] == "#") htmlString += "<td class='blocks'>"
else htmlString += "<td class='circles'>";
htmlString += numbers[i][j];
htmlString += "</td>";
}
htmlString += "</tr>";
}
htmlString += "</table>";
return htmlString;
}